Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions ml-proto/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,12 @@ In order to be able to check and run modules for testing purposes, the S-express
script: <cmd>*

cmd:
<module> ;; define, validate, and initialize module
( invoke <var> <expr>* ) ;; invoke export and print result
<func> ;; = (module <func> (export 0))
( invoke <expr>* ) ;; = (invoke 0 <expr>*)
<module> ;; define, validate, and initialize module
( invoke <var> <expr>* ) ;; invoke export and print result
( asserteq (invoke <var> <expr>* ) <expr>* ) ;; assert expected results of invocation
<func> ;; = (module <func> (export 0))
( invoke <expr>* ) ;; = (invoke 0 <expr>*)
( asserteq (invoke <expr>* ) <expr>* ) ;; = (asserteq (invoke 0 <expr>*) <expr>*)
```

Invocation is only possible after a module has been defined.
Expand Down
7 changes: 4 additions & 3 deletions ml-proto/src/eval.ml
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ let invoke m x vs =
let f = export m (x @@ Source.no_region) in
eval_func m f vs

let eval m e =
let f = {params = []; results = []; locals = []; body = e} @@ Source.no_region
in unary (eval_func m f []) e.at
let eval e =
let f = {params = []; results = []; locals = []; body = e} @@ Source.no_region in
let m = {funcs = [f]; exports = [f]; tables = []; globals = []; memory = (Memory.create 0)} in
unary (eval_func m f []) e.at
2 changes: 1 addition & 1 deletion ml-proto/src/eval.mli
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ type value = Values.value
val init : Ast.modul -> module_instance
val invoke : module_instance -> int -> value list -> value list
(* raise Error.Error *)
val eval : module_instance -> Ast.expr -> value (* raise Error.Error *)
val eval : Ast.expr -> value (* raise Error.Error *)
1 change: 1 addition & 0 deletions ml-proto/src/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ rule token = parse
| "table" { TABLE }

| "invoke" { INVOKE }
| "asserteq" { ASSERTEQ }

| ";;"[^'\n']*eof { EOF }
| ";;"[^'\n']*'\n' { Lexing.new_line lexbuf; token lexbuf }
Expand Down
6 changes: 5 additions & 1 deletion ml-proto/src/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ let literal at s t =
%token GETPARAM GETLOCAL SETLOCAL GETGLOBAL SETGLOBAL GETMEMORY SETMEMORY
%token CONST UNARY BINARY COMPARE CONVERT
%token FUNC PARAM RESULT LOCAL MODULE MEMORY DATA GLOBAL IMPORT EXPORT TABLE
%token INVOKE
%token INVOKE ASSERTEQ
%token EOF

%token<string> INT
Expand Down Expand Up @@ -205,6 +205,10 @@ cmd :
| modul { Define $1 @@ at() }
| LPAR INVOKE INT expr_list RPAR { Invoke (int_of_string $3, $4) @@ at() }
| LPAR INVOKE expr_list RPAR { Invoke (0, $3) @@ at() } /* Sugar */
| LPAR ASSERTEQ LPAR INVOKE INT expr_list RPAR expr_list RPAR
{ AssertEqInvoke (int_of_string $5, $6, $8) @@ at() }
| LPAR ASSERTEQ LPAR INVOKE expr_list RPAR expr_list RPAR
{ AssertEqInvoke (0, $5, $7) @@ at() } /* Sugar */
;
cmd_list :
| /* empty */ { [] }
Expand Down
20 changes: 19 additions & 1 deletion ml-proto/src/script.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type command = command' phrase
and command' =
| Define of Ast.modul
| Invoke of int * Ast.expr list
| AssertEqInvoke of int * Ast.expr list * Ast.expr list

type script = command list

Expand All @@ -34,13 +35,29 @@ let run_command cmd =
current_module := Some (Eval.init m)
| Invoke (i, es) ->
trace "Invoking...";
let vs = List.map Eval.eval es in
let m = match !current_module with
| Some m -> m
| None -> Error.error cmd.at "no module defined to invoke"
in
let vs = List.map (Eval.eval m) es in
let vs' = Eval.invoke m i vs in
if vs' <> [] then Print.print_values vs'
| AssertEqInvoke (i, arg_es, expect_es) ->
trace "AssertEqInvoke...";
let m = match !current_module with
| Some m -> m
| None -> Error.error cmd.at "no module defined to invoke"
in
let arg_vs = List.map Eval.eval arg_es in
let got_vs = Eval.invoke m i arg_vs in
let expect_vs = List.map Eval.eval expect_es in
if got_vs <> expect_vs then begin
print_string "Got: ";
Print.print_values got_vs;
print_string "Expect: ";
Print.print_values expect_vs;
Error.error cmd.at "assertion failed"
end;
with Error.Error (at, s) ->
trace "Error:";
prerr_endline (Source.string_of_region at ^ ": " ^ s)
Expand All @@ -51,6 +68,7 @@ let dry_command cmd =
Check.check_module m;
if !Flags.print_sig then Print.print_module_sig m
| Invoke _ -> ()
| AssertEqInvoke _ -> ()

let run script =
List.iter (if !Flags.dry then dry_command else run_command) script
1 change: 1 addition & 0 deletions ml-proto/src/script.mli
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type command = command' Source.phrase
and command' =
| Define of Ast.modul
| Invoke of int * Ast.expr list
| AssertEqInvoke of int * Ast.expr list * Ast.expr list

type script = command list

Expand Down
9 changes: 9 additions & 0 deletions ml-proto/test/basic.wasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(module
(func (param i32) (result i32)
(return (add.i32 (getparam 0) (const.i32 1)))
)

(export 0)
)

(asserteq (invoke 0 (const.i32 42)) (const.i32 43))