diff --git a/lib_embedded_client_alpha/michelson_v1_parser.ml b/lib_embedded_client_alpha/michelson_v1_parser.ml index 76336ee75..cc82affa8 100644 --- a/lib_embedded_client_alpha/michelson_v1_parser.ml +++ b/lib_embedded_client_alpha/michelson_v1_parser.ml @@ -91,3 +91,6 @@ let parse_expression ?check source = let tokens, lexing_errors = Micheline_parser.tokenize source in let ast, parsing_errors = Micheline_parser.parse_expression ?check tokens in expand_all source ast (lexing_errors @ parsing_errors) + +let expand_all ~source ~original = + expand_all source original [] diff --git a/lib_embedded_client_alpha/michelson_v1_parser.mli b/lib_embedded_client_alpha/michelson_v1_parser.mli index 1aa5dbacc..900cb501d 100644 --- a/lib_embedded_client_alpha/michelson_v1_parser.mli +++ b/lib_embedded_client_alpha/michelson_v1_parser.mli @@ -29,3 +29,4 @@ type parsed = val parse_toplevel : ?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 diff --git a/test/proto_alpha/jbuild b/test/proto_alpha/jbuild index 831bb0587..e145c64e9 100644 --- a/test/proto_alpha/jbuild +++ b/test/proto_alpha/jbuild @@ -2,7 +2,7 @@ (executables ((names (test_endorsement - ;; test_michelson_parser + test_michelson_parser test_origination test_transaction test_vote)) @@ -23,7 +23,7 @@ (alias ((name buildtest) (deps (test_endorsement.exe - ;; test_michelson_parser.exe + test_michelson_parser.exe test_origination.exe test_transaction.exe test_vote.exe)))) @@ -34,6 +34,10 @@ (locks (/tcp-port/18100)) (action (chdir ${ROOT} (run ${exe:test_endorsement.exe} ${bin:tezos-node}))))) +(alias + ((name runtest_michelson_parser) + (action (run ${exe:test_michelson_parser.exe})))) + (alias ((name runtest_origination) (deps (sandbox.json)) @@ -55,6 +59,7 @@ (alias ((name runtest) (deps ((alias runtest_endorsement) + (alias runtest_michelson_parser) (alias runtest_origination) (alias runtest_transaction) (alias runtest_vote))))) diff --git a/test/proto_alpha/test_michelson_parser.ml b/test/proto_alpha/test_michelson_parser.ml index a07555a89..292b6b5c1 100644 --- a/test/proto_alpha/test_michelson_parser.ml +++ b/test/proto_alpha/test_michelson_parser.ml @@ -7,308 +7,342 @@ (* *) (**************************************************************************) -open Tezos_context.Script - module Helpers = Proto_alpha_helpers module Assert = Helpers.Assert -open Script_located_ir +open Tezos_micheline +open Micheline -let zero_loc = { start=point_zero; - stop=point_zero};; +let zero_loc = Micheline_parser.location_zero -let assert_identity f x = - Assert.equal - (f x) - x;; +let prn expr = + expr |> + Micheline_printer.printable (fun s -> s) |> + Format.asprintf "%a" Micheline_printer.print_expr -(* Test expansion *) -Assert.equal (Michelson_macros.expand (Prim (zero_loc, "CAAR", [], None))) - (Seq (zero_loc, - [(Prim (zero_loc, "CAR", [], None)); - (Prim (zero_loc, "CAR", [], None)) ], - None));; +let assert_expands original expanded = + let { Michelson_v1_parser.expanded = expansion }, errors = + let source = prn (Micheline.strip_locations original) in + Michelson_v1_parser.expand_all ~source ~original in + let expanded = Micheline.strip_locations expanded in + 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"))) - (Seq (zero_loc, - [(Prim (zero_loc, "CAR", [], None)); - (Prim (zero_loc, "CAR", [], Some "annot")) ], - None));; +let left_branch = Seq(zero_loc, [ Prim(zero_loc, "SWAP", [], None) ], None) +let right_branch = Seq(zero_loc, [ ], None) -assert_identity Michelson_macros.expand (Prim (zero_loc, "CAR", [], Some "annot"));; - - -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))) +let test_expansion () = + assert_expands (Prim (zero_loc, "CAAR", [], None)) (Seq (zero_loc, - [ Prim (zero_loc, "COMPARE", [], None) ; - Prim (zero_loc, compare_name, [], None) ], None));; + [(Prim (zero_loc, "CAR", [], 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 right_branch = Seq(zero_loc, [ ], None);; -let assert_compare_if_macro prim_name compare_name = - Assert.equal - (Michelson_macros.expand (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 +let assert_unexpansion_consistent original = + let { Michelson_v1_parser.expanded }, errors = + let source = prn (Micheline.strip_locations original) in + Michelson_v1_parser.expand_all ~source ~original in + match errors with + | _ :: _ -> Error errors + | [] -> + let { Michelson_v1_parser.unexpanded } = + Michelson_v1_printer.unparse_expression expanded in + Assert.equal ~prn unexpanded (Micheline.strip_locations original) ; + ok () -assert_compare_macro "CMPEQ" "EQ"; -assert_compare_macro "CMPNEQ" "NEQ"; -assert_compare_macro "CMPLT" "LT"; -assert_compare_macro "CMPLE" "LE"; -assert_compare_macro "CMPGT" "GT"; -assert_compare_macro "CMPGE" "GE"; +let test_unexpansion_consistency () = + assert_unexpansion_consistent (Prim (zero_loc, "PAAAIAIR", [], None)) >>? fun () -> + assert_unexpansion_consistent + (Prim (zero_loc, "DIIIP", [ Seq (zero_loc, [ Prim (zero_loc, "DROP", [], None) ], None) ], None)) >>? fun () -> + assert_unexpansion_consistent (Prim (zero_loc, "SET_CAR", [], None)) >>? fun () -> + 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_compare_if_macro "IFCMPNEQ" "NEQ"; -assert_compare_if_macro "IFCMPLT" "LT"; -assert_compare_if_macro "IFCMPLE" "LE"; -assert_compare_if_macro "IFCMPGT" "GT"; -assert_compare_if_macro "IFCMPGE" "GE"; -Assert.equal (Michelson_macros.expand (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)); -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, "ASSERT_EQ", [], None)) >>? fun () -> + assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_NEQ", [], None)) >>? fun () -> + assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_LT", [], None)) >>? fun () -> + assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_LE", [], None)) >>? fun () -> + assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_GT", [], None)) >>? fun () -> + assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_GE", [], None)) >>? fun () -> + assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_NONE", [], None)) >>? fun () -> + assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_SOME", [], None)) >>? fun () -> + assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_LEFT", [], None)) >>? fun () -> + assert_unexpansion_consistent (Prim (zero_loc, "ASSERT_RIGHT", [], None)) >>? fun () -> + 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 = - Michelson_macros.unexpand (Michelson_macros.expand x);; +let test_parsing () = + 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_identity expand_unexpand (Prim (zero_loc, "DIIIP{DROP}", [], None)); -assert_identity expand_unexpand (Prim (zero_loc, "SET_CAR", [], None)); -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_parses "PUSH int 100" + [ (Prim ((), "PUSH", [ Prim ((), "int", [], None) ; + Int ((), "100") ], None)) ] >>? fun () -> -assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_EQ", [], None)); -assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_NEQ", [], None)); -assert_identity expand_unexpand (Prim (zero_loc, "ASSERT_LT", [], None)); -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_parses "DROP" [ (Prim ((), "DROP", [], None)) ] >>? fun () -> + assert_parses "DIP{DROP}" + [ Prim ((), "DIP", [ Seq((), [ Prim ((), "DROP", [], None) ], None) ], None) ] >>? fun () -> -assert_identity expand_unexpand (Prim (zero_loc, "IF_RIGHT", [ left_branch ; right_branch], None)); -assert_identity expand_unexpand (Prim (zero_loc, "IF_SOME", [ left_branch ; right_branch], None)); + assert_parses "LAMBDA int int {}" + [ Prim ((), "LAMBDA", [ Prim ((), "int", [], None) ; + Prim ((), "int", [], None) ; + Seq ((), [ ], None) ], None) ] >>? fun () -> -Assert.equal (Michelson_macros.expand (Prim (zero_loc, "PAAIR", [], None))) - (Seq (zero_loc, - [Prim - (zero_loc, - "DIP", - [Seq (zero_loc, [Prim - (zero_loc, "PAIR", [], None)], - None)], - None)], - None));; + assert_parses "LAMBDA @name int int {}" + [ Prim ((), "LAMBDA", [ Prim ((), "int", [], None) ; + Prim ((), "int", [], None) ; + Seq ((), [ ], None) ], Some "@name") ] >>? fun () -> -Assert.equal (Michelson_macros.expand (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));; + assert_parses "NIL @annot string; # comment\n" + [ Prim ((), "NIL", [ Prim ((), "string", [], None) ], Some "@annot") ] >>? fun () -> -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 = - List.map (fun x -> x.token);; +let tests = [ + "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") - [ (Ident "int") ]; -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) ]; +let () = + Test.run "michelson." tests