diff --git a/src/bin/expect_tests/lexer_tests.ml b/src/bin/expect_tests/lexer_tests.ml index bde7e658c..20d26ab11 100644 --- a/src/bin/expect_tests/lexer_tests.ml +++ b/src/bin/expect_tests/lexer_tests.ml @@ -2,7 +2,7 @@ open Cli_expect let%expect_test _ = run_ligo_bad [ "compile-contract" ; "../../test/lexer/broken_string.ligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "broken_string.ligo", line 1, characters 18-19: The string starting here is interrupted by a line break. Hint: Remove the break, close the string before or insert a backslash. @@ -19,7 +19,7 @@ ligo: : Lexical error in file "broken_string.ligo", line 1, characters 18-19: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/broken_string.mligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "broken_string.mligo", line 1, characters 8-9: The string starting here is interrupted by a line break. Hint: Remove the break, close the string before or insert a backslash. @@ -36,7 +36,7 @@ ligo: : Lexical error in file "broken_string.mligo", line 1, characters 8-9: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/broken_string.religo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "broken_string.religo", line 1, characters 8-9: The string starting here is interrupted by a line break. Hint: Remove the break, close the string before or insert a backslash. @@ -53,8 +53,8 @@ ligo: : Lexical error in file "broken_string.religo", line 1, characters 8-9: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/negative_byte_sequence.ligo" ; "main" ] ; - [%expect {| -ligo: : Lexical error in file "negative_byte_sequence.ligo", line 1, characters 18-23: + [%expect {| +ligo: : Lexical error in file "negative_byte_sequence.ligo", line 1, characters 18-31: Negative byte sequence. Hint: Remove the leading minus sign. {} @@ -70,8 +70,8 @@ ligo: : Lexical error in file "negative_byte_sequence.ligo", line 1, characters |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/negative_byte_sequence.mligo" ; "main" ] ; - [%expect {| -ligo: : Lexical error in file "negative_byte_sequence.mligo", line 1, characters 8-13: + [%expect {| +ligo: : Lexical error in file "negative_byte_sequence.mligo", line 1, characters 8-21: Negative byte sequence. Hint: Remove the leading minus sign. {} @@ -87,8 +87,8 @@ ligo: : Lexical error in file "negative_byte_sequence.mligo", line 1, characters |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/negative_byte_sequence.religo" ; "main" ] ; - [%expect {| -ligo: : Lexical error in file "negative_byte_sequence.religo", line 1, characters 8-13: + [%expect {| +ligo: : Lexical error in file "negative_byte_sequence.religo", line 1, characters 8-21: Negative byte sequence. Hint: Remove the leading minus sign. {} @@ -103,8 +103,9 @@ ligo: : Lexical error in file "negative_byte_sequence.religo", line 1, character * Check the changelog by running 'ligo changelog' |} ]; +(* run_ligo_bad [ "compile-contract" ; "../../test/lexer/reserved_name.ligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "reserved_name.ligo", line 1, characters 4-13: Reserved name: "arguments". Hint: Change the name. @@ -119,9 +120,10 @@ ligo: : Lexical error in file "reserved_name.ligo", line 1, characters 4-13: * Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new * Check the changelog by running 'ligo changelog' |} ]; + *) run_ligo_bad [ "compile-contract" ; "../../test/lexer/reserved_name.religo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "reserved_name.religo", line 1, characters 4-7: Reserved name: "end". Hint: Change the name. @@ -138,7 +140,7 @@ ligo: : Lexical error in file "reserved_name.religo", line 1, characters 4-7: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/reserved_name.mligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "reserved_name.mligo", line 1, characters 4-10: Reserved name: "object". Hint: Change the name. @@ -155,7 +157,7 @@ ligo: : Lexical error in file "reserved_name.mligo", line 1, characters 4-10: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/unexpected_character.ligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "unexpected_character.ligo", line 1, characters 18-19: Unexpected character '\239'. {} @@ -171,7 +173,7 @@ ligo: : Lexical error in file "unexpected_character.ligo", line 1, characters 18 |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/unexpected_character.mligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "unexpected_character.mligo", line 1, characters 8-9: Unexpected character '\239'. {} @@ -187,7 +189,7 @@ ligo: : Lexical error in file "unexpected_character.mligo", line 1, characters 8 |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/unexpected_character.religo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "unexpected_character.religo", line 1, characters 8-9: Unexpected character '\239'. {} @@ -203,11 +205,10 @@ ligo: : Lexical error in file "unexpected_character.religo", line 1, characters |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/unterminated_comment.mligo" ; "main" ] ; - [%expect {| -ligo: : Lexical error in file "unterminated_comment.mligo", line 1, characters 0-2: + [%expect {| +ligo: : Preprocessing error in file "../../test/lexer/unterminated_comment.mligo", line 1, characters 0-2: Unterminated comment. - Hint: Close with "*)". - {} + Hint: Close with "*)". {} If you're not sure how to fix this error, you can @@ -220,7 +221,7 @@ ligo: : Lexical error in file "unterminated_comment.mligo", line 1, characters 0 |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/invalid_symbol.ligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "invalid_symbol.ligo", line 1, characters 17-20: Invalid symbol. Hint: Check the LIGO syntax you use. @@ -237,7 +238,7 @@ ligo: : Lexical error in file "invalid_symbol.ligo", line 1, characters 17-20: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/invalid_symbol.mligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "invalid_symbol.mligo", line 1, characters 10-13: Invalid symbol. Hint: Check the LIGO syntax you use. @@ -254,7 +255,7 @@ ligo: : Lexical error in file "invalid_symbol.mligo", line 1, characters 10-13: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/invalid_symbol.religo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "invalid_symbol.religo", line 1, characters 10-11: Invalid symbol. Hint: Check the LIGO syntax you use. @@ -271,7 +272,7 @@ ligo: : Lexical error in file "invalid_symbol.religo", line 1, characters 10-11: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/missing_break.ligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "missing_break.ligo", line 1, characters 18-18: Missing break. Hint: Insert some space. @@ -288,7 +289,7 @@ ligo: : Lexical error in file "missing_break.ligo", line 1, characters 18-18: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/missing_break.mligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "missing_break.mligo", line 1, characters 11-11: Missing break. Hint: Insert some space. @@ -305,7 +306,7 @@ ligo: : Lexical error in file "missing_break.mligo", line 1, characters 11-11: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/missing_break.religo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "missing_break.religo", line 1, characters 11-11: Missing break. Hint: Insert some space. @@ -322,7 +323,7 @@ ligo: : Lexical error in file "missing_break.religo", line 1, characters 11-11: |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/invalid_character_in_string.ligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "invalid_character_in_string.ligo", line 1, characters 19-20: Invalid character in string. Hint: Remove or replace the character. @@ -339,7 +340,7 @@ ligo: : Lexical error in file "invalid_character_in_string.ligo", line 1, charac |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/invalid_character_in_string.mligo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "invalid_character_in_string.mligo", line 1, characters 9-10: Invalid character in string. Hint: Remove or replace the character. @@ -356,7 +357,7 @@ ligo: : Lexical error in file "invalid_character_in_string.mligo", line 1, chara |} ]; run_ligo_bad [ "compile-contract" ; "../../test/lexer/invalid_character_in_string.religo" ; "main" ] ; - [%expect {| + [%expect {| ligo: : Lexical error in file "invalid_character_in_string.religo", line 1, characters 9-10: Invalid character in string. Hint: Remove or replace the character. @@ -370,4 +371,4 @@ ligo: : Lexical error in file "invalid_character_in_string.religo", line 1, char * Ask a question on our Discord: https://discord.gg/9rhYaEt * Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new * Check the changelog by running 'ligo changelog' - |} ] \ No newline at end of file + |} ] diff --git a/src/passes/1-parser/cameligo.ml b/src/passes/1-parser/cameligo.ml index 3ae2063c1..79093af97 100644 --- a/src/passes/1-parser/cameligo.ml +++ b/src/passes/1-parser/cameligo.ml @@ -8,15 +8,14 @@ module SSet = Set.Make (String) (* Mock IOs TODO: Fill them with CLI options *) -type language = [`PascaLIGO | `CameLIGO | `ReasonLIGO] - module SubIO = struct type options = < libs : string list; verbose : SSet.t; offsets : bool; - lang : language; + block : EvalOpt.block_comment option; + line : EvalOpt.line_comment option; ext : string; (* ".mligo" *) mode : [`Byte | `Point]; cmd : EvalOpt.command; @@ -24,22 +23,25 @@ module SubIO = > let options : options = - object - method libs = [] - method verbose = SSet.empty - method offsets = true - method lang = `CameLIGO - method ext = ".mligo" - method mode = `Point - method cmd = EvalOpt.Quiet - method mono = false - end + let block = EvalOpt.mk_block ~opening:"(*" ~closing:"*)" + in object + method libs = [] + method verbose = SSet.empty + method offsets = true + method block = Some block + method line = Some "//" + method ext = ".mligo" + method mode = `Point + method cmd = EvalOpt.Quiet + method mono = false + end let make = EvalOpt.make ~libs:options#libs ~verbose:options#verbose ~offsets:options#offsets - ~lang:options#lang + ?block:options#block + ?line:options#line ~ext:options#ext ~mode:options#mode ~cmd:options#cmd diff --git a/src/passes/1-parser/cameligo/.links b/src/passes/1-parser/cameligo/.links index 702a10aca..fc8466c8e 100644 --- a/src/passes/1-parser/cameligo/.links +++ b/src/passes/1-parser/cameligo/.links @@ -2,6 +2,7 @@ $HOME/git/OCaml-build/Makefile ../shared/Lexer.mli ../shared/Lexer.mll +../shared/LexerLib.ml ../shared/EvalOpt.ml ../shared/EvalOpt.mli ../shared/FQueue.ml diff --git a/src/passes/1-parser/cameligo/LexToken.mli b/src/passes/1-parser/cameligo/LexToken.mli index 26cd6416a..4af326823 100644 --- a/src/passes/1-parser/cameligo/LexToken.mli +++ b/src/passes/1-parser/cameligo/LexToken.mli @@ -156,11 +156,22 @@ val eof : Region.t -> token (* Predicates *) -val is_string : token -> bool -val is_bytes : token -> bool -val is_int : token -> bool -val is_ident : token -> bool -val is_kwd : token -> bool -val is_constr : token -> bool -val is_sym : token -> bool val is_eof : token -> bool + +(* Style *) + +type error + +val error_to_string : error -> string + +exception Error of error Region.reg + +val format_error : + ?offsets:bool -> [`Byte | `Point] -> + error Region.reg -> file:bool -> string Region.reg + +val check_right_context : + token -> + (Lexing.lexbuf -> (Markup.t list * token) option) -> + Lexing.lexbuf -> + unit diff --git a/src/passes/1-parser/cameligo/LexToken.mll b/src/passes/1-parser/cameligo/LexToken.mll index a9dc9cfe1..a87150cf7 100644 --- a/src/passes/1-parser/cameligo/LexToken.mll +++ b/src/passes/1-parser/cameligo/LexToken.mll @@ -102,138 +102,167 @@ type t = | EOF of Region.t (* End of file *) + +(* Projections *) + type token = t let proj_token = function - ARROW region -> region, "ARROW" -| CONS region -> region, "CONS" -| CAT region -> region, "CAT" -| MINUS region -> region, "MINUS" -| PLUS region -> region, "PLUS" -| SLASH region -> region, "SLASH" -| TIMES region -> region, "TIMES" -| LPAR region -> region, "LPAR" -| RPAR region -> region, "RPAR" -| LBRACKET region -> region, "LBRACKET" -| RBRACKET region -> region, "RBRACKET" -| LBRACE region -> region, "LBRACE" -| RBRACE region -> region, "RBRACE" -| COMMA region -> region, "COMMA" -| SEMI region -> region, "SEMI" -| VBAR region -> region, "VBAR" -| COLON region -> region, "COLON" -| DOT region -> region, "DOT" -| WILD region -> region, "WILD" -| EQ region -> region, "EQ" -| NE region -> region, "NE" -| LT region -> region, "LT" -| GT region -> region, "GT" -| LE region -> region, "LE" -| GE region -> region, "GE" -| BOOL_OR region -> region, "BOOL_OR" -| BOOL_AND region -> region, "BOOL_AND" -| Ident Region.{region; value} -> - region, sprintf "Ident %s" value -| Constr Region.{region; value} -> - region, sprintf "Constr %s" value + (* Literals *) + + String Region.{region; value} -> + region, sprintf "Str %s" value +| Bytes Region.{region; value = s,b} -> + region, + sprintf "Bytes (\"%s\", \"0x%s\")" s (Hex.show b) | Int Region.{region; value = s,n} -> region, sprintf "Int (\"%s\", %s)" s (Z.to_string n) | Nat Region.{region; value = s,n} -> region, sprintf "Nat (\"%s\", %s)" s (Z.to_string n) | Mutez Region.{region; value = s,n} -> region, sprintf "Mutez (\"%s\", %s)" s (Z.to_string n) -| String Region.{region; value} -> - region, sprintf "Str %s" value -| Bytes Region.{region; value = s,b} -> - region, - sprintf "Bytes (\"%s\", \"0x%s\")" - s (Hex.show b) +| Ident Region.{region; value} -> + region, sprintf "Ident %s" value +| Constr Region.{region; value} -> + region, sprintf "Constr %s" value | Attr Region.{region; value} -> region, sprintf "Attr \"%s\"" value + + (* Symbols *) + +| ARROW region -> region, "ARROW" +| CONS region -> region, "CONS" +| CAT region -> region, "CAT" +| MINUS region -> region, "MINUS" +| PLUS region -> region, "PLUS" +| SLASH region -> region, "SLASH" +| TIMES region -> region, "TIMES" +| LPAR region -> region, "LPAR" +| RPAR region -> region, "RPAR" +| LBRACKET region -> region, "LBRACKET" +| RBRACKET region -> region, "RBRACKET" +| LBRACE region -> region, "LBRACE" +| RBRACE region -> region, "RBRACE" +| COMMA region -> region, "COMMA" +| SEMI region -> region, "SEMI" +| VBAR region -> region, "VBAR" +| COLON region -> region, "COLON" +| DOT region -> region, "DOT" +| WILD region -> region, "WILD" +| EQ region -> region, "EQ" +| NE region -> region, "NE" +| LT region -> region, "LT" +| GT region -> region, "GT" +| LE region -> region, "LE" +| GE region -> region, "GE" +| BOOL_OR region -> region, "BOOL_OR" +| BOOL_AND region -> region, "BOOL_AND" + + (* Keywords *) + | Begin region -> region, "Begin" -| Else region -> region, "Else" -| End region -> region, "End" +| Else region -> region, "Else" +| End region -> region, "End" | False region -> region, "False" -| Fun region -> region, "Fun" -| Rec region -> region, "Rec" -| If region -> region, "If" -| In region -> region, "In" -| Let region -> region, "Let" +| Fun region -> region, "Fun" +| Rec region -> region, "Rec" +| If region -> region, "If" +| In region -> region, "In" +| Let region -> region, "Let" | Match region -> region, "Match" -| Mod region -> region, "Mod" -| Not region -> region, "Not" -| Of region -> region, "Of" -| Or region -> region, "Or" -| Then region -> region, "Then" -| True region -> region, "True" -| Type region -> region, "Type" -| With region -> region, "With" -| C_None region -> region, "C_None" -| C_Some region -> region, "C_Some" +| Mod region -> region, "Mod" +| Not region -> region, "Not" +| Of region -> region, "Of" +| Or region -> region, "Or" +| Then region -> region, "Then" +| True region -> region, "True" +| Type region -> region, "Type" +| With region -> region, "With" + + (* Data *) + +| C_None region -> region, "C_None" +| C_Some region -> region, "C_Some" + + (* Virtual tokens *) + | EOF region -> region, "EOF" -let to_lexeme = function - ARROW _ -> "->" -| CONS _ -> "::" -| CAT _ -> "^" -| MINUS _ -> "-" -| PLUS _ -> "+" -| SLASH _ -> "/" -| TIMES _ -> "*" -| LPAR _ -> "(" -| RPAR _ -> ")" -| LBRACKET _ -> "[" -| RBRACKET _ -> "]" -| LBRACE _ -> "{" -| RBRACE _ -> "}" -| COMMA _ -> "," -| SEMI _ -> ";" -| VBAR _ -> "|" -| COLON _ -> ":" -| DOT _ -> "." -| WILD _ -> "_" -| EQ _ -> "=" -| NE _ -> "<>" -| LT _ -> "<" -| GT _ -> ">" -| LE _ -> "<=" -| GE _ -> ">=" -| BOOL_OR _ -> "||" -| BOOL_AND _ -> "&&" -| Ident id -> id.Region.value -| Constr id -> id.Region.value +let to_lexeme = function + (* Literals *) + + String s -> String.escaped s.Region.value +| Bytes b -> fst b.Region.value | Int i | Nat i -| Mutez i -> fst i.Region.value -| String s -> String.escaped s.Region.value -| Bytes b -> fst b.Region.value -| Attr a -> a.Region.value +| Mutez i -> fst i.Region.value +| Ident id -> id.Region.value +| Constr id -> id.Region.value +| Attr a -> a.Region.value + + (* Symbols *) + +| ARROW _ -> "->" +| CONS _ -> "::" +| CAT _ -> "^" +| MINUS _ -> "-" +| PLUS _ -> "+" +| SLASH _ -> "/" +| TIMES _ -> "*" +| LPAR _ -> "(" +| RPAR _ -> ")" +| LBRACKET _ -> "[" +| RBRACKET _ -> "]" +| LBRACE _ -> "{" +| RBRACE _ -> "}" +| COMMA _ -> "," +| SEMI _ -> ";" +| VBAR _ -> "|" +| COLON _ -> ":" +| DOT _ -> "." +| WILD _ -> "_" +| EQ _ -> "=" +| NE _ -> "<>" +| LT _ -> "<" +| GT _ -> ">" +| LE _ -> "<=" +| GE _ -> ">=" +| BOOL_OR _ -> "||" +| BOOL_AND _ -> "&&" + + (* Keywords *) | Begin _ -> "begin" -| Else _ -> "else" -| End _ -> "end" +| Else _ -> "else" +| End _ -> "end" | False _ -> "false" -| Fun _ -> "fun" -| Rec _ -> "rec" -| If _ -> "if" -| In _ -> "in" -| Let _ -> "let" +| Fun _ -> "fun" +| Rec _ -> "rec" +| If _ -> "if" +| In _ -> "in" +| Let _ -> "let" | Match _ -> "match" -| Mod _ -> "mod" -| Not _ -> "not" -| Of _ -> "of" -| Or _ -> "or" -| True _ -> "true" -| Type _ -> "type" -| Then _ -> "then" -| With _ -> "with" +| Mod _ -> "mod" +| Not _ -> "not" +| Of _ -> "of" +| Or _ -> "or" +| True _ -> "true" +| Type _ -> "type" +| Then _ -> "then" +| With _ -> "with" + +(* Data constructors *) | C_None _ -> "None" | C_Some _ -> "Some" +(* Virtual tokens *) + | EOF _ -> "" +(* CONVERSIONS *) + let to_string token ?(offsets=true) mode = let region, val_str = proj_token token in let reg_str = region#compact ~offsets mode @@ -241,10 +270,6 @@ let to_string token ?(offsets=true) mode = let to_region token = proj_token token |> fst -(* Injections *) - -type int_err = Non_canonical_zero - (* LEXIS *) let keywords = [ @@ -385,6 +410,8 @@ let mk_bytes lexeme region = let value = lexeme, `Hex norm in Bytes Region.{region; value} +type int_err = Non_canonical_zero + let mk_int lexeme region = let z = Str.(global_replace (regexp "_") "" lexeme) |> Z.of_string @@ -398,23 +425,21 @@ type nat_err = let mk_nat lexeme region = match (String.index_opt lexeme 'n') with - | None -> Error Invalid_natural - | Some _ -> ( - let z = - Str.(global_replace (regexp "_") "" lexeme) |> - Str.(global_replace (regexp "n") "") |> - Z.of_string in - if Z.equal z Z.zero && lexeme <> "0n" - then Error Non_canonical_zero_nat - else Ok (Nat Region.{region; value = lexeme,z}) - ) + None -> Error Invalid_natural + | Some _ -> let z = + Str.(global_replace (regexp "_") "" lexeme) |> + Str.(global_replace (regexp "n") "") |> + Z.of_string in + if Z.equal z Z.zero && lexeme <> "0n" + then Error Non_canonical_zero_nat + else Ok (Nat Region.{region; value = lexeme,z}) let mk_mutez lexeme region = let z = Str.(global_replace (regexp "_") "" lexeme) |> Str.(global_replace (regexp "mutez") "") |> Z.of_string in - if Z.equal z Z.zero && lexeme <> "0mutez" + if Z.equal z Z.zero && lexeme <> "0mutez" then Error Non_canonical_zero else Ok (Mutez Region.{region; value = lexeme, z}) @@ -422,8 +447,6 @@ let eof region = EOF region type sym_err = Invalid_symbol -type attr_err = Invalid_attribute - let mk_sym lexeme region = match lexeme with (* Lexemes in common with all concrete syntaxes *) @@ -473,88 +496,80 @@ let mk_constr lexeme region = (* Attributes *) +type attr_err = Invalid_attribute + let mk_attr header lexeme region = - if header = "[@" then - Error Invalid_attribute + if header = "[@" then Error Invalid_attribute else Ok (Attr Region.{value=lexeme; region}) (* Predicates *) -let is_string = function - String _ -> true -| _ -> false +let is_string = function String _ -> true | _ -> false +let is_bytes = function Bytes _ -> true | _ -> false +let is_int = function Int _ -> true | _ -> false +let is_ident = function Ident _ -> true | _ -> false +let is_eof = function EOF _ -> true | _ -> false +let is_minus = function MINUS _ -> true | _ -> false -let is_bytes = function - Bytes _ -> true -| _ -> false +(* Errors *) -let is_int = function - Int _ -> true -| _ -> false +type error = + Odd_lengthed_bytes +| Missing_break +| Negative_byte_sequence -let is_ident = function - Ident _ -> true -| _ -> false +let error_to_string = function + Odd_lengthed_bytes -> + "The length of the byte sequence is an odd number.\n\ + Hint: Add or remove a digit." +| Missing_break -> + "Missing break.\n\ + Hint: Insert some space." +| Negative_byte_sequence -> + "Negative byte sequence.\n\ + Hint: Remove the leading minus sign." -let is_kwd = function - | Begin _ - | Else _ - | End _ - | False _ - | Fun _ - | Rec _ - | If _ - | In _ - | Let _ - | Match _ - | Mod _ - | Not _ - | Of _ - | Or _ - | Then _ - | True _ - | Type _ - | With _ -> true - | _ -> false +exception Error of error Region.reg -let is_constr = function -| Constr _ -| Ident _ -| False _ -| True _ -> true -| _ -> false +let format_error ?(offsets=true) mode Region.{region; value} ~file = + let msg = error_to_string value + and reg = region#to_string ~file ~offsets mode in + let value = sprintf "Lexical error %s:\n%s\n" reg msg + in Region.{value; region} -let is_sym = function -| ARROW _ -| CONS _ -| CAT _ -| MINUS _ -| PLUS _ -| SLASH _ -| TIMES _ -| LPAR _ -| RPAR _ -| LBRACKET _ -| RBRACKET _ -| LBRACE _ -| RBRACE _ -| COMMA _ -| SEMI _ -| VBAR _ -| COLON _ -| DOT _ -| WILD _ -| EQ _ -| NE _ -| LT _ -| GT _ -| LE _ -| GE _ -| BOOL_OR _ -| BOOL_AND _ -> true -| _ -> false +let fail region value = raise (Error Region.{region; value}) -let is_eof = function EOF _ -> true | _ -> false +let check_right_context token next_token buffer : unit = + let pos = (to_region token)#stop in + let region = Region.make ~start:pos ~stop:pos in + match next_token buffer with + None -> () + | Some (markup, next) -> + if is_minus token && is_bytes next + then let region = + Region.cover (to_region token) (to_region next) + in fail region Negative_byte_sequence + else + match markup with + [] -> + if is_int token + then if is_string next || is_ident next + then fail region Missing_break + else () + else + if is_string token + then if is_int next || is_bytes next || is_ident next + then fail region Missing_break + else () + else + if is_bytes token + then if is_string next || is_ident next + then fail region Missing_break + else if is_int next + then fail region Odd_lengthed_bytes + else () + else () + | _::_ -> () (* END TRAILER *) } diff --git a/src/passes/1-parser/cameligo/LexerMain.ml b/src/passes/1-parser/cameligo/LexerMain.ml index 2a281efd5..498098035 100644 --- a/src/passes/1-parser/cameligo/LexerMain.ml +++ b/src/passes/1-parser/cameligo/LexerMain.ml @@ -4,7 +4,10 @@ module Region = Simple_utils.Region module IO = struct - let options = EvalOpt.(read ~lang:`CameLIGO ~ext:".mligo") + let options = + let open EvalOpt in + let block = mk_block ~opening:"(*" ~closing:"*)" + in read ~block ~line:"//" ".mligo" end module M = LexerUnit.Make (IO) (Lexer.Make (LexToken)) @@ -12,4 +15,4 @@ module M = LexerUnit.Make (IO) (Lexer.Make (LexToken)) let () = match M.trace () with Stdlib.Ok () -> () - | Error Region.{value; _} -> Utils.highlight value + | Error Region.{value; _} -> Printf.eprintf "\027[31m%s\027[0m%!" value diff --git a/src/passes/1-parser/cameligo/ParserMain.ml b/src/passes/1-parser/cameligo/ParserMain.ml index bc47d9199..a3d13f3cc 100644 --- a/src/passes/1-parser/cameligo/ParserMain.ml +++ b/src/passes/1-parser/cameligo/ParserMain.ml @@ -5,7 +5,10 @@ module SSet = Set.Make (String) module IO = struct - let options = EvalOpt.(read ~lang:`CameLIGO ~ext:".mligo") + let options = + let open EvalOpt in + let block = mk_block ~opening:"(*" ~closing:"*)" + in read ~block ~line:"//" ".mligo" end module SubIO = @@ -14,7 +17,8 @@ module SubIO = libs : string list; verbose : SSet.t; offsets : bool; - lang : EvalOpt.language; + block : EvalOpt.block_comment option; + line : EvalOpt.line_comment option; ext : string; mode : [`Byte | `Point]; cmd : EvalOpt.command; @@ -26,7 +30,8 @@ module SubIO = method libs = IO.options#libs method verbose = IO.options#verbose method offsets = IO.options#offsets - method lang = IO.options#lang + method block = IO.options#block + method line = IO.options#line method ext = IO.options#ext method mode = IO.options#mode method cmd = IO.options#cmd @@ -37,7 +42,8 @@ module SubIO = EvalOpt.make ~libs:options#libs ~verbose:options#verbose ~offsets:options#offsets - ~lang:options#lang + ?block:options#block + ?line:options#line ~ext:options#ext ~mode:options#mode ~cmd:options#cmd diff --git a/src/passes/1-parser/pascaligo.ml b/src/passes/1-parser/pascaligo.ml index 6e4759fe8..02b8f462e 100644 --- a/src/passes/1-parser/pascaligo.ml +++ b/src/passes/1-parser/pascaligo.ml @@ -8,15 +8,14 @@ module SSet = Set.Make (String) (* Mock IOs TODO: Fill them with CLI options *) -type language = [`PascaLIGO | `CameLIGO | `ReasonLIGO] - module SubIO = struct type options = < libs : string list; verbose : SSet.t; offsets : bool; - lang : language; + block : EvalOpt.block_comment option; + line : EvalOpt.line_comment option; ext : string; (* ".ligo" *) mode : [`Byte | `Point]; cmd : EvalOpt.command; @@ -24,22 +23,25 @@ module SubIO = > let options : options = - object - method libs = [] - method verbose = SSet.empty - method offsets = true - method lang = `PascaLIGO - method ext = ".ligo" - method mode = `Point - method cmd = EvalOpt.Quiet - method mono = false - end + let block = EvalOpt.mk_block ~opening:"(*" ~closing:"*)" + in object + method libs = [] + method verbose = SSet.empty + method offsets = true + method block = Some block + method line = Some "//" + method ext = ".ligo" + method mode = `Point + method cmd = EvalOpt.Quiet + method mono = false + end let make = EvalOpt.make ~libs:options#libs ~verbose:options#verbose ~offsets:options#offsets - ~lang:options#lang + ?block:options#block + ?line:options#line ~ext:options#ext ~mode:options#mode ~cmd:options#cmd diff --git a/src/passes/1-parser/pascaligo/.links b/src/passes/1-parser/pascaligo/.links index 0b836a2d9..45c9a4602 100644 --- a/src/passes/1-parser/pascaligo/.links +++ b/src/passes/1-parser/pascaligo/.links @@ -2,6 +2,8 @@ $HOME/git/OCaml-build/Makefile ../shared/Lexer.mli ../shared/Lexer.mll +../shared/LexerLib.mli +../shared/LexerLib.ml ../shared/EvalOpt.ml ../shared/EvalOpt.mli ../shared/FQueue.ml @@ -18,5 +20,6 @@ $HOME/git/OCaml-build/Makefile ../shared/LexerUnit.ml ../shared/ParserUnit.mli ../shared/ParserUnit.ml +../shared/LexerLib.ml $HOME/git/ligo/_build/default/src/passes/1-parser/pascaligo/ParErr.ml diff --git a/src/passes/1-parser/pascaligo/LexToken.mli b/src/passes/1-parser/pascaligo/LexToken.mli index 60479955f..be263d9a5 100644 --- a/src/passes/1-parser/pascaligo/LexToken.mli +++ b/src/passes/1-parser/pascaligo/LexToken.mli @@ -1,4 +1,4 @@ -(** This signature defines the lexical tokens for LIGO +(* This signature defines the lexical tokens for LIGO _Tokens_ are the abstract units which are used by the parser to build the abstract syntax tree (AST), in other words, the stream of @@ -163,11 +163,22 @@ val eof : Region.t -> token (* Predicates *) -val is_string : token -> bool -val is_bytes : token -> bool -val is_int : token -> bool -val is_ident : token -> bool -val is_kwd : token -> bool -val is_constr : token -> bool -val is_sym : token -> bool val is_eof : token -> bool + +(* Style *) + +type error + +val error_to_string : error -> string + +exception Error of error Region.reg + +val format_error : + ?offsets:bool -> [`Byte | `Point] -> + error Region.reg -> file:bool -> string Region.reg + +val check_right_context : + token -> + (Lexing.lexbuf -> (Markup.t list * token) option) -> + Lexing.lexbuf -> + unit diff --git a/src/passes/1-parser/pascaligo/LexToken.mll b/src/passes/1-parser/pascaligo/LexToken.mll index 95035cf37..933db3cdb 100644 --- a/src/passes/1-parser/pascaligo/LexToken.mll +++ b/src/passes/1-parser/pascaligo/LexToken.mll @@ -5,24 +5,14 @@ (* Shorthands *) -type lexeme = string - -let sprintf = Printf.sprintf - module Region = Simple_utils.Region module Pos = Simple_utils.Pos module SMap = Map.Make (String) module SSet = Set.Make (String) -(* Hack to roll back one lexeme in the current semantic action *) -(* -let rollback buffer = - let open Lexing in - let len = String.length (lexeme buffer) in - let pos_cnum = buffer.lex_curr_p.pos_cnum - len in - buffer.lex_curr_pos <- buffer.lex_curr_pos - len; - buffer.lex_curr_p <- {buffer.lex_curr_p with pos_cnum} -*) +type lexeme = string + +let sprintf = Printf.sprintf (* TOKENS *) @@ -123,6 +113,8 @@ type t = | EOF of Region.t +(* Projections *) + type token = t let proj_token = function @@ -130,32 +122,20 @@ let proj_token = function String Region.{region; value} -> region, sprintf "String %s" value - | Bytes Region.{region; value = s,b} -> region, - sprintf "Bytes (\"%s\", \"0x%s\")" - s (Hex.show b) - + sprintf "Bytes (\"%s\", \"0x%s\")" s (Hex.show b) | Int Region.{region; value = s,n} -> region, sprintf "Int (\"%s\", %s)" s (Z.to_string n) - | Nat Region.{region; value = s,n} -> region, sprintf "Nat (\"%s\", %s)" s (Z.to_string n) - | Mutez Region.{region; value = s,n} -> region, sprintf "Mutez (\"%s\", %s)" s (Z.to_string n) - | Ident Region.{region; value} -> region, sprintf "Ident \"%s\"" value - | Constr Region.{region; value} -> region, sprintf "Constr \"%s\"" value -(* -| Attr {header; string={region; value}} -> - region, sprintf "Attr (\"%s\",\"%s\")" header value - *) - (* Symbols *) | SEMI region -> region, "SEMI" @@ -244,7 +224,7 @@ let to_lexeme = function | Bytes b -> fst b.Region.value | Int i | Nat i -| Mutez i -> fst i.Region.value +| Mutez i -> fst i.Region.value | Ident id | Constr id -> id.Region.value @@ -382,9 +362,7 @@ let keywords = [ (fun reg -> With reg) ] -let reserved = - let open SSet in - empty |> add "arguments" +let reserved = SSet.empty let constructors = [ (fun reg -> False reg); @@ -483,24 +461,21 @@ type nat_err = | Non_canonical_zero_nat let mk_nat lexeme region = - match (String.index_opt lexeme 'n') with - | None -> Error Invalid_natural - | Some _ -> ( - let z = - Str.(global_replace (regexp "_") "" lexeme) |> - Str.(global_replace (regexp "n") "") |> - Z.of_string in - if Z.equal z Z.zero && lexeme <> "0n" - then Error Non_canonical_zero_nat - else Ok (Nat Region.{region; value = lexeme,z}) - ) + match String.index_opt lexeme 'n' with + None -> Error Invalid_natural + | Some _ -> let z = + Str.(global_replace (regexp "_") "" lexeme) |> + Str.(global_replace (regexp "n") "") |> + Z.of_string in + if Z.equal z Z.zero && lexeme <> "0n" + then Error Non_canonical_zero_nat + else Ok (Nat Region.{region; value = lexeme,z}) let mk_mutez lexeme region = - let z = - Str.(global_replace (regexp "_") "" lexeme) |> - Str.(global_replace (regexp "mutez") "") |> - Z.of_string in - if Z.equal z Z.zero && lexeme <> "0mutez" + let z = Str.(global_replace (regexp "_") "" lexeme) |> + Str.(global_replace (regexp "mutez") "") |> + Z.of_string in + if Z.equal z Z.zero && lexeme <> "0mutez" then Error Non_canonical_zero else Ok (Mutez Region.{region; value = lexeme, z}) @@ -558,104 +533,76 @@ let mk_constr lexeme region = type attr_err = Invalid_attribute -let mk_attr _header _string _region = - Error Invalid_attribute +let mk_attr _ _ _ = Error Invalid_attribute (* Predicates *) -let is_string = function - String _ -> true -| _ -> false +let is_string = function String _ -> true | _ -> false +let is_bytes = function Bytes _ -> true | _ -> false +let is_int = function Int _ -> true | _ -> false +let is_ident = function Ident _ -> true | _ -> false +let is_eof = function EOF _ -> true | _ -> false +let is_minus = function MINUS _ -> true | _ -> false -let is_bytes = function - Bytes _ -> true -| _ -> false +(* Errors *) -let is_int = function - Int _ -> true -| _ -> false +type error = + Odd_lengthed_bytes +| Missing_break +| Negative_byte_sequence -let is_ident = function - Ident _ -> true -| _ -> false +let error_to_string = function + Odd_lengthed_bytes -> + "The length of the byte sequence is an odd number.\n\ + Hint: Add or remove a digit." +| Missing_break -> + "Missing break.\n\ + Hint: Insert some space." +| Negative_byte_sequence -> + "Negative byte sequence.\n\ + Hint: Remove the leading minus sign." -let is_kwd = function - And _ -| Attributes _ -| Begin _ -| BigMap _ -| Block _ -| Case _ -| Const _ -| Contains _ -| Else _ -| End _ -| False _ -| For _ -| From _ -| Function _ -| If _ -| In _ -| Is _ -| List _ -| Map _ -| Mod _ -| Nil _ -| Not _ -| Of _ -| Or _ -| Patch _ -| Record _ -| Remove _ -| Set _ -| Skip _ -| Step _ -| Then _ -| To _ -| True _ -| Type _ -| Unit _ -| Var _ -| While _ -| With _ -> true -| _ -> false +exception Error of error Region.reg -let is_constr = function - Constr _ -| C_None _ -| C_Some _ -> true -| _ -> false +let format_error ?(offsets=true) mode Region.{region; value} ~file = + let msg = error_to_string value + and reg = region#to_string ~file ~offsets mode in + let value = sprintf "Lexical error %s:\n%s\n" reg msg + in Region.{value; region} -let is_sym = function - SEMI _ -| COMMA _ -| LPAR _ -| RPAR _ -| LBRACE _ -| RBRACE _ -| LBRACKET _ -| RBRACKET _ -| CONS _ -| VBAR _ -| ARROW _ -| ASS _ -| EQ _ -| COLON _ -| LT _ -| LE _ -| GT _ -| GE _ -| NE _ -| PLUS _ -| MINUS _ -| SLASH _ -| TIMES _ -| DOT _ -| WILD _ -| CAT _ -> true -| _ -> false +let fail region value = raise (Error Region.{region; value}) -let is_eof = function EOF _ -> true | _ -> false +let check_right_context token next_token buffer : unit = + let pos = (to_region token)#stop in + let region = Region.make ~start:pos ~stop:pos in + match next_token buffer with + None -> () + | Some (markup, next) -> + if is_minus token && is_bytes next + then let region = + Region.cover (to_region token) (to_region next) + in fail region Negative_byte_sequence + else + match markup with + [] -> + if is_int token + then if is_string next || is_ident next + then fail region Missing_break + else () + else + if is_string token + then if is_int next || is_bytes next || is_ident next + then fail region Missing_break + else () + else + if is_bytes token + then if is_string next || is_ident next + then fail region Missing_break + else if is_int next + then fail region Odd_lengthed_bytes + else () + else () + | _::_ -> () (* END TRAILER *) } diff --git a/src/passes/1-parser/pascaligo/LexerMain.ml b/src/passes/1-parser/pascaligo/LexerMain.ml index 3c8d7c642..a497df466 100644 --- a/src/passes/1-parser/pascaligo/LexerMain.ml +++ b/src/passes/1-parser/pascaligo/LexerMain.ml @@ -4,7 +4,10 @@ module Region = Simple_utils.Region module IO = struct - let options = EvalOpt.(read ~lang:`PascaLIGO ~ext:".ligo") + let options = + let open EvalOpt in + let block = mk_block ~opening:"(*" ~closing:"*)" + in read ~block ~line:"//" ".ligo" end module M = LexerUnit.Make (IO) (Lexer.Make (LexToken)) diff --git a/src/passes/1-parser/pascaligo/ParserMain.ml b/src/passes/1-parser/pascaligo/ParserMain.ml index c94ca806d..beb0b4885 100644 --- a/src/passes/1-parser/pascaligo/ParserMain.ml +++ b/src/passes/1-parser/pascaligo/ParserMain.ml @@ -5,7 +5,10 @@ module SSet = Set.Make (String) module IO = struct - let options = EvalOpt.(read ~lang:`PascaLIGO ~ext:".ligo") + let options = + let open EvalOpt in + let block = mk_block ~opening:"(*" ~closing:"*)" + in read ~block ~line:"//" ".ligo" end module SubIO = @@ -14,7 +17,8 @@ module SubIO = libs : string list; verbose : SSet.t; offsets : bool; - lang : EvalOpt.language; + block : EvalOpt.block_comment option; + line : EvalOpt.line_comment option; ext : string; mode : [`Byte | `Point]; cmd : EvalOpt.command; @@ -26,7 +30,8 @@ module SubIO = method libs = IO.options#libs method verbose = IO.options#verbose method offsets = IO.options#offsets - method lang = IO.options#lang + method block = IO.options#block + method line = IO.options#line method ext = IO.options#ext method mode = IO.options#mode method cmd = IO.options#cmd @@ -37,7 +42,8 @@ module SubIO = EvalOpt.make ~libs:options#libs ~verbose:options#verbose ~offsets:options#offsets - ~lang:options#lang + ?block:options#block + ?line:options#line ~ext:options#ext ~mode:options#mode ~cmd:options#cmd diff --git a/src/passes/1-parser/reasonligo.ml b/src/passes/1-parser/reasonligo.ml index 85f9557e4..1af70c927 100644 --- a/src/passes/1-parser/reasonligo.ml +++ b/src/passes/1-parser/reasonligo.ml @@ -11,15 +11,14 @@ module SSet = Set.Make (String) (* Mock IOs TODO: Fill them with CLI options *) -type language = [`PascaLIGO | `CameLIGO | `ReasonLIGO] - module SubIO = struct type options = < libs : string list; verbose : SSet.t; offsets : bool; - lang : language; + block : EvalOpt.block_comment option; + line : EvalOpt.line_comment option; ext : string; (* ".religo" *) mode : [`Byte | `Point]; cmd : EvalOpt.command; @@ -27,22 +26,25 @@ module SubIO = > let options : options = - object - method libs = [] - method verbose = SSet.empty - method offsets = true - method lang = `ReasonLIGO - method ext = ".religo" - method mode = `Point - method cmd = EvalOpt.Quiet - method mono = false - end + let block = EvalOpt.mk_block ~opening:"/*" ~closing:"*/" + in object + method libs = [] + method verbose = SSet.empty + method offsets = true + method block = Some block + method line = Some "//" + method ext = ".religo" + method mode = `Point + method cmd = EvalOpt.Quiet + method mono = false + end let make = EvalOpt.make ~libs:options#libs ~verbose:options#verbose ~offsets:options#offsets - ~lang:options#lang + ?block:options#block + ?line:options#line ~ext:options#ext ~mode:options#mode ~cmd:options#cmd diff --git a/src/passes/1-parser/reasonligo/.links b/src/passes/1-parser/reasonligo/.links index 2be7fda97..214b46e6c 100644 --- a/src/passes/1-parser/reasonligo/.links +++ b/src/passes/1-parser/reasonligo/.links @@ -2,6 +2,7 @@ $HOME/git/OCaml-build/Makefile ../shared/Lexer.mli ../shared/Lexer.mll +../shared/LexerLib.ml ../shared/EvalOpt.ml ../shared/EvalOpt.mli ../shared/FQueue.ml diff --git a/src/passes/1-parser/reasonligo/LexToken.mli b/src/passes/1-parser/reasonligo/LexToken.mli index 4a70d9d13..f568b5894 100644 --- a/src/passes/1-parser/reasonligo/LexToken.mli +++ b/src/passes/1-parser/reasonligo/LexToken.mli @@ -31,48 +31,49 @@ type lexeme = string type t = (* Symbols *) - CAT of Region.t (* "++" *) + CAT of Region.t (* "++" *) (* Arithmetics *) -| MINUS of Region.t (* "-" *) -| PLUS of Region.t (* "+" *) -| SLASH of Region.t (* "/" *) -| TIMES of Region.t (* "*" *) +| MINUS of Region.t (* "-" *) +| PLUS of Region.t (* "+" *) +| SLASH of Region.t (* "/" *) +| TIMES of Region.t (* "*" *) (* Compounds *) -| LPAR of Region.t (* "(" *) -| RPAR of Region.t (* ")" *) +| LPAR of Region.t (* "(" *) +| RPAR of Region.t (* ")" *) | LBRACKET of Region.t (* "[" *) | RBRACKET of Region.t (* "]" *) -| LBRACE of Region.t (* "{" *) -| RBRACE of Region.t (* "}" *) +| LBRACE of Region.t (* "{" *) +| RBRACE of Region.t (* "}" *) (* Separators *) -| COMMA of Region.t (* "," *) -| SEMI of Region.t (* ";" *) -| VBAR of Region.t (* "|" *) -| COLON of Region.t (* ":" *) -| DOT of Region.t (* "." *) +| COMMA of Region.t (* "," *) +| SEMI of Region.t (* ";" *) +| VBAR of Region.t (* "|" *) +| COLON of Region.t (* ":" *) +| DOT of Region.t (* "." *) | ELLIPSIS of Region.t (* "..." *) +| ARROW of Region.t (* "=>" *) (* Wildcard *) -| WILD of Region.t (* "_" *) +| WILD of Region.t (* "_" *) (* Comparisons *) -| EQ of Region.t (* "=" *) -| EQEQ of Region.t (* "==" *) -| NE of Region.t (* "!=" *) -| LT of Region.t (* "<" *) -| GT of Region.t (* ">" *) -| LE of Region.t (* "=<" *) -| GE of Region.t (* ">=" *) +| EQ of Region.t (* "=" *) +| EQEQ of Region.t (* "==" *) +| NE of Region.t (* "!=" *) +| LT of Region.t (* "<" *) +| GT of Region.t (* ">" *) +| LE of Region.t (* "<=" *) +| GE of Region.t (* ">=" *) -| ARROW of Region.t (* "=>" *) + (* Logic *) | BOOL_OR of Region.t (* "||" *) | BOOL_AND of Region.t (* "&&" *) @@ -91,18 +92,18 @@ type t = (* Keywords *) -| Else of Region.t -| False of Region.t -| If of Region.t -| Let of Region.t -| Rec of Region.t +| Else of Region.t +| False of Region.t +| If of Region.t +| Let of Region.t +| Mod of Region.t +| Or of Region.t +| Rec of Region.t | Switch of Region.t -| Mod of Region.t -| Or of Region.t -| True of Region.t -| Type of Region.t +| True of Region.t +| Type of Region.t -(* Data constructors *) + (* Data constructors *) | C_None of Region.t (* "None" *) | C_Some of Region.t (* "Some" *) @@ -111,8 +112,6 @@ type t = | EOF of Region.t (* End of file *) -type token = t - (* Projections The difference between extracting the lexeme and a string from a @@ -121,6 +120,8 @@ type token = t lexeme (concrete syntax). *) +type token = t + val to_lexeme : token -> lexeme val to_string : token -> ?offsets:bool -> [`Byte | `Point] -> string val to_region : token -> Region.t @@ -154,11 +155,22 @@ val eof : Region.t -> token (* Predicates *) -val is_string : token -> bool -val is_bytes : token -> bool -val is_int : token -> bool -val is_ident : token -> bool -val is_kwd : token -> bool -val is_constr : token -> bool -val is_sym : token -> bool val is_eof : token -> bool + +(* Style *) + +type error + +val error_to_string : error -> string + +exception Error of error Region.reg + +val format_error : + ?offsets:bool -> [`Byte | `Point] -> + error Region.reg -> file:bool -> string Region.reg + +val check_right_context : + token -> + (Lexing.lexbuf -> (Markup.t list * token) option) -> + Lexing.lexbuf -> + unit diff --git a/src/passes/1-parser/reasonligo/LexToken.mll b/src/passes/1-parser/reasonligo/LexToken.mll index cd05538e7..a4245fb6d 100644 --- a/src/passes/1-parser/reasonligo/LexToken.mll +++ b/src/passes/1-parser/reasonligo/LexToken.mll @@ -1,66 +1,69 @@ { (* START OF HEADER *) -type lexeme = string - -let sprintf = Printf.sprintf +(* Shorthands *) module Region = Simple_utils.Region module Pos = Simple_utils.Pos module SMap = Utils.String.Map module SSet = Utils.String.Set +type lexeme = string + +let sprintf = Printf.sprintf + (* TOKENS *) type t = (* Symbols *) - CAT of Region.t (* "++" *) + CAT of Region.t (* "++" *) (* Arithmetics *) -| MINUS of Region.t (* "-" *) -| PLUS of Region.t (* "+" *) -| SLASH of Region.t (* "/" *) -| TIMES of Region.t (* "*" *) +| MINUS of Region.t (* "-" *) +| PLUS of Region.t (* "+" *) +| SLASH of Region.t (* "/" *) +| TIMES of Region.t (* "*" *) (* Compounds *) -| LPAR of Region.t (* "(" *) -| RPAR of Region.t (* ")" *) -| LBRACKET of Region.t (* "[" *) -| RBRACKET of Region.t (* "]" *) -| LBRACE of Region.t (* "{" *) -| RBRACE of Region.t (* "}" *) +| LPAR of Region.t (* "(" *) +| RPAR of Region.t (* ")" *) +| LBRACKET of Region.t (* "[" *) +| RBRACKET of Region.t (* "]" *) +| LBRACE of Region.t (* "{" *) +| RBRACE of Region.t (* "}" *) (* Separators *) -| COMMA of Region.t (* "," *) -| SEMI of Region.t (* ";" *) -| VBAR of Region.t (* "|" *) -| COLON of Region.t (* ":" *) -| DOT of Region.t (* "." *) +| COMMA of Region.t (* "," *) +| SEMI of Region.t (* ";" *) +| VBAR of Region.t (* "|" *) +| COLON of Region.t (* ":" *) +| DOT of Region.t (* "." *) | ELLIPSIS of Region.t (* "..." *) +| ARROW of Region.t (* "=>" *) (* Wildcard *) -| WILD of Region.t (* "_" *) +| WILD of Region.t (* "_" *) (* Comparisons *) -| EQ of Region.t (* "=" *) -| EQEQ of Region.t (* "==" *) -| NE of Region.t (* "!=" *) -| LT of Region.t (* "<" *) -| GT of Region.t (* ">" *) -| LE of Region.t (* "<=" *) -| GE of Region.t (* ">=" *) -| ARROW of Region.t (* "=>" *) +| EQ of Region.t (* "=" *) +| EQEQ of Region.t (* "==" *) +| NE of Region.t (* "!=" *) +| LT of Region.t (* "<" *) +| GT of Region.t (* ">" *) +| LE of Region.t (* "<=" *) +| GE of Region.t (* ">=" *) -| BOOL_OR of Region.t (* "||" *) -| BOOL_AND of Region.t (* "&&" *) + (* Logic *) -| NOT of Region.t (* ! *) +| BOOL_OR of Region.t (* "||" *) +| BOOL_AND of Region.t (* "&&" *) +| NOT of Region.t (* ! *) (* Identifiers, labels, numbers and strings *) @@ -75,17 +78,17 @@ type t = (* Keywords *) -(*| And*) -| Else of Region.t -| False of Region.t -| If of Region.t -| Let of Region.t -| Rec of Region.t +| Else of Region.t +| False of Region.t +| If of Region.t +| Let of Region.t +| Mod of Region.t +| Or of Region.t +| Rec of Region.t | Switch of Region.t -| Mod of Region.t -| Or of Region.t -| True of Region.t -| Type of Region.t +| True of Region.t +| Type of Region.t + (* Data constructors *) | C_None of Region.t (* "None" *) @@ -96,121 +99,143 @@ type t = | EOF of Region.t (* End of file *) +(* Projections *) + type token = t let proj_token = function - CAT region -> region, "CAT" -| MINUS region -> region, "MINUS" -| PLUS region -> region, "PLUS" -| SLASH region -> region, "SLASH" -| TIMES region -> region, "TIMES" -| LPAR region -> region, "LPAR" -| RPAR region -> region, "RPAR" -| LBRACKET region -> region, "LBRACKET" -| RBRACKET region -> region, "RBRACKET" -| LBRACE region -> region, "LBRACE" -| RBRACE region -> region, "RBRACE" -| COMMA region -> region, "COMMA" -| SEMI region -> region, "SEMI" -| VBAR region -> region, "VBAR" -| COLON region -> region, "COLON" -| DOT region -> region, "DOT" -| ELLIPSIS region -> region, "ELLIPSIS" -| WILD region -> region, "WILD" -| EQ region -> region, "EQ" -| EQEQ region -> region, "EQEQ" -| NE region -> region, "NE" -| LT region -> region, "LT" -| GT region -> region, "GT" -| LE region -> region, "LE" -| GE region -> region, "GE" -| ARROW region -> region, "ARROW" -| BOOL_OR region -> region, "BOOL_OR" -| BOOL_AND region -> region, "BOOL_AND" -| Ident Region.{region; value} -> - region, sprintf "Ident %s" value -| Constr Region.{region; value} -> - region, sprintf "Constr %s" value + (* Literals *) + + String Region.{region; value} -> + region, sprintf "String %s" value +| Bytes Region.{region; value = s,b} -> + region, + sprintf "Bytes (\"%s\", \"0x%s\")" s (Hex.show b) | Int Region.{region; value = s,n} -> region, sprintf "Int (\"%s\", %s)" s (Z.to_string n) | Nat Region.{region; value = s,n} -> region, sprintf "Nat (\"%s\", %s)" s (Z.to_string n) | Mutez Region.{region; value = s,n} -> region, sprintf "Mutez (\"%s\", %s)" s (Z.to_string n) -| String Region.{region; value} -> - region, sprintf "String %s" value -| Bytes Region.{region; value = s,b} -> - region, - sprintf "Bytes (\"%s\", \"0x%s\")" - s (Hex.show b) -| Else region -> region, "Else" -| False region -> region, "False" -| If region -> region, "If" -| Let region -> region, "Let" -| Rec region -> region, "Rec" -| Switch region -> region, "Switch" -| Mod region -> region, "Mod" -| NOT region -> region, "!" -| Or region -> region, "Or" -| True region -> region, "True" -| Type region -> region, "Type" -| C_None region -> region, "C_None" -| C_Some region -> region, "C_Some" -| Attr Region.{region; value} -> region, sprintf "Attr %s" value -| EOF region -> region, "EOF" +| Ident Region.{region; value} -> + region, sprintf "Ident %s" value +| Constr Region.{region; value} -> + region, sprintf "Constr %s" value + + (* Symbols *) + +| CAT region -> region, "CAT" +| MINUS region -> region, "MINUS" +| PLUS region -> region, "PLUS" +| SLASH region -> region, "SLASH" +| TIMES region -> region, "TIMES" +| LPAR region -> region, "LPAR" +| RPAR region -> region, "RPAR" +| LBRACKET region -> region, "LBRACKET" +| RBRACKET region -> region, "RBRACKET" +| LBRACE region -> region, "LBRACE" +| RBRACE region -> region, "RBRACE" +| COMMA region -> region, "COMMA" +| SEMI region -> region, "SEMI" +| VBAR region -> region, "VBAR" +| COLON region -> region, "COLON" +| DOT region -> region, "DOT" +| ELLIPSIS region -> region, "ELLIPSIS" +| WILD region -> region, "WILD" +| EQ region -> region, "EQ" +| EQEQ region -> region, "EQEQ" +| NE region -> region, "NE" +| LT region -> region, "LT" +| GT region -> region, "GT" +| LE region -> region, "LE" +| GE region -> region, "GE" +| ARROW region -> region, "ARROW" +| NOT region -> region, "NOT" +| BOOL_OR region -> region, "BOOL_OR" +| BOOL_AND region -> region, "BOOL_AND" +| Else region -> region, "Else" +| False region -> region, "False" +| If region -> region, "If" +| Let region -> region, "Let" +| Rec region -> region, "Rec" +| Switch region -> region, "Switch" +| Mod region -> region, "Mod" +| Or region -> region, "Or" +| True region -> region, "True" +| Type region -> region, "Type" +| C_None region -> region, "C_None" +| C_Some region -> region, "C_Some" +| Attr Region.{region; value} -> region, sprintf "Attr %s" value +| EOF region -> region, "EOF" let to_lexeme = function - CAT _ -> "++" -| MINUS _ -> "-" -| PLUS _ -> "+" -| SLASH _ -> "/" -| TIMES _ -> "*" -| LPAR _ -> "(" -| RPAR _ -> ")" -| LBRACKET _ -> "[" -| RBRACKET _ -> "]" -| LBRACE _ -> "{" -| RBRACE _ -> "}" -| COMMA _ -> "," -| SEMI _ -> ";" -| VBAR _ -> "|" -| COLON _ -> ":" -| DOT _ -> "." -| ELLIPSIS _ -> "..." -| WILD _ -> "_" -| EQ _ -> "=" -| EQEQ _ -> "==" -| NE _ -> "!=" -| LT _ -> "<" -| GT _ -> ">" -| LE _ -> "<=" -| GE _ -> ">=" -| ARROW _ -> "=>" -| BOOL_OR _ -> "||" -| BOOL_AND _ -> "&&" -| Ident id -> id.Region.value -| Constr id -> id.Region.value + (* Literals *) + + String s -> s.Region.value +| Bytes b -> fst b.Region.value | Int i | Nat i -| Mutez i -> fst i.Region.value -| String s -> s.Region.value -| Bytes b -> fst b.Region.value -| Else _ -> "else" -| False _ -> "false" -| If _ -> "if" -| Let _ -> "let" -| Rec _ -> "rec" -| Mod _ -> "mod" -| NOT _ -> "!" -| Or _ -> "or" -| Switch _ -> "switch" -| True _ -> "true" -| Type _ -> "type" +| Mutez i -> fst i.Region.value +| Ident id -> id.Region.value +| Constr id -> id.Region.value +| Attr a -> a.Region.value + + (* Symbols *) + +| CAT _ -> "++" +| MINUS _ -> "-" +| PLUS _ -> "+" +| SLASH _ -> "/" +| TIMES _ -> "*" +| LPAR _ -> "(" +| RPAR _ -> ")" +| LBRACKET _ -> "[" +| RBRACKET _ -> "]" +| LBRACE _ -> "{" +| RBRACE _ -> "}" +| COMMA _ -> "," +| SEMI _ -> ";" +| VBAR _ -> "|" +| COLON _ -> ":" +| DOT _ -> "." +| ELLIPSIS _ -> "..." +| WILD _ -> "_" +| EQ _ -> "=" +| EQEQ _ -> "==" +| NE _ -> "!=" +| LT _ -> "<" +| GT _ -> ">" +| LE _ -> "<=" +| GE _ -> ">=" +| ARROW _ -> "=>" +| BOOL_OR _ -> "||" +| BOOL_AND _ -> "&&" +| NOT _ -> "!" + + (* Keywords *) + +| Else _ -> "else" +| False _ -> "false" +| If _ -> "if" +| Let _ -> "let" +| Mod _ -> "mod" +| Or _ -> "or" +| Rec _ -> "rec" +| Switch _ -> "switch" +| True _ -> "true" +| Type _ -> "type" + +(* Data constructors *) + | C_None _ -> "None" | C_Some _ -> "Some" -| Attr a -> a.Region.value + +(* Virtual tokens *) + | EOF _ -> "" +(* CONVERSIONS *) + let to_string token ?(offsets=true) mode = let region, val_str = proj_token token in let reg_str = region#compact ~offsets mode @@ -261,12 +286,9 @@ let reserved = |> add "functor" |> add "inherit" |> add "initializer" - (* |> add "land" - see https://ligo.atlassian.net/browse/LIGO-263 *) |> add "lazy" - (* |> add "lor" - see https://ligo.atlassian.net/browse/LIGO-263 *) |> add "lsl" |> add "lsr" - (* |> add "lxor" - see https://ligo.atlassian.net/browse/LIGO-263 *) |> add "match" |> add "method" |> add "module" @@ -291,7 +313,7 @@ let reserved = let constructors = [ (fun reg -> C_None reg); - (fun reg -> C_Some reg); + (fun reg -> C_Some reg) ] let add map (key, value) = SMap.add key value map @@ -376,20 +398,18 @@ let mk_int lexeme region = else Ok (Int Region.{region; value = lexeme, z}) let mk_nat lexeme region = - let z = - Str.(global_replace (regexp "_") "" lexeme) |> - Str.(global_replace (regexp "n") "") |> - Z.of_string in - if Z.equal z Z.zero && lexeme <> "0n" + let z = Str.(global_replace (regexp "_") "" lexeme) |> + Str.(global_replace (regexp "n") "") |> + Z.of_string in + if Z.equal z Z.zero && lexeme <> "0n" then Error Non_canonical_zero_nat else Ok (Nat Region.{region; value = lexeme, z}) let mk_mutez lexeme region = - let z = - Str.(global_replace (regexp "_") "" lexeme) |> - Str.(global_replace (regexp "mutez") "") |> - Z.of_string in - if Z.equal z Z.zero && lexeme <> "0mutez" + let z = Str.(global_replace (regexp "_") "" lexeme) |> + Str.(global_replace (regexp "mutez") "") |> + Z.of_string in + if Z.equal z Z.zero && lexeme <> "0mutez" then Error Non_canonical_zero else Ok (Mutez Region.{region; value = lexeme, z}) @@ -426,11 +446,11 @@ let mk_sym lexeme region = (* Symbols specific to ReasonLIGO *) - | "..." -> Ok (ELLIPSIS region) - | "=>" -> Ok (ARROW region) - | "==" -> Ok (EQEQ region) - | "!" -> Ok (NOT region) - | "++" -> Ok (CAT region) + | "..." -> Ok (ELLIPSIS region) + | "=>" -> Ok (ARROW region) + | "==" -> Ok (EQEQ region) + | "!" -> Ok (NOT region) + | "++" -> Ok (CAT region) (* Invalid symbols *) @@ -460,75 +480,72 @@ let mk_attr header lexeme region = (* Predicates *) -let is_string = function - String _ -> true -| _ -> false +let is_string = function String _ -> true | _ -> false +let is_bytes = function Bytes _ -> true | _ -> false +let is_int = function Int _ -> true | _ -> false +let is_ident = function Ident _ -> true | _ -> false +let is_eof = function EOF _ -> true | _ -> false +let is_minus = function MINUS _ -> true | _ -> false -let is_bytes = function - Bytes _ -> true -| _ -> false +(* Errors *) -let is_int = function - Int _ -> true -| _ -> false +type error = + Odd_lengthed_bytes +| Missing_break +| Negative_byte_sequence -let is_ident = function - Ident _ -> true -| _ -> false +let error_to_string = function + Odd_lengthed_bytes -> + "The length of the byte sequence is an odd number.\n\ + Hint: Add or remove a digit." +| Missing_break -> + "Missing break.\n\ + Hint: Insert some space." +| Negative_byte_sequence -> + "Negative byte sequence.\n\ + Hint: Remove the leading minus sign." -let is_kwd = function - Else _ -| False _ -| If _ -| Let _ -| Rec _ -| Switch _ -| Mod _ -| Or _ -| True _ -| Type _ -> true -| _ -> false +exception Error of error Region.reg -let is_constr = function - Constr _ -| Ident _ -| False _ -| True _ -> true -| _ -> false +let format_error ?(offsets=true) mode Region.{region; value} ~file = + let msg = error_to_string value + and reg = region#to_string ~file ~offsets mode in + let value = sprintf "Lexical error %s:\n%s\n" reg msg + in Region.{value; region} -let is_sym = function - CAT _ -| MINUS _ -| PLUS _ -| SLASH _ -| TIMES _ -| LPAR _ -| RPAR _ -| LBRACKET _ -| RBRACKET _ -| LBRACE _ -| RBRACE _ -| COMMA _ -| SEMI _ -| VBAR _ -| COLON _ -| DOT _ -| ELLIPSIS _ -| WILD _ -| EQ _ -| EQEQ _ -| NE _ -| LT _ -| GT _ -| LE _ -| GE _ -| ARROW _ -| BOOL_OR _ -| NOT _ -| BOOL_AND _ -> true -| _ -> false +let fail region value = raise (Error Region.{region; value}) -let is_eof = function EOF _ -> true | _ -> false +let check_right_context token next_token buffer : unit = + let pos = (to_region token)#stop in + let region = Region.make ~start:pos ~stop:pos in + match next_token buffer with + None -> () + | Some (markup, next) -> + if is_minus token && is_bytes next + then let region = + Region.cover (to_region token) (to_region next) + in fail region Negative_byte_sequence + else + match markup with + [] -> + if is_int token + then if is_string next || is_ident next + then fail region Missing_break + else () + else + if is_string token + then if is_int next || is_bytes next || is_ident next + then fail region Missing_break + else () + else + if is_bytes token + then if is_string next || is_ident next + then fail region Missing_break + else if is_int next + then fail region Odd_lengthed_bytes + else () + else () + | _::_ -> () (* END TRAILER *) } diff --git a/src/passes/1-parser/reasonligo/LexerMain.ml b/src/passes/1-parser/reasonligo/LexerMain.ml index 4f063582f..f0d6fdfa1 100644 --- a/src/passes/1-parser/reasonligo/LexerMain.ml +++ b/src/passes/1-parser/reasonligo/LexerMain.ml @@ -4,7 +4,10 @@ module Region = Simple_utils.Region module IO = struct - let options = EvalOpt.(read ~lang:`ReasonLIGO ~ext:".religo") + let options = + let open EvalOpt in + let block = mk_block ~opening:"/*" ~closing:"*/" + in read ~block ~line:"//" ".religo" end module M = LexerUnit.Make (IO) (Lexer.Make (LexToken)) @@ -12,4 +15,4 @@ module M = LexerUnit.Make (IO) (Lexer.Make (LexToken)) let () = match M.trace () with Stdlib.Ok () -> () - | Error Region.{value; _} -> Utils.highlight value + | Error Region.{value; _} -> Printf.eprintf "\027[31m%s\027[0m%!" value diff --git a/src/passes/1-parser/reasonligo/Parser.mly b/src/passes/1-parser/reasonligo/Parser.mly index 1697aa9a5..702094ecd 100644 --- a/src/passes/1-parser/reasonligo/Parser.mly +++ b/src/passes/1-parser/reasonligo/Parser.mly @@ -40,11 +40,11 @@ let rec curry hd = function in TFun {value; region} | [] -> hd -let wild_error e = - match e with - | EVar { value = "_"; _} as e -> +let wild_error e = + match e with + | EVar { value = "_"; _} as e -> let open! SyntaxError in - raise (Error (InvalidWild e)) + raise (Error (InvalidWild e)) | _ -> () (* END HEADER *) @@ -270,30 +270,30 @@ let_declaration: let_binding: "" type_annotation? "=" expr { - wild_error $4; + wild_error $4; Scoping.check_reserved_name $1; {binders = PVar $1, []; lhs_type=$2; eq=$3; let_rhs=$4} } | "_" type_annotation? "=" expr { - wild_error $4; + wild_error $4; {binders = PWild $1, []; lhs_type=$2; eq=$3; let_rhs=$4} } | unit type_annotation? "=" expr { - wild_error $4; + wild_error $4; {binders = PUnit $1, []; lhs_type=$2; eq=$3; let_rhs=$4} } | record_pattern type_annotation? "=" expr { - wild_error $4; + wild_error $4; Scoping.check_pattern (PRecord $1); {binders = PRecord $1, []; lhs_type=$2; eq=$3; let_rhs=$4} } | par(closed_irrefutable) type_annotation? "=" expr { - wild_error $4; + wild_error $4; Scoping.check_pattern $1.value.inside; {binders = PPar $1, []; lhs_type=$2; eq=$3; let_rhs=$4} } | tuple(sub_irrefutable) type_annotation? "=" expr { - wild_error $4; + wild_error $4; Utils.nsepseq_iter Scoping.check_pattern $1; let hd, tl = $1 in let start = pattern_to_region hd in @@ -422,7 +422,7 @@ expr: base_cond__open(expr) | switch_expr(base_cond) { $1 } base_cond__open(x): - base_expr(x) | conditional(expr_with_let_expr) { + base_expr(x) | conditional(expr_with_let_expr) { wild_error $1; $1 } @@ -460,11 +460,11 @@ fun_expr: let region = cover start stop in let rec arg_to_pattern = function - EVar v -> + EVar v -> if v.value = "_" then PWild v.region else ( - Scoping.check_reserved_name v; + Scoping.check_reserved_name v; PVar v ) | EAnnot {region; value = {inside = EVar v, colon, typ; _}} -> @@ -895,7 +895,7 @@ path: | projection { Path $1 } update_record: - "{""..."path "," sep_or_term_list(field_path_assignment,",") "}" { + "{" "..." path "," sep_or_term_list(field_path_assignment,",") "}" { let region = cover $1 $6 in let ne_elements, terminator = $5 in let value = { @@ -913,7 +913,7 @@ expr_with_let_expr: expr { $1 } | let_expr(expr_with_let_expr) { $1 } -more_field_assignments: +more_field_assignments: "," sep_or_term_list(field_assignment_punning,",") { let elts, _region = $2 in $1, elts @@ -926,9 +926,9 @@ sequence_or_record_in: PaSequence {s_elts = elts; s_terminator=None} } | field_assignment more_field_assignments? { - match $2 with - | Some (comma, elts) -> - let r_elts = Utils.nsepseq_cons $1 comma elts in + match $2 with + | Some (comma, elts) -> + let r_elts = Utils.nsepseq_cons $1 comma elts in PaRecord {r_elts; r_terminator = None} | None -> PaRecord {r_elts = ($1, []); r_terminator = None} @@ -961,15 +961,15 @@ sequence_or_record: terminator = r.r_terminator} in ERecord {region; value}} -field_assignment_punning: - (* This can only happen with multiple fields - +field_assignment_punning: + (* This can only happen with multiple fields - one item punning does NOT work in ReasonML *) - field_name { + field_name { let value = { field_name = $1; assignment = ghost; field_expr = EVar $1 } - in + in {$1 with value} } | field_assignment { diff --git a/src/passes/1-parser/reasonligo/ParserMain.ml b/src/passes/1-parser/reasonligo/ParserMain.ml index 82ffc7b32..1c173bee0 100644 --- a/src/passes/1-parser/reasonligo/ParserMain.ml +++ b/src/passes/1-parser/reasonligo/ParserMain.ml @@ -5,7 +5,10 @@ module SSet = Set.Make (String) module IO = struct - let options = EvalOpt.(read ~lang:`ReasonLIGO ~ext:".religo") + let options = + let open EvalOpt in + let block = mk_block ~opening:"/*" ~closing:"*/" + in read ~block ~line:"//" ".religo" end module SubIO = @@ -14,7 +17,8 @@ module SubIO = libs : string list; verbose : SSet.t; offsets : bool; - lang : EvalOpt.language; + block : EvalOpt.block_comment option; + line : EvalOpt.line_comment option; ext : string; mode : [`Byte | `Point]; cmd : EvalOpt.command; @@ -26,7 +30,8 @@ module SubIO = method libs = IO.options#libs method verbose = IO.options#verbose method offsets = IO.options#offsets - method lang = IO.options#lang + method block = IO.options#block + method line = IO.options#line method ext = IO.options#ext method mode = IO.options#mode method cmd = IO.options#cmd @@ -37,7 +42,8 @@ module SubIO = EvalOpt.make ~libs:options#libs ~verbose:options#verbose ~offsets:options#offsets - ~lang:options#lang + ?block:options#block + ?line:options#line ~ext:options#ext ~mode:options#mode ~cmd:options#cmd diff --git a/src/passes/1-parser/shared/.links b/src/passes/1-parser/shared/.links deleted file mode 100644 index df8a82cd9..000000000 --- a/src/passes/1-parser/shared/.links +++ /dev/null @@ -1,7 +0,0 @@ -$HOME/git/OCaml-build/Makefile -$HOME/git/OCaml-build/Makefile.cfg - -$HOME/git/ligo/vendors/ligo-utils/simple-utils/pos.mli -$HOME/git/ligo/vendors/ligo-utils/simple-utils/pos.ml -$HOME/git/ligo/vendors/ligo-utils/simple-utils/region.mli -$HOME/git/ligo/vendors/ligo-utils/simple-utils/region.ml diff --git a/src/passes/1-parser/shared/EvalOpt.ml b/src/passes/1-parser/shared/EvalOpt.ml index 54d971846..8cb22608d 100644 --- a/src/passes/1-parser/shared/EvalOpt.ml +++ b/src/passes/1-parser/shared/EvalOpt.ml @@ -5,37 +5,42 @@ type command = Quiet | Copy | Units | Tokens -type language = [`PascaLIGO | `CameLIGO | `ReasonLIGO] - -let lang_to_string = function - `PascaLIGO -> "PascaLIGO" -| `CameLIGO -> "CameLIGO" -| `ReasonLIGO -> "ReasonLIGO" - (* The type [options] gathers the command-line options. *) module SSet = Set.Make (String) +type line_comment = string (* Opening of a line comment *) +type block_comment = + +let mk_block ~opening ~closing : block_comment = + object + method opening = opening + method closing = closing + end + type options = < input : string option; libs : string list; verbose : SSet.t; offsets : bool; - lang : language; - ext : string; (* ".ligo", ".mligo", ".religo" *) + block : block_comment option; + line : line_comment option; + ext : string; mode : [`Byte | `Point]; cmd : command; mono : bool; expr : bool > -let make ~input ~libs ~verbose ~offsets ~lang ~ext ~mode ~cmd ~mono ~expr : options = +let make ~input ~libs ~verbose ~offsets ?block + ?line ~ext ~mode ~cmd ~mono ~expr : options = object method input = input method libs = libs method verbose = verbose method offsets = offsets - method lang = lang + method block = block + method line = line method ext = ext method mode = mode method cmd = cmd @@ -58,10 +63,10 @@ let abort msg = (* Help *) -let help language extension () = +let help extension () = let file = Filename.basename Sys.argv.(0) in printf "Usage: %s [