Michelson: make parsing tests compile again
This commit is contained in:
parent
fe04a872df
commit
bf276fb017
@ -91,3 +91,6 @@ let parse_expression ?check source =
|
|||||||
let tokens, lexing_errors = Micheline_parser.tokenize source in
|
let tokens, lexing_errors = Micheline_parser.tokenize source in
|
||||||
let ast, parsing_errors = Micheline_parser.parse_expression ?check tokens in
|
let ast, parsing_errors = Micheline_parser.parse_expression ?check tokens in
|
||||||
expand_all source ast (lexing_errors @ parsing_errors)
|
expand_all source ast (lexing_errors @ parsing_errors)
|
||||||
|
|
||||||
|
let expand_all ~source ~original =
|
||||||
|
expand_all source original []
|
||||||
|
@ -29,3 +29,4 @@ type parsed =
|
|||||||
|
|
||||||
val parse_toplevel : ?check:bool -> string -> parsed Micheline_parser.parsing_result
|
val parse_toplevel : ?check:bool -> string -> parsed Micheline_parser.parsing_result
|
||||||
val parse_expression : ?check:bool -> string -> parsed Micheline_parser.parsing_result
|
val parse_expression : ?check:bool -> string -> parsed Micheline_parser.parsing_result
|
||||||
|
val expand_all : source:string -> original:Micheline_parser.node -> parsed Micheline_parser.parsing_result
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
(executables
|
(executables
|
||||||
((names (test_endorsement
|
((names (test_endorsement
|
||||||
;; test_michelson_parser
|
test_michelson_parser
|
||||||
test_origination
|
test_origination
|
||||||
test_transaction
|
test_transaction
|
||||||
test_vote))
|
test_vote))
|
||||||
@ -23,7 +23,7 @@
|
|||||||
(alias
|
(alias
|
||||||
((name buildtest)
|
((name buildtest)
|
||||||
(deps (test_endorsement.exe
|
(deps (test_endorsement.exe
|
||||||
;; test_michelson_parser.exe
|
test_michelson_parser.exe
|
||||||
test_origination.exe
|
test_origination.exe
|
||||||
test_transaction.exe
|
test_transaction.exe
|
||||||
test_vote.exe))))
|
test_vote.exe))))
|
||||||
@ -34,6 +34,10 @@
|
|||||||
(locks (/tcp-port/18100))
|
(locks (/tcp-port/18100))
|
||||||
(action (chdir ${ROOT} (run ${exe:test_endorsement.exe} ${bin:tezos-node})))))
|
(action (chdir ${ROOT} (run ${exe:test_endorsement.exe} ${bin:tezos-node})))))
|
||||||
|
|
||||||
|
(alias
|
||||||
|
((name runtest_michelson_parser)
|
||||||
|
(action (run ${exe:test_michelson_parser.exe}))))
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
((name runtest_origination)
|
((name runtest_origination)
|
||||||
(deps (sandbox.json))
|
(deps (sandbox.json))
|
||||||
@ -55,6 +59,7 @@
|
|||||||
(alias
|
(alias
|
||||||
((name runtest)
|
((name runtest)
|
||||||
(deps ((alias runtest_endorsement)
|
(deps ((alias runtest_endorsement)
|
||||||
|
(alias runtest_michelson_parser)
|
||||||
(alias runtest_origination)
|
(alias runtest_origination)
|
||||||
(alias runtest_transaction)
|
(alias runtest_transaction)
|
||||||
(alias runtest_vote)))))
|
(alias runtest_vote)))))
|
||||||
|
@ -7,308 +7,342 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
open Tezos_context.Script
|
|
||||||
|
|
||||||
module Helpers = Proto_alpha_helpers
|
module Helpers = Proto_alpha_helpers
|
||||||
module Assert = Helpers.Assert
|
module Assert = Helpers.Assert
|
||||||
|
|
||||||
open Script_located_ir
|
open Tezos_micheline
|
||||||
|
open Micheline
|
||||||
|
|
||||||
let zero_loc = { start=point_zero;
|
let zero_loc = Micheline_parser.location_zero
|
||||||
stop=point_zero};;
|
|
||||||
|
|
||||||
let assert_identity f x =
|
let prn expr =
|
||||||
Assert.equal
|
expr |>
|
||||||
(f x)
|
Micheline_printer.printable (fun s -> s) |>
|
||||||
x;;
|
Format.asprintf "%a" Micheline_printer.print_expr
|
||||||
|
|
||||||
(* Test expansion *)
|
let assert_expands original expanded =
|
||||||
Assert.equal (Michelson_macros.expand (Prim (zero_loc, "CAAR", [], None)))
|
let { Michelson_v1_parser.expanded = expansion }, errors =
|
||||||
(Seq (zero_loc,
|
let source = prn (Micheline.strip_locations original) in
|
||||||
[(Prim (zero_loc, "CAR", [], None));
|
Michelson_v1_parser.expand_all ~source ~original in
|
||||||
(Prim (zero_loc, "CAR", [], None)) ],
|
let expanded = Micheline.strip_locations expanded in
|
||||||
None));;
|
let expansion = Michelson_v1_primitives.strings_of_prims expansion in
|
||||||
|
match errors with
|
||||||
|
| [] ->
|
||||||
|
Assert.equal ~prn expansion expanded ;
|
||||||
|
ok ()
|
||||||
|
| errors -> Error errors
|
||||||
|
|
||||||
Assert.equal (Michelson_macros.expand (Prim (zero_loc, "CAAR", [], Some "annot")))
|
let left_branch = Seq(zero_loc, [ Prim(zero_loc, "SWAP", [], None) ], None)
|
||||||
(Seq (zero_loc,
|
let right_branch = Seq(zero_loc, [ ], None)
|
||||||
[(Prim (zero_loc, "CAR", [], None));
|
|
||||||
(Prim (zero_loc, "CAR", [], Some "annot")) ],
|
|
||||||
None));;
|
|
||||||
|
|
||||||
assert_identity Michelson_macros.expand (Prim (zero_loc, "CAR", [], Some "annot"));;
|
let test_expansion () =
|
||||||
|
assert_expands (Prim (zero_loc, "CAAR", [], None))
|
||||||
|
|
||||||
let arg = [ Prim (zero_loc, "CAR", [], Some "annot") ] in
|
|
||||||
Assert.equal
|
|
||||||
(Michelson_macros.expand (Prim (zero_loc, "DIP", arg, Some "new_annot")))
|
|
||||||
(Prim (zero_loc, "DIP", arg, Some "new_annot"));
|
|
||||||
Assert.equal
|
|
||||||
(Michelson_macros.expand (Prim (zero_loc, "DIIP", arg, None)))
|
|
||||||
(Seq (zero_loc,
|
|
||||||
[ Prim (zero_loc, "DIP",
|
|
||||||
[ (Seq (zero_loc,
|
|
||||||
[ Prim (zero_loc, "DIP", arg, None) ],
|
|
||||||
None)) ],
|
|
||||||
None) ],
|
|
||||||
None));
|
|
||||||
Assert.equal
|
|
||||||
(Michelson_macros.expand (Prim (zero_loc, "DIIIP", arg, None)))
|
|
||||||
(Seq (zero_loc,
|
|
||||||
[ Prim (zero_loc, "DIP",
|
|
||||||
[ (Seq (zero_loc,
|
|
||||||
[ Prim (zero_loc,
|
|
||||||
"DIP",
|
|
||||||
[ (Seq (zero_loc,
|
|
||||||
[ Prim (zero_loc, "DIP", arg, None) ],
|
|
||||||
None)) ],
|
|
||||||
None) ],
|
|
||||||
None)) ],
|
|
||||||
None) ],
|
|
||||||
None));;
|
|
||||||
|
|
||||||
Assert.equal
|
|
||||||
(Michelson_macros.expand (Prim (zero_loc, "DUUP", [], None)))
|
|
||||||
(Seq (zero_loc,
|
|
||||||
[ Prim (zero_loc, "DIP", [ Seq (zero_loc, [ Prim (zero_loc, "DUP", [], None) ], None) ], None) ;
|
|
||||||
Prim (zero_loc, "SWAP", [], None) ], None));;
|
|
||||||
|
|
||||||
Assert.equal
|
|
||||||
(Michelson_macros.expand (Prim (zero_loc, "DUUUP", [], None)))
|
|
||||||
(Seq (zero_loc,
|
|
||||||
[ Prim (zero_loc, "DIP",
|
|
||||||
[ Seq (zero_loc, [
|
|
||||||
Prim (zero_loc, "DIP", [
|
|
||||||
Seq (zero_loc, [ Prim (zero_loc, "DUP", [], None) ], None)],
|
|
||||||
None);
|
|
||||||
Prim (zero_loc, "SWAP", [], None) ],
|
|
||||||
None) ],
|
|
||||||
None) ;
|
|
||||||
Prim (zero_loc, "SWAP", [], None) ], None));;
|
|
||||||
|
|
||||||
let assert_compare_macro prim_name compare_name =
|
|
||||||
Assert.equal
|
|
||||||
(Michelson_macros.expand (Prim (zero_loc, prim_name, [], None)))
|
|
||||||
(Seq (zero_loc,
|
(Seq (zero_loc,
|
||||||
[ Prim (zero_loc, "COMPARE", [], None) ;
|
[(Prim (zero_loc, "CAR", [], None));
|
||||||
Prim (zero_loc, compare_name, [], None) ], None));;
|
(Prim (zero_loc, "CAR", [], None)) ],
|
||||||
|
None)) >>? fun () ->
|
||||||
|
assert_expands (Prim (zero_loc, "CAAR", [], Some "annot"))
|
||||||
|
(Seq (zero_loc,
|
||||||
|
[(Prim (zero_loc, "CAR", [], None));
|
||||||
|
(Prim (zero_loc, "CAR", [], Some "annot")) ],
|
||||||
|
None)) >>? fun () ->
|
||||||
|
let car = Prim (zero_loc, "CAR", [], Some "annot") in
|
||||||
|
assert_expands car car >>? fun () ->
|
||||||
|
let arg = [ Seq (zero_loc, [ car ], None) ] in
|
||||||
|
assert_expands
|
||||||
|
(Prim (zero_loc, "DIP", arg, Some "new_annot"))
|
||||||
|
(Prim (zero_loc, "DIP", arg, Some "new_annot")) >>? fun () ->
|
||||||
|
assert_expands
|
||||||
|
(Prim (zero_loc, "DIIP", arg, None))
|
||||||
|
(Seq (zero_loc,
|
||||||
|
[ Prim (zero_loc, "DIP",
|
||||||
|
[ (Seq (zero_loc,
|
||||||
|
[ Prim (zero_loc, "DIP", arg, None) ],
|
||||||
|
None)) ],
|
||||||
|
None) ],
|
||||||
|
None)) >>? fun () ->
|
||||||
|
assert_expands
|
||||||
|
(Prim (zero_loc, "DIIIP", arg, None))
|
||||||
|
(Seq (zero_loc,
|
||||||
|
[ Prim (zero_loc, "DIP",
|
||||||
|
[ (Seq (zero_loc,
|
||||||
|
[ Prim (zero_loc,
|
||||||
|
"DIP",
|
||||||
|
[ (Seq (zero_loc,
|
||||||
|
[ Prim (zero_loc, "DIP", arg, None) ],
|
||||||
|
None)) ],
|
||||||
|
None) ],
|
||||||
|
None)) ],
|
||||||
|
None) ],
|
||||||
|
None)) >>? fun () ->
|
||||||
|
assert_expands
|
||||||
|
(Prim (zero_loc, "DUUP", [], None))
|
||||||
|
(Seq (zero_loc,
|
||||||
|
[ Prim (zero_loc, "DIP", [ Seq (zero_loc, [ Prim (zero_loc, "DUP", [], None) ], None) ], None) ;
|
||||||
|
Prim (zero_loc, "SWAP", [], None) ], None)) >>? fun () ->
|
||||||
|
assert_expands
|
||||||
|
(Prim (zero_loc, "DUUUP", [], None))
|
||||||
|
(Seq (zero_loc,
|
||||||
|
[ Prim (zero_loc, "DIP",
|
||||||
|
[ Seq (zero_loc, [
|
||||||
|
Prim (zero_loc, "DIP", [
|
||||||
|
Seq (zero_loc, [ Prim (zero_loc, "DUP", [], None) ], None)],
|
||||||
|
None);
|
||||||
|
Prim (zero_loc, "SWAP", [], None) ],
|
||||||
|
None) ],
|
||||||
|
None) ;
|
||||||
|
Prim (zero_loc, "SWAP", [], None) ], None)) >>? fun () ->
|
||||||
|
let assert_compare_macro prim_name compare_name =
|
||||||
|
assert_expands
|
||||||
|
(Prim (zero_loc, prim_name, [], None))
|
||||||
|
(Seq (zero_loc,
|
||||||
|
[ Prim (zero_loc, "COMPARE", [], None) ;
|
||||||
|
Prim (zero_loc, compare_name, [], None) ], None)) in
|
||||||
|
let assert_compare_if_macro prim_name compare_name =
|
||||||
|
assert_expands
|
||||||
|
(Prim (zero_loc, prim_name,
|
||||||
|
[ left_branch ; right_branch ],
|
||||||
|
None))
|
||||||
|
(Seq (zero_loc, [ Prim(zero_loc, "COMPARE", [], None);
|
||||||
|
Prim(zero_loc, compare_name, [], None);
|
||||||
|
Prim (zero_loc, "IF", [ left_branch ; right_branch ], None) ], None)) in
|
||||||
|
assert_compare_macro "CMPEQ" "EQ" >>? fun () ->
|
||||||
|
assert_compare_macro "CMPNEQ" "NEQ" >>? fun () ->
|
||||||
|
assert_compare_macro "CMPLT" "LT" >>? fun () ->
|
||||||
|
assert_compare_macro "CMPLE" "LE" >>? fun () ->
|
||||||
|
assert_compare_macro "CMPGT" "GT" >>? fun () ->
|
||||||
|
assert_compare_macro "CMPGE" "GE" >>? fun () ->
|
||||||
|
assert_compare_if_macro "IFCMPEQ" "EQ" >>? fun () ->
|
||||||
|
assert_compare_if_macro "IFCMPNEQ" "NEQ" >>? fun () ->
|
||||||
|
assert_compare_if_macro "IFCMPLT" "LT" >>? fun () ->
|
||||||
|
assert_compare_if_macro "IFCMPLE" "LE" >>? fun () ->
|
||||||
|
assert_compare_if_macro "IFCMPGT" "GT" >>? fun () ->
|
||||||
|
assert_compare_if_macro "IFCMPGE" "GE" >>? fun () ->
|
||||||
|
assert_expands (Prim (zero_loc, "ASSERT_LEFT", [], None))
|
||||||
|
(Seq (zero_loc, [ Prim (zero_loc, "IF_LEFT",
|
||||||
|
[ Seq (zero_loc, [ ], None) ;
|
||||||
|
Seq (zero_loc, [ Prim(zero_loc, "FAIL", [], None) ], None) ],
|
||||||
|
None) ], None)) >>? fun () ->
|
||||||
|
assert_expands (Prim (zero_loc, "ASSERT_RIGHT", [], None))
|
||||||
|
(Seq (zero_loc, [ Prim (zero_loc, "IF_LEFT",
|
||||||
|
[ Seq (zero_loc, [ Prim(zero_loc, "FAIL", [], None) ], None) ;
|
||||||
|
Seq (zero_loc, [ ], None) ],
|
||||||
|
None) ], None)) >>? fun () ->
|
||||||
|
assert_expands (Prim (zero_loc, "IF_RIGHT", [ left_branch ; right_branch ], None))
|
||||||
|
(Seq (zero_loc, [ Prim (zero_loc, "IF_LEFT", [ right_branch ; left_branch ], None) ], None)) >>? fun () ->
|
||||||
|
assert_expands (Prim (zero_loc, "IF_SOME", [ left_branch ; right_branch ], None))
|
||||||
|
(Seq (zero_loc, [ Prim (zero_loc, "IF_NONE", [ right_branch ; left_branch ], None) ], None)) >>? fun () ->
|
||||||
|
assert_expands
|
||||||
|
(Prim (zero_loc, "PAIR", [], None))
|
||||||
|
(Prim (zero_loc, "PAIR", [], None)) >>? fun () ->
|
||||||
|
assert_expands
|
||||||
|
(Prim (zero_loc, "PAAIR", [], None))
|
||||||
|
(Seq (zero_loc,
|
||||||
|
[Prim
|
||||||
|
(zero_loc,
|
||||||
|
"DIP",
|
||||||
|
[Seq (zero_loc, [Prim
|
||||||
|
(zero_loc, "PAIR", [], None)],
|
||||||
|
None)],
|
||||||
|
None)],
|
||||||
|
None)) >>? fun () ->
|
||||||
|
assert_expands
|
||||||
|
(Prim (zero_loc, "PAAIAIR", [], None))
|
||||||
|
(Seq (zero_loc, [Prim
|
||||||
|
(zero_loc,
|
||||||
|
"DIP",
|
||||||
|
[Seq
|
||||||
|
(zero_loc,
|
||||||
|
[Prim
|
||||||
|
(zero_loc,
|
||||||
|
"PAIR", [], None)],
|
||||||
|
None)],
|
||||||
|
None);
|
||||||
|
Prim
|
||||||
|
(zero_loc,
|
||||||
|
"PAIR", [], None)],
|
||||||
|
None))
|
||||||
|
|
||||||
let left_branch = Seq(zero_loc, [ Prim(zero_loc, "SWAP", [], None) ], None);;
|
let assert_unexpansion_consistent original =
|
||||||
let right_branch = Seq(zero_loc, [ ], None);;
|
let { Michelson_v1_parser.expanded }, errors =
|
||||||
let assert_compare_if_macro prim_name compare_name =
|
let source = prn (Micheline.strip_locations original) in
|
||||||
Assert.equal
|
Michelson_v1_parser.expand_all ~source ~original in
|
||||||
(Michelson_macros.expand (Prim (zero_loc,
|
match errors with
|
||||||
prim_name,
|
| _ :: _ -> Error errors
|
||||||
[ left_branch ; right_branch ],
|
| [] ->
|
||||||
None)))
|
let { Michelson_v1_parser.unexpanded } =
|
||||||
(Seq (zero_loc, [ Prim(zero_loc, "COMPARE", [], None);
|
Michelson_v1_printer.unparse_expression expanded in
|
||||||
Prim(zero_loc, compare_name, [], None);
|
Assert.equal ~prn unexpanded (Micheline.strip_locations original) ;
|
||||||
Prim (zero_loc, "IF", [ left_branch ; right_branch ], None) ], None)) in
|
ok ()
|
||||||
|
|
||||||
assert_compare_macro "CMPEQ" "EQ";
|
let test_unexpansion_consistency () =
|
||||||
assert_compare_macro "CMPNEQ" "NEQ";
|
assert_unexpansion_consistent (Prim (zero_loc, "PAAAIAIR", [], None)) >>? fun () ->
|
||||||
assert_compare_macro "CMPLT" "LT";
|
assert_unexpansion_consistent
|
||||||
assert_compare_macro "CMPLE" "LE";
|
(Prim (zero_loc, "DIIIP", [ Seq (zero_loc, [ Prim (zero_loc, "DROP", [], None) ], None) ], None)) >>? fun () ->
|
||||||
assert_compare_macro "CMPGT" "GT";
|
assert_unexpansion_consistent (Prim (zero_loc, "SET_CAR", [], None)) >>? fun () ->
|
||||||
assert_compare_macro "CMPGE" "GE";
|
assert_unexpansion_consistent (Prim (zero_loc, "SET_CDR", [], None)) >>? fun () ->
|
||||||
|
assert_unexpansion_consistent (Prim (zero_loc, "DUP", [], None)) >>? fun () ->
|
||||||
|
assert_unexpansion_consistent (Prim (zero_loc, "DUUP", [], None)) >>? fun () ->
|
||||||
|
assert_unexpansion_consistent (Prim (zero_loc, "DUUUP", [], None)) >>? fun () ->
|
||||||
|
assert_unexpansion_consistent (Prim (zero_loc, "DUUUUP", [], None)) >>? fun () ->
|
||||||
|
assert_unexpansion_consistent (Prim (zero_loc, "DUUUUUP", [], None)) >>? fun () ->
|
||||||
|
|
||||||
assert_compare_if_macro "IFCMPEQ" "EQ";
|
assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_EQ", [], None)) >>? fun () ->
|
||||||
assert_compare_if_macro "IFCMPNEQ" "NEQ";
|
assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_NEQ", [], None)) >>? fun () ->
|
||||||
assert_compare_if_macro "IFCMPLT" "LT";
|
assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_LT", [], None)) >>? fun () ->
|
||||||
assert_compare_if_macro "IFCMPLE" "LE";
|
assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_LE", [], None)) >>? fun () ->
|
||||||
assert_compare_if_macro "IFCMPGT" "GT";
|
assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_GT", [], None)) >>? fun () ->
|
||||||
assert_compare_if_macro "IFCMPGE" "GE";
|
assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_GE", [], None)) >>? fun () ->
|
||||||
Assert.equal (Michelson_macros.expand (Prim (zero_loc, "ASSERT_LEFT", [], None)))
|
assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_NONE", [], None)) >>? fun () ->
|
||||||
(Seq (zero_loc, [ Prim (zero_loc, "IF_LEFT",
|
assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_SOME", [], None)) >>? fun () ->
|
||||||
[ Seq (zero_loc, [ ], None) ;
|
assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_LEFT", [], None)) >>? fun () ->
|
||||||
Seq (zero_loc, [ Prim(zero_loc, "FAIL", [], None) ], None) ],
|
assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_RIGHT", [], None)) >>? fun () ->
|
||||||
None) ], None));
|
|
||||||
Assert.equal (Michelson_macros.expand (Prim (zero_loc, "ASSERT_RIGHT", [], None)))
|
|
||||||
(Seq (zero_loc, [ Prim (zero_loc, "IF_LEFT",
|
|
||||||
[ Seq (zero_loc, [ Prim(zero_loc, "FAIL", [], None) ], None) ;
|
|
||||||
Seq (zero_loc, [ ], None) ],
|
|
||||||
None) ], None));
|
|
||||||
Assert.equal (Michelson_macros.expand (Prim (zero_loc, "IF_RIGHT", [ left_branch ; right_branch ], None)))
|
|
||||||
(Seq (zero_loc, [ Prim (zero_loc, "IF_LEFT", [ right_branch ; left_branch ], None) ], None));
|
|
||||||
Assert.equal (Michelson_macros.expand (Prim (zero_loc, "IF_SOME", [ left_branch ; right_branch ], None)))
|
|
||||||
(Seq (zero_loc, [ Prim (zero_loc, "IF_NONE", [ right_branch ; left_branch ], None) ], None));;
|
|
||||||
|
|
||||||
|
assert_unexpansion_consistent (Prim (zero_loc, "IF_RIGHT", [ left_branch ; right_branch], None)) >>? fun () ->
|
||||||
|
assert_unexpansion_consistent (Prim (zero_loc, "IF_SOME", [ left_branch ; right_branch], None))
|
||||||
|
|
||||||
assert_identity Michelson_macros.expand (Prim (zero_loc, "PAIR", [], None));;
|
let test_lexing () =
|
||||||
|
let open Micheline_parser in
|
||||||
|
let assert_tokenize_result source expected =
|
||||||
|
match tokenize source with
|
||||||
|
| tokens, [] ->
|
||||||
|
let tokens =
|
||||||
|
List.map (fun x -> x.token) tokens in
|
||||||
|
Assert.equal tokens expected ;
|
||||||
|
ok ()
|
||||||
|
| _, errors -> Error errors in
|
||||||
|
assert_tokenize_result "int"
|
||||||
|
[ (Ident "int") ] >>? fun () ->
|
||||||
|
assert_tokenize_result "100"
|
||||||
|
[ (Int "100") ] >>? fun () ->
|
||||||
|
assert_tokenize_result "(option int)"
|
||||||
|
[ Open_paren ; Ident "option" ; Ident "int" ; Close_paren ] >>? fun () ->
|
||||||
|
assert_tokenize_result "DIP { ADD }"
|
||||||
|
[ Ident "DIP" ; Open_brace ; Ident "ADD" ; Close_brace ] >>? fun () ->
|
||||||
|
assert_tokenize_result "\"hello\""
|
||||||
|
[ String "hello" ] >>? fun () ->
|
||||||
|
assert_tokenize_result "parameter int;"
|
||||||
|
[ Ident "parameter" ; Ident "int" ; Semi ] >>? fun () ->
|
||||||
|
assert_tokenize_result "PUSH string \"abcd\";"
|
||||||
|
[ Ident "PUSH" ; Ident "string" ; String "abcd" ; Semi ] >>? fun () ->
|
||||||
|
assert_tokenize_result "DROP; SWAP"
|
||||||
|
[ Ident "DROP" ; Semi ; Ident "SWAP" ] >>? fun () ->
|
||||||
|
assert_tokenize_result "string"
|
||||||
|
[ Ident "string" ]
|
||||||
|
|
||||||
let expand_unexpand x =
|
let test_parsing () =
|
||||||
Michelson_macros.unexpand (Michelson_macros.expand x);;
|
let assert_parses source expected =
|
||||||
|
let open Micheline_parser in
|
||||||
|
match tokenize source with
|
||||||
|
| _, (_ :: _ as errors) -> Error errors
|
||||||
|
| tokens, [] ->
|
||||||
|
match Micheline_parser.parse_toplevel tokens with
|
||||||
|
| _, (_ :: _ as errors) -> Error errors
|
||||||
|
| ast, [] ->
|
||||||
|
let ast = List.map Micheline.strip_locations ast in
|
||||||
|
let expected = List.map Micheline.strip_locations expected in
|
||||||
|
Assert.equal (List.length ast) (List.length expected) ;
|
||||||
|
List.iter2 (Assert.equal ~prn) ast expected ;
|
||||||
|
ok () in
|
||||||
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "PAAAIAIR", [], None));
|
assert_parses "PUSH int 100"
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "DIIIP{DROP}", [], None));
|
[ (Prim ((), "PUSH", [ Prim ((), "int", [], None) ;
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "SET_CAR", [], None));
|
Int ((), "100") ], None)) ] >>? fun () ->
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "SET_CDR", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "DUP", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "DUUP", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "DUUUP", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "DUUUUP", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "DUUUUUP", [], None));
|
|
||||||
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_EQ", [], None));
|
assert_parses "DROP" [ (Prim ((), "DROP", [], None)) ] >>? fun () ->
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_NEQ", [], None));
|
assert_parses "DIP{DROP}"
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_LT", [], None));
|
[ Prim ((), "DIP", [ Seq((), [ Prim ((), "DROP", [], None) ], None) ], None) ] >>? fun () ->
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_LE", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_GT", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_GE", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_NONE", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_SOME", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_LEFT", [], None));
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_RIGHT", [], None));
|
|
||||||
|
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "IF_RIGHT", [ left_branch ; right_branch], None));
|
assert_parses "LAMBDA int int {}"
|
||||||
assert_identity expand_unexpand (Prim (zero_loc, "IF_SOME", [ left_branch ; right_branch], None));
|
[ Prim ((), "LAMBDA", [ Prim ((), "int", [], None) ;
|
||||||
|
Prim ((), "int", [], None) ;
|
||||||
|
Seq ((), [ ], None) ], None) ] >>? fun () ->
|
||||||
|
|
||||||
Assert.equal (Michelson_macros.expand (Prim (zero_loc, "PAAIR", [], None)))
|
assert_parses "LAMBDA @name int int {}"
|
||||||
(Seq (zero_loc,
|
[ Prim ((), "LAMBDA", [ Prim ((), "int", [], None) ;
|
||||||
[Prim
|
Prim ((), "int", [], None) ;
|
||||||
(zero_loc,
|
Seq ((), [ ], None) ], Some "@name") ] >>? fun () ->
|
||||||
"DIP",
|
|
||||||
[Seq (zero_loc, [Prim
|
|
||||||
(zero_loc, "PAIR", [], None)],
|
|
||||||
None)],
|
|
||||||
None)],
|
|
||||||
None));;
|
|
||||||
|
|
||||||
Assert.equal (Michelson_macros.expand (Prim (zero_loc, "PAAIAIR", [], None)))
|
assert_parses "NIL @annot string; # comment\n"
|
||||||
(Seq (zero_loc, [Prim
|
[ Prim ((), "NIL", [ Prim ((), "string", [], None) ], Some "@annot") ] >>? fun () ->
|
||||||
(zero_loc,
|
|
||||||
"DIP",
|
|
||||||
[Seq
|
|
||||||
(zero_loc,
|
|
||||||
[Prim
|
|
||||||
(zero_loc,
|
|
||||||
"PAIR", [], None)],
|
|
||||||
None)],
|
|
||||||
None);
|
|
||||||
Prim
|
|
||||||
(zero_loc,
|
|
||||||
"PAIR", [], None)],
|
|
||||||
None));;
|
|
||||||
|
|
||||||
open Michelson_parser;;
|
assert_parses "PUSH (pair bool string) (Pair False \"abc\")"
|
||||||
|
[ Prim ((), "PUSH", [ Prim ((), "pair",
|
||||||
|
[ Prim ((), "bool", [], None) ;
|
||||||
|
Prim ((), "string", [], None) ], None) ;
|
||||||
|
Prim ((), "Pair",
|
||||||
|
[ Prim ((), "False", [], None) ;
|
||||||
|
String ((), "abc")], None) ], None) ] >>? fun () ->
|
||||||
|
assert_parses "PUSH (list nat) (List 1 2 3)"
|
||||||
|
[ Prim ((), "PUSH", [ Prim ((), "list",
|
||||||
|
[ Prim ((), "nat", [], None) ], None) ;
|
||||||
|
Prim ((), "List",
|
||||||
|
[ Int((), "1");
|
||||||
|
Int ((), "2");
|
||||||
|
Int ((), "3")],
|
||||||
|
None) ], None) ] >>? fun () ->
|
||||||
|
assert_parses "PUSH (lambda nat nat) {}"
|
||||||
|
[ Prim ((), "PUSH", [ Prim ((), "lambda",
|
||||||
|
[ Prim ((), "nat", [], None);
|
||||||
|
Prim ((), "nat", [], None)], None) ;
|
||||||
|
Seq((), [], None)],
|
||||||
|
None) ] >>? fun () ->
|
||||||
|
assert_parses "PUSH key \"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx\""
|
||||||
|
[ Prim ((), "PUSH", [ Prim ((), "key", [], None) ;
|
||||||
|
String ((),"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") ],
|
||||||
|
None) ] >>? fun () ->
|
||||||
|
assert_parses "PUSH (map int bool) (Map (Item 100 False))"
|
||||||
|
[ Prim ((), "PUSH", [ Prim ((), "map",
|
||||||
|
[ Prim((), "int", [], None);
|
||||||
|
Prim((), "bool", [], None)], None) ;
|
||||||
|
Prim ((), "Map",
|
||||||
|
[Prim ((), "Item",
|
||||||
|
[Int ((), "100");
|
||||||
|
Prim ((), "False", [], None)], None)], None) ],
|
||||||
|
None) ] >>? fun () ->
|
||||||
|
assert_parses
|
||||||
|
"parameter int; \
|
||||||
|
return int; \
|
||||||
|
storage unit; \
|
||||||
|
code {}"
|
||||||
|
[ Prim ((), "parameter", [ Prim((), "int", [], None) ], None);
|
||||||
|
Prim ((), "return", [ Prim((), "int", [], None) ], None);
|
||||||
|
Prim ((), "storage", [ Prim((), "unit", [], None) ], None);
|
||||||
|
Prim ((), "code", [ Seq((), [], None) ], None)] >>? fun () ->
|
||||||
|
assert_parses
|
||||||
|
"parameter int; \
|
||||||
|
storage unit; \
|
||||||
|
return int; \
|
||||||
|
code {CAR; PUSH int 1; ADD; UNIT; SWAP; PAIR};"
|
||||||
|
[ Prim ((), "parameter", [ Prim((), "int", [], None) ], None);
|
||||||
|
Prim ((), "storage", [ Prim((), "unit", [], None) ], None);
|
||||||
|
Prim ((), "return", [ Prim((), "int", [], None) ], None);
|
||||||
|
Prim ((), "code", [ Seq((), [ Prim ((), "CAR", [], None) ;
|
||||||
|
Prim ((), "PUSH", [ Prim((), "int", [], None) ;
|
||||||
|
Int ((), "1")], None) ;
|
||||||
|
Prim ((), "ADD", [], None) ;
|
||||||
|
Prim ((), "UNIT", [], None) ;
|
||||||
|
Prim ((), "SWAP", [], None) ;
|
||||||
|
Prim ((), "PAIR", [], None)], None) ], None)] >>? fun () ->
|
||||||
|
assert_parses
|
||||||
|
"code {DUP @test; DROP}"
|
||||||
|
[ Prim ((), "code", [Seq ((), [ Prim ((), "DUP", [], Some "@test");
|
||||||
|
Prim ((), "DROP", [], None)], None)], None) ] >>? fun () ->
|
||||||
|
assert_parses
|
||||||
|
"IF {CAR} {CDR}"
|
||||||
|
[ Prim ((), "IF", [ Seq ((), [ Prim ((), "CAR", [], None) ], None);
|
||||||
|
Seq ((), [ Prim ((), "CDR", [], None) ], None) ], None) ] >>? fun () ->
|
||||||
|
assert_parses
|
||||||
|
"IF_NONE {FAIL} {}"
|
||||||
|
[ Prim ((), "IF_NONE", [ Seq ((), [ Prim ((), "FAIL", [], None) ], None);
|
||||||
|
Seq ((), [ ], None) ], None) ]
|
||||||
|
|
||||||
let get_tokens =
|
let tests = [
|
||||||
List.map (fun x -> x.token);;
|
"lexing", (fun _ -> Lwt.return (test_lexing ())) ;
|
||||||
|
"parsing", (fun _ -> Lwt.return (test_parsing ())) ;
|
||||||
|
"expansion", (fun _ -> Lwt.return (test_expansion ())) ;
|
||||||
|
"consistency", (fun _ -> Lwt.return (test_unexpansion_consistency ())) ;
|
||||||
|
]
|
||||||
|
|
||||||
Assert.equal (get_tokens @@ tokenize @@ "int")
|
let () =
|
||||||
[ (Ident "int") ];
|
Test.run "michelson." tests
|
||||||
Assert.equal (get_tokens @@ tokenize @@ "100")
|
|
||||||
[ (Int "100") ];
|
|
||||||
Assert.equal (get_tokens @@ tokenize @@ "(option int)")
|
|
||||||
[ Open_paren ; Ident "option" ; Ident "int" ; Close_paren ];
|
|
||||||
Assert.equal (get_tokens @@ tokenize @@ "DIP { ADD }")
|
|
||||||
[ Ident "DIP" ; Open_brace ; Ident "ADD" ; Close_brace ];
|
|
||||||
Assert.equal (get_tokens @@ tokenize @@ "\"hello\"")
|
|
||||||
[ String "hello" ];
|
|
||||||
Assert.equal (get_tokens @@ tokenize @@ "parameter int;")
|
|
||||||
[ Ident "parameter" ; Ident "int" ; Semi ];
|
|
||||||
Assert.equal (get_tokens @@ tokenize @@ "PUSH string \"abcd\";")
|
|
||||||
[ Ident "PUSH" ; Ident "string" ; String "abcd" ; Semi ];
|
|
||||||
Assert.equal (get_tokens @@ tokenize @@ "DROP; SWAP")
|
|
||||||
[ Ident "DROP" ; Semi ; Ident "SWAP" ];
|
|
||||||
Assert.equal (get_tokens @@ tokenize @@ "string")
|
|
||||||
[ Ident "string" ]
|
|
||||||
|
|
||||||
|
|
||||||
let parse_expr_no_locs str =
|
|
||||||
List.map strip_locations
|
|
||||||
Michelson_parser.(parse_toplevel (tokenize str))
|
|
||||||
|
|
||||||
let assert_parses str parsed =
|
|
||||||
Assert.equal (parse_expr_no_locs str) parsed;;
|
|
||||||
|
|
||||||
assert_parses "PUSH int 100"
|
|
||||||
[ (Prim ((), "PUSH", [ Prim ((), "int", [], None) ;
|
|
||||||
Int ((), "100") ], None)) ];
|
|
||||||
|
|
||||||
assert_parses "DROP" [ (Prim ((), "DROP", [], None)) ];
|
|
||||||
assert_parses "DIP{DROP}"
|
|
||||||
[ Prim ((), "DIP", [ Seq((), [ Prim ((), "DROP", [], None) ], None) ], None) ];
|
|
||||||
|
|
||||||
assert_parses "LAMBDA int int {}"
|
|
||||||
[ Prim ((), "LAMBDA", [ Prim ((), "int", [], None) ;
|
|
||||||
Prim ((), "int", [], None) ;
|
|
||||||
Seq ((), [ ], None) ], None) ];
|
|
||||||
|
|
||||||
assert_parses "LAMBDA @name int int {}"
|
|
||||||
[ Prim ((), "LAMBDA", [ Prim ((), "int", [], None) ;
|
|
||||||
Prim ((), "int", [], None) ;
|
|
||||||
Seq ((), [ ], None) ], Some "@name") ];
|
|
||||||
|
|
||||||
assert_parses "NIL @annot string; # comment\n"
|
|
||||||
[ Prim ((), "NIL", [ Prim ((), "string", [], None) ], Some "@annot") ];
|
|
||||||
|
|
||||||
assert_parses "PUSH (pair bool string) (Pair False \"abc\")"
|
|
||||||
[ Prim ((), "PUSH", [ Prim ((), "pair",
|
|
||||||
[ Prim ((), "bool", [], None) ;
|
|
||||||
Prim ((), "string", [], None) ], None) ;
|
|
||||||
Prim ((), "Pair",
|
|
||||||
[ Prim ((), "False", [], None) ;
|
|
||||||
String ((), "abc")], None) ], None) ];
|
|
||||||
assert_parses "PUSH (list nat) (List 1 2 3)"
|
|
||||||
[ Prim ((), "PUSH", [ Prim ((), "list",
|
|
||||||
[ Prim ((), "nat", [], None) ], None) ;
|
|
||||||
Prim ((), "List",
|
|
||||||
[ Int((), "1");
|
|
||||||
Int ((), "2");
|
|
||||||
Int ((), "3")],
|
|
||||||
None) ], None) ];
|
|
||||||
assert_parses "PUSH (lambda nat nat) {}"
|
|
||||||
[ Prim ((), "PUSH", [ Prim ((), "lambda",
|
|
||||||
[ Prim ((), "nat", [], None);
|
|
||||||
Prim ((), "nat", [], None)], None) ;
|
|
||||||
Seq((), [], None)],
|
|
||||||
None) ];
|
|
||||||
assert_parses "PUSH key \"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx\""
|
|
||||||
[ Prim ((), "PUSH", [ Prim ((), "key", [], None) ;
|
|
||||||
String ((),"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx") ],
|
|
||||||
None) ];
|
|
||||||
assert_parses "PUSH (map int bool) (Map (Item 100 False))"
|
|
||||||
[ Prim ((), "PUSH", [ Prim ((), "map",
|
|
||||||
[ Prim((), "int", [], None);
|
|
||||||
Prim((), "bool", [], None)], None) ;
|
|
||||||
Prim ((), "Map",
|
|
||||||
[Prim ((), "Item",
|
|
||||||
[Int ((), "100");
|
|
||||||
Prim ((), "False", [], None)], None)], None) ],
|
|
||||||
None) ];
|
|
||||||
assert_parses
|
|
||||||
"parameter int; \
|
|
||||||
return int; \
|
|
||||||
storage unit; \
|
|
||||||
code {}"
|
|
||||||
[ Prim ((), "parameter", [ Prim((), "int", [], None) ], None);
|
|
||||||
Prim ((), "return", [ Prim((), "int", [], None) ], None);
|
|
||||||
Prim ((), "storage", [ Prim((), "unit", [], None) ], None);
|
|
||||||
Prim ((), "code", [ Seq((), [], None) ], None)];
|
|
||||||
assert_parses
|
|
||||||
"parameter int; \
|
|
||||||
storage unit; \
|
|
||||||
return int; \
|
|
||||||
code {CAR; PUSH int 1; ADD; UNIT; SWAP; PAIR};"
|
|
||||||
[ Prim ((), "parameter", [ Prim((), "int", [], None) ], None);
|
|
||||||
Prim ((), "storage", [ Prim((), "unit", [], None) ], None);
|
|
||||||
Prim ((), "return", [ Prim((), "int", [], None) ], None);
|
|
||||||
Prim ((), "code", [ Seq((), [ Prim ((), "CAR", [], None) ;
|
|
||||||
Prim ((), "PUSH", [ Prim((), "int", [], None) ;
|
|
||||||
Int ((), "1")], None) ;
|
|
||||||
Prim ((), "ADD", [], None) ;
|
|
||||||
Prim ((), "UNIT", [], None) ;
|
|
||||||
Prim ((), "SWAP", [], None) ;
|
|
||||||
Prim ((), "PAIR", [], None)], None) ], None)];
|
|
||||||
assert_parses
|
|
||||||
"code {DUP @test; DROP}"
|
|
||||||
[ Prim ((), "code", [Seq ((), [ Prim ((), "DUP", [], Some "@test");
|
|
||||||
Prim ((), "DROP", [], None)], None)], None) ];
|
|
||||||
assert_parses
|
|
||||||
"IF {CAR} {CDR}"
|
|
||||||
[ Prim ((), "IF", [ Seq ((), [ Prim ((), "CAR", [], None) ], None);
|
|
||||||
Seq ((), [ Prim ((), "CDR", [], None) ], None) ], None) ];
|
|
||||||
assert_parses
|
|
||||||
"IF_NONE {FAIL} {}"
|
|
||||||
[ Prim ((), "IF_NONE", [ Seq ((), [ Prim ((), "FAIL", [], None) ], None);
|
|
||||||
Seq ((), [ ], None) ], None) ];
|
|
||||||
|
Loading…
Reference in New Issue
Block a user