diff --git a/regression/orig/test057.log b/regression/orig/test057.log new file mode 100644 index 000000000..c03089ce6 --- /dev/null +++ b/regression/orig/test057.log @@ -0,0 +1,3 @@ +> 6 +7 +8 diff --git a/regression/orig/test058.log b/regression/orig/test058.log new file mode 100644 index 000000000..e8398dcb2 --- /dev/null +++ b/regression/orig/test058.log @@ -0,0 +1,9 @@ +> 1 +2 +3 +2 +3 +4 +3 +4 +5 diff --git a/regression/orig/test059.log b/regression/orig/test059.log new file mode 100644 index 000000000..65234a85e --- /dev/null +++ b/regression/orig/test059.log @@ -0,0 +1,3 @@ +> 0 +1 +2 diff --git a/regression/orig/test060.log b/regression/orig/test060.log new file mode 100644 index 000000000..a8d89ee1e --- /dev/null +++ b/regression/orig/test060.log @@ -0,0 +1,5 @@ +> 1 +1 +1 +1 +0 diff --git a/regression/test057.expr b/regression/test057.expr new file mode 100644 index 000000000..3b142076a --- /dev/null +++ b/regression/test057.expr @@ -0,0 +1,12 @@ +fun a (x) {return x + 1} +fun b (x) {return x + 2} +fun c (x) {return x + 3} + +{ + local funs = [a, b, c]; + local n = read (), i; + + for i := 0, i < 3, i := i+1 do + write (funs[i] (n)) + od +} \ No newline at end of file diff --git a/regression/test057.input b/regression/test057.input new file mode 100644 index 000000000..7ed6ff82d --- /dev/null +++ b/regression/test057.input @@ -0,0 +1 @@ +5 diff --git a/regression/test058.expr b/regression/test058.expr new file mode 100644 index 000000000..db8aa9c97 --- /dev/null +++ b/regression/test058.expr @@ -0,0 +1,21 @@ +fun map (f, l) { + case l of + {} -> return {} + | h : tl -> return (f (h) : map (f, tl)) + esac +} + +fun a (x) {return x + 1} +fun b (x) {return x + 2} + +fun print_list (x) { + case x of + {} -> skip + | h : tl -> write (h); print_list (tl) + esac +} + +print_list ({1, 2, 3}); +print_list (map (a, {1, 2, 3})); +print_list (map (b, {1, 2, 3})) + diff --git a/regression/test058.input b/regression/test058.input new file mode 100644 index 000000000..7ed6ff82d --- /dev/null +++ b/regression/test058.input @@ -0,0 +1 @@ +5 diff --git a/regression/test059.expr b/regression/test059.expr new file mode 100644 index 000000000..060a1e571 --- /dev/null +++ b/regression/test059.expr @@ -0,0 +1,20 @@ +fun f (l) { + case l of + {} -> skip + | h : tl -> h (); f (tl) + esac +} + +fun a () { + write (0) +} + +fun b () { + write (1) +} + +fun c () { + write (2) +} + +f ({a, b, c}) \ No newline at end of file diff --git a/regression/test059.input b/regression/test059.input new file mode 100644 index 000000000..7ed6ff82d --- /dev/null +++ b/regression/test059.input @@ -0,0 +1 @@ +5 diff --git a/regression/test060.expr b/regression/test060.expr new file mode 100644 index 000000000..912f71826 --- /dev/null +++ b/regression/test060.expr @@ -0,0 +1,17 @@ +fun f (l) { + infix "===" at "==" (a, b) { + return a == b + } + + case l of + {} -> return 1 + | {_} -> return 1 + | a : b : tl -> return a === b && f (b : tl) + esac +} + +write (f ({})); +write (f ({1})); +write (f ({1, 1})); +write (f ({1, 1, 1})); +write (f ({1, 2, 1})) diff --git a/regression/test060.input b/regression/test060.input new file mode 100644 index 000000000..7ed6ff82d --- /dev/null +++ b/regression/test060.input @@ -0,0 +1 @@ +5 diff --git a/src/Language.ml b/src/Language.ml index 00a7efab3..e658a9c5a 100644 --- a/src/Language.ml +++ b/src/Language.ml @@ -431,7 +431,7 @@ module Expr = let st' = List.fold_left (fun st (x, a) -> State.update x a st) (State.enter st (List.map (fun x -> x, true) args)) (List.combine args es) in let st'', i', o', vs'' = eval env (st', i, o, []) Skip body in (State.leave st'' st, i', o', match vs'' with [v] -> v::vs' | _ -> Value.Empty :: vs') - | _ -> invalid_arg "callee did not evaluate to a function" + | _ -> invalid_arg (Printf.sprintf "callee did not evaluate to a function: %s" (show(Value.t) (fun _ -> "") f)) ))])) | Leave -> eval env (State.drop st, i, o, vs) Skip k @@ -588,9 +588,12 @@ module Expr = basic[def][infix][atr]: !(expr (fun x -> x) (Array.map (fun (a, (atr, l)) -> a, (atr, List.map (fun (s, f) -> ostap (- $(s)), f) l)) infix) (primary def infix) atr); primary[def][infix][atr]: - b:base[def][infix][Val] is:(-"[" i:parse[def][infix][Val] -"]" {`Elem i} | -"." (%"length" {`Len} | %"string" {`Str} | f:LIDENT {`Post f}))+ + b:base[def][infix][Val] is:( "[" i:parse[def][infix][Val] "]" {`Elem i} + | -"." (%"length" {`Len} | %"string" {`Str} | f:LIDENT {`Post f}) + | "(" args:!(Util.list0)[parse def infix Val] ")" {`Call args} + )+ => {match (List.hd (List.rev is)), atr with - | `Elem i, Reff -> true + | `Elem i, Reff -> true | _, Reff -> false | _, _ -> true} => { @@ -600,10 +603,11 @@ module Expr = List.fold_left (fun b -> function - | `Elem i -> Elem (b, i) - | `Len -> Length b - | `Str -> StringVal b - | `Post f -> Call (Var f, [b]) + | `Elem i -> Elem (b, i) + | `Len -> Length b + | `Str -> StringVal b + | `Post f -> Call (Var f, [b]) + | `Call args -> (match b with Sexp _ -> invalid_arg "retry!" | _ -> Call (b, args)) ) b is @@ -614,6 +618,7 @@ module Expr = | `Len, _ -> Length b | `Str, _ -> StringVal b | `Post f, _ -> Call (Var f, [b]) + | `Call args, _ -> (match b with Sexp _ -> invalid_arg "retry!" | _ -> Call (b, args)) in ignore atr res } @@ -632,10 +637,9 @@ module Expr = | None -> [] | Some args -> args)) } - | x:LIDENT s:( "(" args:!(Util.list0)[parse def infix Val] ")" => {notRef atr} => {Call (Var x, args)} - | empty {if notRef atr then Var x else Ref x}) {ignore atr s} + | x:LIDENT {if notRef atr then Var x else Ref x} - | {isVoid atr} => %"skip" {Skip} + | {isVoid atr} => %"skip" {Skip} | %"if" e:parse[def][infix][Val] %"then" the:scope[`Local][def][infix][atr][parse def] elif:(%"elif" parse[def][infix][Val] %"then" scope[`Local][def][infix][atr][parse def])*