├── LICENSE.DJS ├── LICENSE.LamJS ├── LICENSE.Z3 ├── README ├── bin ├── z3-linux-v2.16 ├── z3-linux-v3.2 ├── z3-linux-v4.0 ├── z3-linux-v4.1 ├── z3-osx-v3.2 └── z3-osx-v4.0 ├── prims ├── basics.dref ├── js_natives.dref ├── less-sugar │ ├── js_natives.dref │ └── objects.dref ├── objects.dref ├── other │ ├── basics-curried.dref │ ├── objectsLite.dref │ ├── pervasives.ml │ ├── prelude.js │ ├── preludeLite.js │ ├── theory-2.lisp │ ├── theory-int-2.lisp │ ├── theory-int.smtc │ └── theory.smtc └── theory.smt2 ├── scripts ├── gen-benchmark-linecounts-2.py ├── gen-benchmark-linecounts-3.py ├── gen-benchmark-linecounts-sep2012.py ├── gen-benchmark-linecounts.py ├── gen-benchmark-time-sep2012.py ├── gen-benchmark-time.py ├── run-all-djs-lite.sh ├── run-all-djs.sh ├── run-all-dref.sh ├── run-tests-arrays.sh └── run-tests.py ├── src ├── BNstats │ ├── bNstats.ml │ └── bNstats.mli ├── LamJS │ ├── exprjs_syntax.ml │ ├── exprjs_syntax.mli │ ├── formatExt.ml │ ├── formatExt.mli │ ├── javaScript.ml │ ├── javaScript.mli │ ├── javaScript_lexer.mll │ ├── javaScript_parser.mly │ ├── javaScript_syntax.ml │ ├── javaScript_syntax.mli │ ├── lambdajs.ml │ ├── lambdajs.mli │ ├── lambdajs_syntax.ml │ ├── lambdajs_syntax.mli │ ├── mapExt.ml │ ├── mapExt.mli │ ├── prelude.ml │ ├── prelude.mli │ ├── setExt.ml │ └── setExt.mli ├── Makefile ├── anf.ml ├── anf.mli ├── cnf.ml ├── cnf.mli ├── djsDesugar.ml ├── djsDesugar.mli ├── djsDesugar2.ml ├── djsDesugar2.mli ├── lang.ml ├── langLexer.mll ├── langParser.mly ├── langParser2.mly ├── langUtils.ml ├── langUtils.mli ├── log.ml ├── main.ml ├── parseUtils.ml ├── parseUtils.mli ├── settings.ml ├── sub.ml ├── sub.mli ├── tcDref.ml ├── tcDref.mli ├── tcDref2.ml ├── tcDref2.mli ├── tcDref3.ml ├── tcDref3.mli ├── tcUtils.ml ├── tcUtils.mli ├── utils.ml ├── wf.ml ├── wf.mli ├── zzz.ml └── zzz.mli └── tests ├── apr-benchmarks ├── un │ ├── access-binary-trees.js │ ├── access-nbody.js │ ├── counter.js │ ├── dispatch.js │ ├── functional.js │ ├── negate.js │ ├── parts.js │ ├── passengers.js │ ├── prototypal.js │ ├── pseudoclassical.js │ ├── splay.js │ ├── string-fasta.js │ └── typeOf.js ├── v0 │ ├── access-binary-trees.js │ ├── access-nbody.js │ ├── counter.js │ ├── dispatch.js │ ├── functional.js │ ├── negate.js │ ├── parts.js │ ├── passengers.js │ ├── prototypal.js │ ├── pseudoclassical.js │ ├── splay.js │ ├── string-fasta.js │ └── typeOf.js └── v1 │ ├── access-binary-trees.js │ ├── access-nbody.js │ ├── counter.js │ ├── dispatch.js │ ├── functional.js │ ├── negate.js │ ├── parts.js │ ├── passengers.js │ ├── prototypal.js │ ├── pseudoclassical.js │ ├── splay.js │ ├── string-fasta.js │ └── typeOf.js ├── djs ├── arrays │ ├── andArray00.js │ ├── andArray01.js │ ├── isArray00.js │ ├── matrix00.js │ ├── matrix01.js │ ├── matrix02.js │ ├── quickprop00.js │ ├── simple00.js │ ├── sumArray00.js │ ├── sumArray01.js │ ├── sumArray02.js │ ├── test00-inf.js │ ├── test00.js │ ├── test01-inf.js │ ├── test01.js │ ├── test02-inf.js │ ├── test02.js │ ├── test03-inf.js │ ├── test03.js │ ├── test04-inf.js │ ├── test04.js │ ├── test05-inf.js │ ├── test05.js │ ├── test06.js │ ├── test07-inf.js │ ├── test07.js │ ├── test08.js │ ├── xx_andArray00.js │ ├── xx_matrix02.js │ ├── xx_sumArray00.js │ └── xx_sumArray01.js ├── dec-draft │ ├── 0-basics.js │ ├── 1-negate.js │ ├── 2-counter.js │ ├── 3-dispatch.js │ ├── 4-prototypal.js │ ├── 5-pseudoclassical.js │ ├── 6-functional.js │ └── 7-parts.js ├── forin │ ├── makeCumulative00.js │ ├── makeCumulative01.js │ ├── sumBindings00.js │ ├── xx_forin00.js │ └── xx_make01.js ├── loops │ ├── test00-augment.js │ ├── test00.js │ ├── test01.js │ ├── whileFalse0.js │ ├── whileFalse2.js │ ├── whileFalse3.js │ ├── whileFalse4.js │ └── xx_00.js ├── macros │ ├── test00.js │ ├── test01.js │ ├── test02.js │ ├── test03.js │ ├── test04.js │ └── test05.js ├── misc │ ├── ab00.js │ ├── access00.js │ ├── access01.js │ ├── access02.js │ ├── access03.js │ ├── id.js │ ├── if00.js │ ├── negate00.js │ ├── negate01.js │ ├── negate02.js │ ├── onto00.js │ ├── toNum00.js │ ├── unreachable00.js │ ├── unreachable01.js │ ├── xx_id.js │ ├── xx_string-fasta.js │ └── xx_typedDs00.js ├── objects │ ├── ctor00.js │ ├── ctor01.js │ ├── ctor02.js │ ├── ctor03.js │ ├── family00.js │ ├── get00.js │ ├── hasBool00.js │ ├── hasOwnProp00.js │ ├── localInf00.js │ ├── mem00.js │ ├── mem01.js │ ├── ossugar00.js │ ├── read00.js │ ├── simple00.js │ ├── undef00.js │ └── xx_ctor00.js ├── oopsla12 │ ├── access-binary-trees.js │ ├── access-nbody.js │ ├── counter.js │ ├── dispatch.js │ ├── functional.js │ ├── negate.js │ ├── parts.js │ ├── passengers.js │ ├── prototypal.js │ ├── pseudoclassical.js │ ├── splay.js │ ├── string-fasta.js │ └── typeOf.js ├── operators │ ├── and00.js │ ├── assert00.js │ ├── assert01.js │ ├── betterTypeof00.js │ ├── betterTypeof01.js │ ├── betterTypeof02.js │ ├── eek00.js │ ├── eek01.js │ ├── if00.js │ ├── num00.js │ ├── num01.js │ ├── or00.js │ ├── plus00.js │ ├── plus01.js │ ├── typeof00.js │ ├── typeof01.js │ ├── weirdNumConsts.js │ ├── xx_and00.js │ ├── xx_integer00.js │ └── xx_plus00.js ├── recursion │ ├── fact00.js │ ├── fact01.js │ ├── looper00.js │ ├── looper01.js │ ├── looper02.js │ ├── rec00.js │ ├── rec01.js │ ├── xx_loop00.js │ └── xx_loop01.js ├── smarterds │ ├── ctor00.js │ ├── ctor01.js │ ├── len00-1.js │ ├── len00.js │ ├── len01-1.js │ ├── obj00.js │ ├── obj01.js │ ├── obj02.js │ ├── obj03.js │ ├── test00.js │ ├── test01.js │ ├── test02.js │ ├── thawinf00.js │ ├── thawinf01.js │ ├── thawinf02.js │ ├── thawinf03.js │ ├── thawinf04.js │ ├── thawinf05.js │ ├── toplevel00.js │ ├── toplevel01.js │ ├── xx_len01.js │ ├── xx_obj02.js │ └── xx_test02.js ├── smartertc │ ├── cloinvar00.js │ ├── cloinvar01.js │ ├── cloinvar02.js │ ├── cloinvar03.js │ ├── cloinvar04.js │ ├── cloinvar05.js │ ├── cloinvar06.js │ ├── xx_cloinvar0.js │ └── xx_cloinvar00.js └── weak │ ├── branch.js │ ├── passenger00.js │ ├── passenger01.js │ ├── splay00.js │ ├── splay01.js │ ├── splay02.js │ ├── splay03.js │ ├── sumFields00.js │ ├── test00.js │ ├── test01.js │ ├── this00.js │ ├── tree00.js │ ├── tree01.js │ ├── tree02.js │ ├── xx_branch.js │ ├── xx_splay00.js │ ├── xx_splay01.js │ ├── xx_sumFields00.js │ └── xx_test00.js ├── djsLite ├── arrays │ ├── test00.js │ ├── test01.js │ ├── test02-inf.js │ ├── test02.js │ └── test03.js └── ecoop │ ├── basics.js │ ├── counter.js │ ├── dispatch.js │ └── negate.js ├── functional ├── arrays │ ├── __arrays.ml │ ├── lit00.ml │ ├── lit01.ml │ ├── test00.ml │ ├── test01.ml │ ├── test02.ml │ ├── test03.ml │ └── test04.ml ├── macros │ ├── arrow00.dref │ ├── arrow01.dref │ ├── type00.dref │ ├── type01.dref │ └── xx_type01.dref ├── numbers │ ├── la00.ml │ └── test00.ml ├── quicktypes │ ├── __ops.ml │ ├── bool00.dref │ ├── int00.dref │ ├── int01.dref │ ├── recd00.dref │ ├── recd01.dref │ ├── recd02.dref │ ├── xx_recd00.dref │ ├── xx_recd02.dref │ └── xx_recd03.dref ├── simple │ ├── box00.dref │ ├── box01.dref │ ├── box02.dref │ └── id.dref └── underscore │ └── xx_test00.ml └── imperative ├── arrays ├── __arrays.dref ├── elem_test00.dref ├── test00.dref └── xx_test00.dref ├── control ├── test00.ml ├── test01.ml ├── test02.ml └── xx_test01.ml ├── inference ├── quickthaw00.dref ├── quickthaw01.dref ├── test00.dref └── xx_quickthaw01.dref ├── objects ├── sugar00.dref ├── test00.dref ├── test01.dref ├── test02.dref └── test03.dref ├── quicktypes ├── elem_obj00.dref ├── elem_obj02.dref ├── obj00.dref ├── obj01.dref ├── obj02.dref ├── obj03.dref ├── obj04.dref ├── obj05.dref ├── xx_obj03.dref └── xx_obj05.dref ├── recursion └── test00.dref ├── simple ├── conditional00.dref ├── deref00.dref ├── deref01.dref ├── deref02.dref ├── negate0.dref ├── negate1.dref ├── newref00.dref ├── noop0.dref ├── ref00.dref ├── writeback0.dref └── xx_ref00.dref └── weak ├── null00.dref ├── test00.dref ├── test01.dref ├── test02.dref ├── test03.dref ├── test04.dref ├── xx_null00.dref ├── xx_test00.dref ├── xx_test01.dref ├── xx_test02.dref └── xx_test03.dref /LICENSE.DJS: -------------------------------------------------------------------------------- 1 | Copyright (c) <2011>, 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /bin/z3-linux-v2.16: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravichugh/djs/c4a13e06adb3e0945f39966523a4d944448c1941/bin/z3-linux-v2.16 -------------------------------------------------------------------------------- /bin/z3-linux-v3.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravichugh/djs/c4a13e06adb3e0945f39966523a4d944448c1941/bin/z3-linux-v3.2 -------------------------------------------------------------------------------- /bin/z3-linux-v4.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravichugh/djs/c4a13e06adb3e0945f39966523a4d944448c1941/bin/z3-linux-v4.0 -------------------------------------------------------------------------------- /bin/z3-linux-v4.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravichugh/djs/c4a13e06adb3e0945f39966523a4d944448c1941/bin/z3-linux-v4.1 -------------------------------------------------------------------------------- /bin/z3-osx-v3.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravichugh/djs/c4a13e06adb3e0945f39966523a4d944448c1941/bin/z3-osx-v3.2 -------------------------------------------------------------------------------- /bin/z3-osx-v4.0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravichugh/djs/c4a13e06adb3e0945f39966523a4d944448c1941/bin/z3-osx-v4.0 -------------------------------------------------------------------------------- /prims/other/objectsLite.dref: -------------------------------------------------------------------------------- 1 | 2 | (***** Lite Objects / Arrays **************************************************) 3 | 4 | val getPropLite :: 5 | {(and (v :: [; L; H] 6 | _:[_:Ref(L), k:Str] / [H ++ L |-> d:{Dict|(has v k)}] 7 | -> {(= v (sel d k))} / same) 8 | (v :: [A; L; H] 9 | _:[_:Ref(L), i:{Str|(= v "length")}] / [H ++ L |-> a:Arr(A)] 10 | -> {Int|(implies (packed a) (= v (len a)))} / same))} 11 | 12 | val getIdxLite :: [A;L] _:[_:Ref(L), i:Int] / [L |-> a:Arr(A)] -> 13 | {(ite (and (packed a) (>= i 0)) 14 | (ite (< i (len a)) (and (v::A) (= v (sel a i))) (= v undefined)) 15 | (or (v::A) (= v undefined)))} / same 16 | 17 | val getElemLite :: {(and (type getPropLite) (type getIdxLite))} 18 | 19 | val setPropLite :: 20 | {(and (v :: [;L] 21 | _:[_:Ref(L), k:Str, y:Top] / [L |-> d:Dict] 22 | -> {(= v y)} / [L |-> d':{(= v (upd d k y))}]) 23 | (v :: [A;L] 24 | _:[_:Ref(L), k:{(= v "length")}, n:Int] / [L |-> a:Arr(A)] 25 | -> {(= v n)} 26 | / [L |-> a':{(and (v::Arr(A)) 27 | (implies (and (packed a) (<= n (len a))) 28 | (and (packed v) (= (len v) n))))}]))} 29 | 30 | val setIdxLite :: [A;L] _:[_:Ref(L), i:Int, y:A] / [L |-> a:Arr(A)] -> 31 | {(= v y)} / 32 | [L |-> a':{(and (v::Arr(A)) 33 | (= (sel a i) y) 34 | (implies (and (packed a) (>= i 0) (< i (len a))) 35 | (and (packed v) (= (len v) (len a)))) 36 | (implies (and (packed a) (= i (len a))) 37 | (and (packed v) (= (len v) (+ 1 (len a))))))}] 38 | 39 | val setElemLite :: {(and (type setPropLite) (type setIdxLite))} 40 | 41 | 42 | (******************************************************************************) 43 | 44 | let end_of_djs_prelude :: INT = 0 45 | 46 | -------------------------------------------------------------------------------- /prims/other/pervasives.ml: -------------------------------------------------------------------------------- 1 | 2 | (******************************************************************************) 3 | 4 | (* 5 | let succ :: x:INT -> INT = fun x -> (plus x 1) 6 | 7 | let unary_minus :: x:INT -> INT = fun x -> (minus 0 x) 8 | *) 9 | 10 | (* 11 | (* 9/18 changed type to match the structure that elimBoolFlag requires *) 12 | (* let neg :: b:BOOL -> {(and (implies (= b true) (= v false)) *) 13 | (* (implies (= b false) (= v true)))} = *) 14 | let neg :: b:BOOL -> {BOOL|(iff (= v true) (= b false))} = 15 | fun b -> 16 | if b then false else true 17 | *) 18 | 19 | (* 20 | (* TODO change the types of l_and and l_or *) 21 | 22 | (* would want these as primitives for evaluation, but doesn't matter for 23 | type checking *) 24 | let l_and :: b0:BOOL -> b1:BOOL -> {(and (implies (= b0 true) (= v b1)) 25 | (implies (= b0 false) (= v false)))} = 26 | fun b0 b1 -> 27 | if b0 then b1 else false 28 | 29 | let l_or :: b0:BOOL -> b1:BOOL -> 30 | {BOOL | (iff (= v true) (or (= b0 true) (= b1 true)))} = 31 | fun b0 b1 -> 32 | if b0 then true else b1 33 | 34 | let le :: x:INT -> y:INT -> BOOL = 35 | fun x y -> 36 | l_or (lt x y) (eq x y) 37 | *) 38 | 39 | 40 | (******************************************************************************) 41 | 42 | let end_of_pervasives :: Int = 0 43 | 44 | -------------------------------------------------------------------------------- /prims/other/preludeLite.js: -------------------------------------------------------------------------------- 1 | 2 | "**********************************************************************"; 3 | -------------------------------------------------------------------------------- /prims/other/theory-int-2.lisp: -------------------------------------------------------------------------------- 1 | 2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | ;;;;; Begin Integer Wrapper Axioms 7 | 8 | ; TODO iff instead of implies? 9 | (assert (forall ((w1 DVal) (w2 DVal)) 10 | (and 11 | (iff (< (VIntSel w1) (VIntSel w2)) (my_lt w1 w2)) 12 | (iff (<= (VIntSel w1) (VIntSel w2)) (my_le w1 w2)) 13 | (iff (>= (VIntSel w1) (VIntSel w2)) (my_ge w1 w2)) 14 | (iff (> (VIntSel w1) (VIntSel w2)) (my_gt w1 w2)) 15 | ))) 16 | 17 | ; TODO all these needed? need other axioms? 18 | (assert (forall ((w1 DVal) (w2 DVal)) 19 | (and 20 | (iff (my_le w1 w2) (not (my_gt w1 w2))) 21 | (iff (my_ge w1 w2) (not (my_lt w1 w2))) 22 | (iff (my_le w1 w2) (or (my_lt w1 w2) (= w1 w2))) 23 | (iff (my_ge w1 w2) (or (my_gt w1 w2) (= w1 w2))) 24 | ))) 25 | 26 | (assert (forall (w1 DVal) (w2 DVal) (w3 DVal) 27 | (iff (= w1 (my_plus w2 w3)) 28 | (= (VIntSel w1) (+ (VIntSel w2) (VIntSel w3)))))) 29 | 30 | (assert (forall (w1 DVal) (w2 DVal) (w3 DVal) 31 | (iff (= w1 (my_minus w2 w3)) 32 | (= (VIntSel w1) (- (VIntSel w2) (VIntSel w3)))))) 33 | 34 | ; TODO what is syntax for ~ in smt2? 35 | ; (assert (forall (w1 DVal) (w2 DVal) 36 | ; (iff (= w1 (my_uminus w2)) 37 | ; (= (VIntSel w1) (~ (VIntSel w2)))))) 38 | 39 | 40 | 41 | ;;;;; End Integer Wrapper Axioms 42 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 43 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 44 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 45 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 46 | 47 | -------------------------------------------------------------------------------- /prims/other/theory-int.smtc: -------------------------------------------------------------------------------- 1 | 2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 5 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6 | ;;;;; Begin Integer Wrapper Axioms 7 | 8 | ; TODO iff instead of implies? 9 | (assert (forall (w1 DVal) (w2 DVal) 10 | (and 11 | (iff (< (VIntSel w1) (VIntSel w2)) (my_lt w1 w2)) 12 | (iff (<= (VIntSel w1) (VIntSel w2)) (my_le w1 w2)) 13 | (iff (>= (VIntSel w1) (VIntSel w2)) (my_ge w1 w2)) 14 | (iff (> (VIntSel w1) (VIntSel w2)) (my_gt w1 w2)) 15 | ))) 16 | 17 | ; TODO all these needed? need other axioms? 18 | (assert (forall (w1 DVal) (w2 DVal) 19 | (and 20 | (iff (my_le w1 w2) (not (my_gt w1 w2))) 21 | (iff (my_ge w1 w2) (not (my_lt w1 w2))) 22 | (iff (my_le w1 w2) (or (my_lt w1 w2) (= w1 w2))) 23 | (iff (my_ge w1 w2) (or (my_gt w1 w2) (= w1 w2))) 24 | ))) 25 | 26 | (assert (forall (w1 DVal) (w2 DVal) (w3 DVal) 27 | (iff (= w1 (my_plus w2 w3)) 28 | (= (VIntSel w1) (+ (VIntSel w2) (VIntSel w3)))))) 29 | 30 | (assert (forall (w1 DVal) (w2 DVal) (w3 DVal) 31 | (iff (= w1 (my_minus w2 w3)) 32 | (= (VIntSel w1) (- (VIntSel w2) (VIntSel w3)))))) 33 | 34 | (assert (forall (w1 DVal) (w2 DVal) 35 | (iff (= w1 (my_uminus w2)) 36 | (= (VIntSel w1) (~ (VIntSel w2)))))) 37 | 38 | 39 | ;;;;; End Integer Wrapper Axioms 40 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 41 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 42 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 43 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 44 | 45 | -------------------------------------------------------------------------------- /scripts/gen-benchmark-linecounts-2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # Running ./gen-benchmark-linecounts.py 4 | # produces an intermediate file in $DJS_DIR/src/out/bench.out 5 | # and a bunch of LaTeX macros in $DJS_DIR/src/out/linecounts.tex 6 | # 7 | # this version computes Un from un-foo.js and Ann from foo.js 8 | # 9 | 10 | import os, re, sys 11 | 12 | benchdir = '/tests/apr-benchmarks/v0' 13 | djsdir = os.getenv('DJS_DIR') 14 | outfile = '/src/out/bench.out' 15 | latexfile = '/src/out/linecounts.tex' 16 | 17 | benchmarks = ['prototypal', 'pseudoclassical', 'functional', 'parts', 18 | 'string-fasta', 'access-binary-trees', 'access-nbody', 19 | 'splay', 20 | 'typeOf', 21 | 'negate', 'counter', 'dispatch', 'passengers'] 22 | 23 | os.system('cloc $DJS_DIR/' + benchdir + ' --by-file --skip_uniqueness \ 24 | | grep "^[/]" > ' + djsdir + outfile) 25 | print "Ran CLOC on %s and wrote to %s" % (benchdir,outfile) 26 | 27 | totalUn = 0 28 | totalAnn = 0 29 | 30 | oc = open(djsdir + latexfile, 'w+') 31 | for line in open(djsdir + outfile): 32 | line = line.strip() 33 | tokens = re.split("[ ]*", line) 34 | if len(tokens) != 4: raise Exception("bad line:\n" + line) 35 | bench, blank, comments, code = tokens 36 | m = re.match("^.*/(.*)[.]js$", bench) 37 | if m: 38 | bench = m.group(1) 39 | if bench[0:3] == "un-": 40 | bench = bench[3:] 41 | if not bench in benchmarks: raise Exception("unexpected benchmark: " + bench) 42 | # LaTeX macros don't like '-' characters, so remove them 43 | bench = re.sub("-","",bench) 44 | iCode = int(code) 45 | oc.write('\\newcommand{\\benchUn%s}{%d}\n' % (bench, iCode)) 46 | totalUn += iCode 47 | else: 48 | if not bench in benchmarks: raise Exception("unexpected benchmark: " + bench) 49 | # LaTeX macros don't like '-' characters, so remove them 50 | bench = re.sub("-","",bench) 51 | iComments, iCode = int(comments), int(code) 52 | oc.write('\\newcommand{\\benchAnn%s}{%d}\n' % (bench, iComments + iCode)) 53 | totalAnn += iComments + iCode 54 | 55 | print "Processed %s and wrote LaTeX commands to %s" % (outfile, latexfile) 56 | 57 | print "Total Un : %10d" % totalUn 58 | print "Total Ann : %10d" % totalAnn 59 | -------------------------------------------------------------------------------- /scripts/gen-benchmark-linecounts.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # Running ./gen-benchmark-linecounts.py 4 | # produces an intermediate file in $DJS_DIR/src/out/bench.out 5 | # and a bunch of LaTeX macros in $DJS_DIR/src/out/linecounts.tex 6 | # 7 | # TODO DJS files contain assert() and "#define" statements, which get 8 | # counted as code lines. should subtract only lines like this. 9 | # 10 | 11 | import os, re, sys 12 | 13 | benchdir = '/tests/apr-benchmarks/v0' 14 | djsdir = os.getenv('DJS_DIR') 15 | outfile = '/src/out/bench.out' 16 | latexfile = '/src/out/linecounts.tex' 17 | 18 | benchmarks = ['prototypal', 'pseudoclassical', 'functional', 'parts', 19 | 'string-fasta', 'access-binary-trees', 'access-nbody', 20 | 'splay', 21 | 'typeOf', 22 | 'negate', 'counter', 'dispatch', 'passengers'] 23 | 24 | os.system('cloc $DJS_DIR/' + benchdir + ' --by-file --skip_uniqueness \ 25 | | grep "^[/]" > ' + djsdir + outfile) 26 | print "Ran CLOC on %s and wrote to %s" % (benchdir,outfile) 27 | 28 | totalUn = 0 29 | totalAnn = 0 30 | 31 | oc = open(djsdir + latexfile, 'w+') 32 | for line in open(djsdir + outfile): 33 | line = line.strip() 34 | tokens = re.split("[ ]*", line) 35 | if len(tokens) != 4: raise Exception("bad line:\n" + line) 36 | bench, blank, comments, code = tokens 37 | m = re.match("^.*/(.*)[.]js$", bench) 38 | if m: 39 | bench = m.group(1) 40 | if not bench in benchmarks: raise Exception("unexpected benchmark: " + bench) 41 | # LaTeX macros don't like '-' characters, so remove them 42 | bench = re.sub("-","",bench) 43 | iComments, iCode = int(comments), int(code) 44 | oc.write('\\newcommand{\\benchUn%s}{%d}\n' % (bench, iCode)) 45 | oc.write('\\newcommand{\\benchAnn%s}{%d}\n' % (bench, iComments + iCode)) 46 | totalUn += iCode 47 | totalAnn += iComments + iCode 48 | print "Processed %s and wrote LaTeX commands to %s" % (outfile, latexfile) 49 | 50 | print "Total Un : %10d" % totalUn 51 | print "Total Ann : %10d" % totalAnn 52 | -------------------------------------------------------------------------------- /scripts/gen-benchmark-time-sep2012.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # Requires that djs writes the number of Z3 queries in out/num-queries.txt 4 | 5 | import os, re, sys, time, math 6 | 7 | benchdir = '/tests/djs/oopsla12' 8 | djsdir = os.getenv('DJS_DIR') 9 | latexfile = '/src/out/runningtime-sep2012.tex' 10 | 11 | benchmarks = { 12 | 'prototypal': '', 13 | 'pseudoclassical': '', 14 | 'functional': '', 15 | 'parts': '', 16 | 'string-fasta': '', 17 | 'access-binary-trees': '', 18 | 'access-nbody': '', 19 | 'splay': '', 20 | 'typeOf': '', 21 | 'negate': '', 22 | 'counter': '', 23 | 'dispatch': '', 24 | 'passengers': '', 25 | } 26 | 27 | def nearestInt(f): 28 | if f - math.floor(f) < 0.5: i = int(math.floor(f)) 29 | else: i = int(math.ceil(f)) 30 | if i == 0: return 1 31 | return i 32 | 33 | totalQueries = 0 34 | totalTime = 0 35 | 36 | oc = open(djsdir + latexfile, 'w+') 37 | for top, _, files in os.walk(djsdir + benchdir): 38 | for nm in files: 39 | bench = re.sub("[.]js", "", nm) 40 | bench = bench.strip() 41 | if not bench in benchmarks: raise Exception("unexpected benchmark: " + bench) 42 | options = benchmarks[bench] 43 | # LaTeX macros don't like '-' characters, so remove them 44 | bench = re.sub("-","",bench) 45 | f = os.path.join(top, nm) 46 | print bench, 47 | tBegin = time.time() 48 | os.system("./system-dref -djs -fast %s %s > /dev/null" % (options, f)) 49 | tDiff = time.time() - tBegin 50 | numQueriesFile = open(djsdir + '/src/out/num-queries.txt') 51 | try: 52 | numQueries = int(numQueriesFile.readline()) 53 | except: 54 | numQueries = -1 55 | #iTime = nearestInt(tDiff) 56 | iTime = tDiff 57 | if iTime < 0.1: 58 | iTime = 0.1 59 | oc.write('\\newcommand{\\benchQueries%s}{%d}\n' % (bench, numQueries)) 60 | oc.write('\\newcommand{\\benchTime%s}{%.1f}\n' % (bench, iTime)) 61 | oc.flush() 62 | print "%d %.1f" % (numQueries, iTime) 63 | totalQueries += numQueries 64 | totalTime += iTime 65 | 66 | print "Total Queries : %10d" % totalQueries 67 | #print "Total Time : %10d" % totalTime 68 | print "Total Time : %10.1f" % totalTime 69 | -------------------------------------------------------------------------------- /scripts/gen-benchmark-time.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | # Requires that djs writes the number of Z3 queries in out/num-queries.txt 4 | 5 | import os, re, sys, time, math 6 | 7 | benchdir = '/tests/apr-benchmarks/v1' 8 | djsdir = os.getenv('DJS_DIR') 9 | latexfile = '/src/out/runningtime.tex' 10 | 11 | benchmarks = { 12 | 'prototypal': '', 13 | 'pseudoclassical': '', 14 | 'functional': '', 15 | 'parts': '', 16 | 'string-fasta': '', 17 | 'access-binary-trees': '-augmentHeaps -greedyThaws -assistCtor', 18 | 'access-nbody': '-augmentHeaps -greedyThaws -assistCtor', 19 | 'splay': '-augmentHeaps -greedyThaws', 20 | 'typeOf': '-doFalseChecks', 21 | 'negate': '', 22 | 'counter': '-augmentHeaps', 23 | 'dispatch': '', 24 | 'passengers': '-augmentHeaps', 25 | } 26 | 27 | def nearestInt(f): 28 | if f - math.floor(f) < 0.5: i = int(math.floor(f)) 29 | else: i = int(math.ceil(f)) 30 | if i == 0: return 1 31 | return i 32 | 33 | totalQueries = 0 34 | totalTime = 0 35 | 36 | oc = open(djsdir + latexfile, 'w+') 37 | for top, _, files in os.walk(djsdir + benchdir): 38 | for nm in files: 39 | bench = re.sub("[.]js", "", nm) 40 | bench = bench.strip() 41 | if not bench in benchmarks: raise Exception("unexpected benchmark: " + bench) 42 | options = benchmarks[bench] 43 | # LaTeX macros don't like '-' characters, so remove them 44 | bench = re.sub("-","",bench) 45 | f = os.path.join(top, nm) 46 | print bench, 47 | tBegin = time.time() 48 | os.system("./system-d -djs -fast %s %s > /dev/null" % (options, f)) 49 | tDiff = time.time() - tBegin 50 | numQueriesFile = open(djsdir + '/src/out/num-queries.txt') 51 | try: 52 | numQueries = int(numQueriesFile.readline()) 53 | except: 54 | numQueries = -1 55 | iTime = nearestInt(tDiff) 56 | oc.write('\\newcommand{\\benchQueries%s}{%d}\n' % (bench, numQueries)) 57 | oc.write('\\newcommand{\\benchTime%s}{%d}\n' % (bench, iTime)) 58 | oc.flush() 59 | print numQueries, nearestInt(tDiff) 60 | totalQueries += numQueries 61 | totalTime += iTime 62 | 63 | print "Total Queries : %10d" % totalQueries 64 | print "Total Time : %10d" % totalTime 65 | -------------------------------------------------------------------------------- /scripts/run-all-djs-lite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\e[1;32m" 4 | echo -e "***************************************************************" 5 | echo -e "POSITIVE TESTS" 6 | echo -e "\e[0m" 7 | 8 | for FN in `ls $DJS_DIR/tests/djsLite/*/[^_][^_]*.js` 9 | do 10 | echo -n "$FN " 11 | ./system-d -djsLite $FN | tail -1 12 | done 13 | 14 | -------------------------------------------------------------------------------- /scripts/run-all-djs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\e[1;31m" 4 | echo -e "***************************************************************" 5 | echo -e "NEGATIVE TESTS" 6 | echo -e "\e[0m" 7 | 8 | for FN in `ls $DJS_DIR/tests/djs/*/xx*.js` 9 | do 10 | echo -n "$FN " 11 | ./system-d -djs $FN | tail -1 12 | done 13 | 14 | echo -e "\e[1;32m" 15 | echo -e "***************************************************************" 16 | echo -e "POSITIVE TESTS" 17 | echo -e "\e[0m" 18 | 19 | for FN in `ls $DJS_DIR/tests/djs/[^e][^s]*/[^_x][^_x]*.js` 20 | do 21 | echo -n "$FN " 22 | ./system-d -djs $FN | tail -1 23 | done 24 | 25 | -------------------------------------------------------------------------------- /scripts/run-all-dref.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\e[1;31m" 4 | echo -e "***************************************************************" 5 | echo -e "NEGATIVE TESTS" 6 | echo -e "\e[0m" 7 | 8 | for FN in `ls $DJS_DIR/tests/functional/*/xx*.ml 9 | ls $DJS_DIR/tests/imperative/*/xx*.dref` 10 | do 11 | echo -n "$FN " 12 | ./system-d $FN | tail -1 13 | done 14 | 15 | echo -e "\e[1;32m" 16 | echo -e "***************************************************************" 17 | echo -e "POSITIVE TESTS" 18 | echo -e "\e[0m" 19 | 20 | for FN in `ls $DJS_DIR/tests/functional/*/[^_x][^_x]*.ml 21 | ls $DJS_DIR/tests/imperative/*/[^_x][^_x]*.dref` 22 | do 23 | echo -n "$FN " 24 | ./system-d $FN | tail -1 25 | done 26 | 27 | -------------------------------------------------------------------------------- /scripts/run-tests-arrays.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\e[1;32m" 4 | echo -e "***************************************************************" 5 | echo -e "POSITIVE TESTS" 6 | echo -e "\e[0m" 7 | 8 | for FN in `ls $DJS_DIR/tests/functional/arrays/[^_][^_]*.ml` 9 | do 10 | echo -n "$FN " 11 | ./system-d $FN | tail -1 12 | done 13 | 14 | for FN in `ls $DJS_DIR/tests/imperative/arrays/[^_][^_]*.ml` 15 | do 16 | echo -n "$FN " 17 | ./system-d $FN | tail -1 18 | done 19 | 20 | -------------------------------------------------------------------------------- /scripts/run-tests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys, re, os 4 | 5 | def usage(): 6 | print "Usage: ./run-tests.py (djs|djsLite|functional|imperative)/path " 7 | sys.exit() 8 | 9 | if len(sys.argv) < 2: # != 2: 10 | usage() 11 | 12 | path = sys.argv[1] 13 | systemdoptions = ' '.join(sys.argv[2:]) 14 | 15 | if re.match("^djs", path): mode = "-djs" 16 | elif re.match("^djsLite", path): mode = "-djsLite" 17 | elif re.match("^functional", path): mode = "" 18 | elif re.match("^imperative", path): mode = "" 19 | else: usage() 20 | 21 | test_dir = os.getenv("DJS_DIR") + "/tests/" 22 | 23 | def strip_test_dir(f): 24 | if re.match("^" + test_dir, f): 25 | return f[len(test_dir):] 26 | else: 27 | return f 28 | 29 | def iterate(positive): 30 | for top, _, files in os.walk(test_dir + path): 31 | for nm in files: 32 | if re.match("^__", nm): continue 33 | b = re.match("^xx_", nm) 34 | if positive: 35 | b = not b 36 | if b and nm[0] != '.': 37 | f = os.path.join(top, nm) 38 | os.system("echo -n '%s ' && ./system-dref %s %s %s | tail -1" 39 | % (strip_test_dir(f), mode, systemdoptions, f)) 40 | 41 | print '\033[91m' 42 | print "***************************************************************" 43 | print "NEGATIVE TESTS" 44 | print '\033[0m' 45 | iterate(False) 46 | 47 | print '\033[92m' 48 | print "***************************************************************" 49 | print "POSITIVE TESTS" 50 | print '\033[0m' 51 | iterate(True) 52 | 53 | -------------------------------------------------------------------------------- /src/LamJS/formatExt.ml: -------------------------------------------------------------------------------- 1 | open Format 2 | 3 | type printer = formatter -> unit 4 | 5 | let nest (p : printer) (fmt : formatter) : unit = 6 | pp_open_vbox fmt 2; 7 | p fmt; 8 | pp_close_box fmt () 9 | 10 | let rec sep (lst : printer list) (fmt : formatter) : unit = match lst with 11 | x1 :: x2 :: xs' -> 12 | pp_open_box fmt 2; 13 | x1 fmt; 14 | pp_close_box fmt (); 15 | pp_print_space fmt (); 16 | sep (x2 :: xs') fmt 17 | | [x] -> 18 | pp_open_box fmt 2; 19 | x fmt; 20 | pp_close_box fmt () 21 | | [] -> () 22 | 23 | let rec squish (lst : printer list) (fmt : formatter) : unit = match lst with 24 | | x :: xs -> x fmt; squish xs fmt 25 | | [] -> () 26 | 27 | 28 | let vert (p : printer list) (fmt : formatter) : unit = 29 | pp_open_vbox fmt 0; 30 | sep p fmt; 31 | pp_close_box fmt () 32 | 33 | let horz (p : printer list) (fmt : formatter) : unit = 34 | pp_open_hbox fmt (); 35 | sep p fmt; 36 | pp_close_box fmt () 37 | 38 | let text s fmt = pp_print_string fmt s 39 | 40 | let int n fmt = pp_print_int fmt n 41 | 42 | let enclose l r (inner : printer) (fmt : formatter) = 43 | pp_open_box fmt 2; 44 | pp_print_string fmt l; 45 | inner fmt; 46 | pp_print_string fmt r; 47 | pp_close_box fmt () 48 | 49 | let parens = enclose "(" ")" 50 | 51 | let braces = enclose "{" "}" 52 | 53 | let brackets = enclose "[" "]" 54 | 55 | let angles = enclose "<" ">" 56 | 57 | let to_string (f : 'a -> printer) (x : 'a) : string = 58 | f x str_formatter; 59 | flush_str_formatter () 60 | -------------------------------------------------------------------------------- /src/LamJS/formatExt.mli: -------------------------------------------------------------------------------- 1 | (** Helper functions for working with the builtin [Format] library. *) 2 | open Format 3 | 4 | type printer = formatter -> unit 5 | 6 | val nest : printer -> printer 7 | 8 | val sep : printer list -> printer 9 | 10 | val squish : printer list -> printer 11 | 12 | val vert : printer list -> printer 13 | 14 | val horz : printer list -> printer 15 | 16 | val text : string -> printer 17 | 18 | val int : int -> printer 19 | 20 | val enclose : string -> string -> printer -> printer 21 | 22 | val parens : printer -> printer 23 | 24 | val braces : printer -> printer 25 | 26 | val brackets : printer -> printer 27 | 28 | val angles : printer -> printer 29 | 30 | (** [to_string f x] uses [Format.str_formatter] as the buffer for printing [x] 31 | with [f]. *) 32 | val to_string : ('a -> printer) -> 'a -> string 33 | -------------------------------------------------------------------------------- /src/LamJS/javaScript.mli: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open JavaScript_syntax 3 | 4 | val parse_javascript : string -> string -> prog 5 | val parse_javascript_from_channel : in_channel -> string -> prog 6 | val parse_expr : string -> string -> expr 7 | 8 | module Pretty : sig 9 | 10 | open Format 11 | open FormatExt 12 | 13 | val p_const : const -> printer 14 | val p_expr : expr -> printer 15 | val p_stmt : stmt -> printer 16 | val p_prog : prog -> printer 17 | val p_infixOp : infixOp -> printer 18 | val p_prefixOp : prefixOp -> printer 19 | end 20 | -------------------------------------------------------------------------------- /src/LamJS/lambdajs.ml: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open Lambdajs_syntax 3 | open Lexing 4 | 5 | let parse_lambdajs cin name = 6 | let lexbuf = Lexing.from_channel cin in 7 | try 8 | (* Set the correct filename in lexbuf (for source-tracking). *) 9 | lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = name }; 10 | Lambdajs_parser.prog Lambdajs_lexer.token lexbuf 11 | with 12 | | Failure "lexing: empty token" -> 13 | failwith (sprintf "lexical error at %s" 14 | (string_of_position 15 | (lexbuf.lex_curr_p, lexbuf.lex_curr_p))) 16 | | Lambdajs_parser.Error -> 17 | failwith (sprintf "parse error at %s; unexpected token %s" 18 | (string_of_position 19 | (lexbuf.lex_curr_p, lexbuf.lex_curr_p)) 20 | (lexeme lexbuf)) 21 | -------------------------------------------------------------------------------- /src/LamJS/lambdajs.mli: -------------------------------------------------------------------------------- 1 | open Lambdajs_syntax 2 | open Prelude 3 | 4 | val parse_lambdajs : in_channel -> string -> exp 5 | 6 | -------------------------------------------------------------------------------- /src/LamJS/lambdajs_syntax.mli: -------------------------------------------------------------------------------- 1 | open Prelude 2 | open FormatExt 3 | 4 | type op1 = 5 | | Op1Prefix of id 6 | | Deref 7 | | Ref 8 | | Prim1 of string 9 | 10 | (* TODO: unchecked operations should always use differnet syntax. add an 11 | uncheckedGetField, uncheckedSetField, updateField, App, and if, ? *) 12 | type op2 = 13 | | Op2Infix of id 14 | | Prim2 of string 15 | | GetField 16 | | UnsafeGetField 17 | | DeleteField 18 | | SetRef 19 | 20 | (** NOTE: reference and object manipulation are defined using [EOp1] and 21 | [EOp2]. This design shrinks the size of many cases. *) 22 | type exp = 23 | | EConst of pos * JavaScript_syntax.const 24 | | EId of pos * id 25 | | EObject of pos * (pos * string * exp) list 26 | | EUpdateField of pos * exp * exp * exp 27 | | EOp1 of pos * op1 * exp 28 | | EOp2 of pos * op2 * exp * exp 29 | | EIf of pos * exp * exp * exp 30 | | EApp of pos * exp * exp list 31 | | ESeq of pos * exp * exp 32 | | ELet of pos * id * exp * exp 33 | | EFix of pos * (id * exp) list * exp 34 | (** All bindings must be [ELambda]s. *) 35 | | ELabel of pos * id * exp 36 | | EBreak of pos * id * exp 37 | | ETryCatch of pos * exp * exp 38 | (** Catch block must be an [ELambda] *) 39 | | ETryFinally of pos * exp * exp 40 | | EThrow of pos * exp 41 | | ELambda of pos * id list * exp 42 | 43 | val desugar : Exprjs_syntax.expr -> exp 44 | 45 | module Pretty : sig 46 | val p_op1 : op1 -> printer 47 | val p_op2 : op2 -> printer 48 | val p_exp : exp -> printer 49 | end 50 | 51 | val fv : exp -> IdSet.t 52 | val rename : id -> id -> exp -> exp 53 | val operators : exp -> IdSet.t 54 | -------------------------------------------------------------------------------- /src/LamJS/mapExt.ml: -------------------------------------------------------------------------------- 1 | open FormatExt 2 | 3 | module type S = sig 4 | type key 5 | type +'a t 6 | 7 | val from_list : (key * 'a) list -> 'a t 8 | val to_list : 'a t -> (key * 'a) list 9 | val keys : 'a t -> key list 10 | val values : 'a t -> 'a list 11 | val union : ('a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t 12 | val join : (key -> 'a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t 13 | val p_map : (key -> printer) -> ('a -> printer) -> 'a t -> printer 14 | val diff : 'a t -> 'a t -> 'a t 15 | val filter : (key -> 'a -> bool) -> 'a t -> 'a t 16 | end 17 | 18 | module Make (Ord: Map.OrderedType) (Map : Map.S with type key = Ord.t) = struct 19 | 20 | type key = Ord.t 21 | 22 | type +'a t = 'a Map.t 23 | 24 | let from_list lst = 25 | List.fold_left (fun m (k, v) -> Map.add k v m) Map.empty lst 26 | 27 | let to_list m = 28 | Map.fold (fun k v lst -> (k, v) :: lst) m [] 29 | 30 | let keys m = 31 | Map.fold (fun k _ lst -> k :: lst) m [] 32 | 33 | let values m = 34 | Map.fold (fun _ v lst -> v :: lst) m [] 35 | 36 | let union f m1 m2 = 37 | let rec g (k1, v1) (k2, v2) = 38 | if Ord.compare k1 k2 = 0 then (k1, f v1 v2) 39 | else raise Not_found 40 | in from_list (List.map2 g (to_list m1) (to_list m2)) 41 | 42 | let join f m1 m2 = 43 | let mk k v acc = 44 | if Map.mem k acc then 45 | Map.add k (f k v (Map.find k acc)) acc (* f m1-val m2-val *) 46 | else 47 | Map.add k v acc 48 | in Map.fold mk m1 m2 (* m2 is the accumulator *) 49 | 50 | let p_map p_key p_val t = 51 | vert (List.map (fun (k, v) -> brackets (horz [ p_key k; p_val v ])) 52 | (to_list t)) 53 | 54 | let diff m1 m2 = 55 | let fn key v acc = 56 | if Map.mem key m2 then acc else Map.add key v acc in 57 | Map.fold fn m1 Map.empty 58 | 59 | let filter f m = 60 | let g k v m' = if f k v then Map.add k v m' else m' in 61 | Map.fold g m Map.empty 62 | 63 | 64 | end 65 | -------------------------------------------------------------------------------- /src/LamJS/mapExt.mli: -------------------------------------------------------------------------------- 1 | open FormatExt 2 | 3 | (** Additional functions for working with maps. *) 4 | module type S = sig 5 | type key 6 | type +'a t 7 | 8 | val from_list : (key * 'a) list -> 'a t 9 | val to_list : 'a t -> (key * 'a) list 10 | val keys : 'a t -> key list 11 | val values : 'a t -> 'a list 12 | 13 | (** [union f map1 map2] requires both [map1] and [map2] to have the same set 14 | of keys. [union] signals a [Not_found] exception if either contains keys 15 | that the other does not. *) 16 | val union : ('a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t 17 | 18 | (** [join f map1 map2] returns a new map with all the keys of [map1] and 19 | [map2]. If a key exists on both maps, its two values are combined using 20 | [f]. *) 21 | val join : (key -> 'a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t 22 | 23 | val p_map : (key -> printer) -> ('a -> printer) -> 'a t -> printer 24 | 25 | val diff : 'a t -> 'a t -> 'a t 26 | 27 | val filter : (key -> 'a -> bool) -> 'a t -> 'a t 28 | 29 | end 30 | 31 | module Make : functor (Ord : Map.OrderedType) -> 32 | functor (Map : Map.S with type key = Ord.t) -> S 33 | with type key = Ord.t 34 | and type +'a t = 'a Map.t 35 | -------------------------------------------------------------------------------- /src/LamJS/setExt.ml: -------------------------------------------------------------------------------- 1 | open Format 2 | open FormatExt 3 | 4 | module type S = sig 5 | type elt 6 | type t 7 | 8 | val unions : t list -> t 9 | val from_list : elt list -> t 10 | val to_list : t -> elt list 11 | val p_set : (elt -> printer) -> t -> printer 12 | end 13 | 14 | module Make (Set : Set.S) = struct 15 | 16 | type elt = Set.elt 17 | 18 | type t = Set.t 19 | 20 | let unions lst = List.fold_left Set.union Set.empty lst 21 | 22 | let from_list lst = 23 | List.fold_left (fun set x -> Set.add x set) Set.empty lst 24 | 25 | let to_list set = 26 | Set.fold (fun e lst -> e :: lst) set [] 27 | 28 | let p_set p_elt set = 29 | braces (horz (List.map p_elt (to_list set))) 30 | 31 | end 32 | -------------------------------------------------------------------------------- /src/LamJS/setExt.mli: -------------------------------------------------------------------------------- 1 | (** Additional functions for working with sets. *) 2 | 3 | open Format 4 | open FormatExt 5 | 6 | module type S = sig 7 | type elt 8 | type t 9 | 10 | val unions : t list -> t 11 | val from_list : elt list -> t 12 | val to_list : t -> elt list 13 | val p_set : (elt -> printer) -> t -> printer 14 | 15 | end 16 | 17 | module Make : functor (Set : Set.S) -> S 18 | with type elt = Set.elt 19 | and type t = Set.t 20 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | 2 | LIBS=-libs unix,str 3 | LAM=-I LamJS 4 | STATS=-I BNstats 5 | PARSE=-use-menhir -yaccflag --explain # set to empty for ocamlyacc 6 | 7 | all: 8 | ([ -d out ] && echo "out/ exists") || (mkdir out && echo "out/ created") 9 | ocamlbuild $(LIBS) $(PARSE) $(LAM) $(STATS) -no-links main.native 10 | ln -f -s _build/main.native system-dref 11 | 12 | ## bytecode version with debugging 13 | ##all: 14 | ## ocamlbuild $(LIBS) $(PARSE) $(LAM) -no-links main.d.byte 15 | ## ln -f -s _build/main.d.byte system-dref 16 | 17 | loc: 18 | wc -l lang.ml langUtils.ml zzz.ml \ 19 | sub.ml wf.ml \ 20 | cnf.ml anf.ml main.ml \ 21 | utils.ml log.ml \ 22 | tcDref3.ml \ 23 | parseUtils.ml \ 24 | djsDesugar2.ml \ 25 | settings.ml \ 26 | langLexer.mll langParser2.mly \ 27 | ../prims/*.dref 28 | 29 | clean: 30 | rm -rf _build out system-dref 31 | 32 | -------------------------------------------------------------------------------- /src/anf.mli: -------------------------------------------------------------------------------- 1 | 2 | open Lang 3 | 4 | val anfExp : exp -> exp 5 | 6 | val printAnfExp : exp -> unit 7 | 8 | val badAnf : string -> 'a 9 | 10 | val coerce : exp -> exp 11 | 12 | -------------------------------------------------------------------------------- /src/cnf.mli: -------------------------------------------------------------------------------- 1 | 2 | open Lang 3 | 4 | val orHasTyps : hastyp list -> formula 5 | 6 | val checkConversion : bool ref 7 | 8 | val convert : formula -> clause list 9 | 10 | -------------------------------------------------------------------------------- /src/djsDesugar.mli: -------------------------------------------------------------------------------- 1 | 2 | val desugar : Exprjs_syntax.expr -> Lang.exp 3 | 4 | val makeFlatSeq : Exprjs_syntax.expr -> Exprjs_syntax.expr -> Exprjs_syntax.expr 5 | 6 | -------------------------------------------------------------------------------- /src/djsDesugar2.mli: -------------------------------------------------------------------------------- 1 | 2 | val desugar : Exprjs_syntax.expr -> Lang.exp 3 | 4 | val readCtorProtoHint : string -> string option 5 | 6 | val makeFlatSeq : Exprjs_syntax.expr -> Exprjs_syntax.expr -> Exprjs_syntax.expr 7 | 8 | -------------------------------------------------------------------------------- /src/log.ml: -------------------------------------------------------------------------------- 1 | 2 | let spr = Printf.sprintf 3 | let fpr = Printf.fprintf 4 | 5 | let printToStdout = ref true 6 | let printToLog = ref true 7 | 8 | (*******************************************************************************) 9 | 10 | let oc_log = open_out (Settings.out_dir ^ "log.txt") 11 | 12 | let log0 s = 13 | if !printToLog then fpr oc_log s; 14 | if !printToStdout then fpr stdout s; 15 | () 16 | 17 | let log1 fmt s1 = 18 | if !printToLog then fpr oc_log fmt s1; 19 | if !printToStdout then fpr stdout fmt s1; 20 | () 21 | 22 | let log2 fmt s1 s2 = 23 | if !printToLog then fpr oc_log fmt s1 s2; 24 | if !printToStdout then fpr stdout fmt s1 s2; 25 | () 26 | 27 | let log3 fmt s1 s2 s3 = 28 | if !printToLog then fpr oc_log fmt s1 s2 s3; 29 | if !printToStdout then fpr stdout fmt s1 s2 s3; 30 | () 31 | 32 | let log4 fmt s1 s2 s3 s4 = 33 | if !printToLog then fpr oc_log fmt s1 s2 s3 s4; 34 | if !printToStdout then fpr stdout fmt s1 s2 s3 s4; 35 | () 36 | 37 | let log5 fmt s1 s2 s3 s4 s5 = 38 | if !printToLog then fpr oc_log fmt s1 s2 s3 s4 s5; 39 | if !printToStdout then fpr stdout fmt s1 s2 s3 s4 s5; 40 | () 41 | 42 | let bigTitle s = 43 | log1 "%s\n" (String.make 80 ';'); 44 | log1 ";;; %s\n\n" s 45 | 46 | let smallTitle s = 47 | log1 ";;; %s\n\n" s 48 | 49 | (*******************************************************************************) 50 | 51 | let terminate () = flush stdout; exit 1 52 | 53 | let printBig cap s = 54 | log3 "\n%s\n%s\n\n%s\n\n" (String.make 80 '-') cap s 55 | 56 | let printErr cap s = 57 | printBig cap s; 58 | log1 "%s\n" (Utils.redString cap); 59 | if not !printToStdout then Printf.printf "%s\n" (Utils.redString cap); 60 | terminate () 61 | 62 | let printParseErr s = printErr "PARSE ERROR!" s 63 | 64 | let printTcErr l = printErr "TC ERROR!" (String.concat "\n" l) 65 | 66 | (*******************************************************************************) 67 | 68 | let warn s = 69 | if !Settings.strictWarn then log1 "\n%s\n" (String.make 80 '-'); 70 | log1 "WARN! %s\n" s; 71 | if !Settings.strictWarn then printTcErr ["strict warning"] 72 | 73 | (*******************************************************************************) 74 | 75 | (* TODO should also move other special purpose log files here *) 76 | 77 | -------------------------------------------------------------------------------- /src/parseUtils.mli: -------------------------------------------------------------------------------- 1 | 2 | open Lang 3 | 4 | val argSpecs : (Arg.key * Arg.spec * Arg.doc) list 5 | 6 | (* val mkTupleTyp : typ list -> typ *) 7 | 8 | (* 9 | 10 | (* TODO factor this type and mkFixFun with uarr type *) 11 | 12 | val mkDepTupleArrow : 13 | (vvar list * typ) -> (heap * typ * heap) -> (vvar * typ * heap * typ * heap) 14 | 15 | *) 16 | 17 | (* val mkDepTupleTyp : (vvar * typ) list -> typ *) 18 | 19 | val mkTupleExp : exp list -> exp 20 | 21 | val addLets : exp -> (vvar * exp) list -> exp 22 | 23 | val mkPatFun : pat -> exp -> value 24 | 25 | val maybeAddHeapPrefixVar : uarrow -> uarrow 26 | 27 | val typToFrame : typ -> frame 28 | 29 | (* val mkLetRec : vvar -> uarrow -> exp -> exp -> exp *) 30 | 31 | val mkLetRec_ : vvar -> uarrow -> exp -> exp -> exp 32 | 33 | val doIntersectionHack : vvar -> formula 34 | 35 | val undoIntersectionHack : env -> typ -> typ 36 | 37 | -------------------------------------------------------------------------------- /src/settings.ml: -------------------------------------------------------------------------------- 1 | 2 | let djs_dir = 3 | try 4 | let s = Unix.getenv "DJS_DIR" in 5 | if s.[String.length s - 1] = '/' then s 6 | else s ^ "/" (* ensuring trailing '/' *) 7 | with Not_found -> 8 | Lang.kill "Set and export the environment variable DJS_DIR \ 9 | to the root of the DJS directory" 10 | 11 | let out_dir = djs_dir ^ "src/out/" 12 | let prim_dir = djs_dir ^ "prims/" 13 | 14 | let parseOnly = ref false 15 | let strictWarn = ref true 16 | let printAllTypes = ref false 17 | let printShortQuick = ref true 18 | let doFalseChecks = ref false 19 | let quickTypes = ref true 20 | let checkWfSynthesis = ref true 21 | let tryAllBoxesHack = ref false 22 | 23 | (* DJS options *) 24 | let djsMode = ref false 25 | let augmentHeaps = ref true 26 | -------------------------------------------------------------------------------- /src/sub.mli: -------------------------------------------------------------------------------- 1 | 2 | open Lang 3 | 4 | val writeStats : unit -> unit 5 | 6 | (***** Meet/Join **************************************************************) 7 | 8 | (* val doMeet : bool ref *) 9 | (* val maxJoinSize : int ref *) 10 | (* val meetAll : TypeTerms.t -> typterm option *) 11 | (* val joinAll : TypeTerms.t -> typterm option *) 12 | 13 | (***** Extraction *************************************************************) 14 | 15 | (* val mustFlow : ?filter:(typterm -> bool) -> env -> typ -> TypeTerms.t *) 16 | (* val canFlow : ?filter:(typterm -> bool) -> env -> typ -> TypeTerms.t *) 17 | 18 | val mustFlowIterator : ?filter:(typterm -> bool) -> env -> typ 19 | -> (unit -> typterm option) 20 | 21 | (***** Subtyping **************************************************************) 22 | 23 | val types : string -> env -> prenextyp -> typ -> unit 24 | 25 | val heapSat : string -> env -> heapenv -> heap -> LangUtils.vsubst 26 | 27 | val worldSat : string -> env -> prenextyp * heapenv -> world -> LangUtils.vsubst 28 | 29 | (* 30 | val heaps : string -> ?locsOpt:(loc list option) -> env -> heap -> heap 31 | -> LangUtils.vsubst 32 | 33 | val worlds : string -> env -> world -> world -> LangUtils.vsubst 34 | *) 35 | 36 | -------------------------------------------------------------------------------- /src/tcDref.mli: -------------------------------------------------------------------------------- 1 | 2 | open Lang 3 | 4 | val tsVal : env -> heap -> value -> typ 5 | 6 | val tsExp : env -> heap -> exp -> world 7 | 8 | val tcVal : env -> heap -> typ -> value -> unit 9 | 10 | val tcExp : env -> heap -> world -> exp -> unit 11 | 12 | val typecheck : exp -> unit 13 | 14 | -------------------------------------------------------------------------------- /src/tcDref2.mli: -------------------------------------------------------------------------------- 1 | 2 | open Lang 3 | 4 | val tsVal : env -> heap -> value -> typ 5 | 6 | val tsExp : env -> heap -> exp -> world 7 | 8 | val tcVal : env -> heap -> typ -> value -> unit 9 | 10 | val tcExp : env -> heap -> world -> exp -> unit 11 | 12 | val typecheck : exp -> unit 13 | 14 | -------------------------------------------------------------------------------- /src/tcDref3.mli: -------------------------------------------------------------------------------- 1 | 2 | open Lang 3 | 4 | val tsVal : env -> heapenv -> value -> typ 5 | 6 | val tsExp : env -> heapenv -> exp -> (prenextyp * heapenv) 7 | 8 | val tcVal : env -> heapenv -> typ -> value -> unit 9 | 10 | val tcExp : env -> heapenv -> world -> exp -> unit 11 | 12 | val typecheck : exp -> unit 13 | 14 | -------------------------------------------------------------------------------- /src/tcUtils.mli: -------------------------------------------------------------------------------- 1 | 2 | open Lang 3 | 4 | val elimLocalTyp : vvar -> typ -> typ -> typ 5 | 6 | val elimLocalHeap : vvar -> typ -> heap -> heap 7 | 8 | -------------------------------------------------------------------------------- /src/wf.mli: -------------------------------------------------------------------------------- 1 | 2 | open Lang 3 | 4 | val typ : string -> env -> typ -> unit 5 | 6 | val prenexTyp : string -> env -> prenextyp -> unit 7 | 8 | val heap : string -> env -> heap -> unit 9 | 10 | val world : string -> env -> world -> unit 11 | 12 | val typeTerm : string -> env -> typterm -> unit 13 | 14 | val frame : string -> env -> frame -> unit 15 | 16 | -------------------------------------------------------------------------------- /src/zzz.mli: -------------------------------------------------------------------------------- 1 | 2 | open Lang 3 | 4 | val emitPreamble : unit -> unit 5 | 6 | val queryCount : int ref 7 | 8 | val queryRoot : string ref 9 | 10 | val writeQueryStats : unit -> unit 11 | 12 | val doingExtract : bool ref 13 | 14 | val dump : ?nl:bool -> ?tab:bool -> string -> unit 15 | 16 | val inNewScope : (unit -> 'a) -> 'a 17 | 18 | val assertFormula : formula -> unit 19 | 20 | val addBinding : string -> typ -> unit 21 | 22 | val checkValid : string -> formula -> bool 23 | 24 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/access-binary-trees.js: -------------------------------------------------------------------------------- 1 | 2 | function TreeNode(left,right,item) { 3 | this.left = left; 4 | this.right = right; 5 | this.item = item; 6 | return this; 7 | }; 8 | 9 | var tree1 = new TreeNode(null, null, 10); 10 | var tree2 = new TreeNode(null, null, 20); 11 | var tree3 = new TreeNode(tree1, tree2, 30); 12 | 13 | var i = tree1.item; 14 | 15 | i; 16 | 17 | TreeNode.prototype.itemCheck = function(){ 18 | if (this.left==null) return this.item; 19 | else return this.item + this.left.itemCheck() - this.right.itemCheck(); 20 | } 21 | 22 | 23 | var ic = tree1.itemCheck; 24 | 25 | ic; 26 | ic.apply(tree1)); 27 | 28 | function bottomUpTree(item,depth){ 29 | if (depth>0){ 30 | return new TreeNode( 31 | bottomUpTree(2*item-1, depth-1) 32 | ,bottomUpTree(2*item, depth-1) 33 | ,item 34 | ); 35 | } 36 | else { 37 | return new TreeNode(null,null,item); 38 | } 39 | } 40 | 41 | 42 | var tree4 = bottomUpTree(0,42); 43 | ic = tree4.itemCheck; 44 | 45 | ic; 46 | ic.apply(tree4)); 47 | 48 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/counter.js: -------------------------------------------------------------------------------- 1 | var toNum = function(x) { 2 | if (typeof(x) == "number") { return x; } 3 | else if (typeof(x) == "boolean") { return x ? 1 : 0; } 4 | else { return -1; } 5 | }; 6 | 7 | var getCount = function(t,c) { 8 | if (c in t) { 9 | return toNum(t[c]); 10 | } else { 11 | return 0; 12 | } 13 | }; 14 | 15 | var incCount = function(t,c) { 16 | var i = getCount(t,c); 17 | t[c] = 1 + i; 18 | }; 19 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/dispatch.js: -------------------------------------------------------------------------------- 1 | var dispatch = function(x,f) { 2 | var fn = x[f]; 3 | return fn(x); 4 | }; 5 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/functional.js: -------------------------------------------------------------------------------- 1 | 2 | var mammal = function(priv) { 3 | var x = {}; 4 | x.get_name = function() { 5 | return priv.name; 6 | }; 7 | return x; 8 | }; 9 | 10 | var herbPriv = {name: "Herb"}; 11 | var herb = mammal(herbPriv); 12 | var oldName = herb.get_name(); 13 | 14 | oldName; 15 | 16 | 17 | herbPriv.name = "Herbert"; 18 | var newName = herb.get_name(); 19 | 20 | newName; 21 | 22 | 23 | var cat = function(priv2) { 24 | var obj = mammal(priv2); 25 | obj.purr = function() { return "purr"; }; 26 | return obj; 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/negate.js: -------------------------------------------------------------------------------- 1 | var negate = function(x) { 2 | if (typeof(x) == "number") { 3 | return 0 - x; 4 | } else { 5 | return !x; 6 | } 7 | }; 8 | 9 | assert (typeof (negate(1)) == "number"); 10 | assert (typeof (negate(true)) == "boolean"); 11 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/parts.js: -------------------------------------------------------------------------------- 1 | 2 | var make_dog = function(x) { 3 | x.bark = function() { return "bark"; }; 4 | }; 5 | 6 | var make_cat = function(x) { 7 | x.purr = function() { return "purr"; }; 8 | }; 9 | 10 | var hybrid = {}; 11 | make_dog(hybrid); 12 | make_cat(hybrid); 13 | var noise = hybrid.bark() + hybrid.purr(); 14 | /*: Str */ noise; 15 | 16 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/passengers.js: -------------------------------------------------------------------------------- 1 | var sumWeight = function(passengers, max_weight) { 2 | var i = 0, sum = 0, n = passengers.length; 3 | for (; i < n; i++) { 4 | var p = passengers[i]; 5 | if (p.weight) { sum += p.weight; } 6 | else { sum += max_weight; } 7 | } 8 | return sum; 9 | }; 10 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/prototypal.js: -------------------------------------------------------------------------------- 1 | var beget = function (o) { 2 | function ctor() { return this; }; 3 | ctor.prototype = o; 4 | return new ctor(); 5 | }; 6 | 7 | var herb = { 8 | name : "Herb", 9 | get_name : function() { 10 | return "Hi, I'm " + this.name; 11 | } 12 | }; 13 | 14 | var henrietta = beget(herb); 15 | henrietta.name = "Henrietta"; 16 | var s = henrietta.get_name(); 17 | s; 18 | 19 | herb.get_name = function() { return 42; }; 20 | var i = henrietta.get_name(); 21 | i; 22 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/pseudoclassical.js: -------------------------------------------------------------------------------- 1 | function Mammal(name) { 2 | this.name = name; 3 | return this; 4 | }; 5 | 6 | Mammal.prototype.get_name = function() { 7 | return "Hi, I'm " + this.name; 8 | }; 9 | 10 | function Cat(name) { 11 | this.name = name; 12 | return this; 13 | }; 14 | 15 | Cat.prototype = new Mammal("__dummy__"); 16 | 17 | var henrietta = new Cat("Henrietta"); 18 | 19 | var s = henrietta.get_name(); 20 | 21 | s; 22 | 23 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/splay.js: -------------------------------------------------------------------------------- 1 | 2 | function Node(key, value) { 3 | this.key = key; 4 | this.value = value; 5 | return this; 6 | }; 7 | 8 | var SplayTree = {Node: Node}; 9 | 10 | SplayTree.Node.prototype.left = null; 11 | 12 | SplayTree.Node.prototype.right = null; 13 | 14 | SplayTree.Node.prototype.traverse_ = function(f) { 15 | var current = this; 16 | while (current) { 17 | var left = current.left; 18 | if (left) left.traverse_(f); 19 | f(current); 20 | current = current.right; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/string-fasta.js: -------------------------------------------------------------------------------- 1 | var makeCumulative = function(table) { 2 | var last = null; 3 | var c; 4 | for (c in table) { 5 | if (last) { 6 | table[c] = table[c] + table[last]; 7 | last = c; 8 | } 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/un/typeOf.js: -------------------------------------------------------------------------------- 1 | 2 | var typeOf = function(value) { 3 | var s = typeof value; 4 | if (s == 'object') { 5 | if (value) { return (Array.isArray(value)) ? 'array' : 'object'; } 6 | else { return 'null'; } 7 | } 8 | return s; 9 | }; 10 | 11 | (typeOf(1)); 12 | (typeOf("hi")); 13 | (typeOf(true)); 14 | (typeOf(null)); 15 | (typeOf({})); 16 | (typeOf([])); 17 | (typeOf(undefined)); 18 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v0/counter.js: -------------------------------------------------------------------------------- 1 | /*: #define ty_toNum [[x:Top]] -> Num */ '#define'; 2 | 3 | var toNum = function(x) /*: ty_toNum */ { 4 | if (typeof(x) == "number") { return x; } 5 | else if (typeof(x) == "boolean") { return x ? 1 : 0; } 6 | else { return -1; } 7 | }; 8 | 9 | /*: #define ty_getCount [;Lt,Ltp;] 10 | [[t:Ref(Lt), c:Str]] / [Lt |-> (_:Dict, Ltp), &toNum |-> _:ty_toNum] 11 | -> Num / same */ '#define'; 12 | 13 | var getCount = function(t,c) /*: ty_getCount */ { 14 | if (c in t) { 15 | return toNum(t[c]); 16 | } else { 17 | return 0; 18 | } 19 | }; 20 | 21 | /*: #define ty_incCount [;Lt,Ltp;] 22 | [[t:Ref(Lt), c:Str]] 23 | / [Lt |-> (dt:Dict, Ltp), &toNum |-> blah1:ty_toNum, &getCount |-> blah2:ty_getCount] 24 | -> Top / [Lt |-> (_:{(and (eqmod v dt {c}) ((sel v c) : Num))}, Ltp), 25 | &toNum |-> same, &getCount |-> same] */ "#define"; 26 | 27 | var incCount = function(t,c) /*: ty_incCount */ { 28 | var i = getCount(t,c); 29 | t[c] = 1 + i; 30 | }; 31 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v0/dispatch.js: -------------------------------------------------------------------------------- 1 | var dispatch = function(x,f) /*: [A,B;L1,L2;] 2 | [[x:Ref(L1), f:Str]] 3 | / [L1 |-> (_:{(and (= (tag v) "Dict") (v :: A) 4 | ((sel v f) :: [[_:Ref(L1)]] / [L1 |-> (_:A, L2)] -> B / same))}, L2)] 5 | -> B / same */ { 6 | var fn = x[f]; 7 | return fn(x); 8 | }; 9 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v0/negate.js: -------------------------------------------------------------------------------- 1 | var negate = function(x) /*: [[x:NumOrBool]] -> {(= (tag v) (tag x))} */ { 2 | if (typeof(x) == "number") { 3 | return 0 - x; 4 | } else { 5 | return !x; 6 | } 7 | }; 8 | 9 | assert (typeof (negate(1)) == "number"); 10 | assert (typeof (negate(true)) == "boolean"); 11 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v0/parts.js: -------------------------------------------------------------------------------- 1 | 2 | var make_dog = function(x) /*: ty_make_dog */ { 3 | x.bark = function() /*: ty_sound */ { return "bark"; }; 4 | }; 5 | 6 | var make_cat = function(x) /*: ty_make_cat */ { 7 | x.purr = function() /*: ty_sound */ { return "purr"; }; 8 | }; 9 | 10 | var hybrid = /*: l */ {}; 11 | make_dog(hybrid); 12 | make_cat(hybrid); 13 | var noise = hybrid.bark() + hybrid.purr(); 14 | /*: Str */ noise; 15 | 16 | 17 | /*: #define ty_make_dog 18 | [;L1,L2;] [[x:Ref(L1)]] / [L1 |-> (dThis:Dict, L2)] 19 | -> Top / [L1 |-> (dThis':{(and (eqmod v dThis {"bark"}) 20 | ((sel v "bark") :: ty_sound))}, L2)] 21 | */ '#define'; 22 | 23 | /*: #define ty_make_cat 24 | [;L1,L2;] [[x:Ref(L1)]] / [L1 |-> (dThis:Dict, L2)] 25 | -> Top / [L1 |-> (dThis':{(and (eqmod v dThis {"purr"}) 26 | ((sel v "purr") :: ty_sound))}, L2)] 27 | */ '#define'; 28 | 29 | /*: #define ty_sound [;L1;] [[this:Ref(L1)]] -> Str */ '#define'; 30 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v0/passengers.js: -------------------------------------------------------------------------------- 1 | /*: #define tyPassenger 2 | {Dict|(implies (has v "weight") ((sel v "weight") : Num))} */ "#define"; 3 | 4 | /*: [~lPass |-> (tyPassenger, lObjectProto)] */ "#weak"; 5 | 6 | var sumWeight = function(passengers, max_weight) 7 | /*: [;L] [[passengers:Ref(L), max_weight:Num]] 8 | / [L |-> (a:{Arr(Ref(~lPass))|(packed v)}, lArrayProto), ~lPass |-> frzn, 9 | lObjectProto |-> (objpro:{Dict|(not (has v "weight"))}, lROOT)] 10 | -> Num / same */ { 11 | var i = 0, sum = 0, n = passengers.length; 12 | /*: [&i |-> _:{Int|(>= v 0)}, &sum |-> _:Num, &passengers |-> _:Ref(L), 13 | &max_weight |-> _:Num, &n |-> _:{(= v (len a))}, 14 | L |-> (_:{(= v a)}, lArrayProto), ~lPass |-> frzn, 15 | lObjectProto |-> (_:{(= v objpro)}, lROOT)] -> sameType */ 16 | for (; i < n; i++) { 17 | var p = passengers[i]; 18 | /*: p lThaw1 */ "#thaw"; 19 | if (p.weight) { sum += p.weight; } 20 | else { sum += max_weight; } 21 | /*: p (~lPass, thwd lThaw1) */ "#freeze"; 22 | } 23 | return sum; 24 | }; 25 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v0/prototypal.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define nativeIn 3 | lObjectProto |-> (_:Top, lROOT), 4 | lFunctionProto |-> (_:Top, lObjectProto), 5 | &__FunctionProto |-> _:Ref(lFunctionProto) 6 | */ "#define"; 7 | 8 | /*: #define nativeOut 9 | lObjectProto |-> same, lFunctionProto |-> same, &__FunctionProto |-> same 10 | */ "#define"; 11 | 12 | /*: #define ty_beget [;LL1,LL2,LL3;] 13 | [[o:Ref(LL2)]] / [LL2 |-> (dParent:Top, LL3), nativeIn] 14 | -> Ref(LL1) / [LL1 |-> (dChild:{(= v empty)}, LL2), LL2 |-> same, nativeOut] 15 | */ '#define'; 16 | 17 | /*: #define ty_ctor 18 | new [;Lnew,Lpro;] 19 | [[this:Ref(Lnew)]] / [Lnew |-> (dThis:{(= v empty)}, Lpro)] 20 | -> Ref(Lnew) / same */ '#define'; 21 | 22 | var beget = function (o) /*: ty_beget */ { 23 | function ctor() /*: ty_ctor */ { return this; }; // TODO upper case letter 24 | ctor.prototype = o; 25 | return new /*: [;LL1,LL2;] LL2 */ ctor(); 26 | }; 27 | 28 | /*: #define ty_get_name 29 | [; Lthis,Lpro; H] 30 | [[this:Ref(Lthis)]] 31 | / [H ++ Lthis |-> (dThis:{Dict| 32 | (and (objhas [v] "name" [H] Lpro) 33 | ((objsel [v] "name" [H] Lpro) : Str))}, Lpro)] 34 | -> Str / same */ '#define'; 35 | 36 | var herb = /*: lHerb */ { 37 | name : "Herb", 38 | get_name : function() /*: ty_get_name */ { 39 | return "Hi, I'm " + this.name; 40 | } 41 | }; 42 | 43 | var henrietta = /*: [;lHenrietta,lHerb,lObjectProto;] */ beget(herb); 44 | henrietta.name = "Henrietta"; 45 | var s = henrietta.get_name(); 46 | /*: Str */ s; 47 | 48 | /*: #define ty_get_name_2 [; Lthis; ] [[this:Ref(Lthis)]] -> Int */ '#define'; 49 | 50 | herb.get_name = function() /*: ty_get_name_2 */ { return 42; }; 51 | var i = henrietta.get_name(); 52 | /*: Int */ i; 53 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v0/pseudoclassical.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define ty_mammal 3 | new [;Lthis,Lpro;] 4 | [[this:Ref(Lthis), name:Str]] 5 | / [Lthis |-> (dThis:{(= v empty)}, Lpro)] 6 | -> Ref(Lthis) 7 | / [Lthis |-> (dThis2:{(= v (upd dThis "name" name))}, Lpro)] 8 | */ '#define'; 9 | 10 | /*: #define ty_get_name 11 | [; Lthis,Lpro; H] 12 | [[this:Ref(Lthis)]] 13 | / [H ++ Lthis |-> (dThis:{Dict| 14 | (and (objhas [v] "name" [H] Lpro) 15 | ((objsel [v] "name" [H] Lpro) : Str))}, Lpro)] 16 | -> Str / same */ '#define'; 17 | 18 | function Mammal(name) /*: ty_mammal */ { 19 | this.name = name; 20 | return this; 21 | }; 22 | 23 | Mammal.prototype.get_name = function() /*: ty_get_name */ { 24 | return "Hi, I'm " + this.name; 25 | }; 26 | 27 | function Cat(name) /*: ty_mammal */ { 28 | this.name = name; 29 | return this; 30 | }; 31 | 32 | Cat.prototype = new /*: [;lCatPro,lMammalProto;] lMammalProto */ Mammal("__dummy__"); 33 | 34 | var henrietta = new /*: [;lHenrietta,lCatPro;] lCatPro */ Cat("Henrietta"); 35 | 36 | var s = henrietta.get_name(); 37 | 38 | /*: Str */ s; 39 | 40 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v0/splay.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define tyNode 3 | {(and (= (tag v) "Dict") ((sel v "key") : Int) ((sel v "value") : Str) 4 | (implies (has v "left") ((sel v "left") : Ref(~lNode))) 5 | (implies (has v "right") ((sel v "right") : Ref(~lNode))))} 6 | */ "#define"; 7 | 8 | /*: [~lNode |-> (tyNode, lNodeProto)] */ "#weak"; 9 | 10 | function Node(key, value) 11 | /*: new [;Lnew] 12 | [[this:Ref(Lnew), key:Int, value:Str]] 13 | / [Lnew |-> (_:Empty, lNodeProto), ~lNode |-> frzn] 14 | -> Ref(~lNode) / [~lNode |-> same] */ 15 | { 16 | this.key = key; 17 | this.value = value; 18 | 19 | var self = this; 20 | /*: self (~lNode, frzn) */ "#freeze"; 21 | return self; 22 | }; 23 | 24 | var SplayTree = {Node: Node}; 25 | 26 | SplayTree.Node.prototype.left = null; 27 | 28 | SplayTree.Node.prototype.right = null; 29 | 30 | /*: #define leftAndRight 31 | {Dict|(and ((sel v "left") :: Ref(~lNode)) 32 | ((sel v "right") :: Ref(~lNode)))} */ "#define"; 33 | 34 | SplayTree.Node.prototype.traverse_ = function traverse_() 35 | /*: [[this:Ref(~lNode)]] / [~lNode |-> frzn, lNodeProto |-> (_:leftAndRight , lObjectProto)] 36 | -> Top / same */ 37 | { 38 | var current = this; 39 | 40 | /*: current lThaw1 */ "#thaw"; 41 | var b = current; 42 | /*: current (~lNode, thwd lThaw1) */ "#freeze"; 43 | 44 | /*: [&b |-> _:Top, ¤t |-> _:Ref(~lNode), ~lNode |-> frzn, 45 | lNodeProto |-> (_:leftAndRight, lObjectProto)] 46 | -> [&b |-> _:Top, ¤t |-> _:Ref(~lNode), ~lNode |-> frzn, 47 | lNodeProto |-> same]*/ 48 | while (b) { 49 | 50 | /*: current lThaw2 */ "#thaw"; 51 | var left = current.left; 52 | /*: current (~lNode, thwd lThaw2) */ "#freeze"; 53 | 54 | if (left) traverse_.apply(left); 55 | 56 | /*: current lThaw3 */ "#thaw"; 57 | var right = current.right; 58 | /*: current (~lNode, thwd lThaw3) */ "#freeze"; 59 | 60 | b = current; 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v0/string-fasta.js: -------------------------------------------------------------------------------- 1 | var makeCumulative = function(table) /*: [;L1,L2] 2 | [[table:Ref(L1)]] / [L1 |-> (_:Dict, L2)] -> Top / [L1 |-> (_:Dict, L2)] */ { 3 | var last = null; 4 | var c; 5 | /*: [Heap] [Heap ++ 6 | &last |-> _:{(implies (not (= v null)) 7 | (and (v : Str) 8 | (objhas d v Heap L2) 9 | ((objsel d v Heap L2) : Num)))}, 10 | &c |-> _:Str, &table |-> _:Ref(L1), L1 |-> (d:Dict, L2)] 11 | -> Top / sameType */ 12 | for (c in table) { 13 | if (last) { 14 | if ((typeof table[c]) == "number") { 15 | table[c] = table[c] + table[last]; 16 | last = c; 17 | } 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v0/typeOf.js: -------------------------------------------------------------------------------- 1 | 2 | var typeOf = function(value) 3 | /*: {(and 4 | (v :: [[value:{(or (= (tag v) "number") (= (tag v) "boolean") 5 | (= (tag v) "string") (= (tag v) "undefined") 6 | (= v null))}]] 7 | -> {(ite (= value null) (= v "null") (= v (tag value)))}) 8 | (v :: [A;LL1,LL2;H] [[value:Ref(LL1)]] 9 | / [H ++ LL1 |-> (_:Arr(A), LL2), 10 | &Array |-> _:Ref(lArray), 11 | lArray |-> (_:{Dict|(= (sel v "isArray") ____isArray)}, lObjectProto)] 12 | -> {(= v "array")} / same) 13 | (v :: [;LL1,LL2;H] [[value:Ref(LL1)]] 14 | / [H ++ LL1 |-> (x:Dict, LL2), 15 | &Array |-> _:Ref(lArray), 16 | lArray |-> (_:{Dict|(= (sel v "isArray") ____isArray)}, lObjectProto)] 17 | -> {(= v "object")} / same))} */ 18 | { 19 | var s = typeof value; 20 | if (s == 'object') { 21 | if (value) { return (Array.isArray(value)) ? 'array' : 'object'; } 22 | else { return 'null'; } 23 | } 24 | return s; 25 | }; 26 | 27 | /*: {(= v "number")} */ (typeOf(1)); 28 | /*: {(= v "string")} */ (typeOf("hi")); 29 | /*: {(= v "boolean")} */ (typeOf(true)); 30 | /*: {(= v "null")} */ (typeOf(null)); 31 | /*: {(= v "object")} */ (typeOf({})); 32 | /*: {(= v "array")} */ (typeOf([])); 33 | /*: {(= v "undefined")} */ (typeOf(undefined)); 34 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v1/counter.js: -------------------------------------------------------------------------------- 1 | /*: #define ty_toNum [[x:Top]] -> Num */ '#define'; 2 | 3 | var toNum = function(x) /*: ty_toNum */ { 4 | if (typeof(x) == "number") { return x; } 5 | else if (typeof(x) == "boolean") { return x ? 1 : 0; } 6 | else { return -1; } 7 | }; 8 | 9 | /*: #define ty_getCount [;Lt,Ltp;] 10 | [[t:Ref(Lt), c:Str]] / [Lt |-> (_:Dict, Ltp)] -> Num / same */ '#define'; 11 | 12 | var getCount = function(t,c) /*: ty_getCount */ { 13 | if (c in t) { 14 | return toNum(t[c]); 15 | } else { 16 | return 0; 17 | } 18 | }; 19 | 20 | /*: #define ty_incCount [;Lt,Ltp;] 21 | [[t:Ref(Lt), c:Str]] 22 | / [Lt |-> (dt:Dict, Ltp), &toNum |-> blah1:ty_toNum, &getCount |-> blah2:ty_getCount] 23 | -> Top / [Lt |-> (_:{(and (eqmod v dt {c}) ((sel v c) : Num))}, Ltp), 24 | &toNum |-> sameType, &getCount |-> sameType] */ "#define"; 25 | 26 | var incCount = function(t,c) /*: ty_incCount */ { 27 | var i = getCount(t,c); 28 | t[c] = 1 + i; 29 | }; 30 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v1/dispatch.js: -------------------------------------------------------------------------------- 1 | var dispatch = function(x,f) /*: [A,B;L1,L2;] 2 | [[x:Ref(L1), f:Str]] 3 | / [L1 |-> (_:{(and (= (tag v) "Dict") (v :: A) 4 | ((sel v f) :: [[_:Ref(L1)]] / [L1 |-> (_:A, L2)] -> B / same))}, L2)] 5 | -> B / same */ { 6 | var fn = x[f]; 7 | return fn(x); 8 | }; 9 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v1/negate.js: -------------------------------------------------------------------------------- 1 | var negate = function(x) /*: [[x:NumOrBool]] -> {(= (tag v) (tag x))} */ { 2 | if (typeof(x) == "number") { 3 | return 0 - x; 4 | } else { 5 | return !x; 6 | } 7 | }; 8 | 9 | assert (typeof (negate(1)) == "number"); 10 | assert (typeof (negate(true)) == "boolean"); 11 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v1/parts.js: -------------------------------------------------------------------------------- 1 | 2 | var make_dog = function(x) /*: ty_make_dog */ { 3 | x.bark = function() /*: ty_sound */ { return "bark"; }; 4 | }; 5 | 6 | var make_cat = function(x) /*: ty_make_cat */ { 7 | x.purr = function() /*: ty_sound */ { return "purr"; }; 8 | }; 9 | 10 | var hybrid = {}; 11 | make_dog(hybrid); 12 | make_cat(hybrid); 13 | var noise = hybrid.bark() + hybrid.purr(); 14 | assert (typeof noise == "string"); 15 | 16 | 17 | /*: #define ty_make_dog [;L1,L2;] 18 | [[x:Ref(L1)]] / [L1 |-> (dThis:Dict, L2)] 19 | -> Top / [L1 |-> (dThis':{(and (eqmod v dThis {"bark"}) 20 | ((sel v "bark") :: ty_sound))}, L2)] */ '#define'; 21 | 22 | /*: #define ty_make_cat [;L1,L2;] 23 | [[x:Ref(L1)]] / [L1 |-> (dThis:Dict, L2)] 24 | -> Top / [L1 |-> (dThis':{(and (eqmod v dThis {"purr"}) 25 | ((sel v "purr") :: ty_sound))}, L2)] */ '#define'; 26 | 27 | /*: #define ty_sound [;L1;] [[this:Ref(L1)]] -> Str */ '#define'; 28 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v1/passengers.js: -------------------------------------------------------------------------------- 1 | /*: #define tyPassenger 2 | {Dict|(implies (has v "weight") ((sel v "weight") : Num))} */ "#define"; 3 | 4 | /*: [~lPass |-> (tyPassenger, lObjectProto)] */ "#weak"; 5 | 6 | var sumWeight = function(passengers, max_weight) 7 | /*: [;L] [[passengers:Ref(L), max_weight:Num]] 8 | / [L |-> (a:{Arr(Ref(~lPass))|(packed v)}, lArrayProto), 9 | lObjectProto |-> (objpro:{Dict|(not (has v "weight"))}, lROOT)] 10 | -> Num / same */ { 11 | var i = 0, sum = 0.0, n = passengers.length; 12 | /*: [lObjectProto |-> (_:{(= v objpro)}, lROOT)] -> sameType */ 13 | for (; i < n; i++) { 14 | var p = passengers[i]; 15 | /*: p lThaw1 */ "#thaw"; 16 | if (p.weight) { sum += p.weight; } 17 | else { sum += max_weight; } 18 | /*: p (~lPass, thwd lThaw1) */ "#freeze"; 19 | } 20 | return sum; 21 | }; 22 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v1/prototypal.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define nativeIn 3 | lObjectProto |-> (_:Top, lROOT), lFunctionProto |-> (_:Top, lObjectProto), 4 | &__FunctionProto |-> _:Ref(lFunctionProto) */ "#define"; 5 | 6 | /*: #define nativeOut 7 | lObjectProto |-> same, lFunctionProto |-> same, &__FunctionProto |-> same 8 | */ "#define"; 9 | 10 | /*: #define ty_beget [;LL1,LL2,LL3;] 11 | [[o:Ref(LL2)]] / [LL2 |-> (dParent:Top, LL3), nativeIn] 12 | -> Ref(LL1) / [LL1 |-> (dChild:{(= v empty)}, LL2), LL2 |-> same, nativeOut] 13 | */ '#define'; 14 | 15 | /*: #define ty_ctor [;Lnew,Lpro;] 16 | [[this:Ref(Lnew)]] / [Lnew |-> (dThis:{(= v empty)}, Lpro)] 17 | -> Ref(Lnew) / same */ '#define'; 18 | 19 | var beget = function (o) /*: ty_beget */ { 20 | function ctor() /*: new ty_ctor */ { return this; }; 21 | ctor.prototype = o; 22 | return new /*: [;LL1,LL2;] LL2 */ ctor(); 23 | }; 24 | 25 | /*: #define ty_get_name [; Lthis,Lpro; H] 26 | [[this:Ref(Lthis)]] 27 | / [H ++ Lthis |-> (dThis:{Dict|(objsel [v] "name" [H] Lpro : Str)}, Lpro)] 28 | -> Str / same */ '#define'; 29 | 30 | var herb = /*: lHerb */ { 31 | name : "Herb", 32 | get_name : function() /*: ty_get_name */ { 33 | return "Hi, I'm " + this.name; 34 | } 35 | }; 36 | 37 | var henrietta = /*: [;lHenrietta,lHerb,lObjectProto;] */ beget(herb); 38 | henrietta.name = "Henrietta"; 39 | var s = henrietta.get_name(); 40 | assert (typeof s === "string"); 41 | 42 | /*: #define ty_get_name_2 [; Lthis; ] [[this:Ref(Lthis)]] -> Int */ '#define'; 43 | 44 | herb.get_name = function() /*: ty_get_name_2 */ { return 42; }; 45 | var i = henrietta.get_name(); 46 | assert (typeof i === "number"); 47 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v1/pseudoclassical.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define ty_mammal [;Lthis,Lpro;] 3 | [[this:Ref(Lthis), name:Str]] / [Lthis |-> (dThis:Empty, Lpro)] 4 | -> Ref(Lthis) / [Lthis |-> (dThis2:{(= v (upd dThis "name" name))}, Lpro)] 5 | */ '#define'; 6 | 7 | /*: #define ty_get_name [; Lthis,Lpro; H] 8 | [[this:Ref(Lthis)]] 9 | / [H ++ Lthis |-> (dThis:{Dict|(objsel [v] "name" [H] Lpro : Str)}, Lpro)] 10 | -> Str / same */ '#define'; 11 | 12 | function Mammal(name) /*: new ty_mammal */ { 13 | this.name = name; 14 | return this; 15 | }; 16 | 17 | Mammal.prototype.get_name = function() /*: ty_get_name */ { 18 | return "Hi, I'm " + this.name; 19 | }; 20 | 21 | function Cat(name) /*: new ty_mammal */ { 22 | this.name = name; 23 | return this; 24 | }; 25 | 26 | Cat.prototype = new /*: [;lCatPro,lMammalProto;] lMammalProto */ Mammal("__dummy__"); 27 | 28 | var henrietta = new /*: [;lHenrietta,lCatPro;] lCatPro */ Cat("Henrietta"); 29 | 30 | var s = henrietta.get_name(); 31 | 32 | assert (typeof s === "string"); 33 | 34 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v1/splay.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define tyNode 3 | {(and (= (tag v) "Dict") ((sel v "key") : Int) ((sel v "value") : Str) 4 | (implies (has v "left") ((sel v "left") : Ref(~lNode))) 5 | (implies (has v "right") ((sel v "right") : Ref(~lNode))))} 6 | */ "#define"; 7 | 8 | /*: [~lNode |-> (tyNode, lNodeProto)] */ "#weak"; 9 | 10 | function Node(key, value) /*: new [;Lnew] 11 | [[this:Ref(Lnew), key:Int, value:Str]] / [Lnew |-> (_:Empty, lNodeProto)] 12 | -> Ref(~lNode) / [] */ 13 | { 14 | this.key = key; 15 | this.value = value; 16 | 17 | /*: this (~lNode, frzn) */ "#freeze"; 18 | return this; 19 | }; 20 | 21 | var SplayTree = {Node: Node}; 22 | 23 | SplayTree.Node.prototype.left = null; 24 | 25 | SplayTree.Node.prototype.right = null; 26 | 27 | /*: #define leftAndRight 28 | {Dict|(and ((sel v "left") :: Ref(~lNode)) 29 | ((sel v "right") :: Ref(~lNode)))} */ "#define"; 30 | 31 | SplayTree.Node.prototype.traverse_ = function traverse_() 32 | /*: [[this:Ref(~lNode)]] / [lNodeProto |-> (_:leftAndRight , lObjectProto)] 33 | -> Top / sameType */ 34 | { 35 | var current = this; 36 | var b = current; 37 | /*: [&b |-> _:Top, ¤t |-> _:Ref(~lNode), lNodeProto |-> (_:leftAndRight, lObjectProto)] 38 | -> sameType */ 39 | while (b) { 40 | var left = current.left; 41 | if (left) traverse_.apply(left); 42 | var right = current.right; 43 | b = current; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v1/string-fasta.js: -------------------------------------------------------------------------------- 1 | var makeCumulative = function(table) /*: [;L1,L2] 2 | [[table:Ref(L1)]] / [L1 |-> (_:Dict, L2)] -> Top / [L1 |-> (_:Dict, L2)] */ { 3 | var last = null; 4 | var c; 5 | /*: [Heap] [Heap ++ 6 | &last |-> _:{(implies (not (= v null)) 7 | (and (v : Str) (objsel [d] v Heap L2 : Num)))}, 8 | &c |-> _:Str, &table |-> _:Ref(L1), L1 |-> (d:Dict, L2)] 9 | -> Top / sameType */ 10 | for (c in table) { 11 | if (last) { 12 | if ((typeof table[c]) == "number") { 13 | table[c] = table[c] + table[last]; 14 | last = c; 15 | } 16 | } 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /tests/apr-benchmarks/v1/typeOf.js: -------------------------------------------------------------------------------- 1 | 2 | var typeOf = function(value) 3 | /*: {(and 4 | (v :: [[value:{(or (= (tag v) "number") (= (tag v) "boolean") 5 | (= (tag v) "string") (= (tag v) "undefined") 6 | (= v null))}]] 7 | -> {(ite (= value null) (= v "null") (= v (tag value)))}) 8 | (v :: [A;LL1,LL2;H] [[value:Ref(LL1)]] 9 | / [H ++ LL1 |-> (_:Arr(A), LL2), 10 | &Array |-> _:Ref(lArray), 11 | lArray |-> (_:{Dict|(= (sel v "isArray") ____isArray)}, lObjectProto)] 12 | -> {(= v "array")} / same) 13 | (v :: [;LL1,LL2;H] [[value:Ref(LL1)]] 14 | / [H ++ LL1 |-> (x:Dict, LL2), 15 | &Array |-> _:Ref(lArray), 16 | lArray |-> (_:{Dict|(= (sel v "isArray") ____isArray)}, lObjectProto)] 17 | -> {(= v "object")} / same))} */ 18 | { 19 | var s = typeof value; 20 | if (s == 'object') { 21 | if (value) { return (Array.isArray(value)) ? 'array' : 'object'; } 22 | else { return 'null'; } 23 | } 24 | return s; 25 | }; 26 | 27 | /*: {(= v "number")} */ (typeOf(1)); 28 | /*: {(= v "string")} */ (typeOf("hi")); 29 | /*: {(= v "boolean")} */ (typeOf(true)); 30 | /*: {(= v "null")} */ (typeOf(null)); 31 | /*: {(= v "object")} */ (typeOf({})); 32 | /*: {(= v "array")} */ (typeOf([])); 33 | /*: {(= v "undefined")} */ (typeOf(undefined)); 34 | -------------------------------------------------------------------------------- /tests/djs/arrays/andArray00.js: -------------------------------------------------------------------------------- 1 | var bs = /*: l */ [true, true, false]; 2 | var b = true; 3 | var i; 4 | 5 | /*: (&bs |-> _:Ref(l), &b |-> _:Bool, &i |-> _:{Int|(>= v 0)}, 6 | l |-> _: > lArrPro) 7 | -> (&bs |-> _:Ref(l), &b |-> _:Bool, &i |-> _:{Int|(>= v 0)}, 8 | l |-> _: > lArrPro)) */ 9 | for (i = 0; i < bs.length; i++) { 10 | assert (/*: {(= v 3)} */ (bs.length)); 11 | assert (/*: {(and (>= v 0) (< v 3))} */ (i)); 12 | assert (/*: {(not (= v undefined))} */ (bs[i])); 13 | assert (/*: Bool */ (bs[0])); 14 | assert (/*: Bool */ (bs[1])); 15 | assert (/*: Bool */ (bs[2])); 16 | assert (/*: {(or (= v 0) (= v 1) (= v 2))} */ (i)); 17 | assert (/*: Bool */ (bs[i])); 18 | }; 19 | -------------------------------------------------------------------------------- /tests/djs/arrays/andArray01.js: -------------------------------------------------------------------------------- 1 | var bs = /*: l */ [true, true, false]; 2 | var b = true; 3 | var i; 4 | 5 | /*: (&bs |-> _:Ref(l), &b |-> _:Bool, &i |-> _:{Int|(>= v 0)}, 6 | l |-> _: > lArrPro) 7 | -> (&bs |-> _:Ref(l), &b |-> _:Bool, &i |-> _:{Int|(>= v 0)}, 8 | l |-> _: > lArrPro) */ 9 | for (i = 0; i < bs.length; i++) { 10 | b = b && bs[i]; 11 | }; 12 | 13 | assert (typeof b == "boolean"); 14 | -------------------------------------------------------------------------------- /tests/djs/arrays/isArray00.js: -------------------------------------------------------------------------------- 1 | // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/isArray 2 | 3 | assert (isArray([])); 4 | assert (!isArray({})); 5 | assert (!isArray(null)); 6 | assert (!isArray(undefined)); 7 | assert (!isArray(17)); 8 | assert (!isArray("Array")); 9 | assert (!isArray(true)); 10 | assert (!isArray(false)); 11 | -------------------------------------------------------------------------------- /tests/djs/arrays/matrix00.js: -------------------------------------------------------------------------------- 1 | var row1 = ["00","01"]; 2 | var row2 = ["10","11"]; 3 | 4 | var mat = [row1, row2]; 5 | 6 | assert (mat[0][0] == "00"); 7 | assert (mat[0][1] == "01"); 8 | assert (mat[1][0] == "10"); 9 | assert (mat[1][1] == "11"); 10 | 11 | assert (mat[1][2] == undefined); 12 | -------------------------------------------------------------------------------- /tests/djs/arrays/matrix01.js: -------------------------------------------------------------------------------- 1 | var row1 = /*: lRow */ ["0","1"]; 2 | 3 | // putting the same strong reference in the array, to test out looping 4 | var mat = /*: lMat */ [row1, row1]; 5 | var i; 6 | 7 | /*: heapAnn -> heapAnn */ 8 | for (i=0; i < mat.length; i++) { 9 | assert (/*: Str */ (mat[i][0])); 10 | } 11 | 12 | /*: #define heapAnn 13 | (&i |-> _:{Int|(>= v 0)}, 14 | &mat |-> _:Ref(lMat), 15 | &row1 |-> _:Ref(lRow), 16 | lRow |-> _: > lArrPro, 17 | lMat |-> _: > lArrPro) */ '#define'; 18 | -------------------------------------------------------------------------------- /tests/djs/arrays/matrix02.js: -------------------------------------------------------------------------------- 1 | var row1 = /*: lRow */ ["0","1"]; 2 | 3 | // putting the same strong reference in the array, to test out looping 4 | var mat = /*: lMat */ [row1, row1]; 5 | var i = 0; 6 | var j = 0; 7 | 8 | assert (row1.length == 2); 9 | assert (mat.length == 2); 10 | 11 | assert (/*: Ref(lRow) */ (mat[1])); 12 | assert (/*: {(= v undefined)} */ (mat[2])); 13 | 14 | /*: outerLoop -> sameType */ 15 | for (; i < mat.length; i++) { 16 | /*: innerLoop -> sameType */ 17 | for (; j < 2; j++) { 18 | assert (/*: Ref(lRow) */ (mat[i])); 19 | assert (/*: Str */ (mat[i][j])); 20 | } 21 | } 22 | 23 | /*: #define outerLoop ( 24 | &mat |-> _:Ref(lMat), 25 | lMat |-> _: > lArrPro, 26 | lRow |-> _: > lArrPro, 27 | &i |-> _:{Int|(>= v 0)}, 28 | &j |-> _:{Int|(>= v 0)} ) */ "#define"; 29 | 30 | /*: #define innerLoop ( 31 | &mat |-> _:Ref(lMat), 32 | lMat |-> innerMat: > lArrPro, 33 | lRow |-> _: > lArrPro, 34 | &i |-> _:{Int|(and (>= v 0) (< v (len innerMat)))}, 35 | &j |-> _:{Int|(and (>= v 0))} ) */ "#define"; 36 | -------------------------------------------------------------------------------- /tests/djs/arrays/quickprop00.js: -------------------------------------------------------------------------------- 1 | var a = []; 2 | a.length; 3 | a.push(0); 4 | -------------------------------------------------------------------------------- /tests/djs/arrays/simple00.js: -------------------------------------------------------------------------------- 1 | var arr = [17, "hi", true]; 2 | arr[3] = 3; arr.push(4); 3 | assert (arr.length == 5 && arr[5] == undefined); 4 | -------------------------------------------------------------------------------- /tests/djs/arrays/sumArray00.js: -------------------------------------------------------------------------------- 1 | var sumPackedArray = function(ns) /*: 2 | [;L] (ns:Ref(L)) / (L |-> _:{(and (v::Arr(Int)) (packed v))} > lArrPro) 3 | -> Int / same */ 4 | { 5 | var sum = 0; 6 | var i; 7 | 8 | /*: (&i |-> _:{Int|(>= v 0)}, &sum |-> _:Int, &ns |-> _:Ref(L), 9 | L |-> a:{(and (v::Arr(Int)) (packed v))} > lArrPro) 10 | -> (&i |-> _:{Int|(>= v 0)}, &sum |-> _:Int, &ns |-> _:Ref(L), 11 | L |-> a':{(= v a)} > lArrPro) */ 12 | for (i=0; i < ns.length; i++) 13 | sum += ns[i]; 14 | 15 | return sum; 16 | }; 17 | 18 | var arr = (/*: Arr(Int) */ []); 19 | 20 | sumPackedArray(arr); 21 | 22 | arr.push(1); 23 | arr.push(2); 24 | arr.push(3); 25 | 26 | sumPackedArray(arr); 27 | -------------------------------------------------------------------------------- /tests/djs/arrays/sumArray01.js: -------------------------------------------------------------------------------- 1 | var sumPackedArray = function(ns) /*: 2 | [;L] (ns:Ref(L)) / (L |-> _:{(and (v::Arr(Int)) (packed v))} > lArrPro) 3 | -> Int / sameType */ 4 | { 5 | var sum = 0; 6 | var i; 7 | 8 | /*: (&i |-> _:{Int|(>= v 0)}, &sum |-> _:Int, &ns |-> _:Ref(L), 9 | L |-> _:{(and (v::Arr(Int)) (packed v))} > lArrPro) 10 | -> sameType */ 11 | for (i=0; i < ns.length; i++) 12 | sum += ns[i]; 13 | 14 | return sum; 15 | }; 16 | 17 | var arr = (/*: Arr(Int) */ []); 18 | 19 | sumPackedArray(arr); 20 | 21 | arr.push(1); 22 | arr.push(2); 23 | arr.push(3); 24 | 25 | sumPackedArray(arr); 26 | -------------------------------------------------------------------------------- /tests/djs/arrays/sumArray02.js: -------------------------------------------------------------------------------- 1 | var sumPackedArray = function(ns) /*: 2 | [;L] (ns:Ref(L)) / (L |-> array:{(and (v::Arr(Int)) (packed v))} > lArrPro) 3 | -> Int / sameExact */ 4 | { 5 | var sum = 0; 6 | var i = 0; 7 | var n = ns.length; 8 | /*: (&i |-> _:{Int|(>= v 0)}, &sum |-> _:Int, &ns |-> _:Ref(L), 9 | &n |-> _:{Int|(= v (len array))}, L |-> _:{(= v array)} > lArrPro) 10 | -> sameType */ 11 | for (; i < n; i++) 12 | sum += ns[i]; 13 | 14 | return sum; 15 | }; 16 | 17 | var arr = (/*: Arr(Int) */ []); 18 | 19 | sumPackedArray(arr); 20 | 21 | arr.push(1); 22 | arr.push(2); 23 | arr.push(3); 24 | 25 | sumPackedArray(arr); 26 | -------------------------------------------------------------------------------- /tests/djs/arrays/test00-inf.js: -------------------------------------------------------------------------------- 1 | 2 | var a = [0,"hi",true]; 3 | 4 | assert (a[0] == 0); 5 | 6 | assert (a[1] == "hi"); 7 | 8 | assert (a[2] == true); 9 | 10 | assert (a[3] == undefined); 11 | 12 | assert (a.length == 3); 13 | 14 | assert (a["length"] == 3); 15 | 16 | var s = "length"; 17 | 18 | assert (a[s] == 3); 19 | 20 | var i = 1; 21 | 22 | assert (a[i] == "hi"); 23 | -------------------------------------------------------------------------------- /tests/djs/arrays/test00.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA Arr(Top) */ [0,"hi",true]; 3 | 4 | assert (/*: [Top;lA,lArrPro;] */ a[0] == 0); 5 | 6 | assert (/*: [Top;lA,lArrPro;] */ a[1] == "hi"); 7 | 8 | assert (/*: [Top;lA,lArrPro;] */ a[2] == true); 9 | 10 | assert (/*: [Top;lA,lArrPro] */ a[3] == undefined); 11 | 12 | assert (/*: [Top;lA,lArrPro;] */ a.length == 3); 13 | 14 | assert (/*: [Top;lA,lArrPro;] */ a["length"] == 3); 15 | 16 | var s = "length"; 17 | 18 | assert (/*: [Top;lA,lArrPro] */ a[s] == 3); 19 | 20 | var i = 1; 21 | 22 | assert (/*: [Top;lA,lArrPro;] */ a[i] == "hi"); 23 | -------------------------------------------------------------------------------- /tests/djs/arrays/test01-inf.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA Arr(Int) */ [0,1,2]; 3 | 4 | assert (a.length == 3); 5 | 6 | a.push(3); 7 | 8 | assert (a.length == 4); 9 | 10 | assert (/*: Int */ (a[3])); 11 | 12 | a.pop(); 13 | 14 | assert (a[3] == undefined); 15 | 16 | -------------------------------------------------------------------------------- /tests/djs/arrays/test01.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA Arr(Int) */ [0,1,2]; 3 | 4 | assert (/*: [Int;lA,lArrPro;] */ a.length == 3); 5 | 6 | (/*: [Int;lA,lArrPro;] */ (a.push))(3); 7 | 8 | assert (/*: [Int;lA,lArrPro;] */ a.length == 4); 9 | 10 | assert (/*: Int */ (/*: [Int;lA,lArrPro;] */ a[3])); 11 | 12 | (/*: [Int;lA,lArrPro;] */ (a.pop))(); 13 | 14 | assert (/*: [Int;lA,lArrPro;] */ a[3] == undefined); 15 | 16 | -------------------------------------------------------------------------------- /tests/djs/arrays/test02-inf.js: -------------------------------------------------------------------------------- 1 | 2 | ////// need special typing rule for getElem on arrays and strings 3 | 4 | var a = /*: lA Arr(Int) */ [0,1,2]; 5 | 6 | assert (a.length == 3); 7 | 8 | a["push"](3); 9 | 10 | assert (a.length == 4); 11 | 12 | assert (/*: Int */ (a[3])); 13 | 14 | a["pop"](); 15 | 16 | assert (a[3] == undefined); 17 | 18 | -------------------------------------------------------------------------------- /tests/djs/arrays/test02.js: -------------------------------------------------------------------------------- 1 | 2 | ////// need special typing rule for getElem on arrays and strings 3 | 4 | var a = /*: lA Arr(Int) */ [0,1,2]; 5 | 6 | assert (/*: [Int;lA,lArrPro;] */ a.length == 3); 7 | 8 | (/*: [Int;lA,lArrPro;] */ (a["push"]))(3); 9 | 10 | assert (/*: [Int;lA,lArrPro;] */ a.length == 4); 11 | 12 | assert (/*: Int */ (/*: [Int;lA,lArrPro;] */ a[3])); 13 | 14 | (/*: [Int;lA,lArrPro;] */ (a["pop"]))(); 15 | 16 | assert (/*: [Int;lA,lArrPro;] */ a[3] == undefined); 17 | 18 | -------------------------------------------------------------------------------- /tests/djs/arrays/test03-inf.js: -------------------------------------------------------------------------------- 1 | 2 | var a = [0,1,2]; 3 | 4 | a[3] = 3; 5 | a[4] = 4; 6 | a[5] = 5; 7 | 8 | assert (a.length == 6); 9 | 10 | a.length = 2; 11 | 12 | assert (a.length == 2); 13 | -------------------------------------------------------------------------------- /tests/djs/arrays/test03.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA Arr(Int) */ [0,1,2]; 3 | 4 | /*: [Int;lA,lArrPro] */ a[3] = 3; 5 | /*: [Int;lA,lArrPro] */ a[4] = 4; 6 | /*: [Int;lA,lArrPro] */ a[5] = 5; 7 | 8 | assert (/*: [Int;lA,lArrPro] */ a.length == 6); 9 | 10 | /*: [Int;lA,lArrPro] */ a.length = 2; 11 | 12 | assert (/*: [Int;lA,lArrPro] */ a.length == 2); 13 | -------------------------------------------------------------------------------- /tests/djs/arrays/test04-inf.js: -------------------------------------------------------------------------------- 1 | 2 | var arr = [0,1,2]; 3 | 4 | assert (true == 0 in arr); 5 | 6 | assert (true == 2 in arr); 7 | 8 | assert (false == 3 in arr); 9 | 10 | // note: can't prove anything about negative indices 11 | (-1 in arr); 12 | 13 | assert (true == "length" in arr); 14 | 15 | assert (true == "push" in arr); 16 | 17 | assert (false == "missing" in arr); 18 | -------------------------------------------------------------------------------- /tests/djs/arrays/test04.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA Arr(Int) */ [0,1,2]; 3 | 4 | assert (true == 0 in /*: [Int;lA,lArrPro] */ a); 5 | 6 | assert (true == 2 in /*: [Int;lA,lArrPro] */ a); 7 | 8 | assert (false == 3 in /*: [Int;lA,lArrPro] */ a); 9 | 10 | // note: can't prove anything about negative indices 11 | (-1 in /*: [Int;lA,lArrPro] */ a); 12 | 13 | assert (true == "length" in /*: [Int;lA,lArrPro] */ a); 14 | 15 | assert (true == "push" in /*: [Int;lA,lArrPro] */ a); 16 | 17 | assert (false == "missing" in /*: [Int;lA,lArrPro] */ a); 18 | -------------------------------------------------------------------------------- /tests/djs/arrays/test05-inf.js: -------------------------------------------------------------------------------- 1 | 2 | var a = [0,1,2]; 3 | 4 | assert (true == a.hasOwnProperty(0)); 5 | 6 | assert (true == a.hasOwnProperty(2)); 7 | 8 | assert (false == a.hasOwnProperty(3)); 9 | 10 | -------------------------------------------------------------------------------- /tests/djs/arrays/test05.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA Arr(Int) */ [0,1,2]; 3 | 4 | assert (true == /*: [Int;lA,lArrPro] */ (a.hasOwnProperty)(0)); 5 | 6 | assert (true == /*: [Int;lA,lArrPro] */ (a.hasOwnProperty)(2)); 7 | 8 | assert (false == /*: [Int;lA,lArrPro] */ (a.hasOwnProperty)(3)); 9 | 10 | -------------------------------------------------------------------------------- /tests/djs/arrays/test06.js: -------------------------------------------------------------------------------- 1 | var sumTriple = function(x) /*: 2 | [;Lx;] (x:Ref(Lx)) 3 | / (Lx |-> a:{(and (v::Arr(Int)) (packed v) (= (len v) 3))} > lArrPro) 4 | -> Int / same */ { 5 | return x[0] + x[1] + x[2]; 6 | }; 7 | 8 | var a = /*: lA Arr(Int) */ [10,20,30]; 9 | var b = /*: lB Arr(Int) */ [10,20,30,40]; 10 | 11 | /*: [;lA;] */ sumTriple(a); 12 | 13 | /// this version allows x to have _more_ than 3 elements 14 | var sumThree = function(x) /*: 15 | [;Lx;] (x:Ref(Lx)) 16 | / (Lx |-> a:{(and (v::Arr(Int)) (packed v) (>= (len v) 3))} > lArrPro) 17 | -> Int / same */ { 18 | return x[0] + x[1] + x[2]; 19 | }; 20 | 21 | /*: [;lA;] */ sumThree(a); 22 | /*: [;lB;] */ sumThree(b); 23 | -------------------------------------------------------------------------------- /tests/djs/arrays/test07-inf.js: -------------------------------------------------------------------------------- 1 | var sumTriple = function(x) /*: 2 | [;Lx;] (x:Ref(Lx)) / (Lx |-> a: > lArrPro) 3 | -> Int / same */ { 4 | return x[0] + x[1] + x[2]; 5 | }; 6 | 7 | var a = [10,20,30]; 8 | var b = [10,20,30,40]; 9 | 10 | sumTriple(a); 11 | 12 | /// this version allows x to have _more_ than 3 elements 13 | var sumThree = function(x) /*: 14 | [;Lx;] (x:Ref(Lx)) / (Lx |-> a: > lArrPro) 15 | -> Int / same */ { 16 | return x[0] + x[1] + x[2]; 17 | }; 18 | 19 | sumThree(a); 20 | sumThree(b); 21 | -------------------------------------------------------------------------------- /tests/djs/arrays/test07.js: -------------------------------------------------------------------------------- 1 | var sumTriple = function(x) /*: 2 | [;Lx;] (x:Ref(Lx)) / (Lx |-> a: > lArrPro) 3 | -> Int / same */ { 4 | return x[0] + x[1] + x[2]; 5 | }; 6 | 7 | var a = /*: lA */ [10,20,30]; 8 | var b = /*: lB */ [10,20,30,40]; 9 | 10 | /*: [;lA;] */ sumTriple(a); 11 | 12 | /// this version allows x to have _more_ than 3 elements 13 | var sumThree = function(x) /*: 14 | [;Lx;] (x:Ref(Lx)) / (Lx |-> a: > lArrPro) 15 | -> Int / same */ { 16 | return x[0] + x[1] + x[2]; 17 | }; 18 | 19 | /*: [;lA;] */ sumThree(a); 20 | /*: [;lB;] */ sumThree(b); 21 | -------------------------------------------------------------------------------- /tests/djs/arrays/test08.js: -------------------------------------------------------------------------------- 1 | var foo = function(x) /*: 2 | [;Lx;] (x:Ref(Lx)) / (Lx |-> a: > lArrPro) 3 | -> Int / same */ { 4 | if (x[0]) return 1 + x[1]; 5 | return 2 + x[2]; 6 | }; 7 | -------------------------------------------------------------------------------- /tests/djs/arrays/xx_andArray00.js: -------------------------------------------------------------------------------- 1 | var bs = /*: l */ [true, true, false]; 2 | var b = true; 3 | var i; 4 | 5 | /*: (&bs |-> _:Ref(l), &b |-> _:Bool, &i |-> _:{Int|(>= v 0)}, 6 | l |-> _:Arr(Bool) > lArrPro) 7 | -> (&bs |-> _:Ref(l), &b |-> _:Bool, &i |-> _:{Int|(>= v 0)}, 8 | l |-> _:Arr(Bool) > lArrPro) */ 9 | for (i = 0; i < bs.length; i++) { 10 | b = b && bs[i]; 11 | }; 12 | 13 | assert (/*: Bool */ b); 14 | -------------------------------------------------------------------------------- /tests/djs/arrays/xx_matrix02.js: -------------------------------------------------------------------------------- 1 | var row1 = /*: lRow */ ["0","1"]; 2 | var mat = /*: lMat */ [row1, row1]; 3 | var i = 0; 4 | var j = 0; 5 | 6 | /*: outerLoop -> sameType */ 7 | for (; i < mat.length; i++) { 8 | /*: innerLoop -> sameType */ 9 | for (; j < 3; j++) { // BAD: guard should be j < 2 10 | assert (/*: Str */ (mat[i][j])); 11 | } 12 | } 13 | 14 | /*: #define outerLoop ( 15 | &mat |-> _:Ref(lMat), 16 | lMat |-> _: > lArrPro, 17 | lRow |-> _: > lArrPro, 18 | &i |-> _:{Int|(>= v 0)}, 19 | &j |-> _:{Int|(>= v 0)} 20 | ) */ "#define"; 21 | 22 | /*: #define innerLoop ( 23 | &mat |-> _:Ref(lMat), 24 | lMat |-> innerMat: > lArrPro, 25 | lRow |-> _: > lArrPro, 26 | &i |-> _:{Int|(and (>= v 0) (< v (len innerMat)))}, 27 | &j |-> _:{Int|(and (>= v 0))} 28 | ) */ "#define"; 29 | -------------------------------------------------------------------------------- /tests/djs/arrays/xx_sumArray00.js: -------------------------------------------------------------------------------- 1 | var sumPackedArray = function(ns) /*: 2 | [;L] (ns:Ref(L)) / (L |-> _:{(and (v::Arr(Int)) (packed v))} > lArrPro) 3 | -> Int / same */ 4 | { 5 | var sum = 0; 6 | var i; 7 | 8 | /*: (&i |-> _:{Int|(>= v 0)}, &sum |-> _:Int, &ns |-> _:Ref(L), 9 | L |-> a:{(and (v::Arr(Int)) (packed v))} > lArrPro) 10 | -> (&i |-> _:{Int|(>= v 0)}, &sum |-> _:Int, &ns |-> _:Ref(L), 11 | L |-> a':{(= v a)} > lArrPro) */ 12 | for (i=0; i < ns.length; i++) 13 | sum += ns[i+1]; // NOTE: bad index 14 | 15 | return sum; 16 | }; 17 | -------------------------------------------------------------------------------- /tests/djs/arrays/xx_sumArray01.js: -------------------------------------------------------------------------------- 1 | var sumPackedArray = function(ns) /*: 2 | [;L] (ns:Ref(L)) / (L |-> _:{(and (v::Arr(Int)) (packed v))} > lArrPro) 3 | -> Int / same */ 4 | { 5 | var sum = 0; 6 | var i; 7 | 8 | /*: (&i |-> _:{Int|(>= v 0)}, &sum |-> _:Int, &ns |-> _:Ref(L), 9 | L |-> _:{(and (v::Arr(Int)) (packed v))} > lArrPro) 10 | -> same */ 11 | for (i=0; i < ns.length; i++) 12 | sum += ns[i]; 13 | 14 | return sum; 15 | }; 16 | 17 | var arr = (/*: Arr(Int) */ []); 18 | 19 | sumPackedArray(arr); 20 | 21 | arr.push(1); 22 | arr.push(2); 23 | arr.push(3); 24 | 25 | arr[5] = 1; // this _unpacks_ the array 26 | 27 | sumPackedArray(arr); 28 | -------------------------------------------------------------------------------- /tests/djs/dec-draft/0-basics.js: -------------------------------------------------------------------------------- 1 | var k = "g"; 2 | var x = {"f": k}; 3 | assert ("f" in x); 4 | 5 | var xf = x.f; 6 | assert (xf == "g"); 7 | 8 | x[k] = 3; 9 | assert (x[k] == 3); 10 | 11 | delete x.f; 12 | assert (!("f" in x)); 13 | 14 | var y = x; 15 | y.f = "hi"; 16 | 17 | xf = x.f; 18 | assert (xf == "hi"); 19 | -------------------------------------------------------------------------------- /tests/djs/dec-draft/1-negate.js: -------------------------------------------------------------------------------- 1 | var negate = function(x) /*: (x:NumOrBool) -> {(= (tag v) (tag x))} */ { 2 | if (typeof(x) == "number") { 3 | return 0 - x; 4 | } else { 5 | return !x; 6 | } 7 | }; 8 | 9 | assert (typeof (negate(1)) == "number"); 10 | assert (typeof (negate(true)) == "boolean"); 11 | -------------------------------------------------------------------------------- /tests/djs/dec-draft/2-counter.js: -------------------------------------------------------------------------------- 1 | /*: -augmentHeaps false */ "#options"; 2 | 3 | /*: #define ty_toNum (x:Top) -> Num */ '#define'; 4 | 5 | var toNum = function(x) /*: ty_toNum */ { 6 | if (typeof(x) == "number") { return x; } 7 | else if (typeof(x) == "boolean") { return x ? 1 : 0; } 8 | else { return -1; } 9 | }; 10 | 11 | /*: #define ty_getCount 12 | [;Lt,Ltp;] (t:Ref(Lt), c:Str) 13 | / (Lt |-> _:Dict > Ltp, &toNum |-> _:ty_toNum) 14 | -> Num / same */ '#define'; 15 | 16 | var getCount = function(t,c) /*: ty_getCount */ { 17 | if (c in t) { 18 | return toNum(t[c]); 19 | } else { 20 | return 0; 21 | } 22 | }; 23 | 24 | /*: #define ty_incCount 25 | [;Lt,Ltp;] (t:Ref(Lt), c:Str) 26 | / (Lt |-> dt:Dict > Ltp, 27 | &toNum |-> blah1:ty_toNum, 28 | &getCount |-> blah2:ty_getCount) 29 | -> Top 30 | / (Lt |-> _:{(and (eqmod v dt {c}) (Num (sel v c)))} > Ltp, 31 | &toNum |-> same, 32 | &getCount |-> same) */ "#define"; 33 | 34 | var incCount = function(t,c) /*: ty_incCount */ { 35 | var i = getCount(t,c); 36 | t[c] = 1 + i; 37 | }; 38 | -------------------------------------------------------------------------------- /tests/djs/dec-draft/3-dispatch.js: -------------------------------------------------------------------------------- 1 | var dispatch = function(x,f) 2 | /*: [A,B;L1,L2;] 3 | (x:Ref(L1), f:Str) 4 | / (L1 |-> _:{(and (= (tag v) "Dict") 5 | (v :: A) 6 | ((sel v f) :: (_:Ref(L1)) / (L1 |-> _:A > L2) 7 | -> B / same))} > L2) 8 | -> B / same */ 9 | { 10 | var fn = x[f]; 11 | return fn(x); 12 | }; 13 | -------------------------------------------------------------------------------- /tests/djs/dec-draft/4-prototypal.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define nativeIn lObjPro |-> _:Top > lROOT, lFunPro |-> _:Top > lObjPro */ "#define"; 3 | 4 | /*: #define nativeOut lObjPro |-> same, lFunPro |-> same */ "#define"; 5 | 6 | /*: #define ty_beget 7 | [;LL1,LL2,LL3;] 8 | (o:Ref(LL2)) / (LL2 |-> dParent:Top > LL3, nativeIn) 9 | -> Ref(LL1) / (LL1 |-> dChild:{(= v empty)} > LL2, LL2 |-> same, nativeOut) 10 | */ '#define'; 11 | 12 | /*: #define ty_ctor 13 | new [;Lnew,Lpro;] 14 | (this:Ref(Lnew)) / (Lnew |-> dThis:{(= v empty)} > Lpro) 15 | -> Ref(Lnew) / same */ '#define'; 16 | 17 | var beget = function (o) /*: ty_beget */ { 18 | function ctor() /*: ty_ctor */ { return this; }; // TODO upper case letter 19 | ctor.prototype = o; 20 | return new /*: LL1 > LL2 */ ctor(); 21 | }; 22 | 23 | /*: #define ty_get_name 24 | [; Lthis,Lpro; H] 25 | (this:Ref(Lthis)) 26 | / H + (Lthis |-> dThis:{Dict| 27 | (and (objhas [v] "name" H Lpro) 28 | (Str (objsel [v] "name" H Lpro)))} > Lpro) 29 | -> Str / same */ '#define'; 30 | 31 | var herb = /*: lHerb */ { 32 | name : "Herb", 33 | get_name : function() /*: ty_get_name */ { 34 | return "Hi, I'm " + this.name; 35 | } 36 | }; 37 | 38 | var henrietta = /*: [;lHenrietta,lHerb,lObjPro;] */ beget(herb); 39 | henrietta.name = "Henrietta"; 40 | var s = henrietta.get_name(); 41 | assert (typeof s == "string"); 42 | 43 | /*: #define ty_get_name_2 44 | [; Lthis; ] (this:Ref(Lthis)) -> Int */ '#define'; 45 | 46 | herb.get_name = function() /*: ty_get_name_2 */ { return 42; }; 47 | var i = henrietta.get_name(); 48 | assert (/*: Int */ i); 49 | -------------------------------------------------------------------------------- /tests/djs/dec-draft/5-pseudoclassical.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define ty_mammal 3 | new [;Lthis,Lpro;] 4 | (this:Ref(Lthis), name:Str) 5 | / (Lthis |-> dThis:{(= v empty)} > Lpro) 6 | -> Ref(Lthis) 7 | / (Lthis |-> dThis2:{(= v (upd dThis "name" name))} > Lpro) 8 | */ '#define'; 9 | 10 | /*: #define ty_get_name 11 | [; Lthis,Lpro; H] 12 | (this:Ref(Lthis)) 13 | / H + (Lthis |-> dThis:{Dict| 14 | (and (objhas [v] "name" H Lpro) 15 | (Str (objsel [v] "name" H Lpro)))} > Lpro) 16 | -> Str / same */ '#define'; 17 | 18 | function Mammal(name) /*: ty_mammal */ { 19 | this.name = name; 20 | return this; 21 | }; 22 | 23 | Mammal.prototype.get_name = function() /*: ty_get_name */ { 24 | return "Hi, I'm " + this.name; 25 | }; 26 | 27 | function Cat(name) /*: ty_mammal */ { 28 | this.name = name; 29 | return this; 30 | }; 31 | 32 | Cat.prototype = new /*: lNewCatPro > lMammalProto */ 33 | Mammal("__dummy__"); 34 | 35 | var henrietta = new /*: lHenrietta > lNewCatPro */ 36 | Cat("Henrietta"); 37 | 38 | var s = henrietta.get_name(); 39 | 40 | assert (/*: Str */ s); 41 | 42 | -------------------------------------------------------------------------------- /tests/djs/dec-draft/7-parts.js: -------------------------------------------------------------------------------- 1 | 2 | var make_dog = function(x) /*: ty_make_dog */ { 3 | x.bark = function() /*: ty_sound */ { return "bark"; }; 4 | }; 5 | 6 | var make_cat = function(x) /*: ty_make_cat */ { 7 | x.purr = function() /*: ty_sound */ { return "purr"; }; 8 | }; 9 | 10 | var hybrid = /*: l */ {}; 11 | make_dog(hybrid); 12 | make_cat(hybrid); 13 | var noise = hybrid.bark() + hybrid.purr(); 14 | assert (/*: Str */ noise); 15 | 16 | 17 | /*: #define ty_make_dog 18 | [;L1,L2;] (x:Ref(L1)) / (L1 |-> dThis:Dict > L2) 19 | -> Top / (L1 |-> dThis':{(and (eqmod v dThis {"bark"}) 20 | ((sel v "bark") :: ty_sound))} > L2) 21 | */ '#define'; 22 | 23 | /*: #define ty_make_cat 24 | [;L1,L2;] (x:Ref(L1)) / (L1 |-> dThis:Dict > L2) 25 | -> Top / (L1 |-> dThis':{(and (eqmod v dThis {"purr"}) 26 | ((sel v "purr") :: ty_sound))} > L2) 27 | */ '#define'; 28 | 29 | /*: #define ty_sound [;L1;] (this:Ref(L1)) -> Str */ '#define'; 30 | -------------------------------------------------------------------------------- /tests/djs/forin/makeCumulative00.js: -------------------------------------------------------------------------------- 1 | // adapted from SunSpider string-fasta.js. added explicit tag-tests. 2 | 3 | var makeCumulative = function(table) 4 | /*: [;L1,L2] [[table:Ref(L1)]] / [L1 |-> (_:Dict, L2)] 5 | -> Top / [L1 |-> (_:Dict, L2)] */ 6 | { 7 | var last = null; 8 | var c; 9 | /*: [&c |-> _:Str, 10 | &last |-> _:{(implies (not (= v null)) (v : Str))}, 11 | &table |-> _:Ref(L1), 12 | L1 |-> (_:Dict, L2)] -> sameType */ 13 | for (c in table) { 14 | if (last) { 15 | if (typeof table[c] == "number" && typeof table[last] == "number") { 16 | table[c] = table[c] + table[last]; 17 | } 18 | } 19 | last = c; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /tests/djs/forin/makeCumulative01.js: -------------------------------------------------------------------------------- 1 | var makeCumulative = function(table) 2 | /*: [;L1,L2] [[table:Ref(L1)]] / [L1 |-> (_:Dict, L2)] 3 | -> Top / [L1 |-> (_:Dict, L2)] */ 4 | { 5 | var last = null; 6 | var c; 7 | /*: [Heap] [Heap ++ 8 | &last |-> _:{(implies (not (= v null)) 9 | (and (v : Str) 10 | (objhas d v Heap L2) 11 | ((objsel d v Heap L2) : Num)))}, 12 | &c |-> _:Str, &table |-> _:Ref(L1), L1 |-> (d:Dict, L2)] 13 | -> Top / sameType */ 14 | for (c in table) { 15 | if (last) { 16 | // this is pretty cute. can omit the tag-test for table[last] 17 | // becaues the invariant captures that if last is non-null, then 18 | // it's bound to a number in the dictionary 19 | if (typeof table[c] == "number") { 20 | table[c] = table[c] + table[last]; 21 | last = c; 22 | } 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /tests/djs/forin/sumBindings00.js: -------------------------------------------------------------------------------- 1 | var x = /*: lx */ {f:1, g:true}; 2 | var k; 3 | var sum = 0; 4 | 5 | /*: [&sum |-> _:Num, 6 | &x |-> _:Ref(lx), 7 | &k |-> _:Str, 8 | lx |-> (_:Dict, lObjectProto)] -> sameType */ 9 | for (k in x) { 10 | if (typeof x[k] === "number") { 11 | sum += 1 + x[k]; 12 | } 13 | } 14 | 15 | assert (typeof sum === "number"); 16 | -------------------------------------------------------------------------------- /tests/djs/forin/xx_forin00.js: -------------------------------------------------------------------------------- 1 | var x = /*: lx */ {}; 2 | var k; 3 | 4 | /*: [Heap] 5 | [Heap ++ 6 | &x |-> _:Ref(lx), 7 | &k |-> kk:Str, 8 | lx |-> (d:{Dict|(implies (objhas v kk Heap lObjectProto) 9 | ((objsel v kk Heap lObjectProto) : Bool))}, lObjectProto) 10 | ] -> Top / sameType */ 11 | for (k in x) { 12 | // BAD: the annotation is a _forall_ property, so recursive call won't type check 13 | } 14 | -------------------------------------------------------------------------------- /tests/djs/forin/xx_make01.js: -------------------------------------------------------------------------------- 1 | var makeCumulative = function(table) 2 | /*: [;L1,L2] [[table:Ref(L1)]] / [L1 |-> (_:Dict, L2)] 3 | -> Top / [L1 |-> (_:Dict, L2)] */ 4 | { 5 | var last = null; 6 | var c; 7 | /*: [Heap] [Heap ++ 8 | &last |-> _:{(implies (not (= v null)) 9 | (and (v : Str) 10 | (objhas d v Heap L2) 11 | ((objsel d v Heap L2) : Num)))}, 12 | &c |-> _:Str, &table |-> _:Ref(L1), L1 |-> (d:Dict, L2)] 13 | -> Top / sameType */ 14 | for (c in table) { 15 | if (last) { 16 | // this is pretty cute. can omit the tag-test for table[last] 17 | // becaues the invariant captures that if last is non-null, then 18 | // it's bound to a number in the dictionary 19 | if (typeof table[c] == "number") { 20 | table[c] = table[c] + table[last]; 21 | last = 0; // BAD assignment 22 | } 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /tests/djs/loops/test00-augment.js: -------------------------------------------------------------------------------- 1 | var i /*: Int */ = 0; 2 | while (i < 10) { 3 | i = i + 1; 4 | }; 5 | assert (/*: Int */ i); 6 | -------------------------------------------------------------------------------- /tests/djs/loops/test00.js: -------------------------------------------------------------------------------- 1 | var i = 0; 2 | /*: (&i: Int) -> (&i: Int) */ 3 | while (i < 10) { 4 | i = i + 1; 5 | }; 6 | assert (/*: Int */ i); 7 | -------------------------------------------------------------------------------- /tests/djs/loops/test01.js: -------------------------------------------------------------------------------- 1 | var i = 0; 2 | /*: (&i: n:Int) -> (&i: {Int|(ite (< n 10) (= v 10) (= v n))}) */ 3 | while (i < 10) { 4 | i = i + 1; 5 | }; 6 | assert (i == 10); 7 | -------------------------------------------------------------------------------- /tests/djs/loops/whileFalse0.js: -------------------------------------------------------------------------------- 1 | var b = false; 2 | 3 | /*: (&b |-> x1:Bool) 4 | -> (&b |-> x2:{(= v true)}) */ 5 | while (!b) { b = !b; } 6 | 7 | assert (b == true); 8 | -------------------------------------------------------------------------------- /tests/djs/loops/whileFalse2.js: -------------------------------------------------------------------------------- 1 | var foo = function(b) /*: (b:Bool) -> {(= v true)} */ { 2 | /*: (&b |-> x1:Bool) 3 | -> (&b |-> x2:{(= v true)}) */ 4 | while (!b) { b = !b; } 5 | return b; 6 | }; 7 | 8 | assert (true == foo(true)); 9 | assert (true == foo(false)); 10 | -------------------------------------------------------------------------------- /tests/djs/loops/whileFalse3.js: -------------------------------------------------------------------------------- 1 | var foo = function(b) /*: (b:Bool) -> {(= v true)} */ { 2 | 3 | /*: (&b |-> a1:Bool) -> (&b |-> a2:{(= v true)}) */ 4 | do { b = !b; } 5 | while (!b); 6 | 7 | return b; 8 | }; 9 | 10 | assert (true == foo(true)); 11 | assert (true == foo(false)); 12 | -------------------------------------------------------------------------------- /tests/djs/loops/whileFalse4.js: -------------------------------------------------------------------------------- 1 | var foo = function(b) /*: (b:Bool) -> {(= v true)} */ { 2 | /*: (&b |-> a1:Bool) -> (&b |-> a2:{(= v true)}) */ 3 | for (; !b; b = !b); 4 | return b; 5 | }; 6 | 7 | assert (true == foo(true)); 8 | assert (true == foo(false)); 9 | -------------------------------------------------------------------------------- /tests/djs/loops/xx_00.js: -------------------------------------------------------------------------------- 1 | var i = 0; 2 | /*: (&i|->n:Int) -> 3 | (&i|->m:{Int|(ite (< n 10) (= v 10) (= v n))}) */ 4 | while (i < 10) { 5 | i = i + 2; // incrementing by 2 breaks the desired invariant 6 | }; 7 | assert (i == 10); 8 | -------------------------------------------------------------------------------- /tests/djs/macros/test00.js: -------------------------------------------------------------------------------- 1 | /*: id :: (x:Top) -> {(= v x)} */ "#type"; 2 | var id = function(x) /*: id */ { 3 | return x; 4 | }; 5 | -------------------------------------------------------------------------------- /tests/djs/macros/test01.js: -------------------------------------------------------------------------------- 1 | /*: int_to_int :: (x:Int) -> Int */ "#type"; 2 | /*: bool_to_bool :: (x:Bool) -> Bool */ "#type"; 3 | 4 | var id = function(x) /*: {(and (v :: int_to_int) (v :: bool_to_bool))} */ { 5 | return x; 6 | }; 7 | -------------------------------------------------------------------------------- /tests/djs/macros/test02.js: -------------------------------------------------------------------------------- 1 | /*: id = (x:Top) -> {(= v x)} */ "#type"; 2 | var id = function(x) /*: id */ { 3 | return x; 4 | }; 5 | -------------------------------------------------------------------------------- /tests/djs/macros/test03.js: -------------------------------------------------------------------------------- 1 | /*: id = (x:Top) -> {(= v x)} */ "#type"; 2 | var id = function(x) { 3 | return x; 4 | }; 5 | -------------------------------------------------------------------------------- /tests/djs/macros/test04.js: -------------------------------------------------------------------------------- 1 | /*: id :: (x:Top) -> {(= v x)} */ "#type"; 2 | var id = function(x) { 3 | return x; 4 | }; 5 | -------------------------------------------------------------------------------- /tests/djs/macros/test05.js: -------------------------------------------------------------------------------- 1 | var obj = {}; 2 | 3 | /*: id :: (x:Top) -> {(= v x)} */ "#type"; 4 | obj.id = function(x) { 5 | return x; 6 | }; 7 | -------------------------------------------------------------------------------- /tests/djs/misc/ab00.js: -------------------------------------------------------------------------------- 1 | var A = 1; 2 | 3 | var foo = function() 4 | /*: () / (&A |-> _:Int) -> Int / (&A |-> _:Int) */ 5 | { return A; }; 6 | 7 | var i = foo(); assert (typeof i == "number"); 8 | 9 | assert (typeof foo() == "number"); 10 | -------------------------------------------------------------------------------- /tests/djs/misc/access00.js: -------------------------------------------------------------------------------- 1 | // SunSpider access-nbody.js 2 | 3 | var PI = 3.141592653589793; 4 | var SOLAR_MASS = 4 * PI * PI; 5 | var DAYS_PER_YEAR = 365.24; 6 | 7 | /*: #define tyBody 8 | {Dict|(and (dom v {"x","y","z","vx","vy","vz","mass"}) 9 | (Num (sel v "x")) 10 | (Num (sel v "y")) 11 | (Num (sel v "z")) 12 | (Num (sel v "vx")) 13 | (Num (sel v "vy")) 14 | (Num (sel v "vz")) 15 | (Num (sel v "mass")))} */ "#define"; 16 | 17 | /*: #define ctorBody 18 | [;Lnew] (this:Ref(Lnew),x:Num,y:Num,z:Num,vx:Num,vy:Num,vz:Num,mass:Num) 19 | / (Lnew |-> Empty > lBodyProto) 20 | -> Ref(Lnew) / (Lnew |-> tyBody > lBodyProto) */ "#define"; 21 | 22 | function Body(x,y,z,vx,vy,vz,mass) /*: new ctorBody */ { 23 | this.x = x; 24 | this.y = y; 25 | this.z = z; 26 | this.vx = vx; 27 | this.vy = vy; 28 | this.vz = vz; 29 | this.mass = mass; 30 | return this; 31 | } 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | 35 | /*: #define tyOffsetMomentum 36 | [;L] (this:Ref(L), px:Num, py:Num, pz:Num) 37 | / (L |-> _:tyBody > lBodyProto, &SOLAR_MASS |-> _:Num) 38 | -> Ref(L) / sameType */ "#define"; 39 | 40 | Body.prototype.offsetMomentum = function(px,py,pz) /*: tyOffsetMomentum */ { 41 | this.vx = -px / SOLAR_MASS; 42 | this.vy = -py / SOLAR_MASS; 43 | this.vz = -pz / SOLAR_MASS; 44 | return this; 45 | }; 46 | -------------------------------------------------------------------------------- /tests/djs/misc/id.js: -------------------------------------------------------------------------------- 1 | var id = function(x) /*: (x:Top) -> {(= v x)} */ { 2 | return x; 3 | }; 4 | 5 | assert (id(1) == 1); 6 | assert (id(true) == true); 7 | assert (id({f: 'yo'}.f) == 'yo'); 8 | assert (id({f: 'yo'}.f) != 'hey'); 9 | -------------------------------------------------------------------------------- /tests/djs/misc/if00.js: -------------------------------------------------------------------------------- 1 | var foo = function(b, n) /*: (b:Bool, n:Int) -> Int */ { 2 | if (b) { return n + 2; } 3 | return 0; 4 | }; 5 | -------------------------------------------------------------------------------- /tests/djs/misc/negate00.js: -------------------------------------------------------------------------------- 1 | var negate = function(x) /*: (x:NumOrBool) -> {(ite (Num x) (Num v) (Bool v))} */ { 2 | if (typeof(x) == "number") { x = 0 - x; } 3 | else { x = !x; } 4 | return x; 5 | }; 6 | 7 | assert (typeof (negate(1)) == "number"); 8 | assert (typeof (negate(true)) == "boolean"); 9 | -------------------------------------------------------------------------------- /tests/djs/misc/negate01.js: -------------------------------------------------------------------------------- 1 | var negate = function(x) /*: (x:NumOrBool) -> {(ite (Num x) (Num v) (Bool v))} */ { 2 | x = (typeof(x) == "number") ? 0 - x : !x; 3 | return x; 4 | }; 5 | 6 | assert (typeof (negate(1)) == "number"); 7 | assert (typeof (negate(true)) == "boolean"); 8 | -------------------------------------------------------------------------------- /tests/djs/misc/negate02.js: -------------------------------------------------------------------------------- 1 | var negate = function(x) /*: (x:Top) -> {(ite (Num x) (Num v) (Bool v))} */ { 2 | if (typeof(x) == "number") { return 0 - x; } 3 | else { return !x; } 4 | }; 5 | 6 | assert (typeof (negate(1)) == "number"); 7 | assert (typeof (negate(true)) == "boolean"); 8 | assert (typeof (negate(null)) == "boolean"); 9 | -------------------------------------------------------------------------------- /tests/djs/misc/onto00.js: -------------------------------------------------------------------------------- 1 | 2 | //// this type handles only the fn = null case. 3 | //// need to run with -tryAllBoxes flag. 4 | 5 | 6 | /*: #define TtT _:Top -> Top */ "#define"; 7 | 8 | /*: #define LarrBinding Larr |-> (_:Arr(TtT), lArrayProto)*/ "#define"; 9 | 10 | /*: #define UntamperedPush 11 | lArrayProto |-> 12 | (_:{(= (sel v "push") ____ArrayProto_push)}, lObjectProto) */ "#define"; 13 | 14 | /*: #define ty1 [;Larr] 15 | [[arr:Ref(Larr), obj:TtT, fn:{(= v null)}]] / [LarrBinding, UntamperedPush] 16 | -> Top / [LarrBinding, UntamperedPush] */ "#define"; 17 | 18 | var _onto = function(arr, obj, fn) /*: {(and (v::ty1))} */ { 19 | if (!fn) { arr.push(obj); } 20 | else if (fn) { 21 | var func = (typeof fn == "string") ? obj[fn] : fn; 22 | arr.push(function() /*: [[]] -> Top */ { func.call(obj); }); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /tests/djs/misc/toNum00.js: -------------------------------------------------------------------------------- 1 | var toNum = function(x) /*: (Top) -> Num */ { 2 | if (typeof(x) == "number") { return x; } 3 | else if (typeof(x) == "boolean") { return x ? 1 : 0; } 4 | else { return -1; } 5 | }; 6 | 7 | assert (typeof toNum(1) == "number"); 8 | assert (typeof toNum(null) == "number"); 9 | -------------------------------------------------------------------------------- /tests/djs/misc/unreachable00.js: -------------------------------------------------------------------------------- 1 | if (1 === 2) { 2 | "anything" / "goes"; 3 | } 4 | -------------------------------------------------------------------------------- /tests/djs/misc/unreachable01.js: -------------------------------------------------------------------------------- 1 | var succ = function(i) /*: (i:Int) -> Int */ { return 1 + i; }; 2 | 3 | if (1 === 2) { 4 | succ ("anything" / "goes"); 5 | } 6 | -------------------------------------------------------------------------------- /tests/djs/misc/xx_id.js: -------------------------------------------------------------------------------- 1 | var id = function(x) /*: (x:Top) -> {(= v x)} */ { 2 | return x; 3 | }; 4 | 5 | assert (id(1) == 1); 6 | assert (id(true) == false); 7 | -------------------------------------------------------------------------------- /tests/djs/misc/xx_string-fasta.js: -------------------------------------------------------------------------------- 1 | /*: makeCumulative :: [;L1,L2] 2 | (table:Ref(L1)) / (L1 |-> Dict > L2) -> Int / sameType */ "#type"; 3 | 4 | var makeCumulative = function(table) { 5 | var last = null; 6 | var c; 7 | /*: [Heap] Heap + 8 | (&last |-> {(implies (not (= v null)) 9 | (and (Str v) (Num (objsel [d] v Heap L2))))}, 10 | &c |-> Str, &table |-> Ref(L1), L1 |-> d:Dict > L2) 11 | -> sameType */ 12 | for (c in table) { 13 | if (last) { 14 | if ((typeof table[c]) == "number") { 15 | table[c] = table[c] + table[last]; 16 | last = c; 17 | } 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /tests/djs/misc/xx_typedDs00.js: -------------------------------------------------------------------------------- 1 | Object[1]; 2 | -------------------------------------------------------------------------------- /tests/djs/objects/ctor00.js: -------------------------------------------------------------------------------- 1 | function F() 2 | /*: new [;L;] 3 | (this:Ref(L)) 4 | / (L |-> dThis:{(= v empty)} > &FProto, &FProto |-> _:Top > lObjectProto) 5 | -> Ref(L) 6 | / (L |-> _:{(= v (upd dThis "f" 1))} > &FProto, &FProto |-> same) */ 7 | { 8 | this.f = 1; 9 | return this; 10 | } 11 | -------------------------------------------------------------------------------- /tests/djs/objects/ctor01.js: -------------------------------------------------------------------------------- 1 | function F() 2 | /*: new [;L;] 3 | (this:Ref(L)) 4 | / (L |-> dThis:{(= v empty)} > lFProto, lFProto |-> _:Dict > lObjPro) 5 | -> Ref(L) 6 | / (L |-> _:{(= v (upd dThis "f" 1))} > lFProto, lFProto |-> same) */ 7 | { 8 | this.f = 1; 9 | return this; 10 | } 11 | 12 | assert (/*: Ref(lFProto) */ (F.prototype)); 13 | 14 | F.prototype.g = "sweet"; 15 | 16 | var x = new (/*: lx > lFProto */ F)(); 17 | 18 | assert (x.f == 1); 19 | assert (x.g == "sweet"); 20 | 21 | F.prototype.g = "updated"; 22 | 23 | assert (x.g == "updated"); 24 | -------------------------------------------------------------------------------- /tests/djs/objects/ctor02.js: -------------------------------------------------------------------------------- 1 | 2 | // notice that this constructor doesn't explicitly name H because 3 | // it doesn't mention and Obj* symbols. 4 | // though, of course, a prefix heap var will be added by parser. 5 | 6 | /*: #define tyGetName 7 | [;Lthis,Lpro;HH] 8 | (this:Ref(Lthis)) 9 | / HH + (Lthis |-> innerDThis:{Dict| 10 | (and (objhas [v] "name" HH Lpro) 11 | (Str (objsel [v] "name" HH Lpro)))} > Lpro) 12 | -> {(= v (objsel [innerDThis] "name" HH Lpro))} 13 | / same 14 | */ "#define"; 15 | 16 | function Foo(name) 17 | /*: new [;Lthis;] 18 | (this:Ref(Lthis), name:Str) 19 | / (Lthis |-> dThis:{(= v empty)} > lFooProto) 20 | -> Ref(Lthis) 21 | / (Lthis |-> dThis2:{Dict| 22 | (and (dom v {"name","getName"}) 23 | (= (sel v "name") name) 24 | ((sel v "getName") :: tyGetName) 25 | )} > lFooProto) */ 26 | { 27 | this.name = name; 28 | 29 | this.getName = function() /*: tyGetName */ { return this.name; }; 30 | 31 | return this; 32 | } 33 | 34 | var bob = new /*: lBob > lFooProto */ Foo("bob"); 35 | 36 | assert (bob.name == "bob"); 37 | assert (bob.getName() == "bob"); 38 | -------------------------------------------------------------------------------- /tests/djs/objects/ctor03.js: -------------------------------------------------------------------------------- 1 | function F() /*: new [;L;] (this:Ref(L)) / (L: Empty > &FProto) 2 | -> {(= v this)} / sameExact */ 3 | { 4 | return this; 5 | } 6 | -------------------------------------------------------------------------------- /tests/djs/objects/family00.js: -------------------------------------------------------------------------------- 1 | /*: #define nativeIn 2 | lObjPro |-> _:Top > lROOT, lFunPro |-> _:Top > lObjPro */ "#define"; 3 | 4 | /*: #define nativeOut 5 | lObjPro |-> same, lFunPro |-> same */ "#define"; 6 | 7 | /*: #define ty_beget [;LL1,LL2,LL3;] 8 | (o:Ref(LL2)) / (LL2 |-> dParent:Top > LL3, nativeIn) 9 | -> Ref(LL1) / (LL1 |-> dChild:{(= v empty)} > LL2, LL2 |-> same, nativeOut) 10 | */ '#define'; 11 | 12 | /*: #define ty_ctor [;Lnew,Lpro;] 13 | (this:Ref(Lnew)) / (Lnew |-> dThis:{(= v empty)} > Lpro) 14 | -> Ref(Lnew) / same */ '#define'; 15 | 16 | var beget = function (o) /*: ty_beget */ { 17 | function ctor() /*: new ty_ctor */ { return this; }; 18 | ctor.prototype = o; 19 | return new /*: LL1 > LL2 */ ctor(); 20 | }; 21 | 22 | var parent = /*: lParent */ {"last": " Doe"}; 23 | var child = /*: [;lChild,lParent,lObjPro;] */ beget(parent); 24 | 25 | assert ("last" in child == true); 26 | assert (child.hasOwnProperty("last") == false); 27 | 28 | -------------------------------------------------------------------------------- /tests/djs/objects/get00.js: -------------------------------------------------------------------------------- 1 | var x = {f:1}; 2 | 3 | assert (x.f == 1); 4 | assert (x.g == undefined); 5 | 6 | // 8/29/12: no longer allowing natives to be modified 7 | // Object.prototype.g = "yipee"; 8 | // assert (x.g == "yipee"); 9 | -------------------------------------------------------------------------------- /tests/djs/objects/hasBool00.js: -------------------------------------------------------------------------------- 1 | var hasBool = function(obj) /*: [;LL1,LL2;Heap] 2 | (obj:Ref(LL1)) 3 | / Heap + 4 | (LL1 |-> _:{Dict|(implies (objhas v "f" Heap LL2) 5 | (Bool (objsel v "f" Heap LL2)))} > LL2) 6 | -> Top / same */ 7 | { 8 | if ("f" in obj) { 9 | assert (typeof obj.f === "boolean"); 10 | assert ((obj.f === true) || (obj.f === false)); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /tests/djs/objects/hasOwnProp00.js: -------------------------------------------------------------------------------- 1 | 2 | var x = /*: lx */ {f:0, g:"hi"}; 3 | 4 | assert (/*: {(= v true)} */ 5 | (/*: [;lx,lObjPro;] */ (x.hasOwnProperty)("f"))); 6 | 7 | assert (/*: {(= v true)} */ 8 | (/*: [;lx,lObjPro;] */ (x.hasOwnProperty)("g"))); 9 | 10 | assert (/*: {(= v false)} */ 11 | (/*: [;lx,lObjPro;] */ (x.hasOwnProperty)("h"))); 12 | 13 | -------------------------------------------------------------------------------- /tests/djs/objects/localInf00.js: -------------------------------------------------------------------------------- 1 | 2 | var x = {f:0, g:"hi"}; 3 | 4 | assert (x.g == "hi"); // Look, ma, no location params! 5 | 6 | x.g = "hello"; 7 | 8 | assert (x.g == "hello"); 9 | 10 | var b = x.hasOwnProperty("f") 11 | && x.hasOwnProperty("g") 12 | && !(x.hasOwnProperty("h")); 13 | 14 | assert (b == true); 15 | 16 | -------------------------------------------------------------------------------- /tests/djs/objects/mem00.js: -------------------------------------------------------------------------------- 1 | var x = {}; 2 | x.f = undefined; 3 | assert (/*: {(= v true )} */ ("f" in x)); 4 | -------------------------------------------------------------------------------- /tests/djs/objects/mem01.js: -------------------------------------------------------------------------------- 1 | var x = {}; 2 | assert (/*: {(= v false )} */ ("f" in x)); 3 | assert (/*: {(= v undefined)} */ (x.f)); 4 | 5 | x.f = undefined; 6 | assert (/*: {(= v true )} */ ("f" in x)); 7 | assert (/*: {(= v undefined)} */ (x.f)); 8 | -------------------------------------------------------------------------------- /tests/djs/objects/ossugar00.js: -------------------------------------------------------------------------------- 1 | // /*: #define ty_get_name 2 | // [; Lthis,Lpro; H] 3 | // [[this:Ref(Lthis)]] 4 | // / [H ++ Lthis |-> (dThis:{Dict| 5 | // (and (objhas [v] "name" [H] Lpro) 6 | // ((objsel [v] "name" [H] Lpro) : Str))}, Lpro)] 7 | // -> Str / same */ '#define'; 8 | // 9 | // //// the following uses a modified objsel syntactic sugar macro 10 | // //// in place of the above 11 | 12 | /*: #define ty2 13 | [; Lthis,Lpro; H] 14 | (this:Ref(Lthis)) 15 | / H + (Lthis |-> dThis:{Dict|(Str (objsel [v] "name" H Lpro))} > Lpro) 16 | -> Str / same */ '#define'; 17 | 18 | var herb = { 19 | name : "Herb", 20 | get_name : function() /*: ty2 */ { 21 | return "Hi, I'm " + this.name; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /tests/djs/objects/read00.js: -------------------------------------------------------------------------------- 1 | var read = function(x,f) 2 | /*: [;L,L2;H] (x:Ref(L), f:Str) 3 | / H + (L |-> cx:{Dict|(objhas [v] f H L2)} > L2) 4 | -> {(= v (objsel [cx] f H L2))} 5 | / same */ { 6 | return x[f]; 7 | }; 8 | 9 | assert (read({a:1},"a") == 1); 10 | assert (read({b:true},"b") == true); 11 | -------------------------------------------------------------------------------- /tests/djs/objects/simple00.js: -------------------------------------------------------------------------------- 1 | var x = {"f": 1}; 2 | assert (x.f == 1 && x.g == undefined); 3 | x.g = 2; delete x.f; 4 | assert (x.g == 2 && x.f == undefined); 5 | var k = "h"; x[k] = 3; assert (x[k] == 3); 6 | -------------------------------------------------------------------------------- /tests/djs/objects/undef00.js: -------------------------------------------------------------------------------- 1 | var x = {}; 2 | var y = {"f": undefined}; 3 | assert (x.f == undefined && "f" in x == false); 4 | assert (y.f == undefined && "f" in y == true); 5 | -------------------------------------------------------------------------------- /tests/djs/objects/xx_ctor00.js: -------------------------------------------------------------------------------- 1 | function F() 2 | /*: new [;L;] 3 | (this:Ref(L)) 4 | / (L |-> dThis:{(= v empty)} > lFProto, lFProto |-> _:Top > lObjectProto) 5 | -> Ref(L) 6 | / (L |-> _:{(= v (upd dThis "f" 1))} > lFProto, lFProto |-> same) */ 7 | { 8 | this.f = "not 1"; 9 | return this; 10 | } 11 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/access-binary-trees.js: -------------------------------------------------------------------------------- 1 | /*: (~lTreeNode: {item: Int, left: Ref(~lTreeNode), right:Ref(~lTreeNode), _:Bot} 2 | > lTreeNodeProto) */ "#weak"; 3 | 4 | function TreeNode(left,right,item) 5 | /*: (this:Ref, left:Ref(~lTreeNode), right:Ref(~lTreeNode), item:Int) 6 | / (this: d:Empty > lTreeNodeProto) -> Ref(~lTreeNode) / () */ { 7 | this.left = left; 8 | this.right = right; 9 | this.item = item; 10 | 11 | /*: this (~lTreeNode, frzn) */ "#freeze"; 12 | return this; 13 | }; 14 | 15 | var tree1 = new TreeNode(null, null, 10); 16 | var tree2 = new TreeNode(null, null, 20); 17 | var tree3 = new TreeNode(tree1, tree2, 30); 18 | 19 | var i = tree1.item; 20 | assert (typeof i === "number"); 21 | 22 | TreeNode.prototype.itemCheck = function itemCheck() /*: (this:Ref(~lTreeNode)) -> Int */ { 23 | if (this.left == null) { return this.item; } 24 | else { return this.item + itemCheck.apply(this.left) + itemCheck.apply(this.right); } 25 | }; 26 | 27 | var j = (tree1.itemCheck).apply(tree1); 28 | assert (typeof j === "number"); 29 | 30 | var bottomUpTree = function foo(item,depth) /*: (item:Int, depth:Int) -> Ref(~lTreeNode) */ { 31 | if (depth > 0) { 32 | return new TreeNode( 33 | foo (2*item-1, depth-1), 34 | foo (2*item, depth-1), 35 | item 36 | ); 37 | } 38 | else { 39 | return new TreeNode(null,null,item); 40 | } 41 | }; 42 | 43 | var tree4 = bottomUpTree(0,42); 44 | var k = (tree4.itemCheck).apply(tree4); 45 | assert (typeof k === "number"); 46 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/counter.js: -------------------------------------------------------------------------------- 1 | var toNum = function(x) /*: (Top) -> Num */ { 2 | if (typeof(x) == "number") { return x; } 3 | else if (typeof(x) == "boolean") { return x ? 1 : 0; } 4 | else { return -1; } 5 | }; 6 | 7 | var getCount = function(t,c) /*: (t:Ref, Str) / (t: Dict > t.pro) -> Num / same */ { 8 | if (c in t) { 9 | return toNum(t[c]); 10 | } else { 11 | return 0; 12 | } 13 | }; 14 | 15 | /*: incCount :: (t:Ref, c:Str) / (t: dt:Dict > t.pro) 16 | -> Top / (t: {(and (eqmod v dt {c}) (Num (sel v c)))} > t.pro) */ "#type"; 17 | var incCount = function(t,c) { 18 | var i = getCount(t,c); 19 | t[c] = 1 + i; 20 | }; 21 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/dispatch.js: -------------------------------------------------------------------------------- 1 | /*: dispatch :: [A,B] (x:Ref, f:Str) 2 | / (x: {(and (= (tag v) "Dict") (v :: A) 3 | ((sel v f) :: (Ref(x)) / (x: A > x.pro) -> B / same))} > x.pro) 4 | -> B / same */ "#type"; 5 | var dispatch = function(x,f) { 6 | var fn = x[f]; 7 | return fn(x); 8 | }; 9 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/functional.js: -------------------------------------------------------------------------------- 1 | 2 | var mammal = function(priv) /*: ty_init_mammal */ { 3 | var x = /*: Lnew */ {}; 4 | x.get_name = function() /*: ty_get_name */ { 5 | return priv.name; 6 | }; 7 | return x; 8 | }; 9 | 10 | /*: ty_priv {Dict|(Str (sel v "name"))} */ '#define'; 11 | 12 | /*: ty_init_mammal [;Lnew,Lpriv] 13 | (priv:Ref(Lpriv)) / (Lpriv: dPriv:ty_priv > lObjPro) 14 | -> Ref(Lnew) / (Lpriv: same, &priv: blah1:Ref(Lpriv), 15 | Lnew: dNew:ty_mam > lObjPro) */ '#define'; 16 | 17 | /*: ty_mam {get_name: ty_get_name, _:Bot} */ '#define'; 18 | 19 | /*: ty_get_name 20 | (this:Top) / (Lpriv: ePriv:ty_priv > lObjPro, &priv: blah:Ref(Lpriv)) 21 | -> {(= v (sel ePriv "name"))} / same */ '#define'; 22 | 23 | ////////////////////////////////////////////////////////////////////////////// 24 | 25 | var herbPriv = /*: lHerbPriv */ {name: "Herb"}; 26 | var herb = /*: [;lHerb,lHerbPriv;] */ mammal(herbPriv); 27 | var oldName = herb.get_name(); 28 | 29 | assert (oldName == "Herb"); 30 | 31 | ////////////////////////////////////////////////////////////////////////////// 32 | 33 | 34 | herbPriv.name = "Herbert"; 35 | var newName = herb.get_name(); 36 | 37 | assert (newName == "Herbert"); 38 | 39 | ////////////////////////////////////////////////////////////////////////////// 40 | 41 | 42 | var cat = function(priv2) /*: ty_init_cat */ { 43 | var obj = /*: [;Lnew,Lpriv;] */ mammal(priv2); 44 | obj.purr = function() /*: ty_sound */ { return "purr"; }; 45 | return obj; 46 | }; 47 | 48 | /*: ty_init_cat [;Lnew,Lpriv] 49 | (priv2:Ref(Lpriv)) / (Lpriv: dPriv:ty_priv > lObjPro) 50 | -> Ref(Lnew) / (Lpriv: same, &priv: blah1:Ref(Lpriv), 51 | Lnew: dNew:ty_cat > lObjPro) */ '#define'; 52 | 53 | /*: ty_cat {purr: ty_sound, get_name: ty_get_name, _:Bot} */ '#define'; 54 | 55 | /*: ty_sound (this:Top) -> Str */ '#define'; 56 | 57 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/negate.js: -------------------------------------------------------------------------------- 1 | var negate = function(x) /*: (x:NumOrBool) -> {(= (tag v) (tag x))} */ { 2 | if (typeof(x) == "number") { 3 | return 0 - x; 4 | } else { 5 | return !x; 6 | } 7 | }; 8 | 9 | assert (typeof (negate(1)) == "number"); 10 | assert (typeof (negate(true)) == "boolean"); 11 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/parts.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define ty_sound (this:Top) -> Str */ '#define'; 3 | 4 | /*: ty_make_dog :: (x:Ref) / (x: dThis:Dict > x.pro) 5 | -> Top / (x: {(and (eqmod v dThis {"bark"}) 6 | ((sel v "bark") :: ty_sound))} > x.pro) */ '#type'; 7 | 8 | /*: ty_make_cat :: (x:Ref) / (x: dThis:Dict > x.pro) 9 | -> Top / (x: {(and (eqmod v dThis {"purr"}) 10 | ((sel v "purr") :: ty_sound))} > x.pro) */ '#type'; 11 | 12 | var make_dog = function(x) /*: ty_make_dog */ { 13 | x.bark = function() /*: ty_sound */ { return "bark"; }; 14 | }; 15 | 16 | var make_cat = function(x) /*: ty_make_cat */ { 17 | x.purr = function() /*: ty_sound */ { return "purr"; }; 18 | }; 19 | 20 | var hybrid = {}; 21 | make_dog(hybrid); 22 | make_cat(hybrid); 23 | var noise = hybrid.bark() + hybrid.purr(); 24 | assert (typeof noise == "string"); 25 | 26 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/passengers.js: -------------------------------------------------------------------------------- 1 | /*: (~lPass: {Dict|(implies (has v "weight") (Num (sel v "weight")))} > lObjPro) */ "#weak"; 2 | 3 | /*: sumWeight :: 4 | (passengers:Ref, max_weight:Num) 5 | / (passengers: {Arr(Ref(~lPass))|(packed v)} > lArrPro) -> Num / same */ "#type"; 6 | 7 | var sumWeight = function(passengers, max_weight) { 8 | var sum /*: Num */ = 0.0, n = passengers.length; 9 | for (var i /*: {Int|(>= v 0)} */ = 0; i < n; i++) { 10 | var p = passengers[i]; 11 | /*: p lThaw1 */ "#thaw"; 12 | if (p.weight) { sum += p.weight; } 13 | else { sum += max_weight; } 14 | /*: p (~lPass, thwd lThaw1) */ "#freeze"; 15 | } 16 | return sum; 17 | }; 18 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/prototypal.js: -------------------------------------------------------------------------------- 1 | 2 | /*: beget :: [;LL1,LL2,LL3;] 3 | (Ref(LL2)) / (LL2: Top > LL3) -> Ref(LL1) / (LL1: Empty > LL2, LL2: same) */ '#type'; 4 | 5 | /*: ctor :: (this:Ref) / (this: Empty > this.pro) -> Ref(this) / same */ '#type'; 6 | 7 | var beget = function (o) { 8 | function ctor() { return this; }; 9 | ctor.prototype = o; 10 | return new /*: LL1 > LL2 */ ctor(); 11 | }; 12 | 13 | /*: get_name :: (this:Ref) / (this: {Dict|(Str (objsel [v] "name" cur this.pro))} > this.pro) 14 | -> Str / same */ '#type'; 15 | 16 | var herb = /*: lHerb */ { 17 | name : "Herb", 18 | get_name : function() { 19 | return "Hi, I'm " + this.name; 20 | } 21 | }; 22 | 23 | var henrietta = /*: [;lHenrietta,lHerb,lObjPro;] */ beget(herb); 24 | henrietta.name = "Henrietta"; 25 | var s = henrietta.get_name(); 26 | assert (typeof s === "string"); 27 | 28 | herb.get_name = function() /*: (this:Top) -> Int */ { return 42; }; 29 | var i = henrietta.get_name(); 30 | assert (typeof i === "number"); 31 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/pseudoclassical.js: -------------------------------------------------------------------------------- 1 | 2 | /*: ty_mammal :: 3 | (this:Ref, name:Str) / (this: dThis:Empty > this.pro) 4 | -> Ref(this) / (this: {(= v (upd dThis "name" name))} > this.pro) */ '#type'; 5 | 6 | /*: ty_get_name :: 7 | (this:Ref) / (this: {Dict|(Str (objsel [v] "name" cur this.pro))} > this.pro) 8 | -> Str / same */ '#type'; 9 | 10 | function Mammal(name) /*: ty_mammal */ { 11 | this.name = name; 12 | return this; 13 | }; 14 | 15 | Mammal.prototype.get_name = function() /*: ty_get_name */ { 16 | return "Hi, I'm " + this.name; 17 | }; 18 | 19 | function Cat(name) /*: ty_mammal */ { 20 | this.name = name; 21 | return this; 22 | }; 23 | 24 | Cat.prototype = new /*: lNewCatProto */ Mammal("__dummy__"); 25 | 26 | var henrietta = new /*: lHenrietta > lNewCatProto */ Cat("Henrietta"); 27 | 28 | var s = henrietta.get_name(); 29 | 30 | assert (typeof s === "string"); 31 | 32 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/splay.js: -------------------------------------------------------------------------------- 1 | 2 | /*: tyNode {Dict|(and (Int (sel v "key")) (Str (sel v "value")) 3 | (implies (has v "left") ((sel v "left") :: Ref(~lNode))) 4 | (implies (has v "right") ((sel v "right") :: Ref(~lNode))))} */ "#define"; 5 | 6 | /*: (~lNode: tyNode > lNodeProto) */ "#weak"; 7 | 8 | function Node(key, value) /*: new (this:Ref, key:Int, value:Str) 9 | / (this: Empty > lNodeProto) -> Ref(~lNode) / () */ { 10 | this.key = key; 11 | this.value = value; 12 | /*: this (~lNode, frzn) */ "#freeze"; 13 | return this; 14 | }; 15 | 16 | var SplayTree = {Node: Node}; 17 | 18 | SplayTree.Node.prototype.left = null; 19 | 20 | SplayTree.Node.prototype.right = null; 21 | 22 | /*: leftAndRight {left: Ref(~lNode), right:Ref(~lNode)} */ "#define"; 23 | 24 | Node.prototype.traverse_ = function traverse_() 25 | /*: (this:Ref(~lNode)) / (lNodeProto: leftAndRight [sameExact] > lObjPro) -> Top / same */ { 26 | var current = this; 27 | var b /*: Top */ = current; // TODO get rid of b temporary 28 | while (b) { 29 | var left = current.left; 30 | if (left) traverse_.apply(left); 31 | b = current.right; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/string-fasta.js: -------------------------------------------------------------------------------- 1 | /*: makeCumulative :: [;L1,L2] 2 | (table:Ref(L1)) / (L1: Dict > L2) -> Top / sameType */ "#type"; 3 | 4 | var makeCumulative = function(table) { 5 | var last = null; 6 | var c /*: Str */ = ""; 7 | /*: [Heap] Heap + (L1: d:Dict > L2, 8 | &last: {(implies (not (= v null)) 9 | (and (Str v) (Num (objsel [d] v Heap L2))))}) -> sameType */ 10 | for (c in table) { 11 | if (last) { 12 | if ((typeof table[c]) == "number") { 13 | table[c] = table[c] + table[last]; 14 | last = c; 15 | } 16 | } 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /tests/djs/oopsla12/typeOf.js: -------------------------------------------------------------------------------- 1 | 2 | /*: typeOf = {(and 3 | (v :: (value:Ref) / (value: Dict > value.pro) -> {(= v "object")} / same) 4 | (v :: [A] (value:Ref) / (value: Arr(A) > value.pro) -> {(= v "array")} / same) 5 | (v :: (value:{(or (= v null) (= (tag v) {"number","boolean","string","undefined"}))}) 6 | -> {(ite (= value null) (= v "null") (= v (tag value)))}))} */ "#type"; 7 | 8 | var typeOf = function(value) { 9 | var s = typeof value; 10 | if (s == 'object') { 11 | if (value) { return (isArray(value)) ? 'array' : 'object'; } 12 | else { return 'null'; } 13 | } 14 | return s; 15 | }; 16 | 17 | assert (typeOf(1) == "number"); 18 | assert (typeOf("hi") == "string"); 19 | assert (typeOf(true) == "boolean"); 20 | assert (typeOf(null) == "null"); 21 | assert (typeOf({}) == "object"); 22 | assert (typeOf([]) == "array"); 23 | assert (typeOf(undefined) == "undefined"); 24 | -------------------------------------------------------------------------------- /tests/djs/operators/and00.js: -------------------------------------------------------------------------------- 1 | 2 | assert (/*: {(= v false)} */ (true && false)); 3 | 4 | assert (/*: {(= v 0)} */ (0 && false)); 5 | 6 | assert (/*: {(= v 2)} */ (1 && 2)); 7 | 8 | assert (/*: {(= v 0)} */ (0 && 2)); 9 | 10 | assert (/*: {(= v "")} */ ("" && 2)); 11 | 12 | assert (/*: {(= v 2)} */ ("hi" && 2)); 13 | 14 | assert (/*: {(= v null)} */ (null && 2)); 15 | 16 | -------------------------------------------------------------------------------- /tests/djs/operators/assert00.js: -------------------------------------------------------------------------------- 1 | assert (/*: {(= v "number")} */ (typeof 1)); 2 | assert (/*: {(= v "string")} */ (typeof "hi")); 3 | assert (/*: {(= v "boolean")} */ (typeof true)); 4 | assert (/*: {(= v "object")} */ (typeof null)); 5 | assert (/*: {(= v "object")} */ (typeof {})); 6 | assert (/*: {(= v "object")} */ (typeof [])); 7 | assert (/*: {(= v "undefined")} */ (typeof undefined)); 8 | -------------------------------------------------------------------------------- /tests/djs/operators/assert01.js: -------------------------------------------------------------------------------- 1 | assert (typeof 1 === "number"); 2 | assert (typeof "hi" === "string"); 3 | assert (typeof true === "boolean"); 4 | assert (typeof null === "object"); 5 | assert (typeof {} === "object"); 6 | assert (typeof [] === "object"); 7 | assert (typeof undefined === "undefined"); 8 | -------------------------------------------------------------------------------- /tests/djs/operators/betterTypeof01.js: -------------------------------------------------------------------------------- 1 | 2 | // Simplified version of goog.typeOf(), which wraps the typeof operator to 3 | // return "null" and "array" instead of "object". 4 | // 5 | // http://closure-library.googlecode.com/svn/docs/closure_goog_base.js.source.html#line631 6 | // 7 | // Instead of using (value instanceof Array), 8 | // we use the ES5 function Array.isArray(value). 9 | 10 | var typeOf = function(value) 11 | /*: {(and 12 | 13 | (v :: [[value:{(or (= (tag v) "number") (= (tag v) "boolean") 14 | (= (tag v) "string") (= (tag v) "undefined") 15 | (= v null))}]] 16 | -> {(ite (= value null) (= v "null") (= v (tag value)))}) 17 | 18 | (v :: [A;LL1,LL2;H] [[value:Ref(LL1)]] 19 | / [H ++ LL1 |-> (_:Arr(A), LL2), 20 | &Array |-> _:Ref(lArray), 21 | lArray |-> (_:{Dict|(= (sel v "isArray") ____isArray)}, lObjectProto)] 22 | -> {(= v "array")} / same) 23 | 24 | (v :: [;LL1,LL2;H] [[value:Ref(LL1)]] 25 | / [H ++ LL1 |-> (x:Dict, LL2), 26 | &Array |-> _:Ref(lArray), 27 | lArray |-> (_:{Dict|(= (sel v "isArray") ____isArray)}, lObjectProto)] 28 | -> {(= v "object")} / same) 29 | )} */ 30 | { 31 | var s = typeof value; 32 | if (s == 'object') { 33 | if (value) { return (Array.isArray(value)) ? 'array' : 'object'; } 34 | else { return 'null'; } 35 | } 36 | return s; 37 | }; 38 | 39 | // /*: {(= v "number")} */ (typeOf(1)); 40 | // /*: {(= v "string")} */ (typeOf("hi")); 41 | // /*: {(= v "boolean")} */ (typeOf(true)); 42 | // /*: {(= v "null")} */ (typeOf(null)); 43 | // /*: {(= v "object")} */ (typeOf({})); 44 | // /*: {(= v "array")} */ (typeOf([])); 45 | // /*: {(= v "undefined")} */ (typeOf(undefined)); 46 | -------------------------------------------------------------------------------- /tests/djs/operators/betterTypeof02.js: -------------------------------------------------------------------------------- 1 | /*: #define tyScalar 2 | {(or (= (tag v) "number") (= (tag v) "boolean") (= (tag v) "string") 3 | (= (tag v) "undefined") (= v null))} */ "#define"; 4 | 5 | var typeOf = 6 | /*: {(and 7 | (v :: [[value:tyScalar]] 8 | -> {(ite (= value null) (= v "null") (= v (tag value)))}) 9 | 10 | (v :: [;L1,L2;H] 11 | [[value:Ref(L1)]] / [H ++ L1 |-> (x:Dict, L2)] 12 | -> {(ite (objhas x "__hack__" H L2) (= v "array") (= v "object"))} 13 | / same) 14 | 15 | (v :: [A;L1,L2;H] 16 | [[value:Ref(L1)]] / [H ++ L1 |-> (_:Arr(A), L2)] 17 | -> {(ite (heaphas H L2 "__hack__") (= v "array") (= v "object"))} 18 | / same) 19 | )} 20 | */ "#extern"; 21 | 22 | Array.prototype.__hack__ = "dummy"; 23 | 24 | assert ("number" == typeOf(1)); 25 | assert ("string" == typeOf("hi")); 26 | assert ("boolean" == typeOf(true)); 27 | assert ("undefined" == typeOf(undefined)); 28 | assert ("null" == typeOf(null)); 29 | assert ("object" == typeOf({})); 30 | assert ("array" == typeOf([])); 31 | -------------------------------------------------------------------------------- /tests/djs/operators/eek00.js: -------------------------------------------------------------------------------- 1 | assert (1 === 1); 2 | assert (1 == 1); 3 | assert (!("a" == "b")); 4 | assert (1 + 2 == 3); 5 | assert (1 + 2 === 3); 6 | assert (true || false === true && true); 7 | -------------------------------------------------------------------------------- /tests/djs/operators/eek01.js: -------------------------------------------------------------------------------- 1 | var x = {f:1}; 2 | assert (x.f == 1); 3 | assert (x.g == undefined); 4 | -------------------------------------------------------------------------------- /tests/djs/operators/if00.js: -------------------------------------------------------------------------------- 1 | if (1) { 2 | "always gets here"; 3 | } else { 4 | assert (/*: {FLS} */ "never gets here"); 5 | }; 6 | 7 | if (0) { 8 | assert (/*: {FLS} */ "never gets here"); 9 | } else { 10 | "always gets here"; 11 | }; 12 | 13 | if (null) { 14 | assert (/*: {FLS} */ "never gets here"); 15 | } else { 16 | "always gets here"; 17 | }; 18 | -------------------------------------------------------------------------------- /tests/djs/operators/num00.js: -------------------------------------------------------------------------------- 1 | assert (/*: {(and (= (tag v) "number") (integer v))} */ (1)); 2 | 3 | assert (/*: {(= v 2)} */ (2)); 4 | 5 | assert (/*: {(= v 3)} */ (1 + 2)); 6 | 7 | assert (/*: {(and (= (tag v) "number") (integer v))} */ (1 + 2)); 8 | -------------------------------------------------------------------------------- /tests/djs/operators/num01.js: -------------------------------------------------------------------------------- 1 | assert (/*: {(and (= (tag v) "number"))} */ (1.0)); 2 | 3 | assert (/*: {(and (= (tag v) "number"))} */ (1.0 + 2.0)); 4 | 5 | assert (/*: {(and (= (tag v) "number"))} */ (1.0 + 2)); 6 | 7 | assert (/*: Num */ (1.0 + 2)); 8 | -------------------------------------------------------------------------------- /tests/djs/operators/or00.js: -------------------------------------------------------------------------------- 1 | 2 | assert (/*: {(= v true)} */ (true || false)); 3 | 4 | assert (/*: {(= v false)} */ (0 || false)); 5 | 6 | assert (/*: {(= v 1)} */ (1 || 2)); 7 | 8 | assert (/*: {(= v 2)} */ (0 || 2)); 9 | 10 | assert (/*: {(= v 2)} */ ("" || 2)); 11 | 12 | assert (/*: {(= v "hi")} */ ("hi" || 2)); 13 | 14 | assert (/*: {(= v 2)} */ (null || 2)); 15 | 16 | -------------------------------------------------------------------------------- /tests/djs/operators/plus00.js: -------------------------------------------------------------------------------- 1 | 2 | var i = 1 + 2; 3 | var s = "hello," + " world"; 4 | 5 | assert (/*: Int */ i); 6 | assert (/*: Str */ s); 7 | -------------------------------------------------------------------------------- /tests/djs/operators/plus01.js: -------------------------------------------------------------------------------- 1 | var d = 1.0 + 0.1; 2 | -------------------------------------------------------------------------------- /tests/djs/operators/typeof00.js: -------------------------------------------------------------------------------- 1 | assert (/*: {(= v "number")} */ (typeof 1)); 2 | assert (/*: {(= v "string")} */ (typeof "hi")); 3 | assert (/*: {(= v "boolean")} */ (typeof true)); 4 | assert (/*: {(= v "object")} */ (typeof null)); 5 | assert (/*: {(= v "object")} */ (typeof {})); 6 | assert (/*: {(= v "object")} */ (typeof [])); 7 | assert (/*: {(= v "undefined")} */ (typeof undefined)); 8 | -------------------------------------------------------------------------------- /tests/djs/operators/typeof01.js: -------------------------------------------------------------------------------- 1 | /*: #define tyScalar 2 | {(or (= (tag v) "number") 3 | (= (tag v) "boolean") 4 | (= (tag v) "string") 5 | (= (tag v) "undefined") 6 | (= v null))} */ "#define"; 7 | 8 | /*: #define tagSet 9 | {(or (= v "number") 10 | (= v "boolean") 11 | (= v "string") 12 | (= v "undefined") 13 | (= v "object"))} */ "#define"; 14 | 15 | var typeofScalar = function(x) /*: (x:tyScalar) -> tagSet */ { 16 | return typeof x; 17 | }; 18 | -------------------------------------------------------------------------------- /tests/djs/operators/weirdNumConsts.js: -------------------------------------------------------------------------------- 1 | assert (0 == 0); 2 | assert (-0 == -0); 3 | assert (0 == -0); 4 | 5 | assert (typeof Infinity == "number"); 6 | 7 | assert (typeof NaN == "number"); 8 | assert (typeof (NaN == NaN) == "boolean"); 9 | -------------------------------------------------------------------------------- /tests/djs/operators/xx_and00.js: -------------------------------------------------------------------------------- 1 | assert (/*: {(= v true)} */ (true && false)); 2 | -------------------------------------------------------------------------------- /tests/djs/operators/xx_integer00.js: -------------------------------------------------------------------------------- 1 | assert (/*: Num */ 1.0); 2 | assert (/*: Int */ 1.0); 3 | -------------------------------------------------------------------------------- /tests/djs/operators/xx_plus00.js: -------------------------------------------------------------------------------- 1 | var i = 1 + 2; 2 | var s = "hello," + " world"; 3 | assert (/*: Int */ i); 4 | assert (/*: Int */ s); 5 | -------------------------------------------------------------------------------- /tests/djs/recursion/fact00.js: -------------------------------------------------------------------------------- 1 | // i modified the JS parser and translation to EJS 2 | // to allow named function expressions 3 | 4 | var factorial = function fact(n) /*: (Int) -> Int */ { 5 | return n <= 0 ? 1 : n * fact(-1); 6 | }; 7 | 8 | assert (/*: Int */ (factorial(5))); 9 | -------------------------------------------------------------------------------- /tests/djs/recursion/fact01.js: -------------------------------------------------------------------------------- 1 | var factorial = function fact(n) /*: (n:Int) -> Int */ { 2 | if (n < 0) { return 1; } 3 | else { return n * fact(n-1); } 4 | }; 5 | 6 | assert (/*: Int */ (factorial(5))); 7 | -------------------------------------------------------------------------------- /tests/djs/recursion/looper00.js: -------------------------------------------------------------------------------- 1 | 2 | /*: [~lLooper |-> ({Dict|((sel v "loop") :: tyLoop)}, lObjectProto)] */ "#weak"; 3 | 4 | var foo = function loop() /*: tyLoop */ { 5 | var self = this; 6 | /*: self l */ "#thaw"; 7 | var bar = self.loop; 8 | /*: self (~lLooper, thwd l) */ "#freeze"; 9 | return 1 + bar.apply(self); 10 | }; 11 | 12 | /*: #define tyLoop 13 | [[this:Ref(~lLooper)]] / [~lLooper |-> frzn] -> Int / same */ "#define"; 14 | 15 | var x = {"loop": foo}; 16 | 17 | /*: x (~lLooper, frzn) */ "#freeze"; 18 | 19 | assert (/*: Int */ (foo.apply(x))); 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | 23 | /*: x lThwd */ "#thaw"; 24 | 25 | var xloop = x.loop; 26 | 27 | /*: x (~lLooper, thwd lThwd) */ "#freeze"; 28 | 29 | assert (/*: Int */ (xloop.apply(x))); 30 | 31 | -------------------------------------------------------------------------------- /tests/djs/recursion/looper01.js: -------------------------------------------------------------------------------- 1 | 2 | /*: [~lLooper |-> (tyLooper, lLooperProto)] */ "#weak"; 3 | 4 | function Looper() /*: 5 | new [;Lnew] 6 | [[this:Ref(Lnew)]] 7 | / [~lLooper |-> frzn, Lnew |-> (_:Empty, lLooperProto) ] 8 | -> Ref(~lLooper) / [~lLooper |-> same] 9 | */ 10 | { 11 | this.loop = function loop() /*: tyLoop */ { 12 | var self = this; 13 | /*: self l */ "#thaw"; 14 | var bar = self.loop; 15 | /*: self (~lLooper, thwd l) */ "#freeze"; 16 | return 1 + bar.apply(self); 17 | }; 18 | 19 | var self = this; 20 | /*: self (~lLooper, frzn) */ "#freeze"; 21 | return self; 22 | }; 23 | 24 | /*: #define tyLoop 25 | [[this:Ref(~lLooper)]] / [~lLooper |-> frzn] -> Int / same */ "#define"; 26 | 27 | /*: #define tyLooper {Dict|((sel v "loop") :: tyLoop)} */ "#define"; 28 | 29 | var x = new /*: [;lx] lLooperProto */ Looper(); 30 | /*: x lThaw */ "#thaw"; 31 | var foo = x.loop; 32 | /*: x (~lLooper, thwd lThaw) */ "#freeze"; 33 | assert (/*: Int */ (foo.apply(x))); 34 | -------------------------------------------------------------------------------- /tests/djs/recursion/looper02.js: -------------------------------------------------------------------------------- 1 | 2 | /*: [~lLooper |-> (Empty, lLooperProto)] */ "#weak"; 3 | 4 | function Looper() /*: 5 | new [;Lnew] 6 | [[this:Ref(Lnew)]] / [~lLooper |-> frzn, Lnew |-> (_:Empty, lLooperProto)] 7 | -> Ref(~lLooper) / [~lLooper |-> same] 8 | */ 9 | { 10 | var self = this; 11 | /*: self (~lLooper, frzn) */ "#freeze"; 12 | return self; 13 | }; 14 | 15 | Looper.prototype.loop = function loop() /*: tyLoop */ { 16 | return 1 + loop.apply(this); 17 | }; 18 | 19 | /*: #define tyLoop 20 | [[this:Ref(~lLooper)]] / [~lLooper |-> frzn] -> Int / same */ "#define"; 21 | 22 | //////////////////////////////////////////////////////////////////////////////// 23 | 24 | // the following is: var x = new Looper(); 25 | // x.loop(); 26 | 27 | var x = new /*: [;lx;] lLooperProto */ Looper(); 28 | /*: x lThawX */ "#thaw"; 29 | var xloop = x.loop; 30 | /*: x (~lLooper, thwd lThawX) */ "#freeze"; 31 | xloop.apply(x); 32 | -------------------------------------------------------------------------------- /tests/djs/recursion/rec00.js: -------------------------------------------------------------------------------- 1 | // testing desugaring of letrecs with a dummy function 2 | 3 | var dummy = function f() /*: () -> Int */ { 4 | return 1; 5 | }; 6 | -------------------------------------------------------------------------------- /tests/djs/recursion/rec01.js: -------------------------------------------------------------------------------- 1 | var loop = function f(n) /*: (n:Int) -> Int */ { 2 | return f(n); 3 | }; 4 | -------------------------------------------------------------------------------- /tests/djs/recursion/xx_loop00.js: -------------------------------------------------------------------------------- 1 | var x = /*: lx */ {}; 2 | 3 | x.loop = function _loop() 4 | /*: [[this:Ref(lx)]] 5 | / [lx |-> (dx:{Dict|((sel v "_loop"):tyLoop)}, lObjectProto)] 6 | -> Int / same */ 7 | { 8 | return this._loop(); 9 | }; 10 | 11 | /*: #define tyLoop [[this:Ref(lx)]] -> Int */ "#define"; 12 | 13 | // definitions above type check... 14 | 15 | /////////////////////////////////////////////////////////////////////////////// 16 | 17 | // ... but can't actually check any calls 18 | 19 | var i = x.loop(); 20 | -------------------------------------------------------------------------------- /tests/djs/recursion/xx_loop01.js: -------------------------------------------------------------------------------- 1 | var x = /*: lx */ {}; 2 | 3 | x.loop = function _loop() /*: tyLoop */ { 4 | return this._loop(); 5 | }; 6 | 7 | /*: #define tyLoop 8 | [[this:Ref(lx)]] 9 | / [lx |-> (_:{dx:Dict|(and ((sel dx "_loop"):tyLoopHelp))}, lObjectProto)] 10 | -> Int / same */ "#define"; 11 | 12 | /*: #define tyLoopHelp 13 | [[this:Ref(lx)]] / [lx |-> (_:{(= v dx)}, lObjectProto)] 14 | -> Int / same */ "#define"; 15 | 16 | assert (/*: tyLoop */ (x.loop)); 17 | 18 | x._loop = x.loop; 19 | 20 | assert (/*: tyLoop */ (x._loop)); 21 | 22 | // the trick above allows the definitions above to type check... 23 | 24 | /////////////////////////////////////////////////////////////////////////////// 25 | 26 | // ... but can't actually check any calls 27 | 28 | var i = x.loop(); 29 | -------------------------------------------------------------------------------- /tests/djs/smarterds/ctor00.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define tyFoo {Dict|(and (dom v {"f"}) ((sel v "f") : Int))} */ "#define"; 3 | 4 | /*: #define ctorFoo 5 | [;Lnew] [[this:Ref(Lnew)]] / [Lnew |-> (_:Empty, lFooProto)] 6 | -> {(= v this)} / [Lnew |-> (_:tyFoo, lFooProto)] */ "#define"; 7 | 8 | function Foo() /*: new ctorFoo */ { 9 | this.f = 1; 10 | return this; 11 | } 12 | 13 | var obj = new /*: [;lobj] lFooProto */ Foo(); 14 | 15 | Foo.prototype.g = /*: Int */ 10; 16 | 17 | //// omitting the following from tyBar 18 | //// lFooProto |-> (_:{Dict|((sel v "g") : Int)}, lObjectProto) 19 | 20 | //// TODO: i'm _not_ threading through prototype objects right now, 21 | //// because need to change macros as a pre-pass to expanding them 22 | //// more delayed, and then storing the delayed expansion, not the 23 | //// eager pre-pass one like currently 24 | 25 | /*: #define tyBar 26 | [;L] [[this:Ref(L)]] / [L |-> (_:tyFoo, lFooProto)] 27 | -> Int / sameExact */ "#define"; 28 | 29 | Foo.prototype.bar = function() /*: tyBar */ { 30 | return 1 + this.f + this.g; 31 | }; 32 | 33 | obj.bar(); 34 | 35 | var baz = function(foo) 36 | /*: [;L] [[foo:Ref(L)]] 37 | / [L |-> (_:tyFoo, lFooProto), 38 | lFooProto |-> (_:{Dict|(and ((sel v "g") : Int) 39 | ((sel v "bar") : tyBar))}, lObjectProto)] 40 | -> Int / sameExact */ 41 | { 42 | return 1 + foo.bar(); 43 | }; 44 | 45 | baz(obj); 46 | -------------------------------------------------------------------------------- /tests/djs/smarterds/ctor01.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define tyFoo {Dict|(and (dom v {"f"}) ((sel v "f") : Int))} */ "#define"; 3 | 4 | /*: #define ctorFoo 5 | [;Lnew] [[this:Ref(Lnew)]] / [Lnew |-> (_:Empty, lFooProto)] 6 | -> {(= v this)} / [Lnew |-> (_:tyFoo, lFooProto)] */ "#define"; 7 | 8 | function Foo() /*: new ctorFoo */ { 9 | this.f = 1; 10 | return this; 11 | } 12 | 13 | var wrapFoo = function() 14 | /*: [;L] [[]] 15 | / [lFooObj |-> (_:{Dict| 16 | (and ((sel v "code") : ctorFoo) 17 | ((sel v "prototype") : Ref(lFooProto)))}, lFunctionProto), 18 | lFooProto |-> (_:Dict, lObjectProto)] 19 | -> Ref(L) 20 | / [L |-> (_:tyFoo, lFooProto), 21 | lFooObj |-> sameExact, 22 | lFooProto |-> sameExact] */ 23 | { 24 | return new /*: [;L] lFooProto */ Foo(); 25 | }; 26 | -------------------------------------------------------------------------------- /tests/djs/smarterds/len00-1.js: -------------------------------------------------------------------------------- 1 | var foo = function(ns) 2 | /*: [;L] [[ns:Ref(L)]] 3 | / [L |-> (a:{(and (v::Arr(Int)) (packed v))}, lArrayProto)] 4 | -> Top / sameType */ { 5 | var i = 0; 6 | for (; i < ns.length; i++) ns[i] + 1; 7 | }; 8 | -------------------------------------------------------------------------------- /tests/djs/smarterds/len00.js: -------------------------------------------------------------------------------- 1 | var ns = /*: Arr(Int) */ [0,1,2,3]; 2 | var i = 0; 3 | for (; i < ns.length; i++) ns[i] + 1; 4 | -------------------------------------------------------------------------------- /tests/djs/smarterds/len01-1.js: -------------------------------------------------------------------------------- 1 | var foo = function(ns) 2 | /*: [;L] [[ns:Ref(L)]] 3 | / [L |-> (a:{(and (v::Arr(Int)) (packed v))}, lArrayProto)] 4 | -> Top / sameType */ { 5 | var i = 0; 6 | var size = ns.length; 7 | for (; i < size; i++) ns[i] + 1; 8 | }; 9 | -------------------------------------------------------------------------------- /tests/djs/smarterds/obj00.js: -------------------------------------------------------------------------------- 1 | var foo = function(obj) 2 | /*: [;L] [[obj:Ref(L)]] 3 | / [L |-> (d:{Dict|((sel v "f") : Num)}, lObjectProto)] 4 | -> Top / sameType */ { 5 | while (true) { 6 | 1 + obj.f; 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /tests/djs/smarterds/obj01.js: -------------------------------------------------------------------------------- 1 | var foo = function(obj) 2 | /*: [;L] [[obj:Ref(L)]] 3 | / [L |-> (d:{Dict|(and 4 | ((sel v "f") : Num) 5 | ((sel v "g") : Num))}, lObjectProto)] 6 | -> Top / sameType */ { 7 | while (true) { 8 | obj.f = 1 + obj.f; 9 | obj.g = 2; 10 | obj.h = 3; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /tests/djs/smarterds/obj02.js: -------------------------------------------------------------------------------- 1 | var foo = function(obj) 2 | /*: [;L] [[obj:Ref(L)]] 3 | / [L |-> (d:{Dict|(and (dom v {"f","g"}) 4 | ((sel v "f") : Num) 5 | ((sel v "g") : Num))}, lObjectProto)] 6 | -> Top / sameType */ { 7 | while (true) { 8 | obj.f = 1 + obj.f; 9 | obj.g = 2; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /tests/djs/smarterds/obj03.js: -------------------------------------------------------------------------------- 1 | var foo = function() 2 | /*: [;L] [[this:Ref(L)]] 3 | / [L |-> (d:{Dict|(and (dom v {"f","g"}) 4 | ((sel v "f") : Num) 5 | ((sel v "g") : Num))}, lObjectProto)] 6 | -> Top / sameType */ { 7 | while (true) { 8 | this.f = 1 + this.f; 9 | this.g = 2; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /tests/djs/smarterds/test00.js: -------------------------------------------------------------------------------- 1 | var i = 0; 2 | while (i < 10) i++; 3 | -------------------------------------------------------------------------------- /tests/djs/smarterds/test01.js: -------------------------------------------------------------------------------- 1 | var i = 0; 2 | var j = 0; 3 | while (i < 10) { 4 | j = 0; 5 | while (j < i) { 6 | i + j; 7 | j++; 8 | } 9 | i++; 10 | } 11 | -------------------------------------------------------------------------------- /tests/djs/smarterds/test02.js: -------------------------------------------------------------------------------- 1 | var PI = 3.14; 2 | var i = 0.0; 3 | while (i < 10) i += i + PI; 4 | -------------------------------------------------------------------------------- /tests/djs/smarterds/thawinf00.js: -------------------------------------------------------------------------------- 1 | /*: #define tyFoo {Dict|(and ((sel v "n") : Int) ((sel v "m") : Int))} */ "#define"; 2 | 3 | /*: [~lFoo |-> (tyFoo, lFooProto)] */ "#weak"; 4 | 5 | var bar = function(o) /*: [[o:Ref(~lFoo)]] -> Int */ { 6 | o.n; 7 | o.m; 8 | o.n; 9 | return o.n + o.m; 10 | }; 11 | -------------------------------------------------------------------------------- /tests/djs/smarterds/thawinf01.js: -------------------------------------------------------------------------------- 1 | /*: [~lTreeNode |-> (tyTreeNode, lTreeNodeProto)] */ "#weak"; 2 | 3 | /*: #define tyTreeNode 4 | {Dict|(and (dom v {"item","left","right"}) 5 | ((sel v "item"):Int) 6 | ((sel v "left"):Ref(~lTreeNode)) 7 | ((sel v "right"):Ref(~lTreeNode)))} */ "#define"; 8 | 9 | /*: #define tyg 10 | [[obj:Ref(~lTreeNode)]] -> Int */ "#define"; 11 | 12 | var g = function(obj) /*: tyReadLeftRight */ { 13 | // TODO this would require tracking more syntactically 14 | return obj.item + obj.left.item; 15 | }; 16 | -------------------------------------------------------------------------------- /tests/djs/smarterds/thawinf02.js: -------------------------------------------------------------------------------- 1 | /*: [~lTreeNode |-> (tyTreeNode, lTreeNodeProto)] */ "#weak"; 2 | 3 | /*: #define tyTreeNode 4 | {Dict|(and (dom v {"item","left","right"}) 5 | ((sel v "item"):Int) 6 | ((sel v "left"):Ref(~lTreeNode)) 7 | ((sel v "right"):Ref(~lTreeNode)))} */ "#define"; 8 | 9 | /*: #define tyItemCheck 10 | [[obj:Ref(~lTreeNode)]] / [~lTreeNode |-> frzn] -> Int / same */ "#define"; 11 | 12 | var blah = {}; 13 | blah.itemCheck = function f(obj) /*: tyItemCheck */ { 14 | if (obj.left == null) { return obj.item; } 15 | else { return obj.item + f.apply(obj.left) + f.apply(obj.right); } 16 | }; 17 | -------------------------------------------------------------------------------- /tests/djs/smarterds/thawinf03.js: -------------------------------------------------------------------------------- 1 | /*: [~lTreeNode |-> (tyTreeNode, lTreeNodeProto)] */ "#weak"; 2 | 3 | /*: #define tyTreeNode 4 | {Dict|(and (dom v {"item","left","right"}) 5 | ((sel v "item"):Int) 6 | ((sel v "left"):Ref(~lTreeNode)) 7 | ((sel v "right"):Ref(~lTreeNode)))} */ "#define"; 8 | 9 | /*: #define tyItemCheck [[this:Ref(~lTreeNode)]] -> Int */ "#define"; 10 | 11 | var blah = {}; 12 | blah.itemCheck = function f() /*: tyItemCheck */ { 13 | if (this.left == null) { return this.item; } 14 | else { return this.item + f.apply(this.left) + f.apply(this.right); } 15 | }; 16 | -------------------------------------------------------------------------------- /tests/djs/smarterds/thawinf04.js: -------------------------------------------------------------------------------- 1 | /*: #define tyFoo {Dict|(and ((sel v "n") : Int) ((sel v "m") : Int))} */ "#define"; 2 | 3 | /*: [~lFoo |-> (tyFoo, lFooProto)] */ "#weak"; 4 | 5 | var bar = function(o) /*: [[o:Ref(~lFoo)]] -> Int */ { 6 | o.n = 1; 7 | o.m = 2; 8 | o.n = 3; 9 | return o.n + o.m; 10 | }; 11 | -------------------------------------------------------------------------------- /tests/djs/smarterds/thawinf05.js: -------------------------------------------------------------------------------- 1 | /*: #define tyFoo {Dict|(and ((sel v "n") : Int) ((sel v "m") : Int))} */ "#define"; 2 | 3 | /*: [~lFoo |-> (tyFoo, lFooProto)] */ "#weak"; 4 | 5 | var bar = function(o) /*: [[o:Ref(~lFoo)]] -> Int */ { 6 | o.n = o.m; 7 | o.m = o.m + 2; 8 | o.n = o.n + 3; 9 | return o.n + o.m; 10 | }; 11 | -------------------------------------------------------------------------------- /tests/djs/smarterds/toplevel00.js: -------------------------------------------------------------------------------- 1 | var A = 1; 2 | var B = 23; 3 | 4 | var foo = function() /*: [[]] -> Int */ { return A + B; }; 5 | 6 | var i = foo(); 7 | assert (typeof i == "number"); 8 | -------------------------------------------------------------------------------- /tests/djs/smarterds/toplevel01.js: -------------------------------------------------------------------------------- 1 | var A = 1; 2 | var B = 23; 3 | 4 | var foo = function() /*: [[]] -> Int */ { return A + B; }; 5 | 6 | var i = foo(); 7 | assert (typeof i == "number"); 8 | 9 | var C = 17; 10 | 11 | // TODO: for this -augmentHeaps needs to scrape the type of foo()... 12 | var bar = function() /*: [[]] -> Int */ { return C + foo() + A; }; 13 | 14 | var j = bar(); 15 | assert (typeof j == "number"); 16 | -------------------------------------------------------------------------------- /tests/djs/smarterds/xx_len01.js: -------------------------------------------------------------------------------- 1 | var ns = [0,1,2,3]; 2 | // BAD: there isn't a binder to describe the array value, 3 | // so can't give the required type for frame inference... 4 | var size = ns.length; 5 | var i = 0; 6 | for (; i < size; i++) ns[i] + 1; 7 | -------------------------------------------------------------------------------- /tests/djs/smarterds/xx_obj02.js: -------------------------------------------------------------------------------- 1 | var foo = function(obj) 2 | /*: [;L] [[obj:Ref(L)]] 3 | / [L |-> (d:{Dict|(and (dom v {"f","g"}) 4 | ((sel v "f") : Num) 5 | ((sel v "g") : Num))}, lObjectProto)] 6 | -> Top / sameType */ { 7 | while (true) { 8 | obj.f = 1 + obj.f; 9 | obj.g = 2; 10 | obj.h = 3; // BAD: doesn't preserve domain 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /tests/djs/smarterds/xx_test02.js: -------------------------------------------------------------------------------- 1 | var PI = 3.14; 2 | var i = 0; 3 | while (i < 10) i += i + PI; 4 | // BAD: i gets NonNegInt, but the addition with Num doesn't 5 | // preserve Int-ness, let alone NonNeg-ness 6 | -------------------------------------------------------------------------------- /tests/djs/smartertc/cloinvar00.js: -------------------------------------------------------------------------------- 1 | var i = 1; 2 | var j /*: Int */ = 0; 3 | var f = function () /*: () -> Top */ { 4 | j += i; 5 | }; 6 | f(); 7 | assert (/*: Int */ (j + i + 2)); 8 | -------------------------------------------------------------------------------- /tests/djs/smartertc/cloinvar01.js: -------------------------------------------------------------------------------- 1 | var f = function (i) /*: (i:Int) -> Int */ { 2 | return 1 + i; 3 | }; 4 | var g = function (i) /*: (i:Int) -> Int */ { 5 | return 1 + f(i); 6 | }; 7 | var h = function (i) /*: (i:Int) -> Int */ { 8 | return 1 + g(i); 9 | }; 10 | -------------------------------------------------------------------------------- /tests/djs/smartertc/cloinvar02.js: -------------------------------------------------------------------------------- 1 | var x = {f: 10}; 2 | var y = {g: 10}; 3 | var f = function () /*: () -> Int */ { 4 | return x.f + y.g; 5 | }; 6 | assert (/*: Int */ (x.f)); 7 | assert (/*: Int */ (y.g)); 8 | -------------------------------------------------------------------------------- /tests/djs/smartertc/cloinvar03.js: -------------------------------------------------------------------------------- 1 | var x = {f: 10}; 2 | var y = /*: {Dict|(and (dom v {"g"}) (Int (sel v "g")))} */ {g: 10}; 3 | var f = function () /*: () -> Int */ { 4 | y.g += x.f; 5 | return y.g; 6 | }; 7 | assert (/*: Int */ (x.f)); 8 | assert (/*: Int */ (y.g)); 9 | -------------------------------------------------------------------------------- /tests/djs/smartertc/cloinvar04.js: -------------------------------------------------------------------------------- 1 | /*: foo :: (a:Ref) / (a: d:{Dict|(Int (sel v "n"))} > lObjPro) 2 | -> () / (a: {v=d} > lObjPro) -> Int / same 3 | / same */ "#type"; 4 | var foo = function(a) { 5 | 6 | }; 7 | 8 | var a = [0,1,3]; 9 | -------------------------------------------------------------------------------- /tests/djs/smartertc/cloinvar05.js: -------------------------------------------------------------------------------- 1 | var j /*: Int */ = 1; 2 | 3 | var x = {}; 4 | var k = "f"; 5 | x[k]; // &j gets threaded through the heap frame variable during 6 | // this function call, so don't want to lose the cloinv Int 7 | 8 | var f = function () /*: () -> Top */ { 9 | j += j; 10 | }; 11 | -------------------------------------------------------------------------------- /tests/djs/smartertc/cloinvar06.js: -------------------------------------------------------------------------------- 1 | var j = 0; 2 | var f = function () /*: () -> Top */ { 3 | j += j; 4 | }; 5 | -------------------------------------------------------------------------------- /tests/djs/smartertc/xx_cloinvar0.js: -------------------------------------------------------------------------------- 1 | var i = 1; 2 | var f = function () /*: () -> Top */ { 3 | i = "blah"; 4 | }; 5 | -------------------------------------------------------------------------------- /tests/djs/smartertc/xx_cloinvar00.js: -------------------------------------------------------------------------------- 1 | var i = 1; 2 | var j = 0; 3 | var f = function () /*: () -> Top */ { 4 | j += i; 5 | }; 6 | -------------------------------------------------------------------------------- /tests/djs/weak/branch.js: -------------------------------------------------------------------------------- 1 | /*: (~l |-> Top > lObjPro) */ "#weak"; 2 | 3 | var foo = function(x,b) /*: (x:Ref(~l), b:Bool) / (~l |-> frzn) -> Top / same */ { 4 | if (x == null) return; 5 | /*: x l */ "#thaw"; 6 | if (b) { /*: x (~l, thwd l) */ "#freeze"; } 7 | else { /*: x (~l, thwd l) */ "#freeze"; } 8 | }; 9 | -------------------------------------------------------------------------------- /tests/djs/weak/passenger00.js: -------------------------------------------------------------------------------- 1 | /*: #define tyPassenger 2 | {Dict|(and (not (has v "hasOwnProperty")) 3 | (implies (has v "weight") (Num (sel v "weight"))))} */ "#define"; 4 | 5 | /*: (~lPass |-> tyPassenger > lObjPro) */ "#weak"; 6 | 7 | var readWeight = function(p) /*: 8 | (p:Ref(~lPass)) / (~lPass |-> frzn, lObjPro |-> {(= v theObjPro)} > lROOT) 9 | -> Num / same */ 10 | { 11 | var n = 300; 12 | /*: p lThaw1 */ "#thaw"; 13 | if (p.hasOwnProperty("weight")) { n = p.weight; } 14 | /*: p (~lPass, thwd lThaw1) */ "#freeze"; 15 | return n; 16 | }; 17 | -------------------------------------------------------------------------------- /tests/djs/weak/passenger01.js: -------------------------------------------------------------------------------- 1 | /*: #define tyPassenger 2 | {Dict|(implies (has v "weight") (Num (sel v "weight")))} */ "#define"; 3 | 4 | /*: (~lPass |-> tyPassenger > lObjPro) */ "#weak"; 5 | 6 | var readWeight = function(p) /*: 7 | (p:Ref(~lPass)) / (~lPass |-> frzn, lObjPro |-> {(= v theObjPro)} > lROOT) 8 | -> Num / same */ 9 | { 10 | var n = 300; 11 | /*: p lThaw1 */ "#thaw"; 12 | if (p.weight) { n = p.weight; } 13 | /*: p (~lPass, thwd lThaw1) */ "#freeze"; 14 | return n; 15 | }; 16 | -------------------------------------------------------------------------------- /tests/djs/weak/splay00.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define tyNode 3 | {Dict|(and (dom v {"key","value"}) 4 | (Int (sel v "key")) 5 | (Str (sel v "value")))} */ "#define"; 6 | 7 | /*: (~lNode |-> tyNode > lNodeProto) */ "#weak"; 8 | 9 | function Node(key, value) /*: new [;Lnew] 10 | (this:Ref(Lnew), key:Int, value:Str) 11 | / (Lnew |-> _:Empty > lNodeProto, ~lNode |-> frzn) 12 | -> Ref(~lNode) / (~lNode |-> same) */ 13 | { 14 | this.key = key; 15 | this.value = value; 16 | 17 | var self = this; 18 | /*: self (~lNode, frzn) */ "#freeze"; 19 | return self; 20 | }; 21 | 22 | var SplayTree = {Node: Node}; 23 | 24 | SplayTree.Node.prototype.left = null; 25 | 26 | SplayTree.Node.prototype.right = null; 27 | 28 | var node1 = new /*: [;lNew1] lNodeProto */ Node(0, "0"); 29 | 30 | /*: node1 lThaw1 */ "#thaw"; 31 | 32 | assert (/*: Int */ (node1.key)); 33 | assert (/*: Str */ (node1.value)); 34 | assert (/*: Null */ (node1.left)); 35 | assert (/*: Ref(~lNode) */ (node1.left)); 36 | 37 | -------------------------------------------------------------------------------- /tests/djs/weak/splay01.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define tyNode 3 | {(and (= (tag v) "Dict") 4 | (or (dom v {"key","value"}) (dom v {"key","value","left","right"})) 5 | (Int (sel v "key")) 6 | (Str (sel v "value")) 7 | (implies (has v "left") ((sel v "left") :: Ref(~lNode))) 8 | (implies (has v "right") ((sel v "right") :: Ref(~lNode))))} 9 | */ "#define"; 10 | 11 | /*: (~lNode |-> tyNode > lNodeProto) */ "#weak"; 12 | 13 | function Node(key, value) /*: new [;Lnew] 14 | (this:Ref(Lnew), key:Int, value:Str) 15 | / (Lnew |-> _:Empty > lNodeProto, ~lNode |-> frzn) 16 | -> Ref(~lNode) / (~lNode |-> same) */ 17 | { 18 | this.key = key; 19 | this.value = value; 20 | 21 | var self = this; 22 | /*: self (~lNode, frzn) */ "#freeze"; 23 | return self; 24 | }; 25 | 26 | var SplayTree = {Node: Node}; 27 | 28 | SplayTree.Node.prototype.left = null; 29 | 30 | SplayTree.Node.prototype.right = null; 31 | 32 | //////////////////////////////////////////////////////////////////////////////// 33 | 34 | var node1 = new /*: [;lNew1] lNodeProto */ Node(1, "1"); 35 | var node2 = new /*: [;lNew2] lNodeProto */ Node(2, "1"); 36 | var node3 = new /*: [;lNew3] lNodeProto */ Node(3, "3"); 37 | 38 | /*: node1 lThaw1 */ "#thaw"; 39 | 40 | node1.left = node2; 41 | node1.right = node3; 42 | 43 | /*: node1 (~lNode, thwd lThaw1) */ "#freeze"; 44 | 45 | -------------------------------------------------------------------------------- /tests/djs/weak/splay02.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define tyNode 3 | {(and (= (tag v) "Dict") 4 | (Int (sel v "key")) 5 | (Str (sel v "value")) 6 | (implies (has v "left") ((sel v "left") :: Ref(~lNode))) 7 | (implies (has v "right") ((sel v "right") :: Ref(~lNode))))} 8 | */ "#define"; 9 | 10 | /*: (~lNode |-> tyNode > lNodeProto) */ "#weak"; 11 | 12 | function Node(key, value) /*: new [;Lnew] 13 | (this:Ref(Lnew), key:Int, value:Str) 14 | / (Lnew |-> _:Empty > lNodeProto, ~lNode |-> frzn) 15 | -> Ref(~lNode) / (~lNode |-> same) */ 16 | { 17 | this.key = key; 18 | this.value = value; 19 | 20 | var self = this; 21 | /*: self (~lNode, frzn) */ "#freeze"; 22 | return self; 23 | }; 24 | 25 | var SplayTree = {Node: Node}; 26 | 27 | SplayTree.Node.prototype.left = null; 28 | 29 | SplayTree.Node.prototype.right = null; 30 | 31 | //////////////////////////////////////////////////////////////////////////////// 32 | 33 | var node1 = new /*: [;lNew1] lNodeProto */ Node(1, "1"); 34 | var node2 = new /*: [;lNew2] lNodeProto */ Node(2, "1"); 35 | var node3 = new /*: [;lNew3] lNodeProto */ Node(3, "3"); 36 | 37 | /*: node1 lThaw1 */ "#thaw"; 38 | 39 | node1.left = node2; // this time, tyNode allows providing only one of left/right 40 | node1.dummy = 0; // and also adding additional fields 41 | 42 | /*: node1 (~lNode, thwd lThaw1) */ "#freeze"; 43 | 44 | -------------------------------------------------------------------------------- /tests/djs/weak/sumFields00.js: -------------------------------------------------------------------------------- 1 | /*: (~lObj |-> {Dict|(Int (sel v "n"))} > lObjPro) */ "#weak"; 2 | 3 | var sumFields = function(objs) /*: 4 | [;Larr] (objs:Ref(Larr)) 5 | / (~lObj |-> frzn, 6 | Larr |-> array:{(and (v::Arr(Ref(~lObj))) (packed v))} > lArrPro) 7 | -> Int / same */ 8 | { 9 | var i = 0, n = 0; 10 | /*: loopAnn -> sameType */ 11 | for (i=0; i < objs.length; i++) { 12 | var obj = objs[i]; 13 | /*: obj lThaw */ "#thaw"; 14 | n += obj.n; 15 | /*: obj (~lObj, thwd lThaw) */ "#freeze"; 16 | } 17 | return n; 18 | }; 19 | 20 | /*: #define loopAnn ( 21 | &i |-> _:{Int|(>= v 0)}, 22 | &n |-> _:Int, 23 | &objs |-> _:Ref(Larr), 24 | Larr |-> _:{(= v array)} > lArrPro, 25 | ~lObj |-> frzn 26 | ) */ "#define"; 27 | -------------------------------------------------------------------------------- /tests/djs/weak/test00.js: -------------------------------------------------------------------------------- 1 | /*: (~lRow |-> Arr(Str) > lArrPro) */ "#weak"; 2 | 3 | var row1 = /*: lRow1 Arr(Str) */ ["00","01"]; 4 | var row2 = /*: lRow2 Arr(Str) */ ["10","11"]; 5 | 6 | assert (/*: Ref(lRow1) */ row1); 7 | assert (/*: Ref(lRow2) */ row2); 8 | 9 | /*: row1 (~lRow,frzn) */ "#freeze"; 10 | /*: row2 (~lRow,frzn) */ "#freeze"; 11 | 12 | assert (/*: Ref(~lRow) */ row1); 13 | assert (/*: Ref(~lRow) */ row2); 14 | 15 | var mat = /*: Arr(Ref(~lRow)) */ [row1, row2]; 16 | 17 | row1 = mat[0]; 18 | /*: row1 lThwd1 */ "#thaw"; 19 | 20 | var s = row1[0]; 21 | 22 | assert (/*: {(or (= v undefined) (Str v))} */ s); 23 | 24 | s = (s == undefined ? "bleh" : s); 25 | 26 | assert (/*: Str */ s); 27 | 28 | // /*: {(= v true)} */ Array.isArray(row1); 29 | -------------------------------------------------------------------------------- /tests/djs/weak/test01.js: -------------------------------------------------------------------------------- 1 | /*: (~lRow |-> > lArrPro) */ "#weak"; 2 | 3 | var row1 = /*: lRow1 */ ["00","01"]; 4 | var row2 = /*: lRow2 */ ["10","11"]; 5 | 6 | /*: row1 (~lRow,frzn) */ "#freeze"; 7 | /*: row2 (~lRow,frzn) */ "#freeze"; 8 | 9 | var mat = /*: Arr(Ref(~lRow)) */ [row1, row2]; 10 | 11 | row1 = mat[0]; 12 | /*: row1 lThwd1 */ "#thaw"; 13 | 14 | var s0 = row1[0]; 15 | var s1 = row1[1]; 16 | var s2 = row1[2]; 17 | 18 | assert (/*: Str */ s0); 19 | assert (/*: Str */ s1); 20 | assert (/*: {(= v undefined)} */ s2); 21 | 22 | /*: row1 (~lRow, thwd lThwd1) */ "#freeze"; 23 | 24 | row2 = mat[0]; 25 | /*: row2 lThwd2 */ "#thaw"; 26 | 27 | s0 = row2[0]; 28 | s1 = row2[1]; 29 | s2 = row2[2]; 30 | 31 | assert (/*: Str */ s0); 32 | assert (/*: Str */ s1); 33 | assert (/*: {(= v undefined)} */ s2); 34 | 35 | /*: row2 (~lRow, thwd lThwd2) */ "#freeze"; 36 | -------------------------------------------------------------------------------- /tests/djs/weak/this00.js: -------------------------------------------------------------------------------- 1 | 2 | /*: (~lTreeNode |-> tyTreeNode > lTreeNodeProto) */ "#weak"; 3 | 4 | /*: #define tyTreeNode 5 | {Dict|(and (dom v {"item","left","right"}) 6 | (Int (sel v "item")) 7 | ((sel v "left") :: Ref(~lTreeNode)) 8 | ((sel v "right") :: Ref(~lTreeNode)))} */ "#define"; 9 | 10 | function TreeNode(left,right,item) 11 | /*: new [;Lthis] 12 | (this:Ref(Lthis), left:Ref(~lTreeNode), right:Ref(~lTreeNode), item:Int) 13 | / (Lthis |-> d:Empty > lTreeNodeProto, ~lTreeNode |-> frzn) 14 | -> Ref(~lTreeNode) / (~lTreeNode |-> same) */ { 15 | this.left = left; 16 | this.right = right; 17 | this.item = item; 18 | 19 | /*: this (~lTreeNode,frzn) */ "#freeze"; 20 | return this; 21 | }; 22 | -------------------------------------------------------------------------------- /tests/djs/weak/tree00.js: -------------------------------------------------------------------------------- 1 | 2 | /*: (~lTreeNode |-> tyTreeNode > lTreeNodeProto) */ "#weak"; 3 | 4 | /*: #define tyTreeNode 5 | {Dict|(and (dom v {"item","left","right"}) 6 | (Int (sel v "item")) 7 | ((sel v "left") :: Ref(~lTreeNode)) 8 | ((sel v "right") :: Ref(~lTreeNode)))} */ "#define"; 9 | 10 | function TreeNode(left,right,item) 11 | /*: new [;Lthis] 12 | (this:Ref(Lthis), left:Ref(~lTreeNode), right:Ref(~lTreeNode), item:Int) 13 | / (Lthis |-> d:Empty > lTreeNodeProto, ~lTreeNode |-> frzn) 14 | -> Ref(~lTreeNode) / (~lTreeNode |-> same) */ { 15 | this.left = left; 16 | this.right = right; 17 | this.item = item; 18 | 19 | var self = this; 20 | /*: self (~lTreeNode,frzn) */ "#freeze"; 21 | return self; 22 | }; 23 | 24 | //////////////////////////////////////////////////////////////////////////////// 25 | 26 | var tree1 = new (/*: [;lTree1;] lTreeNodeProto */ TreeNode)(null, null, 10); 27 | var tree2 = new (/*: [;lTree2;] lTreeNodeProto */ TreeNode)(null, null, 20); 28 | var tree3 = new (/*: [;lTree2;] lTreeNodeProto */ TreeNode)(tree1, tree2, 30); 29 | 30 | /*: tree1 lThwd1 */ "#thaw"; 31 | 32 | var i = tree1.item; 33 | 34 | assert (/*: Int */ i); 35 | -------------------------------------------------------------------------------- /tests/djs/weak/xx_branch.js: -------------------------------------------------------------------------------- 1 | /*: (~l |-> Top > lObjPro) */ "#weak"; 2 | 3 | var foo = function(x,b) /*: (x:Ref(~l), b:Bool) / (~l |-> frzn) -> Top / same */ { 4 | /*: x l */ "#thaw"; 5 | if (b) { /*: x (~l, thwd l) */ "#freeze"; } 6 | else { /*: x (~l, thwd l) */ "#freeze"; } 7 | }; 8 | -------------------------------------------------------------------------------- /tests/djs/weak/xx_splay00.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define tyNode 3 | {Dict|(and TRU 4 | (Int (sel v "key")) 5 | (Str (sel v "value")))} */ "#define"; 6 | 7 | /*: (~lNode |-> tyNode > lNodeProto) */ "#weak"; 8 | 9 | function Node(key, value) /*: new [;Lnew] 10 | (this:Ref(Lnew), key:Int, value:Str) 11 | / (Lnew |-> _:Empty > lNodeProto, ~lNode |-> frzn) 12 | -> Ref(~lNode) / (~lNode |-> same) */ 13 | { 14 | this.key = key; 15 | this.value = value; 16 | 17 | var self = this; 18 | /*: self (~lNode, frzn) */ "#freeze"; 19 | return self; 20 | }; 21 | 22 | var SplayTree = {Node: Node}; 23 | 24 | SplayTree.Node.prototype.left = null; 25 | 26 | SplayTree.Node.prototype.right = null; 27 | 28 | var node1 = new /*: [;lNew1] lNodeProto */ Node(0, "0"); 29 | 30 | /*: node1 lThaw1 */ "#thaw"; 31 | 32 | assert (/*: Int */ (node1.key)); 33 | assert (/*: Str */ (node1.value)); 34 | 35 | // FAIL: because tyNode doesn't include domain predicate 36 | 37 | assert (/*: Null */ (node1.left)); 38 | 39 | -------------------------------------------------------------------------------- /tests/djs/weak/xx_splay01.js: -------------------------------------------------------------------------------- 1 | 2 | /*: #define tyNode 3 | {(and (= (tag v) "Dict") 4 | (or (dom v {"key","value"}) (dom v {"key","value","left","right"})) 5 | (Int (sel v "key")) 6 | (Str (sel v "value")) 7 | (implies (has v "left") ((sel v "left") :: Ref(~lNode))) 8 | (implies (has v "right") ((sel v "right") :: Ref(~lNode))))} 9 | */ "#define"; 10 | 11 | /*: (~lNode |-> tyNode > lNodeProto) */ "#weak"; 12 | 13 | function Node(key, value) /*: new [;Lnew] 14 | (this:Ref(Lnew), key:Int, value:Str) 15 | / (Lnew |-> _:Empty > lNodeProto, ~lNode |-> frzn) 16 | -> Ref(~lNode) / (~lNode |-> same) */ 17 | { 18 | this.key = key; 19 | this.value = value; 20 | 21 | var self = this; 22 | /*: self (~lNode, frzn) */ "#freeze"; 23 | return self; 24 | }; 25 | 26 | var SplayTree = {Node: Node}; 27 | 28 | SplayTree.Node.prototype.left = null; 29 | 30 | SplayTree.Node.prototype.right = null; 31 | 32 | //////////////////////////////////////////////////////////////////////////////// 33 | 34 | var node1 = new /*: [;lNew1] lNodeProto */ Node(1, "1"); 35 | var node2 = new /*: [;lNew2] lNodeProto */ Node(2, "1"); 36 | var node3 = new /*: [;lNew3] lNodeProto */ Node(3, "3"); 37 | 38 | /*: node1 lThaw1 */ "#thaw"; 39 | 40 | node1.left = node2; 41 | 42 | // FAIL: since "left" is added to own object, so must "right" be 43 | 44 | /*: node1 (~lNode, thwd lThaw1) */ "#freeze"; 45 | 46 | -------------------------------------------------------------------------------- /tests/djs/weak/xx_sumFields00.js: -------------------------------------------------------------------------------- 1 | /*: (~lObj |-> {Dict|(Int (sel v "n"))} > lObjPro) */ "#weak"; 2 | 3 | var sumFields = function(objs) /*: 4 | [;Larr] (objs:Ref(Larr)) 5 | / (~lObj |-> frzn, 6 | Larr |-> array:{(and (v::Arr(Ref(~lObj))) (packed v))} > lArrPro) 7 | -> Int / same */ 8 | { 9 | var i = 0, n = 0; 10 | /*: loopAnn -> sameType */ 11 | for (i=-1; i < objs.length; i++) { // BAD: i isn't >= 0 12 | var obj = objs[i]; 13 | /*: obj lThaw */ "#thaw"; 14 | n += obj.n; 15 | /*: obj (~lObj, thwd lThaw) */ "#freeze"; 16 | } 17 | return n; 18 | }; 19 | 20 | /*: #define loopAnn ( 21 | &i |-> _:{Int|(>= v 0)}, 22 | &n |-> _:Int, 23 | &objs |-> _:Ref(Larr), 24 | Larr |-> _:{(= v array)} > lArrPro, 25 | ~lObj |-> frzn 26 | ) */ "#define"; 27 | -------------------------------------------------------------------------------- /tests/djs/weak/xx_test00.js: -------------------------------------------------------------------------------- 1 | /*: (~lRow |-> Arr(Str) > lArrPro) */ "#weak"; 2 | 3 | var row1 = /*: lRow1 Arr(Str) */ ["00","01"]; 4 | var row2 = /*: lRow2 Arr(Str) */ ["10","11"]; 5 | 6 | assert (/*: Ref(lRow1) */ row1); 7 | assert (/*: Ref(lRow2) */ row2); 8 | 9 | /*: row1 (~lRow,frzn) */ "#freeze"; 10 | 11 | // row2 not frozen 12 | var mat = /*: Arr(Ref(~lRow)) */ [row1, row2]; 13 | -------------------------------------------------------------------------------- /tests/djsLite/arrays/test00.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA */ [0,"hi",true]; 3 | 4 | /*: {(= v 0)} */ (/*: [Top;lA;] */ a[0]); 5 | 6 | /*: {(= v "hi")} */ (/*: [Top;lA;] */ a[1]); 7 | 8 | /*: {(= v true)} */ (/*: [Top;lA;] */ a[2]); 9 | 10 | /*: {(= v undefined)} */ (/*: [Top;lA;] */ a[3]); 11 | 12 | /*: {(= v 3)} */ (/*: [Top;lA;] */ a["length"]); 13 | 14 | /*: {(= v 3)} */ (/*: [Top;lA;] */ a.length); 15 | 16 | var s = "length"; 17 | 18 | /*: {(= v 3)} */ (/*: [Top;lA;] */ a[s]); 19 | 20 | var i = 1; 21 | 22 | /*: {(= v "hi")} */ (/*: [Top;lA;] */ a[i]); 23 | -------------------------------------------------------------------------------- /tests/djsLite/arrays/test01.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA Arr(Int) */ [0]; 3 | 4 | /*: {(= v 1)} */ (/*: [Int;lA;] */ a.length); 5 | 6 | /*: [Int;lA;] */ a[1] = 1; 7 | 8 | /*: {(= v 2)} */ (/*: [Int;lA;] */ a.length); 9 | 10 | /*: [Int;lA;] */ a[1] = 11111; 11 | 12 | /*: {(= v 2)} */ (/*: [Int;lA;] */ a.length); 13 | 14 | /*: [Int;lA;] */ a[2] = 2; 15 | 16 | /*: {(= v 3)} */ (/*: [Int;lA;] */ a.length); 17 | 18 | var i = 3; 19 | 20 | /*: [Int;lA;] */ a[i] = 3; 21 | 22 | /*: {(= v 4)} */ (/*: [Int;lA;] */ a.length); 23 | 24 | i = 4; 25 | 26 | /*: [Int;lA;] */ a[i] = 4; 27 | 28 | /*: {(= v 5)} */ (/*: [Int;lA;] */ a.length); 29 | 30 | -------------------------------------------------------------------------------- /tests/djsLite/arrays/test02-inf.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA Arr(Int) */ [0,1,2]; 3 | 4 | a[a.length] = a.length; 5 | a[a.length] = a.length; 6 | a[a.length] = a.length; 7 | 8 | /*: {(= v 6)} */ (a.length); 9 | 10 | -------------------------------------------------------------------------------- /tests/djsLite/arrays/test02.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA Arr(Int) */ [0,1,2]; 3 | 4 | (/*: [Int;lA;] */ a[/*: [Int;lA;] */ a.length] = (/*: [Int;lA;] */ a.length)); 5 | (/*: [Int;lA;] */ a[/*: [Int;lA;] */ a.length] = (/*: [Int;lA;] */ a.length)); 6 | (/*: [Int;lA;] */ a[/*: [Int;lA;] */ a.length] = (/*: [Int;lA;] */ a.length)); 7 | 8 | /*: {(= v 6)} */ (/*: [Int;lA;] */ a.length); 9 | 10 | -------------------------------------------------------------------------------- /tests/djsLite/arrays/test03.js: -------------------------------------------------------------------------------- 1 | 2 | var a = /*: lA */ [0,1,2]; 3 | 4 | /*: {(= v 3)} */ (/*: [Top;lA;] */ a.length); 5 | 6 | /*: [Top;lA;] */ a.length = 2; 7 | 8 | /*: {(= v 2)} */ (/*: [Top;lA;] */ a.length); 9 | 10 | /*: {(= v undefined)} */ (/*: [Top;lA;] */ a[2]); 11 | 12 | -------------------------------------------------------------------------------- /tests/djsLite/ecoop/basics.js: -------------------------------------------------------------------------------- 1 | var k = "g"; 2 | var x = {"f": k}; 3 | /*: {(= v true)} */ ("f" in x); 4 | 5 | var xf = x.f; 6 | /*: {(= v "g")} */ xf; 7 | 8 | x[k] = 3; 9 | /*: {(= v 3)} */ (x[k]); 10 | 11 | delete x.f; 12 | /*: {(= v false)} */ ("f" in x); 13 | 14 | var y = x; 15 | y.f = "hi"; 16 | 17 | xf = x.f; 18 | /*: {(= v "hi")} */ xf; 19 | -------------------------------------------------------------------------------- /tests/djsLite/ecoop/counter.js: -------------------------------------------------------------------------------- 1 | /*: #define ty_toInt [[x:Top]] -> Int */ '#define'; 2 | 3 | var toInt = function(x) /*: ty_toInt */ { 4 | if (typeof(x) == "number") { return x; } 5 | else if (typeof(x) == "boolean") { return x ? 1 : 0; } 6 | else { return -1; } 7 | }; 8 | 9 | /*: #define ty_getCount 10 | [;Lt;] [[t:Ref(Lt), c:Str]] 11 | / [Lt |-> dt:Dict, &toInt |-> blah:ty_toInt] 12 | -> Int / same */ '#define'; 13 | 14 | var getCount = function(t,c) /*: ty_getCount */ { 15 | if (c in t) { 16 | return toInt(t[c]); 17 | } else { 18 | return 0; 19 | } 20 | }; 21 | 22 | /*: #define ty_incCount 23 | [;Lt;] [[t:Ref(Lt), c:Str]] 24 | / [Lt |-> dt:Dict, 25 | &toInt |-> blah1:ty_toInt, 26 | &getCount |-> blah2:ty_getCount] 27 | -> Top 28 | / [Lt |-> dt2:{(and (eqmod v dt {c}) ((sel v c) : Int))}, 29 | &toInt |-> same, 30 | &getCount |-> same] */ "#define"; 31 | 32 | var incCount = function(t,c) /*: ty_incCount */ { 33 | var i = /*: [;Lt;] */ getCount(t,c); 34 | t[c] = 1 + i; 35 | }; 36 | -------------------------------------------------------------------------------- /tests/djsLite/ecoop/dispatch.js: -------------------------------------------------------------------------------- 1 | var dispatch = function(x,f) 2 | /*: [A,B;Lx;] [[x:Ref(Lx), f:Str]] 3 | / [Lx |-> dx:{Dict|(and 4 | (v :: A) 5 | ((sel v f) :: [[_:Ref(Lx)]] / [Lx |-> blah:A] -> B / same))}] 6 | -> B / same */ { 7 | var fn = x[f]; 8 | return fn(x); 9 | }; 10 | -------------------------------------------------------------------------------- /tests/djsLite/ecoop/negate.js: -------------------------------------------------------------------------------- 1 | var negate = function(x) /*: [[x:IntOrBool]] -> {(= (tag v) (tag x))} */ { 2 | if (typeof(x) == "number") { 3 | return 0 - x; 4 | } else { 5 | return !x; 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /tests/functional/arrays/__arrays.ml: -------------------------------------------------------------------------------- 1 | 2 | (***** "functional arrays" ****************************************************) 3 | 4 | (* TODO add finite-foralls for seti, push, and pop *) 5 | 6 | val length :: [A] a:Arr(A) -> {Int | (implies (packed a) (= v (len a)))} 7 | 8 | val geti :: [A] a:Arr(A) -> i:Int -> 9 | {(ite (and (packed a) (>= i 0)) 10 | (ite (< i (len a)) (and (v::A) (= v (sel a i))) (= v undefined)) 11 | (or (v::A) (= v undefined)))} 12 | 13 | val seti :: [A] a:Arr(A) -> i:Int -> x:A -> 14 | {(and (v::Arr(A)) 15 | (= (sel a i) x) 16 | (implies (and (packed a) (>= i 0) (< i (len a))) 17 | (and (packed v) (= (len v) (len a)))) 18 | (implies (and (packed a) (= i (len a))) 19 | (and (packed v) (= (len v) (+ 1 (len a))))))} 20 | 21 | val push :: [A] a:Arr(A) -> x:A -> 22 | {(and (v::Arr(A)) 23 | (implies (packed a) (and (packed v) 24 | (= (len v) (+ 1 (len a))) 25 | (= (sel a (len a)) x))))} 26 | 27 | val top :: [A] a:Arr(A) -> 28 | {(ite (packed a) 29 | (and (v::A) (= v (sel a (- (len a) 1)))) 30 | (or (v::A) (= v undefined)))} 31 | 32 | val pop :: [A] a:Arr(A) -> 33 | {(and (v::Arr(A)) 34 | (implies (packed a) 35 | (and (packed v) (= (len v) (- (len a) 1)) (> (len a) 0))))} 36 | 37 | -------------------------------------------------------------------------------- /tests/functional/arrays/lit00.ml: -------------------------------------------------------------------------------- 1 | 2 | #use "tests/functional/arrays/__arrays.ml" 3 | 4 | let tup0 = <> in 5 | let tup1 = <1> in 6 | let tup2 = <1, true> in 7 | 8 | let _ :: {(and (v :: Arr({(not (= v undefined))})) (packed v) (= (len v) 0))} = tup0 in 9 | let _ :: {(and (v :: Arr({(not (= v undefined))})) (packed v) (= (len v) 1))} = tup1 in 10 | let _ :: {(and (v :: Arr({(not (= v undefined))})) (packed v) (= (len v) 2))} = tup2 in 11 | 12 | let _ :: {(= v 1)} = ([{(not (= v undefined))}] geti) tup1 0 in 13 | let _ :: {(= v 1)} = ([{(not (= v undefined))}] geti) tup2 0 in 14 | let _ :: {(= v true)} = ([{(not (= v undefined))}] geti) tup2 1 in 15 | 16 | let tup3 = ([{(not (= v undefined))}] push) tup2 "hi" in 17 | 18 | let _ :: {(and (v :: Arr({(not (= v undefined))})) (packed v) (= (len v) 3))} = tup3 in 19 | 20 | 0 21 | -------------------------------------------------------------------------------- /tests/functional/arrays/lit01.ml: -------------------------------------------------------------------------------- 1 | 2 | #use "tests/functional/arrays/__arrays.ml" 3 | 4 | let tup0 = <> as Arr(IntOrBool) in 5 | let tup1 = ([IntOrBool] push) tup0 17 in 6 | 7 | let tup2 = <1, true> as Arr(IntOrBool) in 8 | let tup3 = ([IntOrBool] push) tup2 17 in 9 | 10 | let _ :: {(= (len v) 0)} = tup0 in 11 | let _ :: {(= (len v) 1)} = tup1 in 12 | let _ :: {(= (len v) 2)} = tup2 in 13 | let _ :: {(= (len v) 3)} = tup3 in 14 | 15 | 0 16 | -------------------------------------------------------------------------------- /tests/functional/arrays/test00.ml: -------------------------------------------------------------------------------- 1 | 2 | (***** lame arrays ************************************************************) 3 | 4 | (* just for experimenting. every read produces a possibly null value *) 5 | 6 | val _newarr :: [A] _:Top -> Arr(A) 7 | 8 | val _geti :: [A] a:Arr(A) -> i:Int -> {(or (v::A) (= v null))} 9 | 10 | val _seti :: [A] a:Arr(A) -> i:Int -> x:A -> Arr(A) 11 | 12 | val _length :: [A] a:Arr(Top) -> Int 13 | 14 | val _append :: [A] a:Arr(A) -> x:A -> Arr(A) 15 | 16 | (******************************************************************************) 17 | 18 | let tops = ([Top] _newarr) 0 in 19 | let _ = ([Top] _geti) tops 1 in 20 | 21 | let ints = ([Int] _newarr) 10 in 22 | let _ :: {(or (= v null) (Int v))} = ([Int] _geti) ints 1 in 23 | 0 24 | 25 | -------------------------------------------------------------------------------- /tests/functional/arrays/test01.ml: -------------------------------------------------------------------------------- 1 | 2 | #use "tests/functional/arrays/__arrays.ml" 3 | 4 | val tup0 :: {(and (v::Arr(Int)) (packed v) (= (len v) 0))} 5 | 6 | let _ :: {(= v 0)} = ([Int] length) tup0 in 7 | let _ :: Top = ([Int] geti) tup0 0 in 8 | let _ :: {(or (Int v) (= v undefined))} = ([Int] geti) tup0 0 in 9 | let _ :: {(= v undefined)} = ([Int] geti) tup0 0 in 10 | 11 | let tup1 = ([Int] push) tup0 0 in 12 | let _ :: {(= v 1)} = ([Int] length) tup1 in 13 | 14 | let tup2 = ([Int] push) tup1 1 in 15 | let _ :: {(= v 2)} = ([Int] length) tup2 in 16 | let _ :: Int = ([Int] geti) tup2 0 in 17 | let _ :: Int = ([Int] geti) tup2 1 in 18 | let _ :: {(= v undefined)} = ([Int] geti) tup2 2 in 19 | 20 | 0 21 | -------------------------------------------------------------------------------- /tests/functional/arrays/test02.ml: -------------------------------------------------------------------------------- 1 | 2 | #use "tests/functional/arrays/__arrays.ml" 3 | 4 | val tup2 :: {(and (v::Arr(Int)) (packed v) (= (len v) 2) 5 | (= (sel v 0) 0) 6 | (= (sel v 1) 1))} 7 | 8 | let _ :: {(= v 2)} = ([Int] length) tup2 in 9 | let _ :: {(= v 0)} = ([Int] geti) tup2 0 in 10 | let _ :: {(= v 1)} = ([Int] geti) tup2 1 in 11 | let _ :: {(= v undefined)} = ([Int] geti) tup2 2 in 12 | 13 | 0 14 | -------------------------------------------------------------------------------- /tests/functional/arrays/test03.ml: -------------------------------------------------------------------------------- 1 | 2 | #use "tests/functional/arrays/__arrays.ml" 3 | 4 | val tup4 :: {(and (v::Arr({(or (Int v) (Bool v) (Str v))})) 5 | (packed v) (= (len v) 4) 6 | (Int (sel v 0)) 7 | (Bool (sel v 1)))} 8 | 9 | let _ :: Int = 10 | ([{(or (Int v) (Bool v) (Str v))}] geti) tup4 0 in 11 | 12 | let _ :: Bool = 13 | ([{(or (Int v) (Bool v) (Str v))}] geti) tup4 1 in 14 | 15 | let _ :: {(or (Int v) (Bool v) (Str v))} = 16 | ([{(or (Int v) (Bool v) (Str v))}] geti) tup4 2 in 17 | 18 | let _ :: {(or (Int v) (Bool v) (Str v))} = 19 | ([{(or (Int v) (Bool v) (Str v))}] geti) tup4 3 in 20 | 21 | let _ :: {(= v undefined)} = 22 | ([{(or (Int v) (Bool v) (Str v))}] geti) tup4 4 in 23 | 24 | 0 25 | 26 | -------------------------------------------------------------------------------- /tests/functional/arrays/test04.ml: -------------------------------------------------------------------------------- 1 | 2 | #use "tests/functional/arrays/__arrays.ml" 3 | 4 | val tup3 :: {(and (v::Arr({(not (= v undefined))})) 5 | (packed v) (= (len v) 3) 6 | (Int (sel v 0)) 7 | (Bool (sel v 1)) 8 | (Str (sel v 2)))} 9 | 10 | let tup2 = ([{(not (= v undefined))}] pop) tup3 in 11 | 12 | let _ :: {(= (len tup2) 2)} = 0 in 13 | 14 | let _ :: {(= v undefined)} = ([{(not (= v undefined))}] geti) tup2 2 in 15 | 16 | let _ :: {(not (= v undefined))} = ([{(not (= v undefined))}] geti) tup2 1 in 17 | 18 | 0 19 | -------------------------------------------------------------------------------- /tests/functional/macros/arrow00.dref: -------------------------------------------------------------------------------- 1 | type int_to_int :: x:Int -> Int 2 | let _ :: {(v :: int_to_int)} = fun x -> (js_plus (x, 17)) in 3 | let _ :: int_to_int = fun x -> (x) in 4 | 0 5 | -------------------------------------------------------------------------------- /tests/functional/macros/arrow01.dref: -------------------------------------------------------------------------------- 1 | type int_to_int :: x:Int -> Int 2 | type bool_to_bool :: b:Bool -> Bool 3 | let _ :: {(and (v :: int_to_int) (v :: bool_to_bool))} = 4 | fun y -> (y) 5 | in 6 | 0 7 | -------------------------------------------------------------------------------- /tests/functional/macros/type00.dref: -------------------------------------------------------------------------------- 1 | type pos_int = {Int|(> v 0)} 2 | let _ :: pos_int = 5 in 3 | 0 4 | -------------------------------------------------------------------------------- /tests/functional/macros/type01.dref: -------------------------------------------------------------------------------- 1 | type int_to_int = x:Int -> Int 2 | let _ :: int_to_int = fun x -> (x) in 3 | 0 4 | -------------------------------------------------------------------------------- /tests/functional/macros/xx_type01.dref: -------------------------------------------------------------------------------- 1 | type int_to_int = x:Int -> Int 2 | let _ :: {(v :: int_to_int)} = fun x -> (js_plus (x, 17)) in 3 | 0 4 | -------------------------------------------------------------------------------- /tests/functional/numbers/la00.ml: -------------------------------------------------------------------------------- 1 | 2 | val i :: {Int|(and (>= v 0) (< v 1))} 3 | let _ :: {(= v 0)} = i in 4 | 5 | val j :: {Int|(and (>= v 0) (< v 2))} 6 | let _ :: Num = j in 7 | let _ :: Int = j in 8 | let _ :: {(or (= v 0) (= v 1))} = j in 9 | 10 | 0 11 | -------------------------------------------------------------------------------- /tests/functional/numbers/test00.ml: -------------------------------------------------------------------------------- 1 | 2 | let _ :: {(= v 3)} = js_plus (1, 2) in 3 | 4 | let _ :: {(= v (+ 1 2))} = js_plus (1, 2) in 5 | 6 | let _ :: {(= (tag v) "number")} = js_plus (1, 2) in 7 | 8 | let _ :: Num = js_plus (1, 2) in 9 | 10 | let _ :: {(integer v)} = js_plus (1, 2) in 11 | 12 | let _ :: Int = js_plus (1, 2) in 13 | 14 | 0 15 | -------------------------------------------------------------------------------- /tests/functional/quicktypes/__ops.ml: -------------------------------------------------------------------------------- 1 | val plus :: x:Int -> y:Int -> {Int|(= v (+ x y))} 2 | val neg :: x:Bool -> {Bool|(iff (= v true) (= x false))} 3 | -------------------------------------------------------------------------------- /tests/functional/quicktypes/bool00.dref: -------------------------------------------------------------------------------- 1 | #use "tests/functional/quicktypes/__ops.ml" 2 | let b = neg true in 3 | let _ :: Bool = b in 4 | let _ :: {(= v false)} = b in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/functional/quicktypes/int00.dref: -------------------------------------------------------------------------------- 1 | #use "tests/functional/quicktypes/__ops.ml" 2 | let i = 1 in 3 | let j = plus i i in 4 | let k = plus i j in 5 | let _ :: Int = k in 6 | let _ :: {(= v 3)} = k in 7 | 0 8 | -------------------------------------------------------------------------------- /tests/functional/quicktypes/int01.dref: -------------------------------------------------------------------------------- 1 | let i = 0 in 2 | let j = i in 3 | let _ :: {(= v 0)} = j in 4 | 0 5 | -------------------------------------------------------------------------------- /tests/functional/quicktypes/recd00.dref: -------------------------------------------------------------------------------- 1 | val b :: Bool 2 | let d0 = {"f"=0; "g"="hi"} in 3 | let d1 = (d0 with "h" = b) in 4 | let _ :: [[Dict,Str]] = (d1, "f") in 5 | let _ :: [[Dict,Str]] = (d1, "f", 1) in 6 | let _ :: [[Dict,Str,Int]] = (d1, "f", 1) in 7 | 0 8 | -------------------------------------------------------------------------------- /tests/functional/quicktypes/recd01.dref: -------------------------------------------------------------------------------- 1 | val b :: Bool 2 | let d0 = {"f"=0; "g"="hi"} in 3 | let d1 = (d0 with "h" = b) in 4 | let _ :: Int = get (d1, "f") in 5 | let _ :: Str = get (d1, "g") in 6 | let _ :: Bool = get (d1, "h") in 7 | 0 8 | -------------------------------------------------------------------------------- /tests/functional/quicktypes/recd02.dref: -------------------------------------------------------------------------------- 1 | val d0 :: {"f":Int, "g":Str} 2 | let d1 = (d0 with "h" = true) in 3 | let _ :: Int = get (d1, "f") in 4 | let _ :: Str = get (d1, "g") in 5 | let _ :: Bool = get (d1, "h") in 6 | 0 7 | -------------------------------------------------------------------------------- /tests/functional/quicktypes/xx_recd00.dref: -------------------------------------------------------------------------------- 1 | val b :: Bool 2 | let d0 = {"f"=0; "g"="hi"} in 3 | let d1 = (d0 with "h" = b) in 4 | let _ :: [[_:Dict,_:Bool]] = (d1, "f") in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/functional/quicktypes/xx_recd02.dref: -------------------------------------------------------------------------------- 1 | val d0 :: {f:Int, g:Str, _:Bot} 2 | let _ :: Int = get (d0, "f") in 3 | let _ :: Str = get (d0, "g") in 4 | let _ :: Undef = get (d0, "h") in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/functional/quicktypes/xx_recd03.dref: -------------------------------------------------------------------------------- 1 | val d0 :: {f:Int, g:Str} 2 | let _ :: Int = get (d0, "f") in 3 | let _ :: Str = get (d0, "g") in 4 | let _ :: Undef = get (d0, "h") in (* don't know whether domain is exact *) 5 | 0 6 | -------------------------------------------------------------------------------- /tests/functional/simple/box00.dref: -------------------------------------------------------------------------------- 1 | val f :: x:Int -> Int 2 | let _ :: {(v :: x:Int -> Int)} = f in 3 | 0 4 | -------------------------------------------------------------------------------- /tests/functional/simple/box01.dref: -------------------------------------------------------------------------------- 1 | val f :: x:Int -> Int 2 | let _ :: y:Int -> Int = f in 3 | 0 4 | -------------------------------------------------------------------------------- /tests/functional/simple/box02.dref: -------------------------------------------------------------------------------- 1 | val f :: _:Int -> Int 2 | let _ :: _:Int -> Int = f in 3 | 0 4 | -------------------------------------------------------------------------------- /tests/functional/simple/id.dref: -------------------------------------------------------------------------------- 1 | let id :: x:Top -> {y|(= y x)} = 2 | fun x -> (x) in 3 | let _ :: {(= v 0)} = id 0 in 4 | let _ :: {(= v "hi")} = id "hi" in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/functional/underscore/xx_test00.ml: -------------------------------------------------------------------------------- 1 | let _ :: Int = 1 in 2 | let _ :: Str = "hi" in 3 | let sanity_check :: FLS = "should fail" in 4 | 0 5 | -------------------------------------------------------------------------------- /tests/imperative/arrays/__arrays.dref: -------------------------------------------------------------------------------- 1 | 2 | val impGetProp :: 3 | {(and (v :: [; L; H] 4 | _:[x:Ref(L), k:Str] / [H ++ L |-> d:{Dict|(has v k)}] 5 | -> {(= v (sel d k))} / same) 6 | (v :: [A; L; H] 7 | _:[x:Ref(L), i:{Str|(= v "length")}] / [H ++ L |-> a:Arr(A)] 8 | -> {Int|(implies (packed a) (= v (len a)))} / same))} 9 | 10 | val impGetArr :: [A;L] _:[x:Ref(L), i:Int] / [L |-> a:Arr(A)] -> 11 | {(ite (and (packed a) (>= i 0)) 12 | (ite (< i (len a)) (and (v::A) (= v (sel a i))) (= v undefined)) 13 | (or (v::A) (= v undefined)))} / same 14 | 15 | -------------------------------------------------------------------------------- /tests/imperative/arrays/elem_test00.dref: -------------------------------------------------------------------------------- 1 | let a = new (<0, 1>, lA, objROOT, lROOT) in 2 | 3 | let _ :: {(= v 2)} = ([NotUndef;lA,lROOT] getElem) (a, "length") in 4 | let _ :: {(= v 0)} = ([NotUndef;lA,lROOT] getElem) (a, 0) in 5 | let _ :: {(= v 1)} = ([NotUndef;lA,lROOT] getElem) (a, 1) in 6 | let _ :: Undef = ([NotUndef;lA,lROOT] getElem) (a, 2) in 7 | 0 8 | -------------------------------------------------------------------------------- /tests/imperative/arrays/test00.dref: -------------------------------------------------------------------------------- 1 | let a = new (<0, 1>, lA, objROOT, lROOT) in 2 | 3 | let _ :: {(= v 2)} = ([NotUndef;lA,lROOT] getPropArr) (a, "length") in 4 | let _ :: {(= v 0)} = ([NotUndef;lA,lROOT] getIdx) (a, 0) in 5 | let _ :: {(= v 1)} = ([NotUndef;lA,lROOT] getIdx) (a, 1) in 6 | let _ :: Undef = ([NotUndef;lA,lROOT] getIdx) (a, 2) in 7 | 0 8 | 9 | (* 10 | #use "tests/imperative/arrays/__arrays.dref" 11 | 12 | let d = ref lD {"f" = 1} in 13 | let _ :: {(= v 1)} = ([;lD] impGetProp) (d, "f") in 14 | 15 | let a = ref lA <0, 1> in 16 | let _ :: {(= v 2)} = ([{(not (= v undefined))};lA] impGetProp) (a, "length") in 17 | let _ :: {(= v 0)} = ([{(not (= v undefined))};lA] impGetArr) (a, 0) in 18 | let _ :: {(= v 1)} = ([{(not (= v undefined))};lA] impGetArr) (a, 1) in 19 | let _ :: {(= v undefined)} = ([{(not (= v undefined))};lA] impGetArr) (a, 2) in 20 | 21 | 0 22 | *) 23 | -------------------------------------------------------------------------------- /tests/imperative/arrays/xx_test00.dref: -------------------------------------------------------------------------------- 1 | let a = new (<0, 1>, lA, objROOT, lROOT) in 2 | let _ :: {(= v 1)} = ([NotUndef;lA,lROOT] getPropArrLen) (a, "length") in 3 | 0 4 | -------------------------------------------------------------------------------- /tests/imperative/control/test00.ml: -------------------------------------------------------------------------------- 1 | let id :: x:Top -> {(= v x)} = 2 | fun x -> ( #return { break #return x }) in 3 | 4 | let _ :: {(= v 1)} = id 1 in 5 | let _ :: {(= v 2)} = id 2 in 6 | let _ :: {(= v true)} = id true in 7 | 0 8 | -------------------------------------------------------------------------------- /tests/imperative/control/test01.ml: -------------------------------------------------------------------------------- 1 | let id :: x:Top -> {(= v x)} = 2 | fun x -> ( #return { x }) in 3 | 4 | let _ :: {(= v 1)} = id 1 in 5 | let _ :: {(= v 2)} = id 2 in 6 | let _ :: {(= v true)} = id true in 7 | 0 8 | -------------------------------------------------------------------------------- /tests/imperative/control/test02.ml: -------------------------------------------------------------------------------- 1 | let id :: x:Top -> {(= v x)} = 2 | fun x -> ( #return { let y = break #return x in undefined }) in 3 | 4 | let _ :: {(= v 1)} = id 1 in 5 | let _ :: {(= v 2)} = id 2 in 6 | let _ :: {(= v true)} = id true in 7 | 0 8 | -------------------------------------------------------------------------------- /tests/imperative/control/xx_test01.ml: -------------------------------------------------------------------------------- 1 | let id :: x:Top -> {(= v x)} = 2 | fun x -> ( #return { 0 }) in 3 | 0 4 | -------------------------------------------------------------------------------- /tests/imperative/inference/quickthaw00.dref: -------------------------------------------------------------------------------- 1 | weak (~lBlah: {Dict|(Int (sel v "n"))} > lObjPro) 2 | val x :: Ref(~lBlah) 3 | let _ :: Int = getElem (x, "n") in 4 | 0 5 | -------------------------------------------------------------------------------- /tests/imperative/inference/quickthaw01.dref: -------------------------------------------------------------------------------- 1 | weak (~lBlah: {Dict|(Int (sel v "n"))} > lObjPro) 2 | val x :: Ref(~lBlah) 3 | let _ :: Int = getElem (x, "n") in 4 | let _ = setElem (x, "n", 10) in 5 | let _ = setElem (x, "n", getElem (x, "n")) in 6 | let _ = setElem (x, "f", "hi") in 7 | 0 8 | -------------------------------------------------------------------------------- /tests/imperative/inference/test00.dref: -------------------------------------------------------------------------------- 1 | weak (~lWeak |-> {Dict|(Int (sel v "f"))} > lObjPro) 2 | 3 | val weak_obj :: Ref(~lWeak) 4 | 5 | let thaw_obj_1 = thaw (lThaw1, weak_obj) in 6 | 7 | let _ :: Int = ([;lThaw1,lObjPro;] getPropObj) (thaw_obj_1, "f") in 8 | 9 | let _ :: Int = getPropObj (thaw_obj_1, "f") in 10 | 11 | 0 12 | -------------------------------------------------------------------------------- /tests/imperative/inference/xx_quickthaw01.dref: -------------------------------------------------------------------------------- 1 | weak (~lBlah: {Dict|(Int (sel v "n"))} > lObjPro) 2 | val x :: Ref(~lBlah) 3 | let _ :: Int = getElem (x, "n") in 4 | let _ = setElem (x, "n", "true") in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/imperative/objects/sugar00.dref: -------------------------------------------------------------------------------- 1 | val f :: (x:Ref) / (x: d:Dict > lObjPro) -> Ref(x) / same 2 | 3 | val g :: (x:Ref?) / (x: d:Dict > lObjPro) -> Int / same 4 | 5 | val h :: (x:Ref) / (x: d:Dict > x.pro) -> Ref(x.pro) / same 6 | 7 | val i :: (x:Ref) / (x: d:Dict > x.pro) -> {(= v (heapsel Cur x.pro "f"))} / same 8 | 9 | 0 10 | -------------------------------------------------------------------------------- /tests/imperative/objects/test00.dref: -------------------------------------------------------------------------------- 1 | (* val ____ObjectProto :: Ref(lROOT) *) 2 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 3 | let _ = ([;lx,lROOT;] getPropObj) (x, "f") in 4 | let _ :: {(= v 100)} = ([;lx,lROOT;] getPropObj) (x, "f") in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/imperative/objects/test01.dref: -------------------------------------------------------------------------------- 1 | (* val ____ObjectProto :: Ref(lObjPro) *) 2 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 3 | let _ = ([;lx,lROOT;] setPropObj) (x, "f", "hi") in 4 | let _ :: {(= v "hi")} = ([;lx,lROOT;] getPropObj) (x, "f") in 5 | let _ :: {(= v undefined)} = ([;lx,lROOT;] getPropObj) (x, "g") in 6 | 0 7 | -------------------------------------------------------------------------------- /tests/imperative/objects/test02.dref: -------------------------------------------------------------------------------- 1 | (* val ____ObjectProto :: Ref(lObjPro) *) 2 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 3 | let _ = ([;lx,lROOT;] delPropObj) (x, "f") in 4 | let _ :: {(= v undefined)} = ([;lx,lROOT;] getPropObj) (x, "f") in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/imperative/objects/test03.dref: -------------------------------------------------------------------------------- 1 | (* val ____ObjectProto :: Ref(lROOT) *) 2 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 3 | let xf :: {(= v 200)} = ([;lx,lROOT;] setPropObj) (x, "f", 200) in 4 | let _ :: {(= v 200)} = xf in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/imperative/quicktypes/elem_obj00.dref: -------------------------------------------------------------------------------- 1 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 2 | let _ :: Int = getElem (x, "f") in 3 | let _ :: Undef = getElem (x, "g") in 4 | let _ :: Undef = getElem (x, "h") in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/imperative/quicktypes/elem_obj02.dref: -------------------------------------------------------------------------------- 1 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 2 | let _ :: Int = getElem (x, "f") in 3 | let _ :: Undef = getElem (x, "g") in 4 | let _ = setElem (x, "f", true) in 5 | let _ = setElem (x, "g", false) in 6 | let _ :: Bool = getElem (x, "f") in 7 | let _ :: Bool = getElem (x, "g") in 8 | 0 9 | -------------------------------------------------------------------------------- /tests/imperative/quicktypes/obj00.dref: -------------------------------------------------------------------------------- 1 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 2 | let _ :: Int = getPropObj (x, "f") in 3 | let _ :: Undef = getPropObj (x, "g") in 4 | let _ :: Undef = getPropObj (x, "h") in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/imperative/quicktypes/obj01.dref: -------------------------------------------------------------------------------- 1 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 2 | let y = new ({"g" = true}, ly, x, lx) in 3 | let _ :: Int = getPropObj (y, "f") in 4 | let _ :: Bool = getPropObj (y, "g") in 5 | let _ :: Undef = getPropObj (y, "h") in 6 | 0 7 | -------------------------------------------------------------------------------- /tests/imperative/quicktypes/obj02.dref: -------------------------------------------------------------------------------- 1 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 2 | let _ :: Int = getPropObj (x, "f") in 3 | let _ :: Undef = getPropObj (x, "g") in 4 | let _ = setPropObj (x, "f", true) in 5 | let _ = setPropObj (x, "g", false) in 6 | let _ :: Bool = getPropObj (x, "f") in 7 | let _ :: Bool = getPropObj (x, "g") in 8 | 0 9 | -------------------------------------------------------------------------------- /tests/imperative/quicktypes/obj03.dref: -------------------------------------------------------------------------------- 1 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 2 | let y = new ({"g" = true}, ly, x, lx) in 3 | let _ :: Int = getPropObj (y, "f") in 4 | let _ = setPropObj (x, "f", "hi") in 5 | let _ :: Str = getPropObj (y, "f") in 6 | 0 7 | -------------------------------------------------------------------------------- /tests/imperative/quicktypes/obj04.dref: -------------------------------------------------------------------------------- 1 | let readF :: (x:Ref) / (x: {f:Int} > lObjPro) -> Int / same = 2 | fun (x) -> (getPropObj (x, "f")) 3 | in 4 | 0 5 | -------------------------------------------------------------------------------- /tests/imperative/quicktypes/obj05.dref: -------------------------------------------------------------------------------- 1 | (* constraint lObjPro so that quick TS-App can resolve entire prototype chain *) 2 | let readF :: (x:Ref) / (x: {f:Int, _:Bot} > lObjPro, lObjPro: Empty > lROOT) 3 | -> Undef / same = 4 | fun (x) -> (getPropObj (x, "g")) 5 | in 6 | 0 7 | -------------------------------------------------------------------------------- /tests/imperative/quicktypes/xx_obj03.dref: -------------------------------------------------------------------------------- 1 | let x = new ({"f" = 100}, lx, objROOT, lROOT) in 2 | let y = new ({"g" = true}, ly, x, lx) in 3 | let _ :: Int = getPropObj (y, "f") in 4 | let _ = setPropObj (x, "f", "hi") in 5 | let _ :: Int = getPropObj (y, "f") in 6 | 0 7 | -------------------------------------------------------------------------------- /tests/imperative/quicktypes/xx_obj05.dref: -------------------------------------------------------------------------------- 1 | (* can't prove Undef since don't know if domain is exact *) 2 | let readF :: (x:Ref) / (x: {f:Int} > lObjPro) -> Undef / same = 3 | fun (x) -> (getPropObj (x, "g")) 4 | in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/imperative/recursion/test00.dref: -------------------------------------------------------------------------------- 1 | let foo :: [;L] x:Ref(L) / (L |-> n:Int) -> Int / same = 2 | ([ [;L] x:Ref(L) / (L |-> n:Int) -> Int / same] fix) 3 | (fun f -> 4 | (fun i -> (([;L;] f) (i)))) 5 | in 0 6 | -------------------------------------------------------------------------------- /tests/imperative/simple/conditional00.dref: -------------------------------------------------------------------------------- 1 | val b :: Bool 2 | let x = ref &x 0 in 3 | let _ = if b then x := 1 else x := 2 in 4 | let _ :: {(or (= v 1) (= v 2))} = !x in 5 | 0 6 | -------------------------------------------------------------------------------- /tests/imperative/simple/deref00.dref: -------------------------------------------------------------------------------- 1 | 2 | let foo :: [;L] x:Ref(L) / (L|->y:Top) -> {(= v y)} / (L|->z:Top) = 3 | fun x -> 4 | (!x) 5 | in 6 | 7 | 0 8 | -------------------------------------------------------------------------------- /tests/imperative/simple/deref01.dref: -------------------------------------------------------------------------------- 1 | 2 | (* multiple reads with no intervening writes *) 3 | 4 | let foo :: [A;L] x:Ref(L) / (L|->yy:A) -> {(= v true)} / (L|->_:{(= v yy)}) = 5 | fun x -> 6 | (js_eek ((!x),(!x))) 7 | in 8 | 9 | 0 10 | -------------------------------------------------------------------------------- /tests/imperative/simple/deref02.dref: -------------------------------------------------------------------------------- 1 | 2 | let foo :: [;L] xx:Ref(L) / (L|->yy:Int) -> Int / (L|->_:{(= v yy)}) = 3 | fun xx -> 4 | (js_plus ((!xx), 1)) 5 | in 6 | 7 | 0 8 | -------------------------------------------------------------------------------- /tests/imperative/simple/negate0.dref: -------------------------------------------------------------------------------- 1 | 2 | let negate :: [;L] x:Ref(L) / (L|->y:Bool) 3 | -> Top / (L|->z:{Bool|(iff (= v true) (= y false))}) = 4 | fun x -> 5 | (x := (js_not (!x))) 6 | in 7 | 8 | 0 9 | -------------------------------------------------------------------------------- /tests/imperative/simple/negate1.dref: -------------------------------------------------------------------------------- 1 | 2 | let negate :: [;L] x:Ref(L) / (L|->y:Bool) 3 | -> Top / (L|->z:{Bool|(iff (= v true) (= y false))}) = 4 | fun x -> 5 | (x := (js_not (js_not (js_not (!x))))) 6 | in 7 | 8 | 0 9 | -------------------------------------------------------------------------------- /tests/imperative/simple/newref00.dref: -------------------------------------------------------------------------------- 1 | 2 | let px = ref &px 1 in 3 | let _ :: {(= v 1)} = !px in 4 | 5 | (* strong update *) 6 | let _ = px := 2 in 7 | let _ :: {(= v 2)} = !px in 8 | 9 | let _ = px := true in 10 | let _ :: {(= v true)} = !px in 11 | 12 | 0 13 | 14 | -------------------------------------------------------------------------------- /tests/imperative/simple/noop0.dref: -------------------------------------------------------------------------------- 1 | 2 | let foo :: [;L] x:Ref(L) / (L|->y:Top) 3 | -> Top / (L|->z:{(= v y)}) = 4 | fun x -> 5 | (0) 6 | in 7 | 8 | 0 9 | -------------------------------------------------------------------------------- /tests/imperative/simple/ref00.dref: -------------------------------------------------------------------------------- 1 | 2 | let begin_main = 0 in 3 | 4 | let a = ref &a 0 in 5 | 6 | let b = !a in 7 | 8 | let _ :: {(= v 0)} = b in 9 | 10 | let c = a := 1 in 11 | 12 | let d = !a in 13 | 14 | let _ :: {(= v 1)} = d in 15 | 16 | (* this forces variable elim even for ERef rule *) 17 | let e = a := b in 18 | 19 | 0 20 | -------------------------------------------------------------------------------- /tests/imperative/simple/writeback0.dref: -------------------------------------------------------------------------------- 1 | 2 | let foo :: [;L] x:Ref(L) / (L|->y:Top) 3 | -> Top / (L|->z:{(= v y)}) = 4 | fun x -> 5 | (x := (!x)) 6 | in 7 | 8 | 0 9 | -------------------------------------------------------------------------------- /tests/imperative/simple/xx_ref00.dref: -------------------------------------------------------------------------------- 1 | let a = ref &a 0 in 2 | let _ = a := 1 in 3 | let _ :: {(= v 0)} = !a in 4 | 0 5 | -------------------------------------------------------------------------------- /tests/imperative/weak/null00.dref: -------------------------------------------------------------------------------- 1 | let _ :: Ref(~blah) = null in 2 | 0 3 | -------------------------------------------------------------------------------- /tests/imperative/weak/test00.dref: -------------------------------------------------------------------------------- 1 | weak (~lWeak |-> {(Int (sel v "f"))} > lROOT) 2 | 3 | let strong_obj_1 = new ({"f" = 100}, lStrong1, objROOT, lROOT) in 4 | let weak_obj_1 = freeze (~lWeak, frzn, strong_obj_1) in 5 | 6 | let strong_obj_2 = new ({"f" = true}, lStrong2, objROOT, lROOT) in 7 | let _ :: Int = ([;lStrong2,lROOT;] setPropObj) (strong_obj_2, "f", 200) in 8 | let weak_obj_2 = freeze (~lWeak, frzn, strong_obj_2) in 9 | 10 | let _ :: Ref(~lWeak) = weak_obj_1 in 11 | let _ :: Ref(~lWeak) = weak_obj_2 in 12 | let _ :: {(not (= v null))} = weak_obj_1 in 13 | let _ :: {(not (= v null))} = weak_obj_2 in 14 | 15 | 0 16 | -------------------------------------------------------------------------------- /tests/imperative/weak/test01.dref: -------------------------------------------------------------------------------- 1 | weak (~lWeak |-> {Dict|(Int (sel v "f"))} > lROOT) 2 | 3 | let strong_obj_1 = new ({"f" = 100}, lStrong1, objROOT, lROOT) in 4 | let _ :: {(= v 100)} = ([;lStrong1,lROOT;] getPropObj) (strong_obj_1, "f") in 5 | 6 | let weak_obj_1 = freeze (~lWeak, frzn, strong_obj_1) in 7 | 8 | let thaw_obj_1 = thaw (lThaw1, weak_obj_1) in 9 | 10 | let _ :: Int = ([;lThaw1,lROOT;] getPropObj) (thaw_obj_1, "f") in 11 | 12 | 0 13 | -------------------------------------------------------------------------------- /tests/imperative/weak/test02.dref: -------------------------------------------------------------------------------- 1 | weak (~lWeak |-> {Dict|(Int (sel v "f"))} > lROOT) 2 | 3 | val weak_obj :: Ref(~lWeak) 4 | 5 | let thaw_obj_1 = thaw (lThaw1, weak_obj) in 6 | 7 | let _ :: Int = ([;lThaw1,lROOT;] getPropObj) (thaw_obj_1, "f") in 8 | 9 | 0 10 | -------------------------------------------------------------------------------- /tests/imperative/weak/test03.dref: -------------------------------------------------------------------------------- 1 | weak (~lWeak |-> {Dict|(Int (sel v "f"))} > lROOT) 2 | 3 | let strong_obj_1 = new ({"f" = 100}, lStrong1, objROOT, lROOT) in 4 | let _ :: {(= v 100)} = ([;lStrong1,lROOT;] getPropObj) (strong_obj_1, "f") in 5 | 6 | let weak_obj_1 = freeze (~lWeak, frzn, strong_obj_1) in 7 | 8 | let thaw_obj_1 = thaw (lThaw1, weak_obj_1) in 9 | 10 | let _ :: Int = ([;lThaw1,lROOT;] getPropObj) (thaw_obj_1, "f") in 11 | 12 | let weak_obj_2 = freeze (~lWeak, thwd lThaw1, thaw_obj_1) in 13 | 14 | let thaw_obj_2 = thaw (lThaw2, weak_obj_2) in 15 | 16 | (* temporary invariant violation *) 17 | let _ = ([;lThaw2,lROOT;] setPropObj) (thaw_obj_2, "f", true) in 18 | 19 | (* invariant restored *) 20 | let _ = ([;lThaw2,lROOT;] setPropObj) (thaw_obj_2, "f", 10) in 21 | 22 | let _ :: Int = ([;lThaw2,lROOT;] getPropObj) (thaw_obj_2, "f") in 23 | 24 | 0 25 | -------------------------------------------------------------------------------- /tests/imperative/weak/test04.dref: -------------------------------------------------------------------------------- 1 | weak (~lWeak |-> {Dict|(Int (sel v "f"))} > lROOT) 2 | let strong_obj_1 = new ({"f" = 100}, lStrong1, objROOT, lROOT) in 3 | let weak_obj_1 = freeze (~lWeak, frzn, strong_obj_1) in 4 | let thaw_obj_1 = thaw (lThaw1, weak_obj_1) in 5 | (* immediate re-freeze, need to know thaw_obj_1 is non-null *) 6 | let weak_obj_2 = freeze (~lWeak, thwd lThaw1, thaw_obj_1) in 7 | 0 8 | -------------------------------------------------------------------------------- /tests/imperative/weak/xx_null00.dref: -------------------------------------------------------------------------------- 1 | let _ :: Ref(~blah) = 0 in 2 | 0 3 | -------------------------------------------------------------------------------- /tests/imperative/weak/xx_test00.dref: -------------------------------------------------------------------------------- 1 | weak (~lWeak |-> {(Int (sel v "f"))} > lROOT) 2 | 3 | let strong_obj_1 = new ({"f" = 100}, lStrong1, objROOT, lROOT) in 4 | let _ :: {(= v 100)} = ([;lStrong1,lROOT;] getPropObj) (strong_obj_1, "f") in 5 | 6 | let weak_obj_1 = freeze (~lWeak, frzn, strong_obj_1) in 7 | 8 | (* this reference was frozen *) 9 | let _ :: {(= v 100)} = ([;lStrong1,lROOT;] getPropObj) (strong_obj_1, "f") in 10 | 11 | 0 12 | -------------------------------------------------------------------------------- /tests/imperative/weak/xx_test01.dref: -------------------------------------------------------------------------------- 1 | weak (~lWeak |-> {Dict|(Int (sel v "f"))} > lROOT) 2 | 3 | let strong_obj_1 = new ({"f" = 100}, lStrong1, objROOT, lROOT) in 4 | let _ :: {(= v 100)} = ([;lStrong1,lROOT;] getPropObj) (strong_obj_1, "f") in 5 | 6 | let weak_obj_1 = freeze (~lWeak, frzn, strong_obj_1) in 7 | 8 | let thaw_obj_1 = thaw (lThaw1, weak_obj_1) in 9 | 10 | (* still thawed *) 11 | let thaw_obj_2 = thaw (lThaw2, weak_obj_1) in 12 | 13 | 0 14 | -------------------------------------------------------------------------------- /tests/imperative/weak/xx_test02.dref: -------------------------------------------------------------------------------- 1 | weak (~lWeak |-> {Dict|(Int (sel v "f"))} > lROOT) 2 | 3 | let strong_obj_1 = new ({"f" = 100}, lStrong1, objROOT, lROOT) in 4 | let _ :: {(= v 100)} = ([;lStrong1,lROOT;] getPropObj) (strong_obj_1, "f") in 5 | 6 | let weak_obj_1 = freeze (~lWeak, frzn, strong_obj_1) in 7 | 8 | let thaw_obj_1 = thaw (lThaw1, weak_obj_1) in 9 | 10 | let _ :: Int = ([;lThaw1,lROOT;] getPropObj) (thaw_obj_1, "f") in 11 | 12 | let weak_obj_2 = freeze (~lWeak, thwd lThaw1, thaw_obj_1) in 13 | 14 | (* already re-frozen *) 15 | let _ :: Int = ([;lThaw1,lROOT;] getPropObj) (thaw_obj_1, "f") in 16 | 17 | 0 18 | -------------------------------------------------------------------------------- /tests/imperative/weak/xx_test03.dref: -------------------------------------------------------------------------------- 1 | weak (~lWeak |-> {Dict|(Int (sel v "f"))} > lROOT) 2 | 3 | let strong_obj_1 = new ({"f" = 100}, lStrong1, objROOT, lROOT) in 4 | let _ :: {(= v 100)} = ([;lStrong1,lROOT;] getPropObj) (strong_obj_1, "f") in 5 | 6 | let weak_obj_1 = freeze (~lWeak, frzn, strong_obj_1) in 7 | 8 | let thaw_obj_1 = thaw (lThaw1, weak_obj_1) in 9 | 10 | let _ :: Int = ([;lThaw1,lROOT;] getPropObj) (thaw_obj_1, "f") in 11 | 12 | let weak_obj_2 = freeze (~lWeak, thwd lThaw1, thaw_obj_1) in 13 | 14 | let thaw_obj_2 = thaw (lThaw2, weak_obj_2) in 15 | 16 | (* invariant violation *) 17 | let _ = ([;lThaw2,lROOT;] setPropObj) (thaw_obj_2, "f", true) in 18 | 19 | (* invariant not restored *) 20 | let _ :: Int = ([;lThaw2,lROOT;] getPropObj) (thaw_obj_2, "f") in 21 | 22 | 0 23 | --------------------------------------------------------------------------------