From f5b802ebed5af3842d18be35ef5735edeb538a8c Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Thu, 19 Sep 2019 18:37:08 +0300 Subject: [PATCH] Global definitions; regression tests fixed --- regression/test001.expr | 2 ++ regression/test002.expr | 2 ++ regression/test003.expr | 2 ++ regression/test004.expr | 2 ++ regression/test005.expr | 2 ++ regression/test006.expr | 2 ++ regression/test007.expr | 2 ++ regression/test008.expr | 2 ++ regression/test009.expr | 2 ++ regression/test010.expr | 2 ++ regression/test011.expr | 2 ++ regression/test012.expr | 2 ++ regression/test013.expr | 2 ++ regression/test014.expr | 2 ++ regression/test015.expr | 8 +++++--- regression/test016.expr | 2 ++ regression/test017.expr | 2 ++ regression/test018.expr | 2 ++ regression/test019.expr | 2 ++ regression/test020.expr | 2 ++ regression/test021.expr | 2 ++ regression/test022.expr | 2 ++ regression/test023.expr | 2 ++ regression/test024.expr | 2 ++ regression/test025.expr | 2 ++ regression/test026.expr | 2 ++ regression/test027.expr | 2 ++ regression/test028.expr | 2 ++ regression/test029.expr | 2 ++ regression/test030.expr | 2 ++ regression/test031.expr | 2 ++ regression/test032.expr | 2 ++ regression/test033.expr | 2 ++ regression/test034.expr | 2 ++ regression/test035.expr | 2 ++ regression/test036.expr | 2 ++ regression/test037.expr | 2 ++ regression/test038.expr | 2 ++ regression/test039.expr | 2 ++ regression/test040.expr | 2 ++ regression/test041.expr | 2 ++ regression/test042.expr | 2 ++ regression/test043.expr | 2 ++ regression/test044.expr | 2 ++ regression/test045.expr | 2 ++ regression/test046.expr | 2 ++ regression/test047.expr | 2 ++ regression/test048.expr | 2 ++ regression/test049.expr | 2 ++ regression/test050.expr | 2 ++ regression/test051.expr | 2 ++ regression/test052.expr | 2 ++ regression/test053.expr | 2 ++ regression/test054.expr | 2 ++ src/Language.ml | 15 +++++++++------ src/SM.ml | 2 +- 56 files changed, 121 insertions(+), 10 deletions(-) diff --git a/regression/test001.expr b/regression/test001.expr index f8bdc2601..fcec90eef 100644 --- a/regression/test001.expr +++ b/regression/test001.expr @@ -1,3 +1,5 @@ +global x, y, z; + x := read (); y := read (); z := x*y*3; diff --git a/regression/test002.expr b/regression/test002.expr index 1b521061b..4343f3567 100644 --- a/regression/test002.expr +++ b/regression/test002.expr @@ -1,3 +1,5 @@ +global x, y, z; + x := read (); y := read (); z := y*y; diff --git a/regression/test003.expr b/regression/test003.expr index 408d8de2e..9cac44ef0 100644 --- a/regression/test003.expr +++ b/regression/test003.expr @@ -1,3 +1,5 @@ +global x, y; + x := read (); y := read (); write (x-y); diff --git a/regression/test004.expr b/regression/test004.expr index fb492c160..dde774752 100644 --- a/regression/test004.expr +++ b/regression/test004.expr @@ -1,3 +1,5 @@ +global x, y, z; + x := read (); y := read (); z := ((x + y) + (x - y)) + ((x - y) - (x + y)); diff --git a/regression/test005.expr b/regression/test005.expr index 03b1df0f6..128ead80a 100644 --- a/regression/test005.expr +++ b/regression/test005.expr @@ -1,3 +1,5 @@ +global x, y, z; + x := read (); y := read (); z := ((x + y) + (x - y)) + ((x - y) - (x / y)); diff --git a/regression/test006.expr b/regression/test006.expr index 0fa1b7315..99de2c6e0 100644 --- a/regression/test006.expr +++ b/regression/test006.expr @@ -1,3 +1,5 @@ +global x, y, z; + x := read (); y := read (); z := x < y; diff --git a/regression/test007.expr b/regression/test007.expr index c00002359..3ea167ce5 100644 --- a/regression/test007.expr +++ b/regression/test007.expr @@ -1,3 +1,5 @@ +global x, y, z; + x := 1; y := 2; z := x - y - 3; diff --git a/regression/test008.expr b/regression/test008.expr index 6d9daeef1..9394c421b 100644 --- a/regression/test008.expr +++ b/regression/test008.expr @@ -1,2 +1,4 @@ +global z; + z := 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9; write (z) diff --git a/regression/test009.expr b/regression/test009.expr index 153699d11..2ae2b774f 100644 --- a/regression/test009.expr +++ b/regression/test009.expr @@ -1,3 +1,5 @@ +global n, k, res; + n := 2; k := 10; res := 1; diff --git a/regression/test010.expr b/regression/test010.expr index 0b6a42527..ab9ffce02 100644 --- a/regression/test010.expr +++ b/regression/test010.expr @@ -1,3 +1,5 @@ +global i, s, j; + i := 0; s := 0; diff --git a/regression/test011.expr b/regression/test011.expr index a89428dc7..0aed934c1 100644 --- a/regression/test011.expr +++ b/regression/test011.expr @@ -1,3 +1,5 @@ +global x; + x:=0; if x then write(1) diff --git a/regression/test012.expr b/regression/test012.expr index 6d94211db..19323a619 100644 --- a/regression/test012.expr +++ b/regression/test012.expr @@ -1,3 +1,5 @@ +global n; + n := read (); while n >= 0 do if n > 1 diff --git a/regression/test013.expr b/regression/test013.expr index 560ef085d..7eacfdc95 100644 --- a/regression/test013.expr +++ b/regression/test013.expr @@ -1,3 +1,5 @@ +global n; + n := read (); repeat diff --git a/regression/test014.expr b/regression/test014.expr index bd64a0c01..1e3eb51cc 100644 --- a/regression/test014.expr +++ b/regression/test014.expr @@ -1,3 +1,5 @@ +global n; + n := read (); while n > 0 do diff --git a/regression/test015.expr b/regression/test015.expr index fe062ae5e..d53dc4cee 100644 --- a/regression/test015.expr +++ b/regression/test015.expr @@ -1,10 +1,11 @@ +global s, n, p; + s := 0; n := read (); p := 2; -while n > 0 do - c := 2; - f := 1; +while n > 0 do { + local c = 2, f = 1; while c*c <= p && f do f := (p % c) != 0; @@ -17,4 +18,5 @@ while n > 0 do else skip fi; p := p + 1 +} od diff --git a/regression/test016.expr b/regression/test016.expr index 1cd2b9ed1..8cb05ff4d 100644 --- a/regression/test016.expr +++ b/regression/test016.expr @@ -1,3 +1,5 @@ +global s, n; + n := read (); s := 1; diff --git a/regression/test017.expr b/regression/test017.expr index 5de7fe893..8e0d92af0 100644 --- a/regression/test017.expr +++ b/regression/test017.expr @@ -1,3 +1,5 @@ +global n, fib_1, fib_2, fib, i; + n := read (); i := 2; diff --git a/regression/test018.expr b/regression/test018.expr index 13bbce88d..37be45939 100644 --- a/regression/test018.expr +++ b/regression/test018.expr @@ -1,3 +1,5 @@ +global n, c, p, cc, q, i, m, d; + n := read (); c := 1; diff --git a/regression/test019.expr b/regression/test019.expr index cdf9b51f9..d4e02b668 100644 --- a/regression/test019.expr +++ b/regression/test019.expr @@ -1,3 +1,5 @@ +global i, s, j; + i := 0; s := 0; diff --git a/regression/test020.expr b/regression/test020.expr index f8ab24ad6..beea18a74 100644 --- a/regression/test020.expr +++ b/regression/test020.expr @@ -1,3 +1,5 @@ +global s, n, p, c, f; + s := 0; n := read (); p := 2; diff --git a/regression/test021.expr b/regression/test021.expr index aca5f17c8..d59a0dad7 100644 --- a/regression/test021.expr +++ b/regression/test021.expr @@ -1,3 +1,5 @@ +global n, f; + n := read (); f := 1; diff --git a/regression/test022.expr b/regression/test022.expr index ae7ff6c07..c00de50c0 100644 --- a/regression/test022.expr +++ b/regression/test022.expr @@ -1,3 +1,5 @@ +global n, fib_1, fib_2, fib, i; + n := read (); fib_1 := 1; diff --git a/regression/test023.expr b/regression/test023.expr index a616f2b4b..dbd4c2375 100644 --- a/regression/test023.expr +++ b/regression/test023.expr @@ -1,3 +1,5 @@ +global s, n; + s := 0; repeat diff --git a/regression/test024.expr b/regression/test024.expr index 8eba11e8d..7daf2d703 100644 --- a/regression/test024.expr +++ b/regression/test024.expr @@ -6,6 +6,8 @@ fun test2 (b) { a := b } +global x, a, b; + x := read (); test1 (); diff --git a/regression/test025.expr b/regression/test025.expr index 5d4576d6d..3d13f368d 100644 --- a/regression/test025.expr +++ b/regression/test025.expr @@ -1,3 +1,5 @@ +global x, a, b, c; + fun test1 (a) { write (a) } diff --git a/regression/test026.expr b/regression/test026.expr index 1e3d005c6..960a88e6d 100644 --- a/regression/test026.expr +++ b/regression/test026.expr @@ -1,3 +1,5 @@ +global x, a, b, c; + fun test1 (a) { write (a); print () diff --git a/regression/test027.expr b/regression/test027.expr index 84fe93f97..d6dc0b03c 100644 --- a/regression/test027.expr +++ b/regression/test027.expr @@ -1,3 +1,5 @@ +global x, a, b, c; + fun print () { write (a); write (b); diff --git a/regression/test028.expr b/regression/test028.expr index bc480de75..fe1fd6338 100644 --- a/regression/test028.expr +++ b/regression/test028.expr @@ -1,3 +1,5 @@ +global n, i, result; + fun fact (n) { if n <= 1 then result := 1 diff --git a/regression/test029.expr b/regression/test029.expr index 63e9885de..6e90cb8fb 100644 --- a/regression/test029.expr +++ b/regression/test029.expr @@ -1,3 +1,5 @@ +global i, n, result; + fun fib (n) { local r; if n <= 1 diff --git a/regression/test030.expr b/regression/test030.expr index 5c4b90314..de0af0696 100644 --- a/regression/test030.expr +++ b/regression/test030.expr @@ -1,3 +1,5 @@ +global n, i; + fun fib (n) { if n <= 1 then return 1 diff --git a/regression/test031.expr b/regression/test031.expr index 14d166a16..10eb9a6b9 100644 --- a/regression/test031.expr +++ b/regression/test031.expr @@ -1,3 +1,5 @@ +global n, i; + fun fact (n) { if n <= 1 then return 1 diff --git a/regression/test032.expr b/regression/test032.expr index cb19d72d7..bdd90a832 100644 --- a/regression/test032.expr +++ b/regression/test032.expr @@ -1,3 +1,5 @@ +global x, m, n; + fun ack (m, n) { if m == 0 then return (n+1) elif m > 0 && n == 0 then return ack (m-1, 1) diff --git a/regression/test033.expr b/regression/test033.expr index 324e81cc2..f99ce3cf6 100644 --- a/regression/test033.expr +++ b/regression/test033.expr @@ -1,3 +1,5 @@ +global x; + fun test (n, m) { local i, s; s := 0; diff --git a/regression/test034.expr b/regression/test034.expr index 90e74b95f..f02da7c6c 100644 --- a/regression/test034.expr +++ b/regression/test034.expr @@ -1,3 +1,5 @@ +global n, x, i; + fun printString (x) { for i:=0, i return y diff --git a/regression/test039.expr b/regression/test039.expr index c79c66878..77a720164 100644 --- a/regression/test039.expr +++ b/regression/test039.expr @@ -1,3 +1,5 @@ +global n, t; + fun insert (t, x) { case t of Leaf -> return Node (x, Leaf, Leaf) diff --git a/regression/test040.expr b/regression/test040.expr index aa2933f32..9f025cb2b 100644 --- a/regression/test040.expr +++ b/regression/test040.expr @@ -1,3 +1,5 @@ +global x; + fun f (x) { case x of A -> write (1) diff --git a/regression/test041.expr b/regression/test041.expr index a6299d630..9932a2be7 100644 --- a/regression/test041.expr +++ b/regression/test041.expr @@ -1,3 +1,5 @@ +global x; + fun f (a) { case a of A (x, y, z) -> write (x + y + z) diff --git a/regression/test042.expr b/regression/test042.expr index a45a732cc..862bfd8e6 100644 --- a/regression/test042.expr +++ b/regression/test042.expr @@ -1,3 +1,5 @@ +global x, y, i; + fun f (x) { case x of Nil -> write (0) diff --git a/regression/test043.expr b/regression/test043.expr index 996cb062a..733771c3a 100644 --- a/regression/test043.expr +++ b/regression/test043.expr @@ -1,3 +1,5 @@ +global x; + fun sum (x) { case x of Nil -> return 0 diff --git a/regression/test044.expr b/regression/test044.expr index cd5baf59d..f2e7687ce 100644 --- a/regression/test044.expr +++ b/regression/test044.expr @@ -1,3 +1,5 @@ +global x, y, z; + fun zip (x) { case x of Pair (x, y) -> case x of diff --git a/regression/test045.expr b/regression/test045.expr index dc423d525..656ae5482 100644 --- a/regression/test045.expr +++ b/regression/test045.expr @@ -1,3 +1,5 @@ +global x; + fun printString (s) { local i; for i := 0, i < s.length, i := i + 1 do diff --git a/regression/test046.expr b/regression/test046.expr index a0fc12a9d..40c4b6fb4 100644 --- a/regression/test046.expr +++ b/regression/test046.expr @@ -1,3 +1,5 @@ +global n; + n := read (); case 3 of diff --git a/regression/test047.expr b/regression/test047.expr index 288bae09b..690e98d76 100644 --- a/regression/test047.expr +++ b/regression/test047.expr @@ -1,3 +1,5 @@ +global n; + fun collect_ints_acc (v, tail) { local i; case v of diff --git a/regression/test048.expr b/regression/test048.expr index 00b4d8b13..27b58abb0 100644 --- a/regression/test048.expr +++ b/regression/test048.expr @@ -1,3 +1,5 @@ +global n, y; + fun test (n, m) { local i, s; write (n); diff --git a/regression/test049.expr b/regression/test049.expr index f3389fd8a..740bb50b0 100644 --- a/regression/test049.expr +++ b/regression/test049.expr @@ -1,3 +1,5 @@ +global n, y, y2, t; + fun test (n, m) { local i, s; s := 0; diff --git a/regression/test050.expr b/regression/test050.expr index 6430356b2..e4d5fcae2 100644 --- a/regression/test050.expr +++ b/regression/test050.expr @@ -1,3 +1,5 @@ +global n, x, y; + n := read (); x := [1]; y := [x, x]; diff --git a/regression/test051.expr b/regression/test051.expr index 3e2c4757a..247600d84 100644 --- a/regression/test051.expr +++ b/regression/test051.expr @@ -1,3 +1,5 @@ +global n; + fun sum (l) { case l of {} -> return 0 diff --git a/regression/test052.expr b/regression/test052.expr index 2083dc7ab..bdf94113e 100644 --- a/regression/test052.expr +++ b/regression/test052.expr @@ -1,3 +1,5 @@ +global n; + fun hd (l) { case l of h : _ -> return h diff --git a/regression/test053.expr b/regression/test053.expr index 6b5f48bba..0ef525ed6 100644 --- a/regression/test053.expr +++ b/regression/test053.expr @@ -1,3 +1,5 @@ +global n; + infix "===" at "==" (v1, v2) { local s1, s2, i; diff --git a/regression/test054.expr b/regression/test054.expr index c4c13b15f..b085b709a 100644 --- a/regression/test054.expr +++ b/regression/test054.expr @@ -1,3 +1,5 @@ +global x, y, z, s, i, n; + x := y := z := 105; n := read (); diff --git a/src/Language.ml b/src/Language.ml index 769d75b22..b30c55ead 100644 --- a/src/Language.ml +++ b/src/Language.ml @@ -91,7 +91,7 @@ module State = (* State: global state, local state, scope variables *) type t = - | G of (string -> Value.t) + | G of string list * (string -> Value.t) | L of string list * (string -> Value.t) * t (* Undefined state *) @@ -101,14 +101,17 @@ module State = let bind x v s = fun y -> if x = y then v else s y (* Empty state *) - let empty = G undefined + let global vars = G (vars, undefined) (* Update: non-destructively "modifies" the state s by binding the variable x to value v and returns the new state w.r.t. a scope *) let update x v s = let rec inner = function - | G s -> G (bind x v s) + | G (scope, s) -> + if not (List.mem x scope) + then invalid_arg (Printf.sprintf "undefined variable %s" x) + else G (scope, bind x v s) | L (scope, s, enclosing) -> if List.mem x scope then L (scope, bind x v s, enclosing) else L (scope, s, inner enclosing) in @@ -117,7 +120,7 @@ module State = (* Evals a variable in a state w.r.t. a scope *) let rec eval s x = match s with - | G s -> s x + | G (_, s) -> s x | L (scope, s, enclosing) -> if List.mem x scope then s x else eval enclosing x (* Creates a new scope, based on a given state *) @@ -730,7 +733,7 @@ type t = Definition.t list * Expr.t *) let eval ((defs, body) : t) i = let module M = Map.Make (String) in - let m = List.fold_left (fun m ((name, proc) as def) -> match proc with `Fun (args, stmt) -> M.add name (name, (args, stmt)) m | _ -> m) M.empty defs in + let m, gvars = List.fold_left (fun (m, gv) ((name, proc) as def) -> match proc with `Fun (args, stmt) -> M.add name (name, (args, stmt)) m, gv | _ -> m, name::gv) (M.empty, []) defs in let _, _, o, _ = Expr.eval (object @@ -742,7 +745,7 @@ let eval ((defs, body) : t) i = (State.leave st'' st, i', o', match vs' with [v] -> v::vs | _ -> Value.Empty :: vs) with Not_found -> Builtin.eval conf args f end) - (State.empty, i, [], []) + (State.global gvars, i, [], []) Skip body in diff --git a/src/SM.ml b/src/SM.ml index 428d41890..2e9951d23 100644 --- a/src/SM.ml +++ b/src/SM.ml @@ -143,7 +143,7 @@ let run p i = (cstack, (match r with [r] -> r::stack' | _ -> Value.Empty :: stack'), (st, i, o)) end ) - ([], [], (State.empty, i, [])) + ([], [], (State.global [] (* TODO! *), i, [])) p in o