Merge commit '4977c18e' into bugfix/new-typer

This commit is contained in:
Suzanne Dupéron 2020-01-23 11:55:50 +01:00
commit 1592404e03
124 changed files with 3660 additions and 2148 deletions

View File

@ -50,8 +50,7 @@ let main (parameter, store: parameter * store) : operation list * store =
```reasonligo group=a ```reasonligo group=a
type parameter = unit; type parameter = unit;
type store = unit; type store = unit;
let main = (parameter_store: (parameter, store)) : (list(operation), store) => { let main = ((parameter, store): (parameter, store)) : (list(operation), store) => {
let parameter, store = parameter_store;
(([]: list(operation)), store); (([]: list(operation)), store);
}; };
``` ```
@ -93,7 +92,7 @@ let main (p, s: unit * unit) : operation list * unit =
<!--ReasonLIGO--> <!--ReasonLIGO-->
```reasonligo group=b ```reasonligo group=b
let main = (p_s: (unit, unit)) : (list(operation), unit) => { let main = ((p,s): (unit, unit)) : (list(operation), unit) => {
if (amount > 0mutez) { if (amount > 0mutez) {
(failwith("This contract does not accept tez"): (list(operation), unit)); (failwith("This contract does not accept tez"): (list(operation), unit));
} }
@ -131,7 +130,7 @@ let main (p,s: unit * unit) : operation list * unit =
<!--ReasonLIGO--> <!--ReasonLIGO-->
```reasonligo group=c ```reasonligo group=c
let owner: address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address); let owner: address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address);
let main = (p_s: (unit, unit)) : (list(operation), unit) => { let main = ((p,s): (unit, unit)) : (list(operation), unit) => {
if (source != owner) { if (source != owner) {
(failwith("This address can't call the contract"): (list(operation), unit)); (failwith("This address can't call the contract"): (list(operation), unit));
} }
@ -230,10 +229,10 @@ type action =
let dest: address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3": address); let dest: address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3": address);
let proxy = (param_s: (action, unit)): (list(operation), unit) => let proxy = ((param, s): (action, unit)): (list(operation), unit) =>
let counter: contract(action) = Operation.get_contract(dest); let counter: contract(action) = Operation.get_contract(dest);
let op: operation = Operation.transaction(param_s[0], 0mutez, counter); let op: operation = Operation.transaction(param, 0mutez, counter);
([op], param_s[1]); ([op], s);
``` ```
<!--END_DOCUSAURUS_CODE_TABS--> <!--END_DOCUSAURUS_CODE_TABS-->

View File

@ -107,8 +107,7 @@ type action =
| Decrement(int) | Decrement(int)
| Reset(unit); | Reset(unit);
let main = (p_s: (action, int)) : (list(operation), int) => { let main = ((p,s): (action, int)) : (list(operation), int) => {
let p, s = p_s;
let result = let result =
switch (p) { switch (p) {
| Increment(n) => s + n | Increment(n) => s + n

View File

@ -74,7 +74,7 @@ Currying is however *not* the preferred way to pass function arguments in CameLI
While this approach is faithful to the original OCaml, it's costlier in Michelson While this approach is faithful to the original OCaml, it's costlier in Michelson
than naive function execution accepting multiple arguments. Instead for most than naive function execution accepting multiple arguments. Instead for most
functions with more than one parameter we should place the arguments in a functions with more than one parameter we should place the arguments in a
[tuple](language-basics/sets-lists-touples.md) and pass the tuple in as a single [tuple](language-basics/sets-lists-tuples.md) and pass the tuple in as a single
parameter. parameter.
Here's how you define a basic function that accepts two `ints` and returns an `int` as well: Here's how you define a basic function that accepts two `ints` and returns an `int` as well:
@ -99,7 +99,7 @@ along with a return type.
Here's how you define a basic function that accepts two `ints` and returns an `int` as well: Here's how you define a basic function that accepts two `ints` and returns an `int` as well:
```reasonligo group=b ```reasonligo group=b
let add = (a: int, b: int) : int => a + b; let add = ((a,b): (int, int)) : int => a + b;
``` ```
The function body is a series of expressions, which are evaluated to give the return The function body is a series of expressions, which are evaluated to give the return

View File

@ -182,14 +182,14 @@ function iter_op (const m : moveset) : unit is
<!--CameLIGO--> <!--CameLIGO-->
```cameligo ```cameligo
let iter_op (m : moveset) : unit = let iter_op (m : moveset) : unit =
let assert_eq = fun (i: address * move) -> assert (i.1.0 > 1) let assert_eq = fun (i,j: address * move) -> assert (j.0 > 1)
in Map.iter assert_eq m in Map.iter assert_eq m
``` ```
<!--ReasonLIGO--> <!--ReasonLIGO-->
```reasonligo ```reasonligo
let iter_op = (m: moveset): unit => { let iter_op = (m: moveset): unit => {
let assert_eq = (i: (address, move)) => assert(i[1][0] > 1); let assert_eq = ((i,j): (address, move)) => assert(j[0] > 1);
Map.iter(assert_eq, m); Map.iter(assert_eq, m);
}; };
``` ```
@ -209,14 +209,14 @@ function map_op (const m : moveset) : moveset is
<!--CameLIGO--> <!--CameLIGO-->
```cameligo ```cameligo
let map_op (m : moveset) : moveset = let map_op (m : moveset) : moveset =
let increment = fun (i: address * move) -> (i.1.0, i.1.1 + 1) let increment = fun (i,j: address * move) -> (j.0, j.1 + 1)
in Map.map increment m in Map.map increment m
``` ```
<!--ReasonLIGO--> <!--ReasonLIGO-->
```reasonligo ```reasonligo
let map_op = (m: moveset): moveset => { let map_op = (m: moveset): moveset => {
let increment = (i: (address, move)) => (i[1][0], i[1][1] + 1); let increment = ((i,j): (address, move)) => (j[0], j[1] + 1);
Map.map(increment, m); Map.map(increment, m);
}; };
``` ```
@ -243,14 +243,14 @@ function fold_op (const m : moveset) : int is
<!--CameLIGO--> <!--CameLIGO-->
```cameligo ```cameligo
let fold_op (m : moveset) : moveset = let fold_op (m : moveset) : moveset =
let aggregate = fun (i: int * (address * (int * int))) -> i.0 + i.1.1.1 in let aggregate = fun (i,j: int * (address * (int * int))) -> i + j.1.1 in
Map.fold aggregate m 5 Map.fold aggregate m 5
``` ```
<!--ReasonLIGO--> <!--ReasonLIGO-->
```reasonligo ```reasonligo
let fold_op = (m: moveset): moveset => { let fold_op = (m: moveset): moveset => {
let aggregate = (i: (int, (address, (int,int)))) => i[0] + i[1][1][1]; let aggregate = ((i,j): (int, (address, (int,int)))) => i + j[1][1];
Map.fold(aggregate, m, 5); Map.fold(aggregate, m, 5);
}; };

View File

@ -1,5 +1,5 @@
--- ---
id: sets-lists-touples id: sets-lists-tuples
title: Sets, Lists, Tuples title: Sets, Lists, Tuples
--- ---
@ -257,7 +257,7 @@ let sum_of_a_list: int = List.fold sum my_list 0
<!--ReasonLIGO--> <!--ReasonLIGO-->
```reasonligo group=b ```reasonligo group=b
let sum = (result_i: (int, int)): int => result_i[0] + result_i[1]; let sum = ((result, i): (int, int)): int => result + i;
(* Outputs 6 *) (* Outputs 6 *)
let sum_of_a_list: int = List.fold(sum, my_list, 0); let sum_of_a_list: int = List.fold(sum, my_list, 0);
``` ```

View File

@ -0,0 +1,144 @@
---
id: tezos-specific
title: Tezos Domain-Specific Operations
---
LIGO is a language for writing Tezos smart contracts. It would be a little odd if
it didn't have any Tezos specific functions. This page will tell you about them.
## Pack and Unpack
Michelson provides the `PACK` and `UNPACK` instructions for data serialization.
`PACK` converts Michelson data structures to a binary format, and `UNPACK`
reverses it. This functionality can be accessed from within LIGO.
> ⚠️ `PACK` and `UNPACK` are features of Michelson that are intended to be used by people that really know what they're doing. There are several failure cases (such as `UNPACK`ing a lambda from an untrusted source), most of which are beyond the scope of this document. Don't use these functions without doing your homework first.
<!--DOCUSAURUS_CODE_TABS-->
<!--PascaLIGO-->
```pascaligo
function id_string (const p : string) : option(string) is block {
const packed : bytes = bytes_pack(p) ;
} with (bytes_unpack(packed): option(string))
```
<!--CameLIGO-->
```cameligo
let id_string (p: string) : string option =
let packed: bytes = Bytes.pack p in
((Bytes.unpack packed): string option)
```
<!--ReasonLIGO-->
```reasonligo
let id_string = (p: string) : option(string) => {
let packed : bytes = Bytes.pack(p);
((Bytes.unpack(packed)): option(string));
};
```
<!--END_DOCUSAURUS_CODE_TABS-->
## Hashing Keys
It's often desirable to hash a public key. In Michelson, certain data structures
such as maps will not allow the use of the `key` type. Even if this weren't the case
hashes are much smaller than keys, and storage on blockchains comes at a cost premium.
You can hash keys with the `key_hash` type and associated built in function.
<!--DOCUSAURUS_CODE_TABS-->
<!--PascaLIGO-->
```pascaligo
function check_hash_key (const kh1 : key_hash; const k2 : key) : bool * key_hash is block {
var ret : bool := False ;
var kh2 : key_hash := crypto_hash_key(k2) ;
if kh1 = kh2 then ret := True else skip;
} with (ret, kh2)
```
<!--CameLIGO-->
```cameligo
let check_hash_key (kh1, k2: key_hash * key) : bool * key_hash =
let kh2 : key_hash = Crypto.hash_key k2 in
if kh1 = kh2
then (true, kh2)
else (false, kh2)
```
<!--ReasonLIGO-->
```reasonligo
let check_hash_key = ((kh1, k2): (key_hash, key)) : (bool, key_hash) => {
let kh2 : key_hash = Crypto.hash_key(k2);
if (kh1 == kh2) {
(true, kh2);
}
else {
(false, kh2);
}
};
```
<!--END_DOCUSAURUS_CODE_TABS-->
## Checking Signatures
Sometimes a contract will want to check that a message has been signed by a
particular key. For example, a point-of-sale system might want a customer to
sign a transaction so it can be processed asynchronously. You can do this in LIGO
using the `key` and `signature` types.
> ⚠️ There is no way to *generate* a signed message in LIGO. This is because that would require storing a private key on chain, at which point it isn't very private anymore.
<!--DOCUSAURUS_CODE_TABS-->
<!--PascaLIGO-->
```pascaligo
function check_signature
(const pk: key;
const signed: signature;
const msg: bytes) : bool
is crypto_check(pk, signed, msg)
```
<!--CameLIGO-->
```cameligo
let check_signature (pk, signed, msg: key * signature * bytes) : bool =
Crypto.check pk signed msg
```
<!--ReasonLIGO-->
```reasonligo
let check_signature = ((pk, signed, msg): (key, signature, bytes)) : bool => {
Crypto.check(pk, signed, msg);
};
```
<!--END_DOCUSAURUS_CODE_TABS-->
## Getting The Contract's Own Address
Often you want to get the address of the contract being executed. You can do it with
`self_address`.
> ⚠️ Due to limitations in Michelson, self_address in a contract is only allowed at the entry-point level. Using it in a utility function will cause an error.
<!--DOCUSAURUS_CODE_TABS-->
<!--PascaLIGO-->
```pascaligo
const current_addr : address = self_address;
```
<!--CameLIGO-->
```cameligo
let current_addr : address = Current.self_address
```
<!--ReasonLIGO-->
```reasonligo
let current_addr : address = Current.self_address;
```
<!--END_DOCUSAURUS_CODE_TABS-->

View File

@ -108,7 +108,7 @@ with a new value being bound in place of the old one.
```reasonligo ```reasonligo
let add = (a: int, b: int): int => { let add = ((a,b): (int, int)): int => {
let c: int = a + b; let c: int = a + b;
c; c;
}; };

View File

@ -24,51 +24,48 @@ ${pre}`;
const CAMELIGO_EXAMPLE = `${pre}ocaml const CAMELIGO_EXAMPLE = `${pre}ocaml
type storage = int type storage = int
(* variant defining pseudo multi-entrypoint (* variant defining pseudo multi-entrypoint actions *)
actions *)
type action = type action =
| Increment of int | Increment of int
| Decrement of int | Decrement of int
let add (a: int) (b: int): int = a + b let add (a,b: int * int) : int = a + b
let sub (a,b: int * int) : int = a - b
let subtract (a: int) (b: int): int = a - b (* real entrypoint that re-routes the flow based on the action provided *)
(* real entrypoint that re-routes the flow let main (p,s: action * storage) =
based on the action provided *)
let%entry main(p : action) storage =
let storage = let storage =
match p with match p with
| Increment n -> add storage n | Increment n -> add (s, n)
| Decrement n -> subtract storage n | Decrement n -> sub (s, n)
in (([] : operation list), storage) in ([] : operation list), storage
${pre}`; ${pre}`;
const REASONLIGO_EXAMPLE = `${pre}reasonligo const REASONLIGO_EXAMPLE = `${pre}reasonligo
type storage = int; type storage = int;
/* variant defining pseudo multi-entrypoint /* variant defining pseudo multi-entrypoint actions */
actions */
type action = type action =
| Increment(int) | Increment(int)
| Decrement(int); | Decrement(int);
let add = (a: int, b: int): int => a + b; let add = ((a,b): (int, int)): int => a + b;
let sub = ((a,b): (int, int)): int => a - b;
let subtract = (a: int, b: int): int => a - b; /* real entrypoint that re-routes the flow based on the action provided */
/* real entrypoint that re-routes the flow let main = ((p,storage): (action, storage)) => {
based on the action provided */
let main = (p: action, storage) => {
let storage = let storage =
switch (p) { switch (p) {
| Increment(n) => add(storage, n) | Increment(n) => add((storage, n))
| Decrement(n) => subtract(storage, n) | Decrement(n) => sub((storage, n))
}; };
([]: list(operation), storage); ([]: list(operation), storage);
}; };
${pre}`; ${pre}`;

View File

@ -11,7 +11,8 @@
"language-basics/loops", "language-basics/loops",
"language-basics/unit-option-pattern-matching", "language-basics/unit-option-pattern-matching",
"language-basics/maps-records", "language-basics/maps-records",
"language-basics/sets-lists-touples" "language-basics/sets-lists-tuples",
"language-basics/tezos-specific"
], ],
"Advanced": [ "Advanced": [
"advanced/timestamps-addresses", "advanced/timestamps-addresses",

View File

@ -138,6 +138,57 @@ let compile_file =
let doc = "Subcommand: compile a contract." in let doc = "Subcommand: compile a contract." in
(Term.ret term , Term.info ~doc cmdname) (Term.ret term , Term.info ~doc cmdname)
let print_cst =
let f source_file syntax display_format = (
toplevel ~display_format @@
let%bind pp = Compile.Of_source.pretty_print source_file (Syntax_name syntax) in
ok @@ Format.asprintf "%s \n" (Buffer.contents pp)
)
in
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
let cmdname = "print-cst" in
let doc = "Subcommand: print the cst. Warning: intended for development of LIGO and can break at any time." in
(Term.ret term, Term.info ~doc cmdname)
let print_ast =
let f source_file syntax display_format = (
toplevel ~display_format @@
let%bind simplified = Compile.Of_source.compile source_file (Syntax_name syntax) in
ok @@ Format.asprintf "%a\n" Compile.Of_simplified.pretty_print simplified
)
in
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
let cmdname = "print-ast" in
let doc = "Subcommand: print the ast. Warning: intended for development of LIGO and can break at any time." in
(Term.ret term, Term.info ~doc cmdname)
let print_typed_ast =
let f source_file syntax display_format = (
toplevel ~display_format @@
let%bind simplified = Compile.Of_source.compile source_file (Syntax_name syntax) in
let%bind typed,_ = Compile.Of_simplified.compile simplified in
ok @@ Format.asprintf "%a\n" Compile.Of_typed.pretty_print typed
)
in
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
let cmdname = "print-typed-ast" in
let doc = "Subcommand: print the typed ast. Warning: intended for development of LIGO and can break at any time." in
(Term.ret term, Term.info ~doc cmdname)
let print_mini_c =
let f source_file syntax display_format = (
toplevel ~display_format @@
let%bind simplified = Compile.Of_source.compile source_file (Syntax_name syntax) in
let%bind typed,_ = Compile.Of_simplified.compile simplified in
let%bind mini_c = Compile.Of_typed.compile typed in
ok @@ Format.asprintf "%a\n" Compile.Of_mini_c.pretty_print mini_c
)
in
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
let cmdname = "print-mini-c" in
let doc = "Subcommand: print mini c. Warning: intended for development of LIGO and can break at any time." in
(Term.ret term, Term.info ~doc cmdname)
let measure_contract = let measure_contract =
let f source_file entry_point syntax display_format = let f source_file entry_point syntax display_format =
toplevel ~display_format @@ toplevel ~display_format @@
@ -371,4 +422,8 @@ let run ?argv () =
run_function ; run_function ;
evaluate_value ; evaluate_value ;
dump_changelog ; dump_changelog ;
print_cst ;
print_ast ;
print_typed_ast ;
print_mini_c
] ]

View File

@ -2,6 +2,8 @@ open Cli_expect
let contract basename = let contract basename =
"../../test/contracts/" ^ basename "../../test/contracts/" ^ basename
let bad_contract basename =
"../../test/contracts/negative/" ^ basename
let%expect_test _ = let%expect_test _ =
run_ligo_good [ "measure-contract" ; contract "coase.ligo" ; "main" ] ; run_ligo_good [ "measure-contract" ; contract "coase.ligo" ; "main" ] ;
@ -1024,3 +1026,15 @@ let%expect_test _ =
[%expect {| [%expect {|
failwith("This contract always fails") |}] failwith("This contract always fails") |}]
let%expect_test _ =
run_ligo_bad [ "compile-contract" ; bad_contract "self_in_lambda.mligo" ; "main" ] ;
[%expect {|
ligo: Wrong SELF_ADDRESS location: SELF_ADDRESS is only allowed at top-level
If you're not sure how to fix this error, you can
do one of the following:
* Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
* 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' |}]

View File

@ -47,6 +47,22 @@ let%expect_test _ =
measure-contract measure-contract
Subcommand: measure a contract's compiled size in bytes. Subcommand: measure a contract's compiled size in bytes.
print-ast
Subcommand: print the ast. Warning: intended for development of
LIGO and can break at any time.
print-cst
Subcommand: print the cst. Warning: intended for development of
LIGO and can break at any time.
print-mini-c
Subcommand: print mini c. Warning: intended for development of
LIGO and can break at any time.
print-typed-ast
Subcommand: print the typed ast. Warning: intended for development
of LIGO and can break at any time.
run-function run-function
Subcommand: run a function with the given parameter. Subcommand: run a function with the given parameter.
@ -104,6 +120,22 @@ let%expect_test _ =
measure-contract measure-contract
Subcommand: measure a contract's compiled size in bytes. Subcommand: measure a contract's compiled size in bytes.
print-ast
Subcommand: print the ast. Warning: intended for development of
LIGO and can break at any time.
print-cst
Subcommand: print the cst. Warning: intended for development of
LIGO and can break at any time.
print-mini-c
Subcommand: print mini c. Warning: intended for development of
LIGO and can break at any time.
print-typed-ast
Subcommand: print the typed ast. Warning: intended for development
of LIGO and can break at any time.
run-function run-function
Subcommand: run a function with the given parameter. Subcommand: run a function with the given parameter.

View File

@ -99,9 +99,9 @@ ligo: lexer error: Negative byte sequence.
run_ligo_bad [ "compile-contract" ; "../../test/lexer/reserved_name.ligo" ; "main" ] ; run_ligo_bad [ "compile-contract" ; "../../test/lexer/reserved_name.ligo" ; "main" ] ;
[%expect {| [%expect {|
ligo: lexer error: Reserved name: args. ligo: lexer error: Reserved name: arguments.
Hint: Change the name. Hint: Change the name.
{"parser_loc":"in file \"reserved_name.ligo\", line 1, characters 4-8"} {"parser_loc":"in file \"reserved_name.ligo\", line 1, characters 4-13"}
If you're not sure how to fix this error, you can If you're not sure how to fix this error, you can

View File

@ -133,3 +133,41 @@ let parsify_string = fun (syntax : v_syntax) source_filename ->
let%bind parsified = parsify source_filename in let%bind parsified = parsify source_filename in
let%bind applied = Self_ast_simplified.all_program parsified in let%bind applied = Self_ast_simplified.all_program parsified in
ok applied ok applied
let pretty_print_pascaligo = fun source ->
let%bind ast = Parser.Pascaligo.parse_file source in
let buffer = Buffer.create 59 in
let state = Parser_pascaligo.ParserLog.mk_state
~offsets:true
~mode:`Byte
~buffer in
Parser_pascaligo.ParserLog.pp_ast state ast;
ok buffer
let pretty_print_cameligo = fun source ->
let%bind ast = Parser.Cameligo.parse_file source in
let buffer = Buffer.create 59 in
let state = Parser_cameligo.ParserLog.mk_state
~offsets:true
~mode:`Byte
~buffer in
Parser.Cameligo.ParserLog.pp_ast state ast;
ok buffer
let pretty_print_reasonligo = fun source ->
let%bind ast = Parser.Reasonligo.parse_file source in
let buffer = Buffer.create 59 in
let state = Parser.Reasonligo.ParserLog.mk_state
~offsets:true
~mode:`Byte
~buffer in
Parser.Reasonligo.ParserLog.pp_ast state ast;
ok buffer
let pretty_print = fun syntax source_filename ->
let%bind v_syntax = syntax_to_variant syntax (Some source_filename) in
(match v_syntax with
| Pascaligo -> pretty_print_pascaligo
| Cameligo -> pretty_print_cameligo
| ReasonLIGO -> pretty_print_reasonligo)
source_filename

View File

@ -5,10 +5,9 @@ open Trace
module Errors = struct module Errors = struct
(* (*
TODO: those errors should have been caught in the earlier stages on the ligo pipeline TODO: those errors should have been caught in the earlier stages on the ligo pipeline
Here, in case of contract not typechecking, we should write a warning with a "please report" build_contract is a kind of security net
on stderr and print the ill-typed michelson code;
*) *)
let title_type_check_msg () = "Invalid contract (This might be a compiler bug, please report) " let title_type_check_msg () = "generated Michelson contract failed to typecheck"
let bad_parameter c () = let bad_parameter c () =
let message () = let message () =
let code = Format.asprintf "%a" Michelson.pp c in let code = Format.asprintf "%a" Michelson.pp c in
@ -22,7 +21,7 @@ module Errors = struct
let bad_contract c () = let bad_contract c () =
let message () = let message () =
let code = Format.asprintf "%a" Michelson.pp c in let code = Format.asprintf "%a" Michelson.pp c in
"bad contract type (contract entry point is expected to be of the form \"parameter * storage -> list(operation) * storage\"):\n"^code in "bad contract type\n"^code in
error title_type_check_msg message error title_type_check_msg message
let unknown () = let unknown () =
let message () = let message () =

View File

@ -3,6 +3,7 @@ open Proto_alpha_utils
open Trace open Trace
let compile_contract : expression -> Compiler.compiled_expression result = fun e -> let compile_contract : expression -> Compiler.compiled_expression result = fun e ->
let%bind e = Self_mini_c.contract_check e in
let%bind (input_ty , _) = get_t_function e.type_value in let%bind (input_ty , _) = get_t_function e.type_value in
let%bind body = get_function e in let%bind body = get_function e in
let%bind body = Compiler.Program.translate_function_body body [] input_ty in let%bind body = Compiler.Program.translate_function_body body [] input_ty in
@ -30,3 +31,6 @@ let aggregate_and_compile_contract = fun (program : Types.program) name ->
let aggregate_and_compile_expression = fun program exp -> let aggregate_and_compile_expression = fun program exp ->
aggregate_and_compile program (ExpressionForm exp) aggregate_and_compile program (ExpressionForm exp)
let pretty_print program =
Mini_c.PP.program program

View File

@ -19,3 +19,6 @@ let apply (entry_point : string) (param : Ast_simplified.expression) : Ast_simpl
{ expression = Ast_simplified.E_application (entry_point_var, param) ; { expression = Ast_simplified.E_application (entry_point_var, param) ;
location = Virtual "generated application" } in location = Virtual "generated application" } in
ok applied ok applied
let pretty_print formatter (program : Ast_simplified.program) =
Ast_simplified.PP.program formatter program

View File

@ -18,3 +18,6 @@ let compile_contract_input : string -> string -> v_syntax -> Ast_simplified.expr
fun storage parameter syntax -> fun storage parameter syntax ->
let%bind (storage,parameter) = bind_map_pair (compile_expression syntax) (storage,parameter) in let%bind (storage,parameter) = bind_map_pair (compile_expression syntax) (storage,parameter) in
ok @@ Ast_simplified.e_pair storage parameter ok @@ Ast_simplified.e_pair storage parameter
let pretty_print source_filename syntax =
Helpers.pretty_print syntax source_filename

View File

@ -22,3 +22,6 @@ let assert_equal_contract_type : check_type -> string -> Ast_typed.program -> As
| _ -> dummy_fail | _ -> dummy_fail
) )
| _ -> dummy_fail ) | _ -> dummy_fail )
let pretty_print ppf program =
Ast_typed.PP.program ppf program

View File

@ -18,7 +18,7 @@ module Errors = struct
] in ] in
error ~data title message error ~data title message
let parser_error source (start: Lexing.position) (end_: Lexing.position) lexbuf = let parser_error source (start: Lexing.position) (stop: Lexing.position) lexbuf =
let title () = "parser error" in let title () = "parser error" in
let file = if source = "" then let file = if source = "" then
"" ""
@ -29,18 +29,18 @@ module Errors = struct
"Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n" "Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n"
(Lexing.lexeme lexbuf) (Lexing.lexeme lexbuf)
start.pos_lnum (start.pos_cnum - start.pos_bol) start.pos_lnum (start.pos_cnum - start.pos_bol)
end_.pos_lnum (end_.pos_cnum - end_.pos_bol) stop.pos_lnum (stop.pos_cnum - stop.pos_bol)
file file
in in
let message () = str in let message () = str in
let loc = if start.pos_cnum = -1 then let loc = if start.pos_cnum = -1 then
Region.make Region.make
~start: Pos.min ~start:(Pos.min ~file:source)
~stop:(Pos.from_byte end_) ~stop:(Pos.from_byte stop)
else else
Region.make Region.make
~start:(Pos.from_byte start) ~start:(Pos.from_byte start)
~stop:(Pos.from_byte end_) ~stop:(Pos.from_byte stop)
in in
let data = let data =
[ [
@ -51,7 +51,7 @@ module Errors = struct
in in
error ~data title message error ~data title message
let unrecognized_error source (start: Lexing.position) (end_: Lexing.position) lexbuf = let unrecognized_error source (start: Lexing.position) (stop: Lexing.position) lexbuf =
let title () = "unrecognized error" in let title () = "unrecognized error" in
let file = if source = "" then let file = if source = "" then
"" ""
@ -62,13 +62,13 @@ module Errors = struct
"Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n" "Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n"
(Lexing.lexeme lexbuf) (Lexing.lexeme lexbuf)
start.pos_lnum (start.pos_cnum - start.pos_bol) start.pos_lnum (start.pos_cnum - start.pos_bol)
end_.pos_lnum (end_.pos_cnum - end_.pos_bol) stop.pos_lnum (stop.pos_cnum - stop.pos_bol)
file file
in in
let message () = str in let message () = str in
let loc = Region.make let loc = Region.make
~start:(Pos.from_byte start) ~start:(Pos.from_byte start)
~stop:(Pos.from_byte end_) ~stop:(Pos.from_byte stop)
in in
let data = [ let data = [
("unrecognized_loc", ("unrecognized_loc",
@ -91,15 +91,15 @@ let parse (parser: 'a parser) source lexbuf =
with with
| Parser.Error -> | Parser.Error ->
let start = Lexing.lexeme_start_p lexbuf in let start = Lexing.lexeme_start_p lexbuf in
let end_ = Lexing.lexeme_end_p lexbuf in let stop = Lexing.lexeme_end_p lexbuf in
fail @@ (parser_error source start end_ lexbuf) fail @@ (parser_error source start stop lexbuf)
| Lexer.Error e -> | Lexer.Error e ->
fail @@ (lexer_error e) fail @@ (lexer_error e)
| _ -> | _ ->
let _ = Printexc.print_backtrace Pervasives.stdout in let _ = Printexc.print_backtrace Pervasives.stdout in
let start = Lexing.lexeme_start_p lexbuf in let start = Lexing.lexeme_start_p lexbuf in
let end_ = Lexing.lexeme_end_p lexbuf in let stop = Lexing.lexeme_end_p lexbuf in
fail @@ (unrecognized_error source start end_ lexbuf) fail @@ (unrecognized_error source start stop lexbuf)
in in
close (); close ();
result result
@ -122,8 +122,8 @@ let parse_file (source: string) : AST.t result =
let parse_string (s:string) : AST.t result = let parse_string (s:string) : AST.t result =
let lexbuf = Lexing.from_string s in let lexbuf = Lexing.from_string s in
parse (Parser.contract) "" lexbuf parse Parser.contract "" lexbuf
let parse_expression (s:string) : AST.expr result = let parse_expression (s:string) : AST.expr result =
let lexbuf = Lexing.from_string s in let lexbuf = Lexing.from_string s in
parse (Parser.interactive_expr) "" lexbuf parse Parser.interactive_expr "" lexbuf

View File

@ -1,5 +1,4 @@
$HOME/git/OCaml-build/Makefile $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.mli
$HOME/git/ligo/vendors/ligo-utils/simple-utils/pos.ml $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.mli

View File

@ -21,15 +21,6 @@ open Utils
type 'a reg = 'a Region.reg type 'a reg = 'a Region.reg
let rec last to_region = function
[] -> Region.ghost
| [x] -> to_region x
| _::t -> last to_region t
let nsepseq_to_region to_region (hd,tl) =
let reg (_, item) = to_region item in
Region.cover (to_region hd) (last reg tl)
(* Keywords of OCaml *) (* Keywords of OCaml *)
type keyword = Region.t type keyword = Region.t
@ -321,6 +312,7 @@ and comp_expr =
| Neq of neq bin_op reg | Neq of neq bin_op reg
and record = field_assign reg ne_injection and record = field_assign reg ne_injection
and projection = { and projection = {
struct_name : variable; struct_name : variable;
selector : dot; selector : dot;
@ -344,6 +336,7 @@ and update = {
updates : record reg; updates : record reg;
rbrace : rbrace; rbrace : rbrace;
} }
and path = and path =
Name of variable Name of variable
| Path of projection reg | Path of projection reg
@ -387,7 +380,16 @@ and cond_expr = {
ifnot : expr ifnot : expr
} }
(* Projecting regions of the input source code *) (* Projecting regions from some nodes of the AST *)
let rec last to_region = function
[] -> Region.ghost
| [x] -> to_region x
| _::t -> last to_region t
let nsepseq_to_region to_region (hd,tl) =
let reg (_, item) = to_region item in
Region.cover (to_region hd) (last reg tl)
let type_expr_to_region = function let type_expr_to_region = function
TProd {region; _} TProd {region; _}

View File

@ -85,7 +85,7 @@ type t =
| Mutez of (string * Z.t) Region.reg | Mutez of (string * Z.t) Region.reg
| String of string Region.reg | String of string Region.reg
| Bytes of (string * Hex.t) Region.reg | Bytes of (string * Hex.t) Region.reg
| Attr2 of string Region.reg | Attr of string Region.reg
(* Keywords *) (* Keywords *)
@ -150,8 +150,7 @@ val mk_kwd : lexeme -> Region.t -> (token, kwd_err) result
val mk_string : lexeme -> Region.t -> token val mk_string : lexeme -> Region.t -> token
val mk_bytes : lexeme -> Region.t -> token val mk_bytes : lexeme -> Region.t -> token
val mk_constr : lexeme -> Region.t -> token val mk_constr : lexeme -> Region.t -> token
val mk_attr : lexeme -> Region.t -> (token, attr_err) result val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
val mk_attr2 : lexeme -> Region.t -> (token, attr_err) result
val eof : Region.t -> token val eof : Region.t -> token
(* Predicates *) (* Predicates *)

View File

@ -69,7 +69,7 @@ type t =
| Mutez of (string * Z.t) Region.reg | Mutez of (string * Z.t) Region.reg
| String of string Region.reg | String of string Region.reg
| Bytes of (string * Hex.t) Region.reg | Bytes of (string * Hex.t) Region.reg
| Attr2 of string Region.reg | Attr of string Region.reg
(* Keywords *) (* Keywords *)
@ -147,6 +147,8 @@ let proj_token = function
region, region,
sprintf "Bytes (\"%s\", \"0x%s\")" sprintf "Bytes (\"%s\", \"0x%s\")"
s (Hex.show b) s (Hex.show b)
| Attr Region.{region; value} ->
region, sprintf "Attr \"%s\"" value
| Begin region -> region, "Begin" | Begin region -> region, "Begin"
| Else region -> region, "Else" | Else region -> region, "Else"
| End region -> region, "End" | End region -> region, "End"
@ -166,7 +168,6 @@ let proj_token = function
| With region -> region, "With" | With region -> region, "With"
| C_None region -> region, "C_None" | C_None region -> region, "C_None"
| C_Some region -> region, "C_Some" | C_Some region -> region, "C_Some"
| Attr2 Region.{region; value} -> region, sprintf "Attr2 %s" value
| EOF region -> region, "EOF" | EOF region -> region, "EOF"
let to_lexeme = function let to_lexeme = function
@ -205,6 +206,7 @@ let to_lexeme = function
| Mutez i -> fst i.Region.value | Mutez i -> fst i.Region.value
| String s -> String.escaped s.Region.value | String s -> String.escaped s.Region.value
| Bytes b -> fst b.Region.value | Bytes b -> fst b.Region.value
| Attr a -> a.Region.value
| Begin _ -> "begin" | Begin _ -> "begin"
| Else _ -> "else" | Else _ -> "else"
@ -226,7 +228,7 @@ let to_lexeme = function
| C_None _ -> "None" | C_None _ -> "None"
| C_Some _ -> "Some" | C_Some _ -> "Some"
| Attr2 a -> a.Region.value
| EOF _ -> "" | EOF _ -> ""
let to_string token ?(offsets=true) mode = let to_string token ?(offsets=true) mode =
@ -469,11 +471,10 @@ let mk_constr lexeme region =
(* Attributes *) (* Attributes *)
let mk_attr _lexeme _region = let mk_attr header lexeme region =
if header = "[@" then
Error Invalid_attribute Error Invalid_attribute
else Ok (Attr Region.{value=lexeme; region})
let mk_attr2 lexeme region =
Ok (Attr2 { value = lexeme; region })
(* Predicates *) (* Predicates *)

View File

@ -0,0 +1,5 @@
SHELL := dash
BFLAGS := -strict-sequence -w +A-48-4 -g
clean::
> rm -f Parser.msg Parser.msg.map Parser.msg.states Version.ml

View File

@ -46,7 +46,7 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 33 -> | 33 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 460 -> | 478 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 27 -> | 27 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
@ -68,9 +68,13 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 133 -> | 133 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 373 -> | 379 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 375 -> | 381 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 472 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 169 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 134 -> | 134 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
@ -80,7 +84,7 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 153 -> | 153 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 374 -> | 380 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 63 -> | 63 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
@ -144,137 +148,141 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 156 -> | 156 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 463 -> | 481 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 465 -> | 483 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 217 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 242 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 219 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 221 -> | 221 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 215 -> | 246 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 226 -> | 223 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 255 -> | 225 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 256 -> | 219 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 243 -> | 230 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 264 -> | 259 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 228 -> | 260 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 257 -> | 247 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 258 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 266 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 268 -> | 268 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 232 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 261 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 262 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 270 -> | 270 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 272 -> | 272 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 274 -> | 274 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 192 -> | 276 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 259 -> | 278 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 285 -> | 195 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 288 -> | 263 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 245 -> | 289 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 293 -> | 292 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 262 -> | 249 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 297 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 266 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 160 -> | 160 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 164 -> | 164 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 429 -> | 445 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 332 -> | 337 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 313 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 431 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 315 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 316 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 317 -> | 317 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 432 -> | 447 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 445 -> | 319 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 446 -> | 320 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 433 -> | 321 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 434 -> | 448 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 435 -> | 462 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 436 -> | 463 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 437 -> | 449 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 438 -> | 450 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 440 -> | 452 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 328 -> | 451 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 330 -> | 453 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 454 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 455 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 457 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 333 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 335 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 339 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 336 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 334 -> | 334 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 331 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 329 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 340 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 341 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 342 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 343 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 344 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 345 -> | 345 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 367 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 346 -> | 346 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 348 -> | 348 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 441 -> | 347 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 443 -> | 349 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 447 -> | 350 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 430 -> | 351 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 312 -> | 373 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 428 -> | 352 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 354 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 458 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 460 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 464 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 446 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 316 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 444 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 165 -> | 165 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
@ -282,65 +290,71 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 168 -> | 168 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 169 -> | 172 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 171 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 163 -> | 163 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 448 -> | 465 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 450 -> | 467 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 451 -> | 468 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 166 -> | 166 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 235 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 236 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 239 -> | 239 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 240 -> | 240 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 425 -> | 243 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 170 -> | 244 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 171 -> | 441 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 172 -> | 173 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 418 -> | 428 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 419 -> | 429 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 174 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 175 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 434 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 435 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 438 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 439 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 427 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 421 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 422 -> | 422 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 423 -> | 423 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 174 -> | 177 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 304 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 305 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 405 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 412 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 404 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 306 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 308 -> | 308 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 320 -> | 309 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 321 -> | 412 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 322 -> | 419 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 323 -> | 411 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 310 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 312 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 324 -> | 324 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
@ -350,67 +364,79 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 327 -> | 327 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 378 -> | 329 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 379 -> | 328 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 381 -> | 330 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 335 -> | 331 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 310 -> | 332 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 307 -> | 384 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 395 -> | 385 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 396 -> | 387 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 397 -> | 340 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 398 -> | 314 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 399 -> | 311 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 400 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 408 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 401 -> | 401 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 402 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 404 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 403 -> | 403 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 175 -> | 405 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 176 -> | 406 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 407 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 415 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 408 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 410 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 178 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 179 -> | 179 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 180 -> | 182 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 183 -> | 183 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 302 -> | 186 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 300 -> | 306 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 185 -> | 304 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 187 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 188 -> | 188 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 189 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 190 -> | 190 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 195 -> | 191 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 192 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 193 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 198 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 218 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 197 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 214 -> | 214 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 194 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 210 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| _ -> | _ ->
raise Not_found raise Not_found

View File

@ -12,7 +12,7 @@
%token <(string * Z.t) Region.reg> Mutez "<mutez>" %token <(string * Z.t) Region.reg> Mutez "<mutez>"
%token <string Region.reg> Ident "<ident>" %token <string Region.reg> Ident "<ident>"
%token <string Region.reg> Constr "<constr>" %token <string Region.reg> Constr "<constr>"
%token <string Region.reg> Attr2 "<attr>" %token <string Region.reg> Attr "<attr>"
(* Symbols *) (* Symbols *)

View File

@ -119,6 +119,7 @@ declaration:
type_decl: type_decl:
"type" type_name "=" type_expr { "type" type_name "=" type_expr {
Scoping.check_reserved_name $2;
let region = cover $1 (type_expr_to_region $4) in let region = cover $1 (type_expr_to_region $4) in
let value = { let value = {
kwd_type = $1; kwd_type = $1;
@ -128,23 +129,23 @@ type_decl:
in {region; value} } in {region; value} }
type_expr: type_expr:
cartesian | sum_type | record_type { $1 } fun_type | sum_type | record_type { $1 }
cartesian:
fun_type { $1 }
| fun_type "*" nsepseq(fun_type,"*") {
let value = Utils.nsepseq_cons $1 $2 $3 in
let region = nsepseq_to_region type_expr_to_region value
in TProd {region; value} }
fun_type: fun_type:
core_type { $1 } cartesian { $1 }
| core_type "->" fun_type { | cartesian "->" fun_type {
let start = type_expr_to_region $1 let start = type_expr_to_region $1
and stop = type_expr_to_region $3 in and stop = type_expr_to_region $3 in
let region = cover start stop in let region = cover start stop in
TFun {region; value=$1,$2,$3} } TFun {region; value=$1,$2,$3} }
cartesian:
core_type { $1 }
| core_type "*" nsepseq(core_type,"*") {
let value = Utils.nsepseq_cons $1 $2 $3 in
let region = nsepseq_to_region type_expr_to_region value
in TProd {region; value} }
core_type: core_type:
type_name { TVar $1 } type_name { TVar $1 }
| par(type_expr) { TPar $1 } | par(type_expr) { TPar $1 }
@ -175,6 +176,7 @@ type_tuple:
sum_type: sum_type:
ioption("|") nsepseq(variant,"|") { ioption("|") nsepseq(variant,"|") {
Scoping.check_variants (Utils.nsepseq_to_list $2);
let region = nsepseq_to_region (fun x -> x.region) $2 let region = nsepseq_to_region (fun x -> x.region) $2
in TSum {region; value=$2} } in TSum {region; value=$2} }
@ -188,6 +190,8 @@ variant:
record_type: record_type:
"{" sep_or_term_list(field_decl,";") "}" { "{" sep_or_term_list(field_decl,";") "}" {
let ne_elements, terminator = $2 in let ne_elements, terminator = $2 in
let () = Utils.nsepseq_to_list ne_elements
|> Scoping.check_fields in
let region = cover $1 $3 let region = cover $1 $3
and value = {compound = Braces ($1,$3); ne_elements; terminator} and value = {compound = Braces ($1,$3); ne_elements; terminator}
in TRecord {region; value} } in TRecord {region; value} }
@ -202,7 +206,7 @@ field_decl:
(* Top-level non-recursive definitions *) (* Top-level non-recursive definitions *)
let_declaration: let_declaration:
"let" let_binding seq(Attr2) { "let" let_binding seq(Attr) {
let kwd_let = $1 in let kwd_let = $1 in
let attributes = $3 in let attributes = $3 in
let binding = $2 in let binding = $2 in
@ -214,9 +218,11 @@ let_declaration:
let_binding: let_binding:
"<ident>" nseq(sub_irrefutable) type_annotation? "=" expr { "<ident>" nseq(sub_irrefutable) type_annotation? "=" expr {
let binders = Utils.nseq_cons (PVar $1) $2 in let binders = Utils.nseq_cons (PVar $1) $2 in
Utils.nseq_iter Scoping.check_pattern binders;
{binders; lhs_type=$3; eq=$4; let_rhs=$5} {binders; lhs_type=$3; eq=$4; let_rhs=$5}
} }
| irrefutable type_annotation? "=" expr { | irrefutable type_annotation? "=" expr {
Scoping.check_pattern $1;
{binders=$1,[]; lhs_type=$2; eq=$3; let_rhs=$4} } {binders=$1,[]; lhs_type=$2; eq=$3; let_rhs=$4} }
type_annotation: type_annotation:
@ -441,10 +447,12 @@ cases(right_expr):
in fst_case, ($2,snd_case)::others } in fst_case, ($2,snd_case)::others }
case_clause(right_expr): case_clause(right_expr):
pattern "->" right_expr { {pattern=$1; arrow=$2; rhs=$3} } pattern "->" right_expr {
Scoping.check_pattern $1;
{pattern=$1; arrow=$2; rhs=$3} }
let_expr(right_expr): let_expr(right_expr):
"let" let_binding seq(Attr2) "in" right_expr { "let" let_binding seq(Attr) "in" right_expr {
let kwd_let = $1 let kwd_let = $1
and binding = $2 and binding = $2
and attributes = $3 and attributes = $3
@ -626,7 +634,7 @@ update_record:
lbrace = $1; lbrace = $1;
record = $2; record = $2;
kwd_with = $3; kwd_with = $3;
updates = { value = {compound = Braces($1,$5); updates = {value = {compound = Braces($1,$5);
ne_elements; ne_elements;
terminator}; terminator};
region = cover $3 $5}; region = cover $3 $5};
@ -656,5 +664,5 @@ sequence:
in {region; value} } in {region; value} }
path : path :
"<ident>" {Name $1} "<ident>" { Name $1 }
| projection { Path $1} | projection { Path $1 }

View File

@ -131,7 +131,7 @@ let rec print_tokens state {decl;eof} =
and print_attributes state attributes = and print_attributes state attributes =
List.iter ( List.iter (
fun ({value = attribute; region}) -> fun ({value = attribute; region}) ->
let attribute_formatted = sprintf "[@%s]" attribute in let attribute_formatted = sprintf "[@@%s]" attribute in
print_token state region attribute_formatted print_token state region attribute_formatted
) attributes ) attributes
@ -610,31 +610,41 @@ let rec pp_ast state {decl; _} =
List.iteri (List.length decls |> apply) decls List.iteri (List.length decls |> apply) decls
and pp_declaration state = function and pp_declaration state = function
Let {value = (_, let_binding, _); region} -> Let {value = (_, let_binding, attr); region} ->
pp_loc_node state "Let" region; pp_loc_node state "Let" region;
pp_let_binding state let_binding pp_let_binding state let_binding attr;
| TypeDecl {value; region} -> | TypeDecl {value; region} ->
pp_loc_node state "TypeDecl" region; pp_loc_node state "TypeDecl" region;
pp_type_decl state value pp_type_decl state value
and pp_let_binding state node = and pp_let_binding state node attr =
let {binders; lhs_type; let_rhs; _} = node in let {binders; lhs_type; let_rhs; _} = node in
let fields = if lhs_type = None then 2 else 3 in let fields = if lhs_type = None then 2 else 3 in
let () = let fields = if attr = [] then fields else fields+1 in
let arity =
let state = state#pad fields 0 in let state = state#pad fields 0 in
pp_node state "<binders>"; pp_node state "<binders>";
pp_binders state binders in pp_binders state binders; 0 in
let () = let arity =
match lhs_type with match lhs_type with
None -> () None -> arity
| Some (_, type_expr) -> | Some (_, type_expr) ->
let state = state#pad fields 1 in let state = state#pad fields (arity+1) in
pp_node state "<lhs type>"; pp_node state "<lhs type>";
pp_type_expr (state#pad 1 0) type_expr in pp_type_expr (state#pad 1 0) type_expr;
let () = arity+1 in
let state = state#pad fields (fields - 1) in let arity =
let state = state#pad fields (arity+1) in
pp_node state "<rhs>"; pp_node state "<rhs>";
pp_expr (state#pad 1 0) let_rhs pp_expr (state#pad 1 0) let_rhs;
arity+1 in
let () =
if attr <> [] then
let state = state#pad fields (arity+1) in
pp_node state "<attributes>";
let length = List.length attr in
let apply len rank = pp_ident (state#pad len rank)
in List.iteri (apply length) attr
in () in ()
and pp_type_decl state decl = and pp_type_decl state decl =
@ -838,28 +848,39 @@ and pp_fun_expr state node =
in () in ()
and pp_let_in state node = and pp_let_in state node =
let {binding; body; _} = node in let {binding; body; attributes; _} = node in
let {binders; lhs_type; let_rhs; _} = binding in let {binders; lhs_type; let_rhs; _} = binding in
let fields = if lhs_type = None then 3 else 4 in let fields = if lhs_type = None then 3 else 4 in
let () = let fields = if attributes = [] then fields else fields+1 in
let arity =
let state = state#pad fields 0 in let state = state#pad fields 0 in
pp_node state "<binders>"; pp_node state "<binders>";
pp_binders state binders in pp_binders state binders; 0 in
let () = let arity =
match lhs_type with match lhs_type with
None -> () None -> arity
| Some (_, type_expr) -> | Some (_, type_expr) ->
let state = state#pad fields 1 in let state = state#pad fields (arity+1) in
pp_node state "<lhs type>"; pp_node state "<lhs type>";
pp_type_expr (state#pad 1 0) type_expr in pp_type_expr (state#pad 1 0) type_expr;
let () = arity+1 in
let state = state#pad fields (fields - 2) in let arity =
let state = state#pad fields (arity+1) in
pp_node state "<rhs>"; pp_node state "<rhs>";
pp_expr (state#pad 1 0) let_rhs in pp_expr (state#pad 1 0) let_rhs;
let () = arity+1 in
let state = state#pad fields (fields - 1) in let arity =
let state = state#pad fields (arity+1) in
pp_node state "<body>"; pp_node state "<body>";
pp_expr (state#pad 1 0) body pp_expr (state#pad 1 0) body;
arity+1 in
let () =
if attributes <> [] then
let state = state#pad fields (arity+1) in
pp_node state "<attributes>";
let length = List.length attributes in
let apply len rank = pp_ident (state#pad len rank)
in List.iteri (apply length) attributes
in () in ()
and pp_tuple_expr state {value; _} = and pp_tuple_expr state {value; _} =

View File

@ -25,6 +25,7 @@ val pattern_to_string :
val expr_to_string : val expr_to_string :
offsets:bool -> mode:[`Point|`Byte] -> AST.expr -> string offsets:bool -> mode:[`Point|`Byte] -> AST.expr -> string
(** {1 Pretty-printing of the AST} *) (** {1 Pretty-printing of AST nodes} *)
val pp_ast : state -> AST.t -> unit val pp_ast : state -> AST.t -> unit
val pp_expr : state -> AST.expr -> unit

View File

@ -6,22 +6,86 @@ module IO =
let options = EvalOpt.read "CameLIGO" ext let options = EvalOpt.read "CameLIGO" ext
end end
module ExtParser = module Parser =
struct struct
type ast = AST.t type ast = AST.t
type expr = AST.expr type expr = AST.expr
include Parser include Parser
end end
module ExtParserLog = module ParserLog =
struct struct
type ast = AST.t type ast = AST.t
type expr = AST.expr
include ParserLog include ParserLog
end end
module MyLexer = Lexer.Make (LexToken) module Lexer = Lexer.Make (LexToken)
module Unit = module Unit =
ParserUnit.Make (IO)(MyLexer)(AST)(ExtParser)(ParErr)(ExtParserLog) ParserUnit.Make (Lexer)(AST)(Parser)(ParErr)(ParserLog)(IO)
let () = Unit.run () (* Main *)
let issue_error point =
let error = Unit.format_error ~offsets:IO.options#offsets
IO.options#mode point
in Stdlib.Error error
let parse parser : ('a,string) Stdlib.result =
try parser () with
(* Scoping errors *)
| Scoping.Error (Scoping.Reserved_name name) ->
let token =
Lexer.Token.mk_ident name.Region.value name.Region.region in
(match token with
(* Cannot fail because [name] is a not a
reserved name for the lexer. *)
Stdlib.Error _ -> assert false
| Ok invalid ->
issue_error
("Reserved name.\nHint: Change the name.\n", None, invalid))
| Scoping.Error (Scoping.Duplicate_variant name) ->
let token =
Lexer.Token.mk_constr name.Region.value name.Region.region in
let point = "Duplicate constructor in this sum type declaration.\n\
Hint: Change the constructor.\n",
None, token
in issue_error point
| Scoping.Error (Scoping.Non_linear_pattern var) ->
let token =
Lexer.Token.mk_ident var.Region.value var.Region.region in
(match token with
(* Cannot fail because [var] is a not a
reserved name for the lexer. *)
Stdlib.Error _ -> assert false
| Ok invalid ->
let point = "Repeated variable in this pattern.\n\
Hint: Change the name.\n",
None, invalid
in issue_error point)
| Scoping.Error (Scoping.Duplicate_field name) ->
let token =
Lexer.Token.mk_ident name.Region.value name.Region.region in
(match token with
(* Cannot fail because [name] is a not a
reserved name for the lexer. *)
Stdlib.Error _ -> assert false
| Ok invalid ->
let point = "Duplicate field name in this record declaration.\n\
Hint: Change the name.\n",
None, invalid
in issue_error point)
let () =
if IO.options#expr
then match parse (fun () -> Unit.parse Unit.parse_expr) with
Stdlib.Ok _ -> ()
| Error msg -> Printf.eprintf "\027[31m%s\027[0m%!" msg
else match parse (fun () -> Unit.parse Unit.parse_contract) with
Stdlib.Ok _ -> ()
| Error msg -> Printf.eprintf "\027[31m%s\027[0m%!" msg

View File

@ -0,0 +1,132 @@
[@@@warning "-42"]
type t =
Reserved_name of AST.variable
| Duplicate_variant of AST.variable
| Non_linear_pattern of AST.variable
| Duplicate_field of AST.variable
type error = t
exception Error of t
open Region
(* Useful modules *)
module SSet = Utils.String.Set
module Ord =
struct
type t = AST.variable
let compare v1 v2 =
compare v1.value v2.value
end
module VarSet = Set.Make (Ord)
(* Checking the definition of reserved names (shadowing) *)
let reserved =
let open SSet in
empty
|> add "assert"
|> add "balance"
|> add "time"
|> add "amount"
|> add "gas"
|> add "sender"
|> add "source"
|> add "failwith"
|> add "continue"
|> add "stop"
|> add "int"
|> add "abs"
|> add "unit"
let check_reserved_names vars =
let is_reserved elt = SSet.mem elt.value reserved in
let inter = VarSet.filter is_reserved vars in
if not (VarSet.is_empty inter) then
let clash = VarSet.choose inter in
raise (Error (Reserved_name clash))
else vars
let check_reserved_name var =
if SSet.mem var.value reserved then
raise (Error (Reserved_name var))
(* Checking the linearity of patterns *)
open! AST
let rec vars_of_pattern env = function
PConstr p -> vars_of_pconstr env p
| PUnit _ | PFalse _ | PTrue _
| PInt _ | PNat _ | PBytes _
| PString _ | PWild _ -> env
| PVar var ->
if VarSet.mem var env then
raise (Error (Non_linear_pattern var))
else VarSet.add var env
| PList l -> vars_of_plist env l
| PTuple t -> Utils.nsepseq_foldl vars_of_pattern env t.value
| PPar p -> vars_of_pattern env p.value.inside
| PRecord p -> vars_of_fields env p.value.ne_elements
| PTyped p -> vars_of_pattern env p.value.pattern
and vars_of_fields env fields =
Utils.nsepseq_foldl vars_of_field_pattern env fields
and vars_of_field_pattern env field =
let var = field.value.field_name in
if VarSet.mem var env then
raise (Error (Non_linear_pattern var))
else
let p = field.value.pattern
in vars_of_pattern (VarSet.add var env) p
and vars_of_pconstr env = function
PNone _ -> env
| PSomeApp {value=_, pattern; _} ->
vars_of_pattern env pattern
| PConstrApp {value=_, Some pattern; _} ->
vars_of_pattern env pattern
| PConstrApp {value=_,None; _} -> env
and vars_of_plist env = function
PListComp {value; _} ->
Utils.sepseq_foldl vars_of_pattern env value.elements
| PCons {value; _} ->
let head, _, tail = value in
List.fold_left vars_of_pattern env [head; tail]
let check_linearity = vars_of_pattern VarSet.empty
(* Checking patterns *)
let check_pattern p =
check_linearity p |> check_reserved_names |> ignore
(* Checking variants for duplicates *)
let check_variants variants =
let add acc {value; _} =
if VarSet.mem value.constr acc then
raise (Error (Duplicate_variant value.constr))
else VarSet.add value.constr acc in
let variants =
List.fold_left add VarSet.empty variants
in ignore variants
(* Checking record fields *)
let check_fields fields =
let add acc {value; _} =
if VarSet.mem (value: field_decl).field_name acc then
raise (Error (Duplicate_field value.field_name))
else VarSet.add value.field_name acc in
let fields =
List.fold_left add VarSet.empty fields
in ignore fields

View File

@ -0,0 +1,16 @@
(* This module exports checks on scoping, called from the parser. *)
type t =
Reserved_name of AST.variable
| Duplicate_variant of AST.variable
| Non_linear_pattern of AST.variable
| Duplicate_field of AST.variable
type error = t
exception Error of t
val check_reserved_name : AST.variable -> unit
val check_pattern : AST.pattern -> unit
val check_variants : AST.variant Region.reg list -> unit
val check_fields : AST.field_decl Region.reg list -> unit

View File

@ -1,10 +0,0 @@
#!/bin/sh
set -e
if test -d ../../.git; then
echo true > dot_git_is_dir
else
echo false > dot_git_is_dir
cat .git >> dot_git_is_dir
fi

View File

@ -1,14 +1,21 @@
;; Build of the lexer
(ocamllex LexToken) (ocamllex LexToken)
;; Build of the parser
(menhir (menhir
(merge_into Parser) (merge_into Parser)
(modules ParToken Parser) (modules ParToken Parser)
(flags -la 1 --table --strict --explain --external-tokens LexToken)) (flags -la 1 --table --strict --explain --external-tokens LexToken))
;; Build of the parser as a library
(library (library
(name parser_cameligo) (name parser_cameligo)
(public_name ligo.parser.cameligo) (public_name ligo.parser.cameligo)
(modules AST cameligo Parser ParserLog LexToken) (modules
Scoping AST cameligo Parser ParserLog LexToken)
(libraries (libraries
menhirLib menhirLib
parser_shared parser_shared
@ -20,6 +27,18 @@
(pps bisect_ppx --conditional)) (pps bisect_ppx --conditional))
(flags (:standard -open Simple_utils -open Parser_shared))) (flags (:standard -open Simple_utils -open Parser_shared)))
;; Build of the unlexer (for covering the
;; error states of the LR automaton)
(executable
(name Unlexer)
(libraries str)
(preprocess
(pps bisect_ppx --conditional))
(modules Unlexer))
;; Local build of a standalone lexer
(executable (executable
(name LexerMain) (name LexerMain)
(libraries parser_cameligo) (libraries parser_cameligo)
@ -28,6 +47,8 @@
(pps bisect_ppx --conditional)) (pps bisect_ppx --conditional))
(flags (:standard -open Parser_shared -open Parser_cameligo))) (flags (:standard -open Parser_shared -open Parser_cameligo)))
;; Local build of a standalone parser
(executable (executable
(name ParserMain) (name ParserMain)
(libraries parser_cameligo) (libraries parser_cameligo)
@ -37,19 +58,16 @@
(pps bisect_ppx --conditional)) (pps bisect_ppx --conditional))
(flags (:standard -open Simple_utils -open Parser_shared -open Parser_cameligo))) (flags (:standard -open Simple_utils -open Parser_shared -open Parser_cameligo)))
(executable ;; Build of the covering of error states in the LR automaton
(name Unlexer)
(libraries str)
(preprocess
(pps bisect_ppx --conditional))
(modules Unlexer))
(rule (rule
(targets Parser.msg) (targets Parser.msg)
(deps (:script_messages ../../../../vendors/ligo-utils/simple-utils/messages.sh) Parser.mly LexToken.mli ParToken.mly) (deps (:script_messages ../../../../vendors/ligo-utils/simple-utils/messages.sh) Parser.mly LexToken.mli ParToken.mly)
(action (run %{script_messages} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly Parser.mly ))) (action (run %{script_messages} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly Parser.mly)))
;; Build of all the LIGO source file that cover all error states
(rule (rule
(targets all.ligo) (targets all.mligo)
(deps (:script_cover ../../../../vendors/ligo-utils/simple-utils/cover.sh) Parser.mly LexToken.mli ParToken.mly Parser.msg Unlexer.exe) (deps (:script_cover ../../../../vendors/ligo-utils/simple-utils/cover.sh) Parser.mly LexToken.mli ParToken.mly Parser.msg Unlexer.exe)
(action (run %{script_cover} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly --ext=ligo --unlexer=./Unlexer.exe --messages=Parser.msg --dir=. --concatenate Parser.mly ))) (action (run %{script_cover} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly --ext=mligo --unlexer=./Unlexer.exe --messages=Parser.msg --dir=. --concatenate Parser.mly )))

View File

@ -7,10 +7,7 @@
parser_shared parser_shared
parser_pascaligo parser_pascaligo
parser_cameligo parser_cameligo
parser_reasonligo parser_reasonligo)
)
(preprocess (preprocess
(pps ppx_let bisect_ppx --conditional) (pps ppx_let bisect_ppx --conditional))
) (flags (:standard -w +1..62-4-9-44-40-42-48-30@39@33 -open Simple_utils -open Parser_shared)))
(flags (:standard -w +1..62-4-9-44-40-42-48-30@39@33 -open Simple_utils -open Parser_shared))
)

View File

@ -1,129 +1,103 @@
open Trace open Trace
module Parser = Parser_pascaligo.Parser
module AST = Parser_pascaligo.AST module AST = Parser_pascaligo.AST
module ParserLog = Parser_pascaligo.ParserLog
module LexToken = Parser_pascaligo.LexToken module LexToken = Parser_pascaligo.LexToken
module Lexer = Lexer.Make(LexToken) module Lexer = Lexer.Make(LexToken)
module SyntaxError = Parser_pascaligo.SyntaxError module Scoping = Parser_pascaligo.Scoping
module Parser = Parser_pascaligo.Parser
module Errors = struct module Errors =
struct
let reserved_name Region.{value; region} =
let title () = Printf.sprintf "reserved name \"%s\"" value in
let message () = "" in
let data = [
("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ region)]
in error ~data title message
let non_linear_pattern Region.{value; region} =
let title () =
Printf.sprintf "repeated variable \"%s\" in this pattern" value in
let message () = "" in
let data = [
("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ region)]
in error ~data title message
let duplicate_parameter Region.{value; region} =
let title () =
Printf.sprintf "duplicate parameter \"%s\"" value in
let message () = "" in
let data = [
("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ region)]
in error ~data title message
let duplicate_variant Region.{value; region} =
let title () =
Printf.sprintf "duplicate variant \"%s\" in this\
type declaration" value in
let message () = "" in
let data = [
("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ region)]
in error ~data title message
let unrecognized_error source (start: Lexing.position)
(stop: Lexing.position) lexbuf =
let title () = "unrecognized error" in
let file =
if source = "" then ""
else
Format.sprintf "In file \"%s|%s\"" start.pos_fname source in
let message () =
Format.sprintf
"Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n"
(Lexing.lexeme lexbuf)
start.pos_lnum (start.pos_cnum - start.pos_bol)
stop.pos_lnum (stop.pos_cnum - stop.pos_bol)
file in
let loc = Region.make ~start:(Pos.from_byte start)
~stop:(Pos.from_byte stop) in
let data = [
("unrecognized_loc",
fun () -> Format.asprintf "%a" Location.pp_lift @@ loc)]
in error ~data title message
let parser_error source (start: Lexing.position)
(stop: Lexing.position) lexbuf =
let title () = "parser error" in
let file =
if source = "" then ""
else
Format.sprintf "In file \"%s|%s\"" start.pos_fname source in
let message () =
Format.sprintf
"Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n"
(Lexing.lexeme lexbuf)
start.pos_lnum (start.pos_cnum - start.pos_bol)
stop.pos_lnum (stop.pos_cnum - stop.pos_bol)
file in
let loc =
if start.pos_cnum = -1 then
Region.make
~start:(Pos.min ~file:source) ~stop:(Pos.from_byte stop)
else
Region.make ~start:(Pos.from_byte start)
~stop:(Pos.from_byte stop) in
let data =
[("parser_loc",
fun () -> Format.asprintf "%a" Location.pp_lift @@ loc)] in
error ~data title message
let lexer_error (e: Lexer.error AST.reg) = let lexer_error (e: Lexer.error AST.reg) =
let title () = "lexer error" in let title () = "lexer error" in
let message () = Lexer.error_to_string e.value in let message () = Lexer.error_to_string e.value in
let data = [ let data = [
("parser_loc", ("parser_loc",
fun () -> Format.asprintf "%a" Location.pp_lift @@ e.region fun () -> Format.asprintf "%a" Location.pp_lift @@ e.region)]
) in error ~data title message
] in
error ~data title message
let reserved_name Region.{value; region} =
let title () = Printf.sprintf "reserved name \"%s\"" value in
let message () = "" in
let data = [
("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ region)
] in
error ~data title message
let non_linear_pattern Region.{value; region} =
let title () = Printf.sprintf "repeated variable \"%s\" in this pattern" value in
let message () = "" in
let data = [
("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ region)
] in
error ~data title message
let duplicate_parameter Region.{value; region} =
let title () = Printf.sprintf "duplicate parameter \"%s\"" value in
let message () = "" in
let data = [
("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ region)
] in
error ~data title message
let duplicate_variant Region.{value; region} =
let title () = Printf.sprintf "duplicate variant \"%s\" in this\
type declaration" value in
let message () = "" in
let data = [
("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ region)
] in
error ~data title message
let detached_attributes (attrs: AST.attributes) =
let title () = "detached attributes" in
let message () = "" in
let data = [
("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ attrs.region)
] in
error ~data title message
let parser_error source (start: Lexing.position) (end_: Lexing.position) lexbuf =
let title () = "parser error" in
let file = if source = "" then
""
else
Format.sprintf "In file \"%s|%s\"" start.pos_fname source
in
let str = Format.sprintf
"Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n"
(Lexing.lexeme lexbuf)
start.pos_lnum (start.pos_cnum - start.pos_bol)
end_.pos_lnum (end_.pos_cnum - end_.pos_bol)
file
in
let message () = str in
let loc = if start.pos_cnum = -1 then
Region.make
~start: Pos.min
~stop:(Pos.from_byte end_)
else
Region.make
~start:(Pos.from_byte start)
~stop:(Pos.from_byte end_)
in
let data =
[
("parser_loc",
fun () -> Format.asprintf "%a" Location.pp_lift @@ loc
)
]
in
error ~data title message
let unrecognized_error source (start: Lexing.position) (end_: Lexing.position) lexbuf =
let title () = "unrecognized error" in
let file = if source = "" then
""
else
Format.sprintf "In file \"%s|%s\"" start.pos_fname source
in
let str = Format.sprintf
"Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n"
(Lexing.lexeme lexbuf)
start.pos_lnum (start.pos_cnum - start.pos_bol)
end_.pos_lnum (end_.pos_cnum - end_.pos_bol)
file
in
let message () = str in
let loc = Region.make
~start:(Pos.from_byte start)
~stop:(Pos.from_byte end_)
in
let data = [
("unrecognized_loc",
fun () -> Format.asprintf "%a" Location.pp_lift @@ loc
)
] in
error ~data title message
end end
open Errors open Errors
@ -131,35 +105,29 @@ open Errors
type 'a parser = (Lexing.lexbuf -> LexToken.token) -> Lexing.lexbuf -> 'a type 'a parser = (Lexing.lexbuf -> LexToken.token) -> Lexing.lexbuf -> 'a
let parse (parser: 'a parser) source lexbuf = let parse (parser: 'a parser) source lexbuf =
let Lexer.{read ; close ; _} = Lexer.open_token_stream None in let Lexer.{read; close; _} = Lexer.open_token_stream None in
let result = let result =
try try ok (parser read lexbuf) with
ok (parser read lexbuf) Lexer.Error e ->
with fail @@ lexer_error e
SyntaxError.Error (Non_linear_pattern var) ->
fail @@ (non_linear_pattern var)
| SyntaxError.Error (Duplicate_parameter name) ->
fail @@ (duplicate_parameter name)
| SyntaxError.Error (Duplicate_variant name) ->
fail @@ (duplicate_variant name)
| SyntaxError.Error (Reserved_name name) ->
fail @@ (reserved_name name)
| SyntaxError.Error (Detached_attributes attrs) ->
fail @@ (detached_attributes attrs)
| Parser.Error -> | Parser.Error ->
let start = Lexing.lexeme_start_p lexbuf in let start = Lexing.lexeme_start_p lexbuf in
let end_ = Lexing.lexeme_end_p lexbuf in let stop = Lexing.lexeme_end_p lexbuf in
fail @@ (parser_error source start end_ lexbuf) fail @@ parser_error source start stop lexbuf
| Lexer.Error e -> | Scoping.Error (Scoping.Non_linear_pattern var) ->
fail @@ (lexer_error e) fail @@ non_linear_pattern var
| Scoping.Error (Duplicate_parameter name) ->
fail @@ duplicate_parameter name
| Scoping.Error (Duplicate_variant name) ->
fail @@ duplicate_variant name
| Scoping.Error (Reserved_name name) ->
fail @@ reserved_name name
| _ -> | _ ->
let _ = Printexc.print_backtrace Pervasives.stdout in let () = Printexc.print_backtrace Pervasives.stdout in
let start = Lexing.lexeme_start_p lexbuf in let start = Lexing.lexeme_start_p lexbuf in
let end_ = Lexing.lexeme_end_p lexbuf in let stop = Lexing.lexeme_end_p lexbuf in
fail @@ (unrecognized_error source start end_ lexbuf) fail @@ unrecognized_error source start stop lexbuf
in in close (); result
close ();
result
let parse_file (source: string) : AST.t result = let parse_file (source: string) : AST.t result =
let pp_input = let pp_input =

View File

@ -1,21 +1,18 @@
(* This file provides an interface to the PascaLIGO parser. *) (** This file provides an interface to the PascaLIGO parser. *)
open Trace
module Parser = Parser_pascaligo.Parser
module AST = Parser_pascaligo.AST module AST = Parser_pascaligo.AST
module ParserLog = Parser_pascaligo.ParserLog
module LexToken = Parser_pascaligo.LexToken
(** Open a PascaLIGO filename given by string and convert into an
(** Open a PascaLIGO filename given by string and convert into an abstract syntax tree. *) abstract syntax tree. *)
val parse_file : string -> (AST.t result) val parse_file : string -> AST.t Trace.result
(** Convert a given string into a PascaLIGO abstract syntax tree *) (** Convert a given string into a PascaLIGO abstract syntax tree *)
val parse_string : string -> AST.t result val parse_string : string -> AST.t Trace.result
(** Parse a given string as a PascaLIGO expression and return an expression AST. (** Parse a given string as a PascaLIGO expression and return an
expression AST.
This is intended to be used for interactive interpreters, or other scenarios This is intended to be used for interactive interpreters, or other
where you would want to parse a PascaLIGO expression outside of a contract. *) scenarios where you would want to parse a PascaLIGO expression
val parse_expression : string -> AST.expr result outside of a contract. *)
val parse_expression : string -> AST.expr Trace.result

View File

@ -1,5 +1,4 @@
$HOME/git/OCaml-build/Makefile $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.mli
$HOME/git/ligo/vendors/ligo-utils/simple-utils/pos.ml $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.mli
@ -19,5 +18,8 @@ $HOME/git/ligo/vendors/ligo-utils/simple-utils/region.ml
../shared/ParserAPI.mli ../shared/ParserAPI.mli
../shared/ParserAPI.ml ../shared/ParserAPI.ml
../shared/LexerUnit.ml ../shared/LexerUnit.ml
../shared/ParserUnit.mli
../shared/ParserUnit.ml ../shared/ParserUnit.ml
../shared/Memo.mli
../shared/Memo.ml
Stubs/Simple_utils.ml Stubs/Simple_utils.ml

View File

@ -25,6 +25,7 @@ type 'a reg = 'a Region.reg
type keyword = Region.t type keyword = Region.t
type kwd_and = Region.t type kwd_and = Region.t
type kwd_attributes = Region.t
type kwd_begin = Region.t type kwd_begin = Region.t
type kwd_block = Region.t type kwd_block = Region.t
type kwd_case = Region.t type kwd_case = Region.t
@ -144,12 +145,13 @@ type t = {
and ast = t and ast = t
and attributes = attribute list reg
and declaration = and declaration =
TypeDecl of type_decl reg TypeDecl of type_decl reg
| ConstDecl of const_decl reg | ConstDecl of const_decl reg
| FunDecl of fun_decl reg | FunDecl of fun_decl reg
| AttrDecl of attr_decl
and attr_decl = string reg ne_injection reg
and const_decl = { and const_decl = {
kwd_const : kwd_const; kwd_const : kwd_const;
@ -159,7 +161,7 @@ and const_decl = {
equal : equal; equal : equal;
init : expr; init : expr;
terminator : semi option; terminator : semi option;
attributes : attributes; attributes : attr_decl option
} }
(* Type declarations *) (* Type declarations *)
@ -217,7 +219,7 @@ and fun_decl = {
block_with : (block reg * kwd_with) option; block_with : (block reg * kwd_with) option;
return : expr; return : expr;
terminator : semi option; terminator : semi option;
attributes : attributes; attributes : attr_decl option
} }
and parameters = (param_decl, semi) nsepseq par reg and parameters = (param_decl, semi) nsepseq par reg
@ -260,6 +262,7 @@ and statements = (statement, semi) nsepseq
and statement = and statement =
Instr of instruction Instr of instruction
| Data of data_decl | Data of data_decl
| Attr of attr_decl
and data_decl = and data_decl =
LocalConst of const_decl reg LocalConst of const_decl reg
@ -562,6 +565,7 @@ and field_assign = {
equal : equal; equal : equal;
field_expr : expr field_expr : expr
} }
and record = field_assign reg ne_injection and record = field_assign reg ne_injection
and projection = { and projection = {

View File

@ -28,6 +28,11 @@ type lexeme = string
(* TOKENS *) (* TOKENS *)
type attribute = {
header : string;
string : lexeme Region.reg
}
type t = type t =
(* Literals *) (* Literals *)
@ -151,8 +156,7 @@ val mk_kwd : lexeme -> Region.t -> (token, kwd_err) result
val mk_string : lexeme -> Region.t -> token val mk_string : lexeme -> Region.t -> token
val mk_bytes : lexeme -> Region.t -> token val mk_bytes : lexeme -> Region.t -> token
val mk_constr : lexeme -> Region.t -> token val mk_constr : lexeme -> Region.t -> token
val mk_attr : lexeme -> Region.t -> (token, attr_err) result val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
val mk_attr2 : lexeme -> Region.t -> (token, attr_err) result
val eof : Region.t -> token val eof : Region.t -> token
(* Predicates *) (* Predicates *)

View File

@ -26,6 +26,11 @@ let rollback buffer =
(* TOKENS *) (* TOKENS *)
type attribute = {
header : string;
string : lexeme Region.reg
}
type t = type t =
(* Literals *) (* Literals *)
@ -144,6 +149,11 @@ let proj_token = function
| Constr Region.{region; value} -> | Constr Region.{region; value} ->
region, sprintf "Constr \"%s\"" value region, sprintf "Constr \"%s\"" value
(*
| Attr {header; string={region; value}} ->
region, sprintf "Attr (\"%s\",\"%s\")" header value
*)
(* Symbols *) (* Symbols *)
| SEMI region -> region, "SEMI" | SEMI region -> region, "SEMI"
@ -312,6 +322,7 @@ let to_lexeme = function
| EOF _ -> "" | EOF _ -> ""
(* CONVERSIONS *)
let to_string token ?(offsets=true) mode = let to_string token ?(offsets=true) mode =
let region, val_str = proj_token token in let region, val_str = proj_token token in
@ -365,7 +376,7 @@ let keywords = [
let reserved = let reserved =
let open SSet in let open SSet in
empty |> add "args" empty |> add "arguments"
let constructors = [ let constructors = [
(fun reg -> False reg); (fun reg -> False reg);
@ -489,8 +500,6 @@ let eof region = EOF region
type sym_err = Invalid_symbol type sym_err = Invalid_symbol
type attr_err = Invalid_attribute
let mk_sym lexeme region = let mk_sym lexeme region =
match lexeme with match lexeme with
(* Lexemes in common with all concrete syntaxes *) (* Lexemes in common with all concrete syntaxes *)
@ -539,10 +548,9 @@ let mk_constr lexeme region =
(* Attributes *) (* Attributes *)
let mk_attr _lexeme _region = type attr_err = Invalid_attribute
Error Invalid_attribute
let mk_attr2 _lexeme _region = let mk_attr _header _string _region =
Error Invalid_attribute Error Invalid_attribute
(* Predicates *) (* Predicates *)

View File

@ -7,3 +7,8 @@ module IO =
end end
module M = LexerUnit.Make (IO) (Lexer.Make (LexToken)) module M = LexerUnit.Make (IO) (Lexer.Make (LexToken))
let () =
match M.trace () with
Stdlib.Ok _ -> ()
| Error msg -> Printf.eprintf "\027[31m%s\027[0m%!" msg

View File

@ -0,0 +1,5 @@
SHELL := dash
BFLAGS := -strict-sequence -w +A-48-4 -g
clean::
> rm -f Parser.msg Parser.msg.map Parser.msg.states Version.ml

View File

@ -0,0 +1,39 @@
module ParserLog = Parser_pascaligo.ParserLog
module ParErr = Parser_pascaligo.ParErr
module SSet = Utils.String.Set
(* Mock options. TODO: Plug in cmdliner. *)
let pre_options =
EvalOpt.make
~libs:[]
~verbose:SSet.empty
~offsets:true
~mode:`Point
~cmd:EvalOpt.Quiet
~mono:true (* Monolithic API of Menhir for now *)
(* ~input:None *)
(* ~expr:true *)
module Parser =
struct
type ast = AST.t
type expr = AST.expr
include Parser_pascaligo.Parser
end
module ParserLog =
struct
type ast = AST.t
type expr = AST.expr
include Parser_pascaligo.ParserLog
end
module PreUnit = ParserUnit.Make (Lexer)(AST)(Parser)(ParErr)(ParserLog)
module Front = ParserAPI.Make (Lexer)(Parser)(ParErr)
let issue_error point =
let error = Front.format_error ~offsets:true (* TODO: CLI *)
`Point (* TODO: CLI *) point
in Stdlib.Error error

View File

@ -58,13 +58,13 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 64 -> | 64 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 517 -> | 543 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 29 -> | 29 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 32 -> | 32 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 515 -> | 541 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 35 -> | 35 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
@ -78,23 +78,9 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 67 -> | 67 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 70 -> | 68 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 71 -> | 84 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 72 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 73 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 80 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 81 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 76 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 77 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 78 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 85 -> | 85 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
@ -102,241 +88,225 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 87 -> | 87 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 88 -> | 514 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 512 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 358 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 359 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 499 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 362 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 360 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 361 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 363 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 364 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 365 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 366 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 367 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 475 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 476 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 477 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 478 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 496 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 503 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 502 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 371 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 372 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 373 -> | 373 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 374 -> | 374 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 507 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 377 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 375 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 376 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 378 -> | 378 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 379 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 380 -> | 380 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 381 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 382 -> | 382 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 383 -> | 484 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 485 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 486 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 487 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 504 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 511 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 510 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 386 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 387 -> | 387 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 384 -> | 388 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 385 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 389 -> | 389 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 390 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 391 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 393 -> | 393 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 395 -> | 395 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 399 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 396 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 397 -> | 397 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 375 -> | 398 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 381 -> | 402 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 399 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 400 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 404 -> | 404 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 408 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 405 -> | 405 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 406 -> | 406 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 492 -> | 390 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 493 -> | 396 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 494 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 407 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 488 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 408 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 452 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 447 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 453 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 409 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 410 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 416 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 420 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 421 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 411 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 424 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 425 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 426 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 413 -> | 413 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 414 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 415 -> | 415 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 435 -> | 500 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 436 -> | 501 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 437 -> | 502 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 440 -> | 416 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 441 -> | 496 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 469 -> | 417 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 470 -> | 461 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 473 -> | 456 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 472 -> | 462 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 438 -> | 418 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 467 -> | 419 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 439 -> | 425 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 69 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 428 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 429 -> | 429 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 430 -> | 430 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 431 -> | 420 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 432 -> | 433 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 508 -> | 434 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 521 -> | 435 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 159 -> | 422 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 523 -> | 424 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 137 -> | 444 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 150 -> | 445 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 166 -> | 446 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 167 -> | 449 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 158 -> | 450 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 173 -> | 478 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 152 -> | 479 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 168 -> | 482 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 169 -> | 481 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 175 -> | 447 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 177 -> | 476 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 179 -> | 448 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 437 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 438 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 439 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 440 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 441 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 536 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 515 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 516 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 517 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 518 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 519 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 520 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 529 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 532 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 524 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 525 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 547 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 181 -> | 181 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 183 -> | 549 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 160 -> | 159 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 170 -> | 172 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 157 -> | 188 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 163 -> | 189 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 187 -> | 180 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 92 -> | 195 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 318 -> | 174 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 319 -> | 190 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 322 -> | 191 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 323 -> | 197 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 356 -> | 199 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 351 -> | 201 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 353 -> | 203 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 93 -> | 205 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 94 -> | 182 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 338 -> | 192 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 95 -> | 179 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 96 -> | 185 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 209 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 91 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 342 -> | 342 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
@ -346,169 +316,231 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 347 -> | 347 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 349 -> | 371 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 97 -> | 366 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 136 -> | 368 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 92 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 93 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 362 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 94 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 95 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 144 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 145 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 148 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 149 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 364 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 96 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 158 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 100 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 217 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 218 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 220 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 221 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 224 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 225 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 358 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 353 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 355 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 101 -> | 101 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 195 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 196 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 198 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 199 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 202 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 203 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 334 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 329 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 331 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 102 -> | 102 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 350 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 336 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 338 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 103 -> | 103 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 326 -> | 332 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 312 -> | 330 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 314 -> | 333 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 104 -> | 334 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 308 -> | 328 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 306 -> | 156 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 105 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 320 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 321 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 322 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 323 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 324 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 137 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 138 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 139 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 140 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 151 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 106 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 107 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 309 -> | 309 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 310 -> | 310 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 304 -> | 154 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 134 -> | 177 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 106 -> | 312 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 296 -> | 315 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 297 -> | 316 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 298 -> | 133 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 299 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 300 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 107 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 108 -> | 108 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 285 -> | 69 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 286 -> | 70 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 132 -> | 71 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 155 -> | 72 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 79 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 80 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 75 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 76 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 77 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 109 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 110 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 111 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 112 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 114 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 117 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 230 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 231 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 269 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 293 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 270 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 272 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 273 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 294 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 300 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 299 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 303 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 302 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 240 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 283 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 284 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 287 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 288 -> | 288 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 291 -> | 291 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 292 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 128 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 110 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 113 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 208 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 209 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 247 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 271 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 248 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 250 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 251 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 272 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 278 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 277 -> | 277 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 281 -> | 279 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 280 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 218 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 261 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 262 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 265 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 266 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 269 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 255 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 257 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 219 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 244 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 245 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 253 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 241 -> | 241 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 210 -> | 266 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 267 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 275 -> | 275 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 211 -> | 263 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 223 -> | 232 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 224 -> | 297 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 240 -> | 233 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 225 -> | 245 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 226 -> | 246 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 234 -> | 262 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 114 -> | 247 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 248 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 256 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 118 -> | 118 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 206 -> | 122 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 119 -> | 228 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 125 -> | 123 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 130 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| _ -> | _ ->
raise Not_found raise Not_found

View File

@ -6,39 +6,6 @@
open Region open Region
open AST open AST
type statement_attributes_mixed =
PInstr of instruction
| PData of data_decl
| PAttributes of attributes
let attributes_to_statement (statement, statements) =
if (List.length statements = 0) then
match statement with
| PInstr i -> Instr i, []
| PData d -> Data d, []
| PAttributes a ->
let open! SyntaxError in
raise (Error (Detached_attributes a))
else (
let statements = (Region.ghost, statement) :: statements in
let rec inner result = function
| (t, PData (LocalConst const)) :: (_, PAttributes a) :: rest ->
inner (result @ [(t, Data (LocalConst {const with value = {const.value with attributes = a}}))]) rest
| (t, PData (LocalFun func)) :: (_, PAttributes a) :: rest ->
inner (result @ [(t, Data (LocalFun {func with value = {func.value with attributes = a}}))]) rest
| (t, PData d) :: rest ->
inner (result @ [(t, Data d)]) rest
| (t, PInstr i) :: rest ->
inner (result @ [(t, Instr i)]) rest
| (_, PAttributes _) :: rest ->
inner result rest
| [] ->
result
in
let result = inner [] statements in
(snd (List.hd result), List.tl result)
)
(* END HEADER *) (* END HEADER *)
%} %}
@ -146,12 +113,21 @@ declaration:
type_decl { TypeDecl $1 } type_decl { TypeDecl $1 }
| const_decl { ConstDecl $1 } | const_decl { ConstDecl $1 }
| fun_decl { FunDecl $1 } | fun_decl { FunDecl $1 }
| attr_decl { AttrDecl $1 }
(* Attribute declarations *)
attr_decl:
open_attr_decl ";"? { $1 }
open_attr_decl:
ne_injection("attributes","<string>") { $1 }
(* Type declarations *) (* Type declarations *)
type_decl: type_decl:
"type" type_name "is" type_expr ";"? { "type" type_name "is" type_expr ";"? {
ignore (SyntaxError.check_reserved_name $2); Scoping.check_reserved_name $2;
let stop = let stop =
match $5 with match $5 with
Some region -> region Some region -> region
@ -219,7 +195,7 @@ type_tuple:
sum_type: sum_type:
"|"? nsepseq(variant,"|") { "|"? nsepseq(variant,"|") {
SyntaxError.check_variants (Utils.nsepseq_to_list $2); Scoping.check_variants (Utils.nsepseq_to_list $2);
let region = nsepseq_to_region (fun x -> x.region) $2 let region = nsepseq_to_region (fun x -> x.region) $2
in TSum {region; value=$2} } in TSum {region; value=$2} }
@ -234,7 +210,7 @@ record_type:
"record" sep_or_term_list(field_decl,";") "end" { "record" sep_or_term_list(field_decl,";") "end" {
let ne_elements, terminator = $2 in let ne_elements, terminator = $2 in
let () = Utils.nsepseq_to_list ne_elements let () = Utils.nsepseq_to_list ne_elements
|> SyntaxError.check_fields in |> Scoping.check_fields in
let region = cover $1 $3 let region = cover $1 $3
and value = {opening = Kwd $1; and value = {opening = Kwd $1;
ne_elements; ne_elements;
@ -268,21 +244,19 @@ fun_expr:
colon = $3; colon = $3;
ret_type = $4; ret_type = $4;
kwd_is = $5; kwd_is = $5;
return = $6 return = $6}
}
in {region; value} } in {region; value} }
(* Function declarations *) (* Function declarations *)
open_fun_decl: open_fun_decl:
"function" fun_name parameters ":" type_expr "is" "function" fun_name parameters ":" type_expr "is"
block block "with" expr {
"with" expr { Scoping.check_reserved_name $2;
let fun_name = SyntaxError.check_reserved_name $2 in
let stop = expr_to_region $9 in let stop = expr_to_region $9 in
let region = cover $1 stop let region = cover $1 stop
and value = {kwd_function = $1; and value = {kwd_function = $1;
fun_name; fun_name = $2;
param = $3; param = $3;
colon = $4; colon = $4;
ret_type = $5; ret_type = $5;
@ -290,14 +264,15 @@ open_fun_decl:
block_with = Some ($7, $8); block_with = Some ($7, $8);
return = $9; return = $9;
terminator = None; terminator = None;
attributes = {value = []; region = Region.ghost}} attributes = None}
in {region; value} } in {region; value}
}
| "function" fun_name parameters ":" type_expr "is" expr { | "function" fun_name parameters ":" type_expr "is" expr {
let fun_name = SyntaxError.check_reserved_name $2 in Scoping.check_reserved_name $2;
let stop = expr_to_region $7 in let stop = expr_to_region $7 in
let region = cover $1 stop let region = cover $1 stop
and value = {kwd_function = $1; and value = {kwd_function = $1;
fun_name; fun_name = $2;
param = $3; param = $3;
colon = $4; colon = $4;
ret_type = $5; ret_type = $5;
@ -305,39 +280,36 @@ open_fun_decl:
block_with = None; block_with = None;
return = $7; return = $7;
terminator = None; terminator = None;
attributes = {value = []; region = Region.ghost}} attributes = None}
in {region; value} } in {region; value} }
fun_decl: fun_decl:
open_fun_decl semi_attributes { open_fun_decl ";"? {
let attributes, terminator = $2 in {$1 with value = {$1.value with terminator=$2}} }
{$1 with value = {$1.value with terminator = terminator; attributes = attributes}}
}
parameters: parameters:
par(nsepseq(param_decl,";")) { par(nsepseq(param_decl,";")) {
let params = let params =
Utils.nsepseq_to_list ($1.value: _ par).inside Utils.nsepseq_to_list ($1.value: _ par).inside
in SyntaxError.check_parameters params; in Scoping.check_parameters params; $1 }
$1 }
param_decl: param_decl:
"var" var ":" param_type { "var" var ":" param_type {
let var = SyntaxError.check_reserved_name $2 in Scoping.check_reserved_name $2;
let stop = type_expr_to_region $4 in let stop = type_expr_to_region $4 in
let region = cover $1 stop let region = cover $1 stop
and value = {kwd_var = $1; and value = {kwd_var = $1;
var; var = $2;
colon = $3; colon = $3;
param_type = $4} param_type = $4}
in ParamVar {region; value} in ParamVar {region; value}
} }
| "const" var ":" param_type { | "const" var ":" param_type {
let var = SyntaxError.check_reserved_name $2 in Scoping.check_reserved_name $2;
let stop = type_expr_to_region $4 in let stop = type_expr_to_region $4 in
let region = cover $1 stop let region = cover $1 stop
and value = {kwd_const = $1; and value = {kwd_const = $1;
var; var = $2;
colon = $3; colon = $3;
param_type = $4} param_type = $4}
in ParamConst {region; value} } in ParamConst {region; value} }
@ -350,7 +322,7 @@ block:
let statements, terminator = $2 in let statements, terminator = $2 in
let region = cover $1 $3 let region = cover $1 $3
and value = {opening = Begin $1; and value = {opening = Begin $1;
statements = attributes_to_statement statements; statements;
terminator; terminator;
closing = End $3} closing = End $3}
in {region; value} in {region; value}
@ -359,15 +331,15 @@ block:
let statements, terminator = $3 in let statements, terminator = $3 in
let region = cover $1 $4 let region = cover $1 $4
and value = {opening = Block ($1,$2); and value = {opening = Block ($1,$2);
statements = attributes_to_statement statements; statements;
terminator; terminator;
closing = Block $4} closing = Block $4}
in {region; value} } in {region; value} }
statement: statement:
instruction { PInstr $1 } instruction { Instr $1 }
| open_data_decl { PData $1 } | open_data_decl { Data $1 }
| attributes { PAttributes $1 } | open_attr_decl { Attr $1 }
open_data_decl: open_data_decl:
open_const_decl { LocalConst $1 } open_const_decl { LocalConst $1 }
@ -385,10 +357,9 @@ open_const_decl:
equal; equal;
init; init;
terminator = None; terminator = None;
attributes = {value = []; region = Region.ghost}} attributes = None}
in {region; value} } in {region; value} }
open_var_decl: open_var_decl:
"var" unqualified_decl(":=") { "var" unqualified_decl(":=") {
let name, colon, var_type, assign, init, stop = $2 in let name, colon, var_type, assign, init, stop = $2 in
@ -399,33 +370,18 @@ open_var_decl:
var_type; var_type;
assign; assign;
init; init;
terminator = None; terminator=None}
}
in {region; value} } in {region; value} }
unqualified_decl(OP): unqualified_decl(OP):
var ":" type_expr OP expr { var ":" type_expr OP expr {
let var = SyntaxError.check_reserved_name $1 in Scoping.check_reserved_name $1;
let region = expr_to_region $5 let region = expr_to_region $5
in var, $2, $3, $4, $5, region } in $1, $2, $3, $4, $5, region }
attributes:
"attributes" "[" nsepseq(String,";") "]" {
let region = cover $1 $4 in
let value = (Utils.nsepseq_to_list $3) in
{region; value}
}
semi_attributes:
/* empty */ { {value = []; region = Region.ghost}, None }
| ";" { {value = []; region = Region.ghost}, Some $1 }
| ";" attributes ";" { $2, Some $1 }
const_decl: const_decl:
open_const_decl semi_attributes { open_const_decl ";"? {
let attributes, terminator = $2 in {$1 with value = {$1.value with terminator=$2}} }
{$1 with value = {$1.value with terminator = terminator; attributes = attributes }}
}
instruction: instruction:
conditional { Cond $1 } conditional { Cond $1 }
@ -589,7 +545,7 @@ clause_block:
let statements, terminator = $2 in let statements, terminator = $2 in
let region = cover $1 $3 in let region = cover $1 $3 in
let value = {lbrace = $1; let value = {lbrace = $1;
inside = attributes_to_statement statements, terminator; inside = statements, terminator;
rbrace = $3} in rbrace = $3} in
ShortBlock {value; region} } ShortBlock {value; region} }
@ -629,7 +585,7 @@ cases(rhs):
case_clause(rhs): case_clause(rhs):
pattern "->" rhs { pattern "->" rhs {
SyntaxError.check_pattern $1; Scoping.check_pattern $1;
fun rhs_to_region -> fun rhs_to_region ->
let start = pattern_to_region $1 in let start = pattern_to_region $1 in
let region = cover start (rhs_to_region $3) let region = cover start (rhs_to_region $3)
@ -671,10 +627,10 @@ for_loop:
in For (ForInt {region; value}) in For (ForInt {region; value})
} }
| "for" var arrow_clause? "in" collection expr block { | "for" var arrow_clause? "in" collection expr block {
let var = SyntaxError.check_reserved_name $2 in Scoping.check_reserved_name $2;
let region = cover $1 $7.region in let region = cover $1 $7.region in
let value = {kwd_for = $1; let value = {kwd_for = $1;
var; var = $2;
bind_to = $3; bind_to = $3;
kwd_in = $4; kwd_in = $4;
collection = $5; collection = $5;
@ -689,13 +645,13 @@ collection:
var_assign: var_assign:
var ":=" expr { var ":=" expr {
let name = SyntaxError.check_reserved_name $1 in Scoping.check_reserved_name $1;
let region = cover name.region (expr_to_region $3) let region = cover $1.region (expr_to_region $3)
and value = {name; assign=$2; expr=$3} and value = {name=$1; assign=$2; expr=$3}
in {region; value} } in {region; value} }
arrow_clause: arrow_clause:
"->" var { $1, SyntaxError.check_reserved_name $2 } "->" var { Scoping.check_reserved_name $2; ($1,$2) }
(* Expressions *) (* Expressions *)

View File

@ -114,29 +114,25 @@ let rec print_tokens state ast =
Utils.nseq_iter (print_decl state) decl; Utils.nseq_iter (print_decl state) decl;
print_token state eof "EOF" print_token state eof "EOF"
and print_attributes state attributes = and print_attr_decl state =
let attributes = List.fold_left (fun all a -> all ^ a.value ^ ";") "" attributes.value in print_ne_injection state "attributes" print_string
let line =
sprintf "attributes[%s]"
attributes
in Buffer.add_string state#buffer line
and print_decl state = function and print_decl state = function
TypeDecl decl -> print_type_decl state decl TypeDecl decl -> print_type_decl state decl
| ConstDecl decl -> print_const_decl state decl | ConstDecl decl -> print_const_decl state decl
| FunDecl decl -> print_fun_decl state decl | FunDecl decl -> print_fun_decl state decl
| AttrDecl decl -> print_attr_decl state decl
and print_const_decl state {value; _} = and print_const_decl state {value; _} =
let {kwd_const; name; colon; const_type; let {kwd_const; name; colon; const_type;
equal; init; terminator; attributes} = value in equal; init; terminator; _} = value in
print_token state kwd_const "const"; print_token state kwd_const "const";
print_var state name; print_var state name;
print_token state colon ":"; print_token state colon ":";
print_type_expr state const_type; print_type_expr state const_type;
print_token state equal "="; print_token state equal "=";
print_expr state init; print_expr state init;
print_terminator state terminator; print_terminator state terminator
print_attributes state attributes
and print_type_decl state {value; _} = and print_type_decl state {value; _} =
let {kwd_type; name; kwd_is; let {kwd_type; name; kwd_is;
@ -206,7 +202,7 @@ and print_type_tuple state {value; _} =
and print_fun_decl state {value; _} = and print_fun_decl state {value; _} =
let {kwd_function; fun_name; param; colon; let {kwd_function; fun_name; param; colon;
ret_type; kwd_is; block_with; ret_type; kwd_is; block_with;
return; terminator; attributes } = value in return; terminator; _} = value in
print_token state kwd_function "function"; print_token state kwd_function "function";
print_var state fun_name; print_var state fun_name;
print_parameters state param; print_parameters state param;
@ -220,7 +216,6 @@ and print_fun_decl state {value; _} =
print_token state kwd_with "with"); print_token state kwd_with "with");
print_expr state return; print_expr state return;
print_terminator state terminator; print_terminator state terminator;
print_attributes state attributes
and print_fun_expr state {value; _} = and print_fun_expr state {value; _} =
let {kwd_function; param; colon; let {kwd_function; param; colon;
@ -296,6 +291,7 @@ and print_statements state sequence =
and print_statement state = function and print_statement state = function
Instr instr -> print_instruction state instr Instr instr -> print_instruction state instr
| Data data -> print_data_decl state data | Data data -> print_data_decl state data
| Attr attr -> print_attr_decl state attr
and print_instruction state = function and print_instruction state = function
Cond {value; _} -> print_conditional state value Cond {value; _} -> print_conditional state value
@ -688,10 +684,10 @@ and print_opening state lexeme = function
print_token state kwd lexeme print_token state kwd lexeme
| KwdBracket (kwd, lbracket) -> | KwdBracket (kwd, lbracket) ->
print_token state kwd lexeme; print_token state kwd lexeme;
print_token state lbracket "{" print_token state lbracket "["
and print_closing state = function and print_closing state = function
RBracket rbracket -> print_token state rbracket "}" RBracket rbracket -> print_token state rbracket "]"
| End kwd_end -> print_token state kwd_end "end" | End kwd_end -> print_token state kwd_end "end"
and print_binding state {value; _} = and print_binding state {value; _} =
@ -848,21 +844,27 @@ and pp_declaration state = function
| FunDecl {value; region} -> | FunDecl {value; region} ->
pp_loc_node state "FunDecl" region; pp_loc_node state "FunDecl" region;
pp_fun_decl state value pp_fun_decl state value
| AttrDecl {value; region} ->
pp_loc_node state "AttrDecl" region;
pp_attr_decl state value
and pp_attr_decl state = pp_ne_injection pp_string state
and pp_fun_decl state decl = and pp_fun_decl state decl =
let arity = 5 in
let () = let () =
let state = state#pad 5 0 in let state = state#pad arity 0 in
pp_ident state decl.fun_name in pp_ident state decl.fun_name in
let () = let () =
let state = state#pad 5 1 in let state = state#pad arity 1 in
pp_node state "<parameters>"; pp_node state "<parameters>";
pp_parameters state decl.param in pp_parameters state decl.param in
let () = let () =
let state = state#pad 5 2 in let state = state#pad arity 2 in
pp_node state "<return type>"; pp_node state "<return type>";
pp_type_expr (state#pad 1 0) decl.ret_type in pp_type_expr (state#pad 1 0) decl.ret_type in
let () = let () =
let state = state#pad 5 3 in let state = state#pad arity 3 in
pp_node state "<body>"; pp_node state "<body>";
let statements = let statements =
match decl.block_with with match decl.block_with with
@ -870,15 +872,16 @@ and pp_fun_decl state decl =
| None -> Instr (Skip Region.ghost), [] in | None -> Instr (Skip Region.ghost), [] in
pp_statements state statements in pp_statements state statements in
let () = let () =
let state = state#pad 5 4 in let state = state#pad arity 4 in
pp_node state "<return>"; pp_node state "<return>";
pp_expr (state#pad 1 0) decl.return pp_expr (state#pad 1 0) decl.return
in () in ()
and pp_const_decl state decl = and pp_const_decl state decl =
pp_ident (state#pad 3 0) decl.name; let arity = 3 in
pp_type_expr (state#pad 3 1) decl.const_type; pp_ident (state#pad arity 0) decl.name;
pp_expr (state#pad 3 2) decl.init pp_type_expr (state#pad arity 1) decl.const_type;
pp_expr (state#pad arity 2) decl.init
and pp_type_expr state = function and pp_type_expr state = function
TProd cartesian -> TProd cartesian ->
@ -979,6 +982,9 @@ and pp_statement state = function
| Data data_decl -> | Data data_decl ->
pp_node state "Data"; pp_node state "Data";
pp_data_decl (state#pad 1 0) data_decl pp_data_decl (state#pad 1 0) data_decl
| Attr attr_decl ->
pp_node state "Attr";
pp_attr_decl state attr_decl.value
and pp_instruction state = function and pp_instruction state = function
Cond {value; region} -> Cond {value; region} ->

View File

@ -18,6 +18,7 @@ val print_tokens : state -> AST.t -> unit
val print_path : state -> AST.path -> unit val print_path : state -> AST.path -> unit
val print_pattern : state -> AST.pattern -> unit val print_pattern : state -> AST.pattern -> unit
val print_instruction : state -> AST.instruction -> unit val print_instruction : state -> AST.instruction -> unit
val print_expr : state -> AST.expr -> unit
(** {1 Printing tokens from the AST in a string} *) (** {1 Printing tokens from the AST in a string} *)
@ -30,6 +31,7 @@ val pattern_to_string :
val instruction_to_string : val instruction_to_string :
offsets:bool -> mode:[`Point|`Byte] -> AST.instruction -> string offsets:bool -> mode:[`Point|`Byte] -> AST.instruction -> string
(** {1 Pretty-printing of the AST} *) (** {1 Pretty-printing of AST nodes} *)
val pp_ast : state -> AST.t -> unit val pp_ast : state -> AST.t -> unit
val pp_expr : state -> AST.expr -> unit

View File

@ -6,100 +6,97 @@ module IO =
let options = EvalOpt.read "PascaLIGO" ext let options = EvalOpt.read "PascaLIGO" ext
end end
module ExtParser = module Parser =
struct struct
type ast = AST.t type ast = AST.t
type expr = AST.expr type expr = AST.expr
include Parser include Parser
end end
module ExtParserLog = module ParserLog =
struct struct
type ast = AST.t type ast = AST.t
type expr = AST.expr
include ParserLog include ParserLog
end end
module MyLexer = Lexer.Make (LexToken) module Lexer = Lexer.Make (LexToken)
module Unit = module Unit =
ParserUnit.Make (IO)(MyLexer)(AST)(ExtParser)(ParErr)(ExtParserLog) ParserUnit.Make (Lexer)(AST)(Parser)(ParErr)(ParserLog)(IO)
open! SyntaxError (* Main *)
let () = let issue_error point =
try Unit.run () with let error = Unit.format_error ~offsets:IO.options#offsets
(* Ad hoc errors from the parser *) IO.options#mode point
in Stdlib.Error error
Error (Reserved_name name) -> let parse parser : ('a,string) Stdlib.result =
let () = Unit.close_all () in try parser () with
(* Scoping errors *)
| Scoping.Error (Scoping.Duplicate_parameter name) ->
let token = let token =
MyLexer.Token.mk_ident name.Region.value name.Region.region in Lexer.Token.mk_ident name.Region.value name.Region.region in
(match token with (match token with
Stdlib.Error _ -> (* Cannot fail because [name] is a not a
assert false (* Should not fail if [name] is valid. *) reserved name for the lexer. *)
Stdlib.Error _ -> assert false
| Ok invalid -> | Ok invalid ->
let point = "Reserved name.\nHint: Change the name.\n", issue_error ("Duplicate parameter.\nHint: Change the name.\n",
None, invalid in None, invalid))
let error =
Unit.format_error ~offsets:IO.options#offsets
IO.options#mode point
in Printf.eprintf "\027[31m%s\027[0m%!" error)
| Error (Duplicate_parameter name) -> | Scoping.Error (Scoping.Reserved_name name) ->
let () = Unit.close_all () in
let token = let token =
MyLexer.Token.mk_ident name.Region.value name.Region.region in Lexer.Token.mk_ident name.Region.value name.Region.region in
(match token with (match token with
Stdlib.Error _ -> (* Cannot fail because [name] is a not a
assert false (* Should not fail if [name] is valid. *) reserved name for the lexer. *)
Stdlib.Error _ -> assert false
| Ok invalid -> | Ok invalid ->
let point = "Duplicate parameter.\nHint: Change the name.\n", issue_error
None, invalid in ("Reserved name.\nHint: Change the name.\n", None, invalid))
let error =
Unit.format_error ~offsets:IO.options#offsets
IO.options#mode point
in Printf.eprintf "\027[31m%s\027[0m%!" error)
| Error (Duplicate_variant name) -> | Scoping.Error (Scoping.Duplicate_variant name) ->
let () = Unit.close_all () in
let token = let token =
MyLexer.Token.mk_constr name.Region.value name.Region.region in Lexer.Token.mk_constr name.Region.value name.Region.region in
let point = "Duplicate variant in this sum type declaration.\n\ let point = "Duplicate constructor in this sum type declaration.\n\
Hint: Change the name.\n", Hint: Change the constructor.\n",
None, token in None, token
let error = in issue_error point
Unit.format_error ~offsets:IO.options#offsets
IO.options#mode point
in Printf.eprintf "\027[31m%s\027[0m%!" error
| Error (Non_linear_pattern var) -> | Scoping.Error (Scoping.Non_linear_pattern var) ->
let () = Unit.close_all () in
let token = let token =
MyLexer.Token.mk_ident var.Region.value var.Region.region in Lexer.Token.mk_ident var.Region.value var.Region.region in
(match token with (match token with
Stdlib.Error _ -> (* Cannot fail because [var] is a not a
assert false (* Should not fail if [name] is valid. *) reserved name for the lexer. *)
Stdlib.Error _ -> assert false
| Ok invalid -> | Ok invalid ->
let point = "Repeated variable in this pattern.\n\ let point = "Repeated variable in this pattern.\n\
Hint: Change the name.\n", Hint: Change the name.\n",
None, invalid in None, invalid
let error = in issue_error point)
Unit.format_error ~offsets:IO.options#offsets
IO.options#mode point
in Printf.eprintf "\027[31m%s\027[0m%!" error)
| Error (Duplicate_field name) -> | Scoping.Error (Scoping.Duplicate_field name) ->
let () = Unit.close_all () in
let token = let token =
MyLexer.Token.mk_ident name.Region.value name.Region.region in Lexer.Token.mk_ident name.Region.value name.Region.region in
(match token with (match token with
Stdlib.Error _ -> (* Cannot fail because [name] is a not a
assert false (* Should not fail if [name] is valid. *) reserved name for the lexer. *)
Stdlib.Error _ -> assert false
| Ok invalid -> | Ok invalid ->
let point = "Duplicate field name in this record declaration.\n\ let point = "Duplicate field name in this record declaration.\n\
Hint: Change the name.\n", Hint: Change the name.\n",
None, invalid in None, invalid
let error = in issue_error point)
Unit.format_error ~offsets:IO.options#offsets
IO.options#mode point let () =
in Printf.eprintf "\027[31m%s\027[0m%!" error) if IO.options#expr
then match parse (fun () -> Unit.parse Unit.parse_expr) with
Stdlib.Ok _ -> ()
| Error msg -> Printf.eprintf "\027[31m%s\027[0m%!" msg
else match parse (fun () -> Unit.parse Unit.parse_contract) with
Stdlib.Ok _ -> ()
| Error msg -> Printf.eprintf "\027[31m%s\027[0m%!" msg

View File

@ -1,12 +1,12 @@
[@@@warning "-42"] [@@@warning "-42"]
type t = type t =
Reserved_name of AST.variable Reserved_name of AST.variable
| Duplicate_parameter of AST.variable | Duplicate_parameter of AST.variable
| Duplicate_variant of AST.variable | Duplicate_variant of AST.variable
| Non_linear_pattern of AST.variable | Non_linear_pattern of AST.variable
| Duplicate_field of AST.variable | Duplicate_field of AST.variable
| Detached_attributes of AST.attributes
type error = t type error = t
@ -95,11 +95,6 @@ let check_reserved_names vars =
let check_reserved_name var = let check_reserved_name var =
if SSet.mem var.value reserved then if SSet.mem var.value reserved then
raise (Error (Reserved_name var)) raise (Error (Reserved_name var))
else var
let check_reserved_name_opt = function
Some var -> ignore (check_reserved_name var)
| None -> ()
(* Checking the linearity of patterns *) (* Checking the linearity of patterns *)

View File

@ -0,0 +1,18 @@
(* This module exports checks on scoping, called from the parser. *)
type t =
Reserved_name of AST.variable
| Duplicate_parameter of AST.variable
| Duplicate_variant of AST.variable
| Non_linear_pattern of AST.variable
| Duplicate_field of AST.variable
type error = t
exception Error of t
val check_reserved_name : AST.variable -> unit
val check_pattern : AST.pattern -> unit
val check_variants : AST.variant Region.reg list -> unit
val check_parameters : AST.param_decl list -> unit
val check_fields : AST.field_decl Region.reg list -> unit

View File

@ -1,27 +0,0 @@
type t =
Reserved_name of AST.variable
| Duplicate_parameter of AST.variable
| Duplicate_variant of AST.variable
| Non_linear_pattern of AST.variable
| Duplicate_field of AST.variable
| Detached_attributes of AST.attributes
type error = t
exception Error of t
module Ord :
sig
type t = AST.variable
val compare : t -> t -> int
end
module VarSet : Set.S with type elt = Ord.t
val check_reserved_name : AST.variable -> AST.variable
val check_reserved_name_opt : AST.variable option -> unit
val check_reserved_names : VarSet.t -> VarSet.t
val check_pattern : AST.pattern -> unit
val check_variants : AST.variant Region.reg list -> unit
val check_parameters : AST.param_decl list -> unit
val check_fields : AST.field_decl Region.reg list -> unit

View File

@ -63,12 +63,12 @@ function claim (var store : store) : list (operation) * store is
case store.backers[sender] of case store.backers[sender] of
None -> None ->
failwith ("Not a backer.") failwith ("Not a backer.")
| Some (amount) -> | Some (quantity) ->
if balance >= store.goal or store.funded then if balance >= store.goal or store.funded then
failwith ("Goal reached: no refund.") failwith ("Goal reached: no refund.")
else else
begin begin
operations.0.foo := list [transaction (unit, sender, amount)]; operations.0.foo := list [transaction (unit, sender, quantity)];
remove sender from map store.backers remove sender from map store.backers
end end
end end

View File

@ -1,10 +0,0 @@
#!/bin/sh
set -e
if test -d ../../.git; then
echo true > dot_git_is_dir
else
echo false > dot_git_is_dir
cat .git >> dot_git_is_dir
fi

View File

@ -15,7 +15,7 @@
(name parser_pascaligo) (name parser_pascaligo)
(public_name ligo.parser.pascaligo) (public_name ligo.parser.pascaligo)
(modules (modules
SyntaxError AST pascaligo Parser ParserLog LexToken) Scoping AST pascaligo Parser ParserLog LexToken ParErr)
(libraries (libraries
menhirLib menhirLib
parser_shared parser_shared
@ -53,32 +53,21 @@
(name ParserMain) (name ParserMain)
(libraries parser_pascaligo) (libraries parser_pascaligo)
(modules (modules
ParErr ParserMain) ParserMain)
(preprocess (preprocess
(pps bisect_ppx --conditional)) (pps bisect_ppx --conditional))
(flags (:standard -open Simple_utils -open Parser_shared -open Parser_pascaligo))) (flags (:standard -open Simple_utils -open Parser_shared -open Parser_pascaligo)))
;; Les deux directives (rule) qui suivent sont pour le dev local. ;; Build of the covering of error states in the LR automaton
;; Il suffit de faire "dune build Parser.exe" pour avoir un Parser.exe dans le dossier.
;; Pour le purger, il faut faire "dune clean".
;(rule
; (targets Parser.exe)
; (deps ParserMain.exe)
; (action (copy ParserMain.exe Parser.exe))
; (mode promote-until-clean))
;(rule
; (targets Lexer.exe)
; (deps LexerMain.exe)
; (action (copy LexerMain.exe Lexer.exe))
; (mode promote-until-clean))
(rule (rule
(targets Parser.msg) (targets Parser.msg)
(deps (:script_messages ../../../../vendors/ligo-utils/simple-utils/messages.sh) Parser.mly LexToken.mli ParToken.mly) (deps (:script_messages ../../../../vendors/ligo-utils/simple-utils/messages.sh) Parser.mly LexToken.mli ParToken.mly)
(action (run %{script_messages} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly Parser.mly ))) (action (run %{script_messages} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly Parser.mly)))
;; Build of all the LIGO source file that cover all error states
(rule (rule
(targets all.ligo) (targets all.ligo)
(deps (:script_cover ../../../../vendors/ligo-utils/simple-utils/cover.sh) Parser.mly LexToken.mli ParToken.mly Parser.msg Unlexer.exe) (deps (:script_cover ../../../../vendors/ligo-utils/simple-utils/cover.sh) Parser.mly LexToken.mli ParToken.mly Parser.msg Unlexer.exe)
(action (run %{script_cover} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly --ext=ligo --unlexer=./Unlexer.exe --messages=Parser.msg --dir=. --concatenate Parser.mly ))) (action (run %{script_cover} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly --ext=ligo --unlexer=./Unlexer.exe --messages=Parser.msg --dir=. --concatenate Parser.mly)))

View File

@ -1,5 +1,5 @@
module Parser = Parser
module AST = AST
module Lexer = Lexer module Lexer = Lexer
module LexToken = LexToken module LexToken = LexToken
module AST = AST
module Parser = Parser
module ParserLog = ParserLog module ParserLog = ParserLog

View File

@ -6,18 +6,17 @@ module ParserLog = Parser_cameligo.ParserLog
module LexToken = Parser_reasonligo.LexToken module LexToken = Parser_reasonligo.LexToken
module Lexer = Lexer.Make(LexToken) module Lexer = Lexer.Make(LexToken)
module SyntaxError = Parser_reasonligo.SyntaxError module SyntaxError = Parser_reasonligo.SyntaxError
module Scoping = Parser_cameligo.Scoping
module Errors = struct module Errors =
struct
let lexer_error (e: Lexer.error AST.reg) = let lexer_error (e: Lexer.error AST.reg) =
let title () = "lexer error" in let title () = "lexer error" in
let message () = Lexer.error_to_string e.value in let message () = Lexer.error_to_string e.value in
let data = [ let data = [
("parser_loc", ("parser_loc",
fun () -> Format.asprintf "%a" Location.pp_lift @@ e.region fun () -> Format.asprintf "%a" Location.pp_lift @@ e.region)]
) in error ~data title message
] in
error ~data title message
let wrong_function_arguments expr = let wrong_function_arguments expr =
let title () = "wrong function arguments" in let title () = "wrong function arguments" in
@ -25,68 +24,58 @@ module Errors = struct
let expression_loc = AST.expr_to_region expr in let expression_loc = AST.expr_to_region expr in
let data = [ let data = [
("location", ("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ expression_loc) fun () -> Format.asprintf "%a" Location.pp_lift @@ expression_loc)]
] in in error ~data title message
error ~data title message
let parser_error source (start: Lexing.position) (end_: Lexing.position) lexbuf = let parser_error source (start: Lexing.position)
(end_: Lexing.position) lexbuf =
let title () = "parser error" in let title () = "parser error" in
let file = if source = "" then let file =
"" if source = "" then ""
else else
Format.sprintf "In file \"%s|%s\"" start.pos_fname source Format.sprintf "In file \"%s|%s\"" start.pos_fname source in
in let str =
let str = Format.sprintf Format.sprintf
"Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n" "Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n"
(Lexing.lexeme lexbuf) (Lexing.lexeme lexbuf)
start.pos_lnum (start.pos_cnum - start.pos_bol) start.pos_lnum (start.pos_cnum - start.pos_bol)
end_.pos_lnum (end_.pos_cnum - end_.pos_bol) end_.pos_lnum (end_.pos_cnum - end_.pos_bol)
file file in
in
let message () = str in let message () = str in
let loc = if start.pos_cnum = -1 then let loc =
Region.make if start.pos_cnum = -1
~start: Pos.min then Region.make
~start:(Pos.min ~file:source)
~stop:(Pos.from_byte end_) ~stop:(Pos.from_byte end_)
else else Region.make
Region.make
~start:(Pos.from_byte start) ~start:(Pos.from_byte start)
~stop:(Pos.from_byte end_) ~stop:(Pos.from_byte end_) in
in
let data = let data =
[ [("parser_loc",
("parser_loc", fun () -> Format.asprintf "%a" Location.pp_lift @@ loc)]
fun () -> Format.asprintf "%a" Location.pp_lift @@ loc in error ~data title message
)
]
in
error ~data title message
let unrecognized_error source (start: Lexing.position) (end_: Lexing.position) lexbuf = let unrecognized_error source (start: Lexing.position) (end_: Lexing.position) lexbuf =
let title () = "unrecognized error" in let title () = "unrecognized error" in
let file = if source = "" then let file =
"" if source = "" then ""
else else
Format.sprintf "In file \"%s|%s\"" start.pos_fname source Format.sprintf "In file \"%s|%s\"" start.pos_fname source in
in let str =
let str = Format.sprintf Format.sprintf
"Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n" "Parse error at \"%s\" from (%d, %d) to (%d, %d). %s\n"
(Lexing.lexeme lexbuf) (Lexing.lexeme lexbuf)
start.pos_lnum (start.pos_cnum - start.pos_bol) start.pos_lnum (start.pos_cnum - start.pos_bol)
end_.pos_lnum (end_.pos_cnum - end_.pos_bol) end_.pos_lnum (end_.pos_cnum - end_.pos_bol)
file file in
in
let message () = str in let message () = str in
let loc = Region.make let loc = Region.make
~start:(Pos.from_byte start) ~start:(Pos.from_byte start)
~stop:(Pos.from_byte end_) ~stop:(Pos.from_byte end_) in
in
let data = [ let data = [
("location", ("location",
fun () -> Format.asprintf "%a" Location.pp_lift @@ loc fun () -> Format.asprintf "%a" Location.pp_lift @@ loc)]
) in error ~data title message
] in
error ~data title message
end end

View File

@ -1,5 +1,4 @@
$HOME/git/OCaml-build/Makefile $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.mli
$HOME/git/ligo/vendors/ligo-utils/simple-utils/pos.ml $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.mli
@ -22,7 +21,8 @@ $HOME/git/ligo/vendors/ligo-utils/simple-utils/region.ml
../shared/ParserUnit.ml ../shared/ParserUnit.ml
Stubs/Simple_utils.ml Stubs/Simple_utils.ml
Stubs/Parser_cameligo.ml Stubs/Parser_cameligo.ml
../cameligo/AST.mli
../cameligo/AST.ml ../cameligo/AST.ml
../cameligo/ParserLog.mli ../cameligo/ParserLog.mli
../cameligo/ParserLog.ml ../cameligo/ParserLog.ml
../cameligo/Scoping.mli
../cameligo/Scoping.ml

View File

@ -143,8 +143,7 @@ val mk_int : lexeme -> Region.t -> (token, int_err) result
val mk_nat : lexeme -> Region.t -> (token, nat_err) result val mk_nat : lexeme -> Region.t -> (token, nat_err) result
val mk_mutez : lexeme -> Region.t -> (token, int_err) result val mk_mutez : lexeme -> Region.t -> (token, int_err) result
val mk_ident : lexeme -> Region.t -> (token, ident_err) result val mk_ident : lexeme -> Region.t -> (token, ident_err) result
val mk_attr : lexeme -> Region.t -> (token, attr_err) result val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
val mk_attr2 : lexeme -> Region.t -> (token, attr_err) result
val mk_sym : lexeme -> Region.t -> (token, sym_err) result val mk_sym : lexeme -> Region.t -> (token, sym_err) result
val mk_kwd : lexeme -> Region.t -> (token, kwd_err) result val mk_kwd : lexeme -> Region.t -> (token, kwd_err) result
val mk_string : lexeme -> Region.t -> token val mk_string : lexeme -> Region.t -> token

View File

@ -453,11 +453,10 @@ let mk_constr lexeme region = mk_constr' lexeme region lexicon
(* Attributes *) (* Attributes *)
let mk_attr lexeme region = let mk_attr header lexeme region =
Ok (Attr { value = lexeme; region }) if header = "[@" then
Ok (Attr Region.{value=lexeme; region})
let mk_attr2 _lexeme _region = else Error Invalid_attribute
Error Invalid_attribute
(* Predicates *) (* Predicates *)

View File

@ -0,0 +1,5 @@
SHELL := dash
BFLAGS := -strict-sequence -w +A-48-4 -g
clean::
> rm -f Parser.msg Parser.msg.map Parser.msg.states Version.ml

View File

@ -0,0 +1,65 @@
type error =
IntErr of LexToken.int_err
| IdentErr of LexToken.ident_err
| NatErr of LexToken.nat_err
| SymErr of LexToken.sym_err
| KwdErr of LexToken.kwd_err
let rec first_of_expr = function
ECase {value; _} ->
(match LexToken.mk_kwd "switch" value.kwd_match with
Error e -> Error (KwdErr e)
| Ok token -> Ok token)
| ECond {value; _} ->
(match LexToken.mk_kwd "if" value.kwd_if with
Error e -> Error (KwdErr e)
| Ok token -> Ok token)
| EPar {value; _} ->
(match LexToken.mk_sym "(" value.lpar with
Error e -> Error (SymErr e)
| Ok token -> Ok token)
| EAnnot {value; _} ->
(match LexToken.mk_sym "(" value.lpar with
Error e -> Error (SymErr e)
| Ok token -> Ok token)
| EUnit {value=opening, _; _} ->
(match LexToken.mk_sym "(" opening with
Error e -> Error (SymErr e)
| Ok token -> Ok token)
| EBytes b ->
Ok (LexToken.mk_bytes (fst b.value) b.region)
| EVar v ->
(match LexToken.mk_ident v.value v.region with
Error e -> Error (IdentErr e)
| Ok token -> Ok token)
| ESeq {value; _} ->
let opening =
match value.compound with
BeginEnd (opening, _)
| Braces (opening, _)
| Brackets (opening, _) -> opening
in (match LexToken.mk_sym "{" opening with
Error e -> Error (SymErr e)
| Ok token -> Ok token)
| EProj {value; _} ->
let structure = value.struct_name in
(match LexToken.mk_ident structure.value structure.region with
Error e -> Error (IdentErr e)
| Ok token -> Ok token)
| EFun {value; _} ->
(match LexToken.mk_kwd "fun" value.kwd_fun with
Error e -> Error (KwdErr e)
| Ok token -> Ok token)
| _ -> failwith "TODO"
(*
| ELogic expr -> first_of_logic_expr expr
| EArith expr -> first_of_arith_expr expr
| EString expr -> first_of_string_expr expr
| EList expr -> first_of_list_expr expr
| EConstr expr -> first_of_constr_expr expr
| ECall {value=expr,_; _} -> first_of_expr expr
| ERecord {value; _} -> (*field_assign reg ne_injection *)
| ETuple {value; _} -> (* (expr, comma) nsepseq *)
| ELetIn {value; _} -> first_of_let_in value
*)

View File

@ -46,9 +46,9 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 11 -> | 11 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 509 -> | 528 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 503 -> | 61 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 48 -> | 48 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
@ -68,335 +68,387 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 14 -> | 14 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 60 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 65 -> | 65 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 505 -> | 70 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 145 -> | 524 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 146 -> | 185 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 144 -> | 186 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 329 -> | 184 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 331 -> | 302 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 330 -> | 304 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 61 -> | 303 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 66 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 69 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 64 -> | 64 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 59 -> | 183 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 143 -> | 311 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 338 -> | 313 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 340 -> | 312 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 339 -> | 191 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 151 -> | 192 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 152 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 78 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 325 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 327 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 326 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 92 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 155 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 118 -> | 118 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 125 -> | 298 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 87 -> | 300 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 105 -> | 299 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 107 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 108 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 106 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 88 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 93 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 80 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 81 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 82 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 132 -> | 132 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 334 -> | 195 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 336 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 335 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 133 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 136 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 137 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 157 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 159 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 158 -> | 158 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 512 -> | 165 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 218 -> | 127 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 514 -> | 145 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 216 -> | 147 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 250 -> | 148 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 248 -> | 146 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 249 -> | 128 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 230 -> | 133 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 235 -> | 120 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 252 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 254 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 255 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 258 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 219 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 226 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 227 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 260 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 262 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 264 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 266 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 194 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 195 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 206 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 215 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 199 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 207 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 208 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 196 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 197 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 198 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 256 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 257 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 277 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 233 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 279 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 67 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 463 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 464 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 387 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 121 -> | 121 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 122 -> | 122 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 120 -> | 172 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 466 -> | 307 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 467 -> | 309 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 308 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 173 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 176 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 177 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 197 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 199 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 198 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 59 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 531 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 225 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 533 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 223 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 257 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 255 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 256 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 237 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 242 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 259 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 261 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 262 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 265 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 226 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 233 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 234 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 267 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 269 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 271 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 273 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 201 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 202 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 213 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 222 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 206 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 214 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 215 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 203 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 204 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 205 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 263 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 284 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 240 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 286 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 72 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 483 -> | 483 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 492 -> | 484 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 469 -> | 423 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 470 -> | 161 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 468 -> | 162 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 471 -> | 160 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 472 -> | 486 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 473 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 475 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 476 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 477 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 478 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 487 -> | 487 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 488 -> | 504 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 474 -> | 513 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 498 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 499 -> | 499 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 497 -> | 497 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 465 -> | 488 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 321 -> | 489 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 490 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 492 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 493 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 494 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 495 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 509 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 510 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 491 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 520 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 518 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 485 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 372 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 366 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 367 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 369 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 368 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 365 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 76 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 446 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 326 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 332 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 333 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 336 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 337 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 328 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 339 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 100 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 78 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 80 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 315 -> | 315 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 316 -> | 316 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 318 -> | 117 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 317 -> | 82 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 314 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 71 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 410 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 298 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 304 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 305 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 308 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 309 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 300 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 178 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 73 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 75 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 419 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 420 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 77 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 160 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 412 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 413 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 415 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 416 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 193 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 229 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 74 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 447 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 448 -> | 448 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 456 -> | 449 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 457 -> | 451 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 459 -> | 452 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 200 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 236 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 79 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 467 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 468 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 476 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 477 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 479 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 480 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 469 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 470 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 81 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 460 -> | 460 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 449 -> | 461 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 450 -> | 455 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 76 -> | 454 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 458 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 348 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 356 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 360 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 359 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 355 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 349 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 457 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 340 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 341 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 346 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 347 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 342 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 343 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 344 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 84 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 85 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 318 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 323 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 324 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 389 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 436 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 437 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 438 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 439 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 440 -> | 440 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 441 -> | 441 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 425 -> | 435 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 422 -> | 325 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 428 -> | 362 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 429 -> | 363 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 434 -> | 373 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 438 -> | 374 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 437 -> | 413 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 433 -> | 420 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 423 -> | 408 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 427 -> | 409 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 162 -> | 407 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 163 -> | 375 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 290 -> | 376 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 295 -> | 377 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 296 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 357 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 400 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 401 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 402 -> | 402 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
@ -406,105 +458,69 @@ let message =
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 405 -> | 405 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 399 -> | 417 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 297 -> | 418 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 311 -> | 401 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 312 -> | 429 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 322 -> | 427 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 323 -> | 364 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 377 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 384 -> | 384 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 342 -> | 385 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 343 -> | 383 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 324 -> | 378 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 344 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 345 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 346 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 370 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 371 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 372 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 373 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 379 -> | 379 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 380 -> | 380 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 369 -> | 394 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 395 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 396 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 397 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 399 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 398 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 393 -> | 393 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 391 -> | 320 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 313 -> | 321 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 348 -> | 86 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 349 -> | 87 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 347 -> | 88 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 350 -> | 89 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 351 -> | 90 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 352 -> | 91 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 359 -> | 96 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 360 -> | 97 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 361 -> | 98 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 362 -> | 111 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 364 -> | 244 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 363 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 358 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 292 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 293 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 164 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 165 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 166 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 167 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 168 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 169 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 174 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 175 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 176 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 188 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| 237 ->
"<YOUR SYNTAX ERROR MESSAGE HERE>\n" "<YOUR SYNTAX ERROR MESSAGE HERE>\n"
| _ -> | _ ->
raise Not_found raise Not_found

View File

@ -148,6 +148,7 @@ declaration:
type_decl: type_decl:
"type" type_name "=" type_expr { "type" type_name "=" type_expr {
Scoping.check_reserved_name $2;
let region = cover $1 (type_expr_to_region $4) let region = cover $1 (type_expr_to_region $4)
and value = {kwd_type = $1; and value = {kwd_type = $1;
name = $2; name = $2;
@ -192,6 +193,7 @@ core_type:
sum_type: sum_type:
"|" nsepseq(variant,"|") { "|" nsepseq(variant,"|") {
Scoping.check_variants (Utils.nsepseq_to_list $2);
let region = nsepseq_to_region (fun x -> x.region) $2 let region = nsepseq_to_region (fun x -> x.region) $2
in TSum {region; value=$2} } in TSum {region; value=$2} }
@ -205,6 +207,8 @@ variant:
record_type: record_type:
"{" sep_or_term_list(field_decl,",") "}" { "{" sep_or_term_list(field_decl,",") "}" {
let ne_elements, terminator = $2 in let ne_elements, terminator = $2 in
let () = Utils.nsepseq_to_list ne_elements
|> Scoping.check_fields in
let region = cover $1 $3 let region = cover $1 $3
and value = {compound = Braces ($1,$3); ne_elements; terminator} and value = {compound = Braces ($1,$3); ne_elements; terminator}
in TRecord {region; value} } in TRecord {region; value} }
@ -240,21 +244,25 @@ es6_func:
let_binding: let_binding:
"<ident>" type_annotation? "=" expr { "<ident>" type_annotation? "=" expr {
{binders = PVar $1,[]; lhs_type=$2; eq=$3; let_rhs=$4} Scoping.check_reserved_name $1;
{binders = PVar $1, []; lhs_type=$2; eq=$3; let_rhs=$4}
} }
| "_" type_annotation? "=" expr { | "_" type_annotation? "=" expr {
{binders = PWild $1,[]; lhs_type=$2; eq=$3; let_rhs=$4} {binders = PWild $1, []; lhs_type=$2; eq=$3; let_rhs=$4}
} }
| unit type_annotation? "=" expr { | unit type_annotation? "=" expr {
{binders = PUnit $1,[]; lhs_type=$2; eq=$3; let_rhs=$4} {binders = PUnit $1, []; lhs_type=$2; eq=$3; let_rhs=$4}
} }
| record_pattern type_annotation? "=" expr { | record_pattern type_annotation? "=" expr {
Scoping.check_pattern (PRecord $1);
{binders = PRecord $1, []; lhs_type=$2; eq=$3; let_rhs=$4} {binders = PRecord $1, []; lhs_type=$2; eq=$3; let_rhs=$4}
} }
| par(closed_irrefutable) type_annotation? "=" expr { | par(closed_irrefutable) type_annotation? "=" expr {
Scoping.check_pattern $1.value.inside;
{binders = PPar $1, []; lhs_type=$2; eq=$3; let_rhs=$4} {binders = PPar $1, []; lhs_type=$2; eq=$3; let_rhs=$4}
} }
| tuple(sub_irrefutable) type_annotation? "=" expr { | tuple(sub_irrefutable) type_annotation? "=" expr {
Utils.nsepseq_iter Scoping.check_pattern $1;
let hd, tl = $1 in let hd, tl = $1 in
let start = pattern_to_region hd in let start = pattern_to_region hd in
let stop = last fst tl in let stop = last fst tl in
@ -419,8 +427,11 @@ fun_expr:
let region = cover start stop in let region = cover start stop in
let rec arg_to_pattern = function let rec arg_to_pattern = function
EVar v -> PVar v EVar v ->
Scoping.check_reserved_name v;
PVar v
| EAnnot {region; value = {inside = EVar v, colon, typ; _}} -> | EAnnot {region; value = {inside = EVar v, colon, typ; _}} ->
Scoping.check_reserved_name v;
let value = {pattern = PVar v; colon; type_expr = typ} let value = {pattern = PVar v; colon; type_expr = typ}
in PTyped {region; value} in PTyped {region; value}
| EPar p -> | EPar p ->
@ -428,8 +439,22 @@ fun_expr:
{p.value with inside = arg_to_pattern p.value.inside} {p.value with inside = arg_to_pattern p.value.inside}
in PPar {p with value} in PPar {p with value}
| EUnit u -> PUnit u | EUnit u -> PUnit u
| e -> let open! SyntaxError | ETuple { value; region } ->
in raise (Error (WrongFunctionArguments e)) PTuple { value = Utils.nsepseq_map arg_to_pattern value; region}
| EAnnot {region; value = {inside = t, colon, typ; _}} ->
let value = { pattern = arg_to_pattern t; colon; type_expr = typ} in
PPar {
value = {
lpar = Region.ghost;
rpar = Region.ghost;
inside = PTyped {region; value}
};
region
}
| e -> (
let open! SyntaxError in
raise (Error (WrongFunctionArguments e))
)
in in
let fun_args_to_pattern = function let fun_args_to_pattern = function
EAnnot { EAnnot {
@ -454,8 +479,9 @@ fun_expr:
arg_to_pattern (EAnnot e), [] arg_to_pattern (EAnnot e), []
| ETuple {value = fun_args; _} -> | ETuple {value = fun_args; _} ->
let bindings = let bindings =
List.map (arg_to_pattern <@ snd) (snd fun_args) List.map (arg_to_pattern <@ snd) (snd fun_args) in
in arg_to_pattern (fst fun_args), bindings List.iter Scoping.check_pattern bindings;
arg_to_pattern (fst fun_args), bindings
| EUnit e -> | EUnit e ->
arg_to_pattern (EUnit e), [] arg_to_pattern (EUnit e), []
| e -> let open! SyntaxError | e -> let open! SyntaxError
@ -541,6 +567,7 @@ cases(right_expr):
case_clause(right_expr): case_clause(right_expr):
"|" pattern "=>" right_expr ";"? { "|" pattern "=>" right_expr ";"? {
Scoping.check_pattern $2;
let start = pattern_to_region $2 let start = pattern_to_region $2
and stop = expr_to_region $4 in and stop = expr_to_region $4 in
let region = cover start stop let region = cover start stop

View File

@ -6,32 +6,37 @@ module IO =
let options = EvalOpt.read "ReasonLIGO" ext let options = EvalOpt.read "ReasonLIGO" ext
end end
module ExtParser = module Parser =
struct struct
type ast = AST.t type ast = AST.t
type expr = AST.expr type expr = AST.expr
include Parser include Parser
end end
module ExtParserLog = module ParserLog =
struct struct
type ast = AST.t type ast = AST.t
type expr = AST.expr
include ParserLog include ParserLog
end end
module MyLexer = Lexer.Make (LexToken) module Lexer = Lexer.Make (LexToken)
module Unit = module Unit =
ParserUnit.Make (IO)(MyLexer)(AST)(ExtParser)(ParErr)(ExtParserLog) ParserUnit.Make (Lexer)(AST)(Parser)(ParErr)(ParserLog)(IO)
(* Main *) (* Main *)
let () = let issue_error point =
try Unit.run () with let error = Unit.format_error ~offsets:IO.options#offsets
(* Ad hoc errors from the parsers *) IO.options#mode point
in Stdlib.Error error
let parse parser : ('a,string) Stdlib.result =
try parser () with
(* Ad hoc errors from the parser *)
SyntaxError.Error (SyntaxError.WrongFunctionArguments expr) -> SyntaxError.Error (SyntaxError.WrongFunctionArguments expr) ->
let () = Unit.close_all () in
let msg = "It looks like you are defining a function, \ let msg = "It looks like you are defining a function, \
however we do not\n\ however we do not\n\
understand the parameters declaration.\n\ understand the parameters declaration.\n\
@ -41,4 +46,61 @@ let () =
and reg = AST.expr_to_region expr in and reg = AST.expr_to_region expr in
let error = Unit.short_error ~offsets:IO.options#offsets let error = Unit.short_error ~offsets:IO.options#offsets
IO.options#mode msg reg IO.options#mode msg reg
in Printf.eprintf "\027[31m%s\027[0m%!" error in Stdlib.Error error
(* Scoping errors *)
| Scoping.Error (Scoping.Reserved_name name) ->
let token =
Lexer.Token.mk_ident name.Region.value name.Region.region in
(match token with
(* Cannot fail because [name] is a not a
reserved name for the lexer. *)
Stdlib.Error _ -> assert false
| Ok invalid ->
issue_error
("Reserved name.\nHint: Change the name.\n", None, invalid))
| Scoping.Error (Scoping.Duplicate_variant name) ->
let token =
Lexer.Token.mk_constr name.Region.value name.Region.region in
let point = "Duplicate constructor in this sum type declaration.\n\
Hint: Change the constructor.\n",
None, token
in issue_error point
| Scoping.Error (Scoping.Non_linear_pattern var) ->
let token =
Lexer.Token.mk_ident var.Region.value var.Region.region in
(match token with
(* Cannot fail because [var] is a not a
reserved name for the lexer. *)
Stdlib.Error _ -> assert false
| Ok invalid ->
let point = "Repeated variable in this pattern.\n\
Hint: Change the name.\n",
None, invalid
in issue_error point)
| Scoping.Error (Scoping.Duplicate_field name) ->
let token =
Lexer.Token.mk_ident name.Region.value name.Region.region in
(match token with
(* Cannot fail because [name] is a not a
reserved name for the lexer. *)
Stdlib.Error _ -> assert false
| Ok invalid ->
let point =
"Duplicate field name in this record declaration.\n\
Hint: Change the name.\n",
None, invalid
in issue_error point)
let () =
if IO.options#expr
then match parse (fun () -> Unit.parse Unit.parse_expr) with
Stdlib.Ok _ -> ()
| Error msg -> Printf.eprintf "\027[31m%s\027[0m%!" msg
else match parse (fun () -> Unit.parse Unit.parse_contract) with
Stdlib.Ok _ -> ()
| Error msg -> Printf.eprintf "\027[31m%s\027[0m%!" msg

View File

@ -1,10 +1,16 @@
;; Build of the lexer
(ocamllex LexToken) (ocamllex LexToken)
;; Build of the parser
(menhir (menhir
(merge_into Parser) (merge_into Parser)
(modules ParToken Parser) (modules ParToken Parser)
(flags -la 1 --table --explain --strict --external-tokens LexToken)) (flags -la 1 --table --explain --strict --external-tokens LexToken))
;; Build of the parser as a library
(library (library
(name parser_reasonligo) (name parser_reasonligo)
(public_name ligo.parser.reasonligo) (public_name ligo.parser.reasonligo)
@ -22,6 +28,18 @@
(pps bisect_ppx --conditional)) (pps bisect_ppx --conditional))
(flags (:standard -open Simple_utils -open Parser_shared -open Parser_cameligo))) (flags (:standard -open Simple_utils -open Parser_shared -open Parser_cameligo)))
;; Build of the unlexer (for covering the
;; error states of the LR automaton)
(executable
(name Unlexer)
(libraries str)
(preprocess
(pps bisect_ppx --conditional))
(modules Unlexer))
;; Local build of a standalone lexer
(executable (executable
(name LexerMain) (name LexerMain)
(libraries parser_reasonligo) (libraries parser_reasonligo)
@ -30,6 +48,8 @@
(pps bisect_ppx --conditional)) (pps bisect_ppx --conditional))
(flags (:standard -open Parser_shared -open Parser_reasonligo))) (flags (:standard -open Parser_shared -open Parser_reasonligo)))
;; Local build of a standalone parser
(executable (executable
(name ParserMain) (name ParserMain)
(libraries (libraries
@ -41,19 +61,16 @@
(pps bisect_ppx --conditional)) (pps bisect_ppx --conditional))
(flags (:standard -open Simple_utils -open Parser_cameligo -open Parser_shared -open Parser_reasonligo))) (flags (:standard -open Simple_utils -open Parser_cameligo -open Parser_shared -open Parser_reasonligo)))
(executable ;; Build of the covering of error states in the LR automaton
(name Unlexer)
(libraries str)
(preprocess
(pps bisect_ppx --conditional))
(modules Unlexer))
(rule (rule
(targets Parser.msg) (targets Parser.msg)
(deps (:script_messages ../../../../vendors/ligo-utils/simple-utils/messages.sh) Parser.mly LexToken.mli ParToken.mly) (deps (:script_messages ../../../../vendors/ligo-utils/simple-utils/messages.sh) Parser.mly LexToken.mli ParToken.mly)
(action (run %{script_messages} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly Parser.mly ))) (action (run %{script_messages} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly Parser.mly )))
;; Build of all the LIGO source file that cover all error states
(rule (rule
(targets all.ligo) (targets all.religo)
(deps (:script_cover ../../../../vendors/ligo-utils/simple-utils/cover.sh) Parser.mly LexToken.mli ParToken.mly Parser.msg Unlexer.exe) (deps (:script_cover ../../../../vendors/ligo-utils/simple-utils/cover.sh) Parser.mly LexToken.mli ParToken.mly Parser.msg Unlexer.exe)
(action (run %{script_cover} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly --ext=ligo --unlexer=./Unlexer.exe --messages=Parser.msg --dir=. --concatenate Parser.mly ))) (action (run %{script_cover} --lex-tokens=LexToken.mli --par-tokens=ParToken.mly --ext=religo --unlexer=./Unlexer.exe --messages=Parser.msg --dir=. --concatenate Parser.mly )))

View File

@ -14,10 +14,11 @@ type options = <
offsets : bool; offsets : bool;
mode : [`Byte | `Point]; mode : [`Byte | `Point];
cmd : command; cmd : command;
mono : bool mono : bool;
expr : bool
> >
let make ~input ~libs ~verbose ~offsets ~mode ~cmd ~mono = let make ~input ~libs ~verbose ~offsets ~mode ~cmd ~mono ~expr =
object object
method input = input method input = input
method libs = libs method libs = libs
@ -26,6 +27,7 @@ let make ~input ~libs ~verbose ~offsets ~mode ~cmd ~mono =
method mode = mode method mode = mode
method cmd = cmd method cmd = cmd
method mono = mono method mono = mono
method expr = expr
end end
(** {1 Auxiliary functions} *) (** {1 Auxiliary functions} *)
@ -42,17 +44,18 @@ let abort msg =
let help language extension () = let help language extension () =
let file = Filename.basename Sys.argv.(0) in let file = Filename.basename Sys.argv.(0) in
printf "Usage: %s [<option> ...] [<input>%s | \"-\"]\n" file extension; printf "Usage: %s [<option> ...] [<input>%s | \"-\"]\n" file extension;
printf "where <input>%s is the %s source file (default: stdin)," extension language; printf "where <input>%s is the %s source file (default: stdin),\n" extension language;
print "and each <option> (if any) is one of the following:"; print "and each <option> (if any) is one of the following:";
print " -I <paths> Library paths (colon-separated)"; print " -I <paths> Library paths (colon-separated)";
print " -c, --copy Print lexemes of tokens and markup (lexer)"; print " -t, --tokens Print tokens";
print " -t, --tokens Print tokens (lexer)"; print " -u, --units Print lexical units";
print " -u, --units Print tokens and markup (lexer)"; print " -c, --copy Print lexemes and markup";
print " -q, --quiet No output, except errors (default)"; print " -q, --quiet No output, except errors (default)";
print " --columns Columns for source locations"; print " --columns Columns for source locations";
print " --bytes Bytes for source locations"; print " --bytes Bytes for source locations";
print " --mono Use Menhir monolithic API"; print " --mono Use Menhir monolithic API";
print " --verbose=<stages> cmdline, cpp, ast-tokens, ast (colon-separated)"; print " --expr Parse an expression";
print " --verbose=<stages> cli, cpp, ast-tokens, ast (colon-separated)";
print " --version Commit hash on stdout"; print " --version Commit hash on stdout";
print " -h, --help This help"; print " -h, --help This help";
exit 0 exit 0
@ -74,6 +77,7 @@ and input = ref None
and libs = ref [] and libs = ref []
and verb_str = ref "" and verb_str = ref ""
and mono = ref false and mono = ref false
and expr = ref false
let split_at_colon = Str.(split (regexp ":")) let split_at_colon = Str.(split (regexp ":"))
@ -94,6 +98,7 @@ let specs language extension =
noshort, "columns", set columns true, None; noshort, "columns", set columns true, None;
noshort, "bytes", set bytes true, None; noshort, "bytes", set bytes true, None;
noshort, "mono", set mono true, None; noshort, "mono", set mono true, None;
noshort, "expr", set expr true, None;
noshort, "verbose", None, Some add_verbose; noshort, "verbose", None, Some add_verbose;
'h', "help", Some (help language extension), None; 'h', "help", Some (help language extension), None;
noshort, "version", Some version, None noshort, "version", Some version, None
@ -129,7 +134,8 @@ let print_opt () =
printf "quiet = %b\n" !quiet; printf "quiet = %b\n" !quiet;
printf "columns = %b\n" !columns; printf "columns = %b\n" !columns;
printf "bytes = %b\n" !bytes; printf "bytes = %b\n" !bytes;
printf "mono = %b\b" !mono; printf "mono = %b\n" !mono;
printf "expr = %b\n" !expr;
printf "verbose = %s\n" !verb_str; printf "verbose = %s\n" !verb_str;
printf "input = %s\n" (string_of quote !input); printf "input = %s\n" (string_of quote !input);
printf "libs = %s\n" (string_of_path !libs) printf "libs = %s\n" (string_of_path !libs)
@ -137,7 +143,7 @@ let print_opt () =
let check extension = let check extension =
let () = let () =
if Utils.String.Set.mem "cmdline" !verbose then print_opt () in if Utils.String.Set.mem "cli" !verbose then print_opt () in
let input = let input =
match !input with match !input with
@ -158,11 +164,12 @@ let check extension =
and offsets = not !columns and offsets = not !columns
and mode = if !bytes then `Byte else `Point and mode = if !bytes then `Byte else `Point
and mono = !mono and mono = !mono
and expr = !expr
and verbose = !verbose and verbose = !verbose
and libs = !libs in and libs = !libs in
let () = let () =
if Utils.String.Set.mem "cmdline" verbose then if Utils.String.Set.mem "cli" verbose then
begin begin
printf "\nEXPORTED COMMAND LINE\n"; printf "\nEXPORTED COMMAND LINE\n";
printf "copy = %b\n" copy; printf "copy = %b\n" copy;
@ -172,6 +179,7 @@ let check extension =
printf "offsets = %b\n" offsets; printf "offsets = %b\n" offsets;
printf "mode = %s\n" (if mode = `Byte then "`Byte" else "`Point"); printf "mode = %s\n" (if mode = `Byte then "`Byte" else "`Point");
printf "mono = %b\n" mono; printf "mono = %b\n" mono;
printf "expr = %b\n" expr;
printf "verbose = %s\n" !verb_str; printf "verbose = %s\n" !verb_str;
printf "input = %s\n" (string_of quote input); printf "input = %s\n" (string_of quote input);
printf "libs = %s\n" (string_of_path libs) printf "libs = %s\n" (string_of_path libs)
@ -186,7 +194,7 @@ let check extension =
| false, false, false, true -> Tokens | false, false, false, true -> Tokens
| _ -> abort "Choose one of -q, -c, -u, -t." | _ -> abort "Choose one of -q, -c, -u, -t."
in make ~input ~libs ~verbose ~offsets ~mode ~cmd ~mono in make ~input ~libs ~verbose ~offsets ~mode ~cmd ~mono ~expr
(** {1 Parsing the command-line options} *) (** {1 Parsing the command-line options} *)
@ -195,7 +203,7 @@ let read language extension =
Getopt.parse_cmdline (specs language extension) anonymous; Getopt.parse_cmdline (specs language extension) anonymous;
(verb_str := (verb_str :=
let apply e a = let apply e a =
if a <> "" then Printf.sprintf "%s, %s" e a else e if a = "" then e else Printf.sprintf "%s, %s" e a
in Utils.String.Set.fold apply !verbose ""); in Utils.String.Set.fold apply !verbose "");
check extension check extension
with Getopt.Error msg -> abort msg with Getopt.Error msg -> abort msg

View File

@ -1,4 +1,4 @@
(** Parsing the command-line options of PascaLIGO *) (** Parsing the command-line options of LIGO *)
(** The type [command] denotes some possible behaviours of the (** The type [command] denotes some possible behaviours of the
compiler. The constructors are compiler. The constructors are
@ -23,12 +23,11 @@ type command = Quiet | Copy | Units | Tokens
(** The type [options] gathers the command-line options. (** The type [options] gathers the command-line options.
{ul {ul
{li If the field [input] is [Some src], the name of the {li If the field [input] is [Some src], the name of the LIGO
PascaLIGO source file, with the extension ".ligo", is source file is [src]. If [input] is [Some "-"] or [None],
[src]. If [input] is [Some "-"] or [None], the source file the source file is read from standard input.}
is read from standard input.}
{li The field [libs] is the paths where to find PascaLIGO files {li The field [libs] is the paths where to find LIGO files
for inclusion (#include).} for inclusion (#include).}
{li The field [verbose] is a set of stages of the compiler {li The field [verbose] is a set of stages of the compiler
@ -41,8 +40,14 @@ type command = Quiet | Copy | Units | Tokens
{li If the value [mode] is [`Byte], then the unit in which {li If the value [mode] is [`Byte], then the unit in which
source positions and regions are expressed in messages is source positions and regions are expressed in messages is
the byte. If [`Point], the unit is unicode points.} the byte. If [`Point], the unit is unicode points.}
}
*) {li If the field [mono] is [true], then the monolithic API of
Menhir is called, otherwise the incremental API is.}
{li If the field [expr] is [true], then the parser for
expressions is used, otherwise a full-fledged contract is
expected.}
} *)
type options = < type options = <
input : string option; input : string option;
libs : string list; libs : string list;
@ -50,7 +55,8 @@ type options = <
offsets : bool; offsets : bool;
mode : [`Byte | `Point]; mode : [`Byte | `Point];
cmd : command; cmd : command;
mono : bool mono : bool;
expr : bool
> >
val make : val make :
@ -61,6 +67,7 @@ val make :
mode:[`Byte | `Point] -> mode:[`Byte | `Point] ->
cmd:command -> cmd:command ->
mono:bool -> mono:bool ->
expr:bool ->
options options
(** Parsing the command-line options on stdin. The first parameter is (** Parsing the command-line options on stdin. The first parameter is

View File

@ -77,8 +77,7 @@ module type TOKEN =
val mk_string : lexeme -> Region.t -> token val mk_string : lexeme -> Region.t -> token
val mk_bytes : lexeme -> Region.t -> token val mk_bytes : lexeme -> Region.t -> token
val mk_constr : lexeme -> Region.t -> token val mk_constr : lexeme -> Region.t -> token
val mk_attr : lexeme -> Region.t -> (token, attr_err) result val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
val mk_attr2 : lexeme -> Region.t -> (token, attr_err) result
val eof : Region.t -> token val eof : Region.t -> token
(* Predicates *) (* Predicates *)
@ -108,6 +107,8 @@ module type TOKEN =
* a function [get_pos] that returns the current position, and * a function [get_pos] that returns the current position, and
* a function [get_last] that returns the region of the last * a function [get_last] that returns the region of the last
recognised token. recognised token.
* a function [get_file] that returns the name of the file being scanned
(empty string if [stdin]).
Note that a module [Token] is exported too, because the signature Note that a module [Token] is exported too, because the signature
of the exported functions depend on it. of the exported functions depend on it.
@ -140,6 +141,7 @@ module type S =
get_win : unit -> window; get_win : unit -> window;
get_pos : unit -> Pos.t; get_pos : unit -> Pos.t;
get_last : unit -> Region.t; get_last : unit -> Region.t;
get_file : unit -> file_path;
close : unit -> unit close : unit -> unit
} }

View File

@ -119,8 +119,7 @@ module type TOKEN =
val mk_string : lexeme -> Region.t -> token val mk_string : lexeme -> Region.t -> token
val mk_bytes : lexeme -> Region.t -> token val mk_bytes : lexeme -> Region.t -> token
val mk_constr : lexeme -> Region.t -> token val mk_constr : lexeme -> Region.t -> token
val mk_attr : lexeme -> Region.t -> (token, attr_err) result val mk_attr : string -> lexeme -> Region.t -> (token, attr_err) result
val mk_attr2 : lexeme -> Region.t -> (token, attr_err) result
val eof : Region.t -> token val eof : Region.t -> token
(* Predicates *) (* Predicates *)
@ -164,6 +163,7 @@ module type S =
get_win : unit -> window; get_win : unit -> window;
get_pos : unit -> Pos.t; get_pos : unit -> Pos.t;
get_last : unit -> Region.t; get_last : unit -> Region.t;
get_file : unit -> file_path;
close : unit -> unit close : unit -> unit
} }
@ -177,7 +177,8 @@ module type S =
exception Error of error Region.reg exception Error of error Region.reg
val format_error : ?offsets:bool -> [`Byte | `Point] -> val format_error :
?offsets:bool -> [`Byte | `Point] ->
error Region.reg -> file:bool -> string error Region.reg -> file:bool -> string
end end
@ -441,9 +442,9 @@ module Make (Token: TOKEN) : (S with module Token = Token) =
exception Error of error Region.reg exception Error of error Region.reg
let format_error ?(offsets=true) mode Region.{region; value} ~file = let format_error ?(offsets=true) mode Region.{region; value} ~file =
let msg = error_to_string value in let msg = error_to_string value
let reg = region#to_string ~file ~offsets mode in and reg = region#to_string ~file ~offsets mode
sprintf "\027[31mLexical error %s:\n%s\027[0m%!" reg msg in sprintf "Lexical error %s:\n%s" reg msg
let fail region value = raise (Error Region.{region; value}) let fail region value = raise (Error Region.{region; value})
@ -530,17 +531,9 @@ module Make (Token: TOKEN) : (S with module Token = Token) =
Ok token -> token, state Ok token -> token, state
| Error Token.Reserved_name -> fail region (Reserved_name lexeme) | Error Token.Reserved_name -> fail region (Reserved_name lexeme)
let mk_attr state buffer attr = let mk_attr header attr state buffer =
let region, _, state = sync state buffer in let region, _, state = sync state buffer in
match Token.mk_attr attr region with match Token.mk_attr header attr region with
Ok token ->
token, state
| Error Token.Invalid_attribute ->
fail region Invalid_attribute
let mk_attr2 state buffer attr =
let region, _, state = sync state buffer in
match Token.mk_attr2 attr region with
Ok token -> Ok token ->
token, state token, state
| Error Token.Invalid_attribute -> | Error Token.Invalid_attribute ->
@ -579,6 +572,7 @@ let capital = ['A'-'Z']
let letter = small | capital let letter = small | capital
let ident = small (letter | '_' | digit)* let ident = small (letter | '_' | digit)*
let constr = capital (letter | '_' | digit)* let constr = capital (letter | '_' | digit)*
let attr = ident | constr
let hexa_digit = digit | ['A'-'F'] let hexa_digit = digit | ['A'-'F']
let byte = hexa_digit hexa_digit let byte = hexa_digit hexa_digit
let byte_seq = byte | byte (byte | '_')* byte let byte_seq = byte | byte (byte | '_')* byte
@ -586,8 +580,8 @@ let bytes = "0x" (byte_seq? as seq)
let esc = "\\n" | "\\\"" | "\\\\" | "\\b" let esc = "\\n" | "\\\"" | "\\\\" | "\\b"
| "\\r" | "\\t" | "\\x" byte | "\\r" | "\\t" | "\\x" byte
let pascaligo_sym = "=/=" | '#' | ":=" let pascaligo_sym = "=/=" | '#' | ":="
let cameligo_sym = "<>" | "::" | "||" | "&&" | "[@" let cameligo_sym = "<>" | "::" | "||" | "&&"
let reasonligo_sym = '!' | "=>" | "!=" | "==" | "++" | "..." | "||" | "&&" | "[@" let reasonligo_sym = '!' | "=>" | "!=" | "==" | "++" | "..." | "||" | "&&"
let symbol = let symbol =
';' | ',' | '(' | ')'| '[' | ']' | '{' | '}' ';' | ',' | '(' | ')'| '[' | ']' | '{' | '}'
@ -618,16 +612,19 @@ and scan state = parse
| '\t'+ { scan (push_tabs state lexbuf) lexbuf } | '\t'+ { scan (push_tabs state lexbuf) lexbuf }
| ident { mk_ident state lexbuf |> enqueue } | ident { mk_ident state lexbuf |> enqueue }
| constr { mk_constr state lexbuf |> enqueue } | constr { mk_constr state lexbuf |> enqueue }
| bytes { (mk_bytes seq) state lexbuf |> enqueue } | bytes { mk_bytes seq state lexbuf |> enqueue }
| natural 'n' { mk_nat state lexbuf |> enqueue } | natural 'n' { mk_nat state lexbuf |> enqueue }
| natural "mutez" { mk_mutez state lexbuf |> enqueue } | natural "mutez" { mk_mutez state lexbuf |> enqueue }
| natural "tz" { mk_tz state lexbuf |> enqueue } | natural "tz"
| decimal "tz" { mk_tz_decimal state lexbuf |> enqueue } | natural "tez" { mk_tz state lexbuf |> enqueue }
| decimal "tz"
| decimal "tez" { mk_tz_decimal state lexbuf |> enqueue }
| natural { mk_int state lexbuf |> enqueue } | natural { mk_int state lexbuf |> enqueue }
| symbol { mk_sym state lexbuf |> enqueue } | symbol { mk_sym state lexbuf |> enqueue }
| eof { mk_eof state lexbuf |> enqueue } | eof { mk_eof state lexbuf |> enqueue }
| "[@" (ident|constr as attr) "]" { mk_attr state lexbuf attr |> enqueue } | "[@" (attr as a) "]" { mk_attr "[@" a state lexbuf |> enqueue }
| "[@@" (ident|constr as attr) "]" { mk_attr2 state lexbuf attr |> enqueue } | "[@@" (attr as a) "]" { mk_attr "[@@" a state lexbuf |> enqueue }
| '"' { let opening, _, state = sync state lexbuf in | '"' { let opening, _, state = sync state lexbuf in
let thread = {opening; len=1; acc=['"']} in let thread = {opening; len=1; acc=['"']} in
scan_string thread state lexbuf |> mk_string |> enqueue } scan_string thread state lexbuf |> mk_string |> enqueue }
@ -676,8 +673,7 @@ and scan state = parse
and file = Filename.basename file in and file = Filename.basename file in
let pos = state.pos#set ~file ~line ~offset:0 in let pos = state.pos#set ~file ~line ~offset:0 in
let state = {state with pos} in let state = {state with pos} in
scan state lexbuf scan state lexbuf }
}
(* Some special errors (* Some special errors
@ -864,6 +860,7 @@ type instance = {
get_win : unit -> window; get_win : unit -> window;
get_pos : unit -> Pos.t; get_pos : unit -> Pos.t;
get_last : unit -> Region.t; get_last : unit -> Region.t;
get_file : unit -> file_path;
close : unit -> unit close : unit -> unit
} }
@ -871,7 +868,7 @@ let open_token_stream file_path_opt =
let file_path = match file_path_opt with let file_path = match file_path_opt with
None | Some "-" -> "" None | Some "-" -> ""
| Some file_path -> file_path in | Some file_path -> file_path in
let pos = Pos.min#set_file file_path in let pos = Pos.min ~file:file_path in
let buf_reg = ref (pos#byte, pos#byte) let buf_reg = ref (pos#byte, pos#byte)
and first_call = ref true and first_call = ref true
and decoder = Uutf.decoder ~encoding:`UTF_8 `Manual in and decoder = Uutf.decoder ~encoding:`UTF_8 `Manual in
@ -886,7 +883,8 @@ let open_token_stream file_path_opt =
let get_pos () = !state.pos let get_pos () = !state.pos
and get_last () = !state.last and get_last () = !state.last
and get_win () = !state.window in and get_win () = !state.window
and get_file () = file_path in
let patch_buffer (start, stop) buffer = let patch_buffer (start, stop) buffer =
let open Lexing in let open Lexing in
@ -958,7 +956,7 @@ let open_token_stream file_path_opt =
None | Some "-" -> () None | Some "-" -> ()
| Some file_path -> reset ~file:file_path buffer | Some file_path -> reset ~file:file_path buffer
and close () = close_in cin in and close () = close_in cin in
{read = read_token; buffer; get_win; get_pos; get_last; close} {read = read_token; buffer; get_win; get_pos; get_last; get_file; close}
end (* of functor [Make] in HEADER *) end (* of functor [Make] in HEADER *)
(* END TRAILER *) (* END TRAILER *)

View File

@ -1,7 +1,5 @@
(** Embedding the LIGO lexer in a debug module *) (** Embedding the LIGO lexer in a debug module *)
let sprintf = Printf.sprintf
module type S = module type S =
sig sig
module Lexer : Lexer.S module Lexer : Lexer.S
@ -15,12 +13,12 @@ module type S =
val trace : val trace :
?offsets:bool -> [`Byte | `Point] -> ?offsets:bool -> [`Byte | `Point] ->
file_path option -> EvalOpt.command -> unit file_path option -> EvalOpt.command ->
(unit, string) Stdlib.result
end end
module Make (Lexer: Lexer.S) : (S with module Lexer = Lexer) = module Make (Lexer: Lexer.S) : (S with module Lexer = Lexer) =
struct struct
module Lexer = Lexer module Lexer = Lexer
module Token = Lexer.Token module Token = Lexer.Token
@ -49,28 +47,29 @@ module Make (Lexer: Lexer.S) : (S with module Lexer = Lexer) =
type file_path = string type file_path = string
let trace ?(offsets=true) mode file_path_opt command : unit = let trace ?(offsets=true) mode file_path_opt command :
(unit, string) Stdlib.result =
try try
let Lexer.{read; buffer; close; _} = let Lexer.{read; buffer; close; _} =
Lexer.open_token_stream file_path_opt Lexer.open_token_stream file_path_opt in
and cout = stdout in let log = output_token ~offsets mode command stdout
let log = output_token ~offsets mode command cout and close_all () = close (); close_out stdout in
and close_all () = close (); close_out cout in
let rec iter () = let rec iter () =
match read ~log buffer with match read ~log buffer with
token -> token ->
if Token.is_eof token then close_all () if Token.is_eof token
then Stdlib.Ok ()
else iter () else iter ()
| exception Lexer.Error e -> | exception Lexer.Error error ->
let file = let file =
match file_path_opt with match file_path_opt with
None | Some "-" -> false None | Some "-" -> false
| Some _ -> true in | Some _ -> true in
let msg = let msg =
Lexer.format_error ~offsets mode e ~file Lexer.format_error ~offsets mode ~file error
in prerr_string msg; in Stdlib.Error msg in
close_all () let result = iter ()
in iter () in (close_all (); result)
with Sys_error msg -> Utils.highlight (sprintf "%s\n" msg) with Sys_error msg -> Stdlib.Error msg
end end

View File

@ -11,7 +11,8 @@ module type S =
val trace : val trace :
?offsets:bool -> [`Byte | `Point] -> ?offsets:bool -> [`Byte | `Point] ->
file_path option -> EvalOpt.command -> unit file_path option -> EvalOpt.command ->
(unit, string) Stdlib.result
end end
module Make (Lexer: Lexer.S) : S with module Lexer = Lexer module Make (Lexer: Lexer.S) : S with module Lexer = Lexer

View File

@ -1,21 +1,20 @@
(* Functor to build a standalone LIGO lexer *) (* Functor to build a standalone LIGO lexer *)
module type S = module type IO =
sig sig
val ext : string (* LIGO file extension *) val ext : string (* LIGO file extension *)
val options : EvalOpt.options (* CLI options *) val options : EvalOpt.options (* CLI options *)
end end
module Make (IO: S) (Lexer: Lexer.S) = module Make (IO: IO) (Lexer: Lexer.S) =
struct struct
open Printf open Printf
module SSet = Utils.String.Set
(* Error printing and exception tracing *) (* Error printing and exception tracing *)
let () = Printexc.record_backtrace true let () = Printexc.record_backtrace true
let external_ text =
Utils.highlight (sprintf "External error: %s" text); exit 1
(* Preprocessing the input source and opening the input channels *) (* Preprocessing the input source and opening the input channels *)
(* Path for CPP inclusions (#include) *) (* Path for CPP inclusions (#include) *)
@ -48,18 +47,62 @@ module Make (IO: S) (Lexer: Lexer.S) =
sprintf "cpp -traditional-cpp%s %s > %s" sprintf "cpp -traditional-cpp%s %s > %s"
lib_path file pp_input lib_path file pp_input
let () =
if Utils.String.Set.mem "cpp" IO.options#verbose
then eprintf "%s\n%!" cpp_cmd;
if Sys.command cpp_cmd <> 0 then
external_ (sprintf "the command \"%s\" failed." cpp_cmd)
(* Running the lexer on the input file *) (* Running the lexer on the input file *)
let scan () : (Lexer.token list, string) Stdlib.result =
(* Preprocessing the input *)
if SSet.mem "cpp" IO.options#verbose
then eprintf "%s\n%!" cpp_cmd
else ();
if Sys.command cpp_cmd <> 0 then
let msg =
sprintf "External error: the command \"%s\" failed." cpp_cmd
in Stdlib.Error msg
else
try
let Lexer.{read; buffer; close; _} =
Lexer.open_token_stream (Some pp_input) in
let close_all () = close (); close_out stdout in
let rec read_tokens tokens =
match read ~log:(fun _ _ -> ()) buffer with
token ->
if Lexer.Token.is_eof token
then Stdlib.Ok (List.rev tokens)
else read_tokens (token::tokens)
| exception Lexer.Error error ->
let file =
match IO.options#input with
None | Some "-" -> false
| Some _ -> true in
let msg =
Lexer.format_error ~offsets:IO.options#offsets
IO.options#mode ~file error
in Stdlib.Error msg in
let result = read_tokens []
in close_all (); result
with Sys_error msg -> close_out stdout; Stdlib.Error msg
(* Tracing the lexing (effectful) *)
module Log = LexerLog.Make (Lexer) module Log = LexerLog.Make (Lexer)
let () = Log.trace ~offsets:IO.options#offsets let trace () : (unit, string) Stdlib.result =
IO.options#mode (Some pp_input) (* Preprocessing the input *)
if SSet.mem "cpp" IO.options#verbose
then eprintf "%s\n%!" cpp_cmd
else ();
if Sys.command cpp_cmd <> 0 then
let msg =
sprintf "External error: the command \"%s\" failed." cpp_cmd
in Stdlib.Error msg
else
Log.trace ~offsets:IO.options#offsets
IO.options#mode
(Some pp_input)
IO.options#cmd IO.options#cmd
end end

View File

@ -0,0 +1,13 @@
(* Functor to build a standalone LIGO lexer *)
module type IO =
sig
val ext : string (* LIGO file extension *)
val options : EvalOpt.options (* CLI options *)
end
module Make (IO: IO) (Lexer: Lexer.S) :
sig
val scan : unit -> (Lexer.token list, string) Stdlib.result
val trace : unit -> (unit, string) Stdlib.result
end

View File

@ -0,0 +1,163 @@
module Region = Simple_utils.Region
type macro = {
origin : Region.t; (* Not ghost *)
current : Region.t (* Maybe ghost *)
}
type location =
Loc of Region.t (* Not ghost *)
| Link of macro
(* Regions must not be ghosts and strings must not be empty. *)
type valid_lexeme = string Region.reg (* Not ghost, not empty. *)
type invalid_lexeme = string Region.reg (* Not ghost, empty if EOF. *)
type phase =
Lexer
| Parser of valid_lexeme option * invalid_lexeme
| Scoping
type error = <
location : location;
message : string; (* Sentence ending with a period *)
hint : string; (* Suggestion to solve the issue *)
help : string (* Off-program help *)
>
type invalid_error = Ghost_region
let check_loc = function
Loc reg ->
if reg#is_ghost then
Stdlib.Error Ghost_region
else Ok ()
| Link {origin; _} ->
if origin#is_ghost then
Stdlib.Error Ghost_region
else Ok ()
let make_error ~location ~message ~hint ~help =
match check_loc location with
Stdlib.Ok () ->
Ok (object
method location = location
method message = message
method hint = hint
method help = help
end)
| Error _ as e -> e
type warning = <
location : location;
message : string; (* Sentence ending with a period *)
hint : string; (* Idem *)
>
type invalid_warning = invalid_error
let make_warning ~location ~message ~hint =
match check_loc location with
Stdlib.Ok () ->
Ok (object
method location = location
method message = message
method hint = hint
method help = help
end)
| Error _ as e -> e
type kind =
Error of error (* Failure of an external invariant *)
| Internal of string (* Failure of an internal invariant *)
| External of string (* Failure of an external process *)
| Warning of warning
| Info of (unit -> string) (* Log *)
type entry = <
phase : phase;
kind : kind
>
type invalid_entry =
Ghost_lexeme
| Empty_lexeme
let check_phase = function
Parser (Some valid_lexeme, invalid_lexeme) ->
let open Region in
if valid_lexeme.region#is_ghost
|| invalid_lexeme.region#is_ghost
then Stdlib.Error Ghost_lexeme
else if valid_lexeme.value = ""
then Stdlib.Error Empty_lexeme
else Ok ()
| Parser (None, invalid_lexeme) ->
if invalid_lexeme.region#is_ghost
then Stdlib.Error Ghost_lexeme
else Ok ()
| Lexer
| Scoping -> Ok ()
let make_entry ~phase ~kind =
match check_phase phase with
Stdlib.Error _ as e -> e
| Ok () -> Ok (object
method phase = phase
method kind = kind
end)
type memo = <
mode : [`Byte | `Point]; (* Bytes vs UTF-8 *)
offsets : bool; (* [true] for horizontal offsets *)
log : entry FQueue.t
>
type t = memo
let empty_memo ~mode ~offsets : memo =
object
method mode = mode
method offsets = offsets
method log = FQueue.empty
method enqueue entry = {< log = FQueue.enq entry log >}
method dequeue =
match FQueue.deq log with
None -> None
| Some (log, entry) -> Some ({< log=log >}, entry)
end
let sprintf = Printf.sprintf
let string_of_entry ~(file:bool) entry : string =
let reg = entry#region#to_string
~file
~offsets:entry#offsets
error#mode in
let string =
match error#phase with
Parser (None, invalid_lexeme) ->
(match invalid_lexeme.Region.value with
"" -> sprintf "Parse error %s" reg (* EOF *)
| lexeme -> sprintf "Parse error %s, before \"%s\""
reg lexeme)
| Parser (Some valid_lexeme, invalid_lexeme) ->
let string =
sprintf "Parse error %s, after \"%s\""
reg valid_lexeme.Region.value in
(match invalid_lexeme.Region.value with
"" -> string (* EOF *)
| lexeme -> sprintf "%s and before \"%s\"" string lexeme)
| Lexer ->
sprintf "Lexical error %s" reg
| Scoping ->
sprintf "Scoping error %s" reg in
let string =
string
^ (if error#message = "" then "."
else ":\n" ^ error#message) ^ "\n" in
let string =
string ^ (if error#hint = "" then ""
else sprintf "Hint: %s\n" error#hint)
in string

View File

@ -0,0 +1,120 @@
(* This module defines compilation memos. *)
(* Locations *)
module Region = Simple_utils.Region
type macro = private <
origin : Region.t; (* Not ghost *)
current : Region.t (* Maybe ghost *)
>
type location = private
Loc of Region.t (* Not ghost *)
| Link of macro
type invalid_loc = Ghost_region
val make_loc :
Region.t -> (location, invalid_loc) Stdlib.result
val make_link :
origin:Region.t ->
current:Region.t ->
(location, invalid_loc) Stdlib.result
type 'a located = <
value : 'a;
location : location
>
val make_located : value:'a -> location:location -> 'a located
(* Lexemes *)
type lexeme = string location (* Not ghost, empty => EOF *)
type window = <
valid_lexeme : lexeme option;
invalid_lexeme : lexeme
>
val make_window : ?valid:lexeme -> invalid:lexeme -> window
(* Compilation phases *)
type phase =
Lexer
| Parser of window
| Scoping
(* Messages *)
type message = private string
type invalid_message = Empty_message
val make_message : string -> (message, invalid_error) Stdlib.result
val string_of_message : message -> string
(* Errors *)
type error = <
location : location;
message : message; (* Non-empty string (ending with a period) *)
hint : string; (* Suggestion to solve the issue (may be empty) *)
help : string (* Off-program help (may be empty) *)
>
val make_error :
location:location ->
message:message ->
hint:string ->
help:string ->
error
(* Warnings *)
type warning = <
location : location;
message : message; (* Non-empty string (ending with a period) *)
hint : string; (* May empty *)
>
val make_warning :
location:location ->
message:message ->
hint:string ->
warning
(* Kinds of entries *)
type kind =
Error of error (* Failure of an external invariant *)
| Internal of message (* Failure of an internal invariant (non-empty) *)
| External of message (* Failure of an external process (non-empty) *)
| Warning of warning
| Info of (unit -> message) (* Log (not-empty) *)
type entry = private <
phase : phase;
kind : kind
>
val make_entry : phase:phase -> kind:kind -> entry
val string_of_entry : file:bool -> entry -> string
(* Memos *)
type memo = <
mode : [`Byte | `Point]; (* Bytes vs UTF-8 *)
offsets : bool; (* [true] for horizontal offsets *)
log : entry FQueue.t;
enqueue : entry -> memo;
dequeue : (memo * entry) option
>
type t = memo
val empty_memo : mode:[`Byte | `Point] -> offsets:bool -> memo

View File

@ -77,28 +77,6 @@ module Make (Lexer: Lexer.S)
exception Point of error exception Point of error
let failure get_win checkpoint =
let message = ParErr.message (state checkpoint) in
match get_win () with
Lexer.Nil -> assert false
| Lexer.One invalid ->
raise (Point (message, None, invalid))
| Lexer.Two (invalid, valid) ->
raise (Point (message, Some valid, invalid))
(* The two Menhir APIs are called from the following two functions. *)
let incr_contract Lexer.{read; buffer; get_win; close; _} : Parser.ast =
let supplier = I.lexer_lexbuf_to_supplier read buffer
and failure = failure get_win in
let parser = Parser.Incremental.contract buffer.Lexing.lex_curr_p in
let ast = I.loop_handle success failure supplier parser
in close (); ast
let mono_contract = Parser.contract
(* Errors *)
let format_error ?(offsets=true) mode (msg, valid_opt, invalid) = let format_error ?(offsets=true) mode (msg, valid_opt, invalid) =
let invalid_region = Lexer.Token.to_region invalid in let invalid_region = Lexer.Token.to_region invalid in
let header = let header =
@ -119,9 +97,37 @@ module Make (Lexer: Lexer.S)
let header = header ^ trailer in let header = header ^ trailer in
header ^ (if msg = "" then ".\n" else ":\n" ^ msg) header ^ (if msg = "" then ".\n" else ":\n" ^ msg)
let short_error ?(offsets=true) mode msg (invalid_region: Region.t) = let failure get_win checkpoint =
let () = assert (not (invalid_region#is_ghost)) in let message = ParErr.message (state checkpoint) in
let header = match get_win () with
"Parse error " ^ invalid_region#to_string ~offsets mode in Lexer.Nil -> assert false
header ^ (if msg = "" then ".\n" else ":\n" ^ msg) | Lexer.One invalid ->
raise (Point (message, None, invalid))
| Lexer.Two (invalid, valid) ->
raise (Point (message, Some valid, invalid))
(* The monolithic API of Menhir *)
let mono_contract = Parser.contract
let mono_expr = Parser.interactive_expr
(* Incremental API of Menhir *)
module Incr = Parser.Incremental
let incr_contract Lexer.{read; buffer; get_win; close; _} =
let supplier = I.lexer_lexbuf_to_supplier read buffer
and failure = failure get_win in
let parser = Incr.contract buffer.Lexing.lex_curr_p in
let ast = I.loop_handle success failure supplier parser
in close (); ast
let incr_expr Lexer.{read; buffer; get_win; close; _} =
let supplier = I.lexer_lexbuf_to_supplier read buffer
and failure = failure get_win in
let parser = Incr.interactive_expr buffer.Lexing.lex_curr_p in
let expr = I.loop_handle success failure supplier parser
in close (); expr
end end

View File

@ -2,6 +2,9 @@
module Region = Simple_utils.Region module Region = Simple_utils.Region
(* The signature generated by Menhir with additional type definitions
for [ast] and [expr]. *)
module type PARSER = module type PARSER =
sig sig
(* The type of tokens. *) (* The type of tokens. *)
@ -16,8 +19,10 @@ module type PARSER =
(* The monolithic API. *) (* The monolithic API. *)
val interactive_expr : (Lexing.lexbuf -> token) -> Lexing.lexbuf -> expr val interactive_expr :
val contract : (Lexing.lexbuf -> token) -> Lexing.lexbuf -> ast (Lexing.lexbuf -> token) -> Lexing.lexbuf -> expr
val contract :
(Lexing.lexbuf -> token) -> Lexing.lexbuf -> ast
(* The incremental API. *) (* The incremental API. *)
@ -42,14 +47,15 @@ module Make (Lexer: Lexer.S)
(Parser: PARSER with type token = Lexer.Token.token) (Parser: PARSER with type token = Lexer.Token.token)
(ParErr: sig val message : int -> string end) : (ParErr: sig val message : int -> string end) :
sig sig
(* Monolithic and incremental APIs of Menhir for parsing *) (* The monolithic API of Menhir *)
val mono_contract : val mono_contract :
(Lexing.lexbuf -> Lexer.token) -> Lexing.lexbuf -> Parser.ast (Lexing.lexbuf -> Lexer.token) -> Lexing.lexbuf -> Parser.ast
val incr_contract :
Lexer.instance -> Parser.ast
(* Error handling *) val mono_expr :
(Lexing.lexbuf -> Lexer.token) -> Lexing.lexbuf -> Parser.expr
(* Incremental API of Menhir *)
type message = string type message = string
type valid = Parser.token type valid = Parser.token
@ -58,9 +64,8 @@ module Make (Lexer: Lexer.S)
exception Point of error exception Point of error
val format_error : val incr_contract : Lexer.instance -> Parser.ast
?offsets:bool -> [`Byte | `Point] -> error -> string val incr_expr : Lexer.instance -> Parser.expr
val short_error : val format_error : ?offsets:bool -> [`Point | `Byte] -> error -> string
?offsets:bool -> [`Byte | `Point] -> message -> Region.t -> string
end end

View File

@ -1,6 +1,8 @@
(* Functor to build a standalone LIGO parser *) (* Functor to build a standalone LIGO parser *)
module type S = module Region = Simple_utils.Region
module type IO =
sig sig
val ext : string (* LIGO file extension *) val ext : string (* LIGO file extension *)
val options : EvalOpt.options (* CLI options *) val options : EvalOpt.options (* CLI options *)
@ -10,40 +12,35 @@ module type Pretty =
sig sig
type state type state
type ast type ast
val pp_ast : type expr
state -> ast -> unit
val mk_state : val mk_state :
offsets:bool -> mode:[`Point|`Byte] -> buffer:Buffer.t -> state offsets:bool -> mode:[`Point|`Byte] -> buffer:Buffer.t -> state
val print_tokens :
state -> ast -> unit val pp_ast : state -> ast -> unit
val pp_expr : state -> expr -> unit
val print_tokens : state -> ast -> unit
val print_expr : state -> expr -> unit
end end
module Make (IO: S) module Make (Lexer: Lexer.S)
(Lexer: Lexer.S)
(AST: sig type t type expr end) (AST: sig type t type expr end)
(Parser: ParserAPI.PARSER (Parser: ParserAPI.PARSER
with type ast = AST.t with type ast = AST.t
and type expr = AST.expr and type expr = AST.expr
and type token = Lexer.token) and type token = Lexer.token)
(ParErr: sig val message : int -> string end) (ParErr: sig val message : int -> string end)
(ParserLog: Pretty with type ast = AST.t) = (ParserLog: Pretty with type ast = AST.t
and type expr = AST.expr)
(IO: IO) =
struct struct
open Printf open Printf
module SSet = Utils.String.Set
(* Error printing and exception tracing *) (* Error printing and exception tracing *)
let () = Printexc.record_backtrace true let () = Printexc.record_backtrace true
let external_ text =
Utils.highlight (sprintf "External error: %s" text); exit 1
(* Extracting the input file *)
let file =
match IO.options#input with
None | Some "-" -> false
| Some _ -> true
(* Preprocessing the input source and opening the input channels *) (* Preprocessing the input source and opening the input channels *)
(* Path for CPP inclusions (#include) *) (* Path for CPP inclusions (#include) *)
@ -62,9 +59,10 @@ module Make (IO: S)
let suffix = ".pp" ^ IO.ext let suffix = ".pp" ^ IO.ext
let pp_input = let pp_input =
if Utils.String.Set.mem "cpp" IO.options#verbose if SSet.mem "cpp" IO.options#verbose
then prefix ^ suffix then prefix ^ suffix
else let pp_input, pp_out = Filename.open_temp_file prefix suffix else let pp_input, pp_out =
Filename.open_temp_file prefix suffix
in close_out pp_out; pp_input in close_out pp_out; pp_input
let cpp_cmd = let cpp_cmd =
@ -76,100 +74,161 @@ module Make (IO: S)
sprintf "cpp -traditional-cpp%s %s > %s" sprintf "cpp -traditional-cpp%s %s > %s"
lib_path file pp_input lib_path file pp_input
let () = (* Error handling (reexported from [ParserAPI]) *)
if Utils.String.Set.mem "cpp" IO.options#verbose
then eprintf "%s\n%!" cpp_cmd;
if Sys.command cpp_cmd <> 0 then
external_ (sprintf "the command \"%s\" failed." cpp_cmd)
(* Instanciating the lexer *) type message = string
type valid = Parser.token
type invalid = Parser.token
type error = message * valid option * invalid
module ParserFront = ParserAPI.Make (Lexer) (Parser) (ParErr) exception Point of error
let format_error = ParserFront.format_error (* Instantiating the parser *)
let short_error = ParserFront.short_error
let lexer_inst = Lexer.open_token_stream (Some pp_input) module Front = ParserAPI.Make (Lexer)(Parser)(ParErr)
let Lexer.{read; buffer; get_win; get_pos; get_last; close} = lexer_inst
and cout = stdout let format_error = Front.format_error
let close_all () = close (); close_out cout let short_error ?(offsets=true) mode msg (reg: Region.t) =
sprintf "Parse error %s:\n%s" (reg#to_string ~offsets mode) msg
(* Tokeniser *) (* Parsing an expression *)
module Log = LexerLog.Make (Lexer) let parse_expr lexer_inst tokeniser output state :
(AST.expr, string) Stdlib.result =
let log = Log.output_token ~offsets:IO.options#offsets let close_all () =
IO.options#mode IO.options#cmd cout lexer_inst.Lexer.close (); close_out stdout in
let lexbuf = lexer_inst.Lexer.buffer in
let tokeniser = read ~log let expr =
(* Main *)
let run () =
try try
if IO.options#mono then
Front.mono_expr tokeniser lexbuf
else
Front.incr_expr lexer_inst
with exn -> close_all (); raise exn in
let () =
if SSet.mem "ast-tokens" IO.options#verbose then
begin
Buffer.clear output;
ParserLog.print_expr state expr;
Buffer.output_buffer stdout output
end in
let () =
if SSet.mem "ast" IO.options#verbose then
begin
Buffer.clear output;
ParserLog.pp_expr state expr;
Buffer.output_buffer stdout output
end
in close_all (); Ok expr
(* Parsing a contract *)
let parse_contract lexer_inst tokeniser output state
: (AST.t, string) Stdlib.result =
let close_all () =
lexer_inst.Lexer.close (); close_out stdout in
let lexbuf = lexer_inst.Lexer.buffer in
let ast = let ast =
if IO.options#mono try
then ParserFront.mono_contract tokeniser buffer if IO.options#mono then
else ParserFront.incr_contract lexer_inst in Front.mono_contract tokeniser lexbuf
if Utils.String.Set.mem "ast" IO.options#verbose else
then let buffer = Buffer.create 131 in Front.incr_contract lexer_inst
let state = ParserLog.mk_state with exn -> close_all (); raise exn in
~offsets:IO.options#offsets let () =
~mode:IO.options#mode if SSet.mem "ast-tokens" IO.options#verbose then
~buffer in
begin
ParserLog.pp_ast state ast;
Buffer.output_buffer stdout buffer
end
else if Utils.String.Set.mem "ast-tokens" IO.options#verbose
then let buffer = Buffer.create 131 in
let state = ParserLog.mk_state
~offsets:IO.options#offsets
~mode:IO.options#mode
~buffer in
begin begin
Buffer.clear output;
ParserLog.print_tokens state ast; ParserLog.print_tokens state ast;
Buffer.output_buffer stdout buffer Buffer.output_buffer stdout output
end in
let () =
if SSet.mem "ast" IO.options#verbose then
begin
Buffer.clear output;
ParserLog.pp_ast state ast;
Buffer.output_buffer stdout output
end end
with in close_all (); Ok ast
(* Wrapper for the parsers above *)
let parse parser =
(* Preprocessing the input *)
if SSet.mem "cpp" IO.options#verbose
then eprintf "%s\n%!" cpp_cmd
else ();
if Sys.command cpp_cmd <> 0 then
let msg =
sprintf "External error: \"%s\" failed." cpp_cmd
in Stdlib.Error msg
else
(* Instantiating the lexer *)
let lexer_inst = Lexer.open_token_stream (Some pp_input) in
(* Making the tokeniser *)
let module Log = LexerLog.Make (Lexer) in
let log =
Log.output_token ~offsets:IO.options#offsets
IO.options#mode IO.options#cmd stdout in
let tokeniser = lexer_inst.Lexer.read ~log in
let output = Buffer.create 131 in
let state = ParserLog.mk_state
~offsets:IO.options#offsets
~mode:IO.options#mode
~buffer:output in
(* Calling the specific parser (that is, the parameter) *)
match parser lexer_inst tokeniser output state with
Stdlib.Error _ as error -> error
| Stdlib.Ok _ as node -> node
(* Lexing errors *) (* Lexing errors *)
Lexer.Error err -> | exception Lexer.Error err ->
close_all (); let file =
let msg = match IO.options#input with
None | Some "-" -> false
| Some _ -> true in
let error =
Lexer.format_error ~offsets:IO.options#offsets Lexer.format_error ~offsets:IO.options#offsets
IO.options#mode err ~file IO.options#mode err ~file
in prerr_string msg in Stdlib.Error error
(* Incremental API of Menhir *) (* Incremental API of Menhir *)
| ParserFront.Point point -> | exception Front.Point point ->
let () = close_all () in
let error = let error =
ParserFront.format_error ~offsets:IO.options#offsets Front.format_error ~offsets:IO.options#offsets
IO.options#mode point IO.options#mode point
in eprintf "\027[31m%s\027[0m%!" error in Stdlib.Error error
(* Monolithic API of Menhir *) (* Monolithic API of Menhir *)
| Parser.Error -> | exception Parser.Error ->
let () = close_all () in
let invalid, valid_opt = let invalid, valid_opt =
match get_win () with match lexer_inst.Lexer.get_win () with
Lexer.Nil -> Lexer.Nil ->
assert false (* Safe: There is always at least EOF. *) assert false (* Safe: There is always at least EOF. *)
| Lexer.One invalid -> invalid, None | Lexer.One invalid -> invalid, None
| Lexer.Two (invalid, valid) -> invalid, Some valid in | Lexer.Two (invalid, valid) -> invalid, Some valid in
let point = "", valid_opt, invalid in let point = "", valid_opt, invalid in
let error = let error =
ParserFront.format_error ~offsets:IO.options#offsets Front.format_error ~offsets:IO.options#offsets
IO.options#mode point IO.options#mode point
in eprintf "\027[31m%s\027[0m%!" error in Stdlib.Error error
(* I/O errors *) (* I/O errors *)
| Sys_error msg -> Utils.highlight msg | exception Sys_error error -> Stdlib.Error error
end end

View File

@ -0,0 +1,71 @@
(* Functor to build a standalone LIGO parser *)
module Region = Simple_utils.Region
module type IO =
sig
val ext : string (* LIGO file extension *)
val options : EvalOpt.options (* CLI options *)
end
module type Pretty =
sig
type state
type ast
type expr
val mk_state :
offsets:bool -> mode:[`Point|`Byte] -> buffer:Buffer.t -> state
val pp_ast : state -> ast -> unit
val pp_expr : state -> expr -> unit
val print_tokens : state -> ast -> unit
val print_expr : state -> expr -> unit
end
module Make (Lexer: Lexer.S)
(AST: sig type t type expr end)
(Parser: ParserAPI.PARSER
with type ast = AST.t
and type expr = AST.expr
and type token = Lexer.token)
(ParErr: sig val message : int -> string end)
(ParserLog: Pretty with type ast = AST.t
and type expr = AST.expr)
(IO: IO) :
sig
(* Error handling (reexported from [ParserAPI]) *)
type message = string
type valid = Parser.token
type invalid = Parser.token
type error = message * valid option * invalid
exception Point of error
val format_error :
?offsets:bool -> [`Byte | `Point] -> error -> string
val short_error :
?offsets:bool -> [`Point | `Byte] -> string -> Region.t -> string
(* Parsers *)
val parse :
(Lexer.instance ->
(Lexing.lexbuf -> Lexer.token) ->
Buffer.t -> ParserLog.state -> ('a, string) result) ->
('a, string) result
val parse_contract :
Lexer.instance ->
(Lexing.lexbuf -> Lexer.token) ->
Buffer.t -> ParserLog.state ->
(AST.t, string) Stdlib.result
val parse_expr :
Lexer.instance ->
(Lexing.lexbuf -> Lexer.token) ->
Buffer.t -> ParserLog.state -> (AST.expr, string) Stdlib.result
end

View File

@ -36,7 +36,7 @@ module Errors = struct
] in ] in
error ~data title message error ~data title message
let unsuppported_let_in_function (patterns : Raw.pattern list) = let unsupported_let_in_function (patterns : Raw.pattern list) =
let title () = "unsupported 'let ... in' function" in let title () = "unsupported 'let ... in' function" in
let message () = "defining functions via 'let ... in' is not supported yet" in let message () = "defining functions via 'let ... in' is not supported yet" in
let patterns_loc = let patterns_loc =
@ -179,6 +179,10 @@ let rec tuple_pattern_to_typed_vars : Raw.pattern -> _ = fun pattern ->
| Raw.PVar _ -> bind_list [pattern_to_typed_var pattern] | Raw.PVar _ -> bind_list [pattern_to_typed_var pattern]
| other -> (fail @@ wrong_pattern "parenthetical, tuple, or variable" other) | other -> (fail @@ wrong_pattern "parenthetical, tuple, or variable" other)
let rec unpar_pattern : Raw.pattern -> Raw.pattern = function
| PPar p -> unpar_pattern p.value.inside
| _ as p -> p
let rec simpl_type_expression : Raw.type_expr -> type_expression result = fun te -> let rec simpl_type_expression : Raw.type_expr -> type_expression result = fun te ->
trace (simple_info "simplifying this type expression...") @@ trace (simple_info "simplifying this type expression...") @@
match te with match te with
@ -354,7 +358,7 @@ let rec simpl_expression :
(* let f p1 ps... = rhs in body *) (* let f p1 ps... = rhs in body *)
| (f, p1 :: ps) -> | (f, p1 :: ps) ->
fail @@ unsuppported_let_in_function (f :: p1 :: ps) fail @@ unsupported_let_in_function (f :: p1 :: ps)
end end
| Raw.EAnnot a -> | Raw.EAnnot a ->
let Raw.{inside=expr, _, type_expr; _}, loc = r_split a in let Raw.{inside=expr, _, type_expr; _}, loc = r_split a in
@ -541,7 +545,8 @@ and simpl_fun lamb' : expr result =
(match pt with (match pt with
| Raw.PTyped pt -> | Raw.PTyped pt ->
begin begin
match pt.value.pattern with let pt_pattern = unpar_pattern pt.value.pattern in
match pt_pattern with
| Raw.PVar _ -> params | Raw.PVar _ -> params
| Raw.PTuple _ -> | Raw.PTuple _ ->
[Raw.PTyped [Raw.PTyped
@ -581,10 +586,10 @@ and simpl_fun lamb' : expr result =
match destruct with (* Handle tuple parameter destructuring *) match destruct with (* Handle tuple parameter destructuring *)
(* In this section we create a let ... in that binds the original parameters *) (* In this section we create a let ... in that binds the original parameters *)
| Raw.PPar pp -> | Raw.PPar pp ->
(match pp.value.inside with (match unpar_pattern pp.value.inside with
| Raw.PTyped pt -> | Raw.PTyped pt ->
let vars = pt.value in let vars = pt.value in
(match vars.pattern with (match unpar_pattern vars.pattern with
| PTuple vars -> | PTuple vars ->
let let_in_binding: Raw.let_binding = let let_in_binding: Raw.let_binding =
{binders = (PTuple vars, []) ; {binders = (PTuple vars, []) ;

View File

@ -12,8 +12,5 @@
(preprocess (preprocess
(pps (pps
ppx_let ppx_let
bisect_ppx --conditional bisect_ppx --conditional))
) (flags (:standard -w +1..62-4-9-44-40-42-48-30@39@33 -open Simple_utils)))
)
(flags (:standard -w +1..62-4-9-44-40-42-48-30@39@33 -open Simple_utils ))
)

View File

@ -4,14 +4,15 @@ open Ast_simplified
module Raw = Parser.Pascaligo.AST module Raw = Parser.Pascaligo.AST
module SMap = Map.String module SMap = Map.String
module SSet = Set.Make (String) module SSet = Set.Make (String)
module ParserLog = Parser_pascaligo.ParserLog
open Combinators open Combinators
let nseq_to_list (hd, tl) = hd :: tl let nseq_to_list (hd, tl) = hd :: tl
let npseq_to_list (hd, tl) = hd :: (List.map snd tl) let npseq_to_list (hd, tl) = hd :: (List.map snd tl)
let pseq_to_list = function let pseq_to_list = function
| None -> [] None -> []
| Some lst -> npseq_to_list lst | Some lst -> npseq_to_list lst
let get_value : 'a Raw.reg -> 'a = fun x -> x.value let get_value : 'a Raw.reg -> 'a = fun x -> x.value
let is_compiler_generated name = String.contains (Var.to_name name) '#' let is_compiler_generated name = String.contains (Var.to_name name) '#'
@ -132,7 +133,7 @@ module Errors = struct
fun () -> Format.asprintf "%a" Location.pp_lift @@ pattern_loc) ; fun () -> Format.asprintf "%a" Location.pp_lift @@ pattern_loc) ;
(** TODO: The labelled arguments should be flowing from the CLI. *) (** TODO: The labelled arguments should be flowing from the CLI. *)
("pattern", ("pattern",
fun () -> Parser.Pascaligo.ParserLog.pattern_to_string fun () -> ParserLog.pattern_to_string
~offsets:true ~mode:`Point p) ~offsets:true ~mode:`Point p)
] in ] in
error ~data title message error ~data title message
@ -168,7 +169,7 @@ module Errors = struct
(** TODO: The labelled arguments should be flowing from the CLI. *) (** TODO: The labelled arguments should be flowing from the CLI. *)
let data = [ let data = [
("instruction", ("instruction",
fun () -> Parser.Pascaligo.ParserLog.instruction_to_string fun () -> ParserLog.instruction_to_string
~offsets:true ~mode:`Point t) ~offsets:true ~mode:`Point t)
] in ] in
error ~data title message error ~data title message
@ -562,31 +563,43 @@ and simpl_tuple_expression ?loc (lst:Raw.expr list) : expression result =
| [] -> return @@ e_literal Literal_unit | [] -> return @@ e_literal Literal_unit
| [hd] -> simpl_expression hd | [hd] -> simpl_expression hd
| lst -> | lst ->
let%bind lst = bind_list @@ List.map simpl_expression lst in let%bind lst = bind_list @@ List.map simpl_expression lst
return @@ e_tuple ?loc lst in return @@ e_tuple ?loc lst
and simpl_data_declaration : Raw.data_decl -> _ result = fun t -> and simpl_data_declaration : Raw.data_decl -> _ result =
fun t ->
match t with match t with
| LocalVar x -> | LocalVar x ->
let (x , loc) = r_split x in let (x , loc) = r_split x in
let name = x.name.value in let name = x.name.value in
let%bind t = simpl_type_expression x.var_type in let%bind t = simpl_type_expression x.var_type in
let%bind expression = simpl_expression x.init in let%bind expression = simpl_expression x.init in
return_let_in ~loc (Var.of_name name , Some t) false expression return_let_in ~loc (Var.of_name name, Some t) false expression
| LocalConst x -> | LocalConst x ->
let (x , loc) = r_split x in let (x , loc) = r_split x in
let name = x.name.value in let name = x.name.value in
let%bind t = simpl_type_expression x.const_type in let%bind t = simpl_type_expression x.const_type in
let%bind expression = simpl_expression x.init in let%bind expression = simpl_expression x.init in
let inline = List.exists (fun (f: Raw.attribute) -> f.value = "\"inline\"") x.attributes.value in let inline =
return_let_in ~loc (Var.of_name name , Some t) inline expression match x.attributes with
None -> false
| Some {value; _} ->
npseq_to_list value.ne_elements
|> List.exists (fun Region.{value; _} -> value = "\"inline\"")
in return_let_in ~loc (Var.of_name name, Some t) inline expression
| LocalFun f -> | LocalFun f ->
let (f , loc) = r_split f in let (f , loc) = r_split f in
let%bind (binder, expr) = simpl_fun_decl ~loc f in let%bind (binder, expr) = simpl_fun_decl ~loc f in
let inline = List.exists (fun (f: Raw.attribute) -> f.value = "\"inline\"") f.attributes.value in let inline =
return_let_in ~loc binder inline expr match f.attributes with
None -> false
| Some {value; _} ->
npseq_to_list value.ne_elements
|> List.exists (fun Region.{value; _} -> value = "\"inline\"")
in return_let_in ~loc binder inline expr
and simpl_param : Raw.param_decl -> (expression_variable * type_expression) result = and simpl_param :
Raw.param_decl -> (expression_variable * type_expression) result =
fun t -> fun t ->
match t with match t with
| ParamConst c -> | ParamConst c ->
@ -601,11 +614,18 @@ and simpl_param : Raw.param_decl -> (expression_variable * type_expression) resu
ok (type_name , type_expression) ok (type_name , type_expression)
and simpl_fun_decl : and simpl_fun_decl :
loc:_ -> Raw.fun_decl -> ((expression_variable * type_expression option) * expression) result = loc:_ -> Raw.fun_decl ->
((expression_variable * type_expression option) * expression) result =
fun ~loc x -> fun ~loc x ->
let open! Raw in let open! Raw in
let {fun_name;param;ret_type;block_with;return; attributes} : fun_decl = x in let {fun_name; param; ret_type; block_with;
let inline = List.exists (fun (a: Raw.attribute) -> a.value = "\"inline\"") attributes.value in return; attributes} : fun_decl = x in
let inline =
match attributes with
None -> false
| Some {value; _} ->
npseq_to_list value.ne_elements
|> List.exists (fun Region.{value; _} -> value = "\"inline\"") in
let statements = let statements =
match block_with with match block_with with
| Some (block,_) -> npseq_to_list block.value.statements | Some (block,_) -> npseq_to_list block.value.statements
@ -615,9 +635,7 @@ and simpl_fun_decl :
a, [] -> ( a, [] -> (
let%bind input = simpl_param a in let%bind input = simpl_param a in
let (binder , input_type) = input in let (binder , input_type) = input in
let%bind instructions = bind_list let%bind instructions = simpl_statement_list statements in
@@ List.map simpl_statement
@@ statements in
let%bind result = simpl_expression return in let%bind result = simpl_expression return in
let%bind output_type = simpl_type_expression ret_type in let%bind output_type = simpl_type_expression ret_type in
let body = instructions in let body = instructions in
@ -647,9 +665,7 @@ and simpl_fun_decl :
ass ass
in in
bind_list @@ List.mapi aux params in bind_list @@ List.mapi aux params in
let%bind instructions = bind_list let%bind instructions = simpl_statement_list statements in
@@ List.map simpl_statement
@@ statements in
let%bind result = simpl_expression return in let%bind result = simpl_expression return in
let%bind output_type = simpl_type_expression ret_type in let%bind output_type = simpl_type_expression ret_type in
let body = tpl_declarations @ instructions in let body = tpl_declarations @ instructions in
@ -673,9 +689,7 @@ and simpl_fun_expression :
a, [] -> ( a, [] -> (
let%bind input = simpl_param a in let%bind input = simpl_param a in
let (binder , input_type) = input in let (binder , input_type) = input in
let%bind instructions = bind_list let%bind instructions = simpl_statement_list statements in
@@ List.map simpl_statement
@@ statements in
let%bind result = simpl_expression return in let%bind result = simpl_expression return in
let%bind output_type = simpl_type_expression ret_type in let%bind output_type = simpl_type_expression ret_type in
let body = instructions in let body = instructions in
@ -705,9 +719,7 @@ and simpl_fun_expression :
ass ass
in in
bind_list @@ List.mapi aux params in bind_list @@ List.mapi aux params in
let%bind instructions = bind_list let%bind instructions = simpl_statement_list statements in
@@ List.map simpl_statement
@@ statements in
let%bind result = simpl_expression return in let%bind result = simpl_expression return in
let%bind output_type = simpl_type_expression ret_type in let%bind output_type = simpl_type_expression ret_type in
let body = tpl_declarations @ instructions in let body = tpl_declarations @ instructions in
@ -721,44 +733,39 @@ and simpl_fun_expression :
) )
) )
and simpl_declaration : Raw.declaration -> declaration Location.wrap result = and simpl_statement_list statements =
fun t -> let open Raw in
let open! Raw in let rec hook acc = function
match t with [] -> acc
| TypeDecl x -> | [Attr _] ->
let decl, loc = r_split x in (* Detached attributes are erased. TODO: Warning. *)
let {name;type_expr} : Raw.type_decl = decl in acc
let%bind type_expression = simpl_type_expression type_expr in | Attr _ :: (Attr _ :: _ as statements) ->
ok @@ Location.wrap ~loc (Declaration_type (* Detached attributes are erased. TODO: Warning. *)
(Var.of_name name.value, type_expression)) hook acc statements
| Attr decl :: Data (LocalConst {value; region}) :: statements ->
| ConstDecl x -> let new_const =
let simpl_const_decl = fun {name;const_type; init; attributes} -> Data (LocalConst {value = {value with attributes = Some decl}; region})
let%bind expression = simpl_expression init in in hook acc (new_const :: statements)
let%bind t = simpl_type_expression const_type in | Attr decl :: Data (LocalFun {value; region}) :: statements ->
let type_annotation = Some t in let new_fun =
let inline = List.exists (fun (a: Raw.attribute) -> a.value = "\"inline\"") attributes.value in Data (LocalFun {value = {value with attributes = Some decl}; region})
ok @@ Declaration_constant in hook acc (new_fun :: statements)
(Var.of_name name.value, type_annotation, inline, expression) | Attr _ :: statements ->
in bind_map_location simpl_const_decl (Location.lift_region x) (* Detached attributes are erased. TODO: Warning. *)
| FunDecl x -> hook acc statements
let decl, loc = r_split x in | Instr i :: statements ->
let%bind ((name, ty_opt), expr) = simpl_fun_decl ~loc decl in hook (simpl_instruction i :: acc) statements
let inline = List.exists (fun (a: Raw.attribute) -> a.value = "\"inline\"") x.value.attributes.value in | Data d :: statements ->
ok @@ Location.wrap ~loc (Declaration_constant (name, ty_opt, inline, expr)) hook (simpl_data_declaration d :: acc) statements
in bind_list @@ hook [] (List.rev statements)
and simpl_statement : Raw.statement -> (_ -> expression result) result =
fun s ->
match s with
| Instr i -> simpl_instruction i
| Data d -> simpl_data_declaration d
and simpl_single_instruction : Raw.instruction -> (_ -> expression result) result = and simpl_single_instruction : Raw.instruction -> (_ -> expression result) result =
fun t -> fun t ->
match t with match t with
| ProcCall x -> ( | ProcCall x -> (
let ((f, args) , loc) = r_split x in let (f, args) , loc = r_split x in
let (args , args_loc) = r_split args in let args, args_loc = r_split args in
let args' = npseq_to_list args.inside in let args' = npseq_to_list args.inside in
match f with match f with
| EVar name -> ( | EVar name -> (
@ -1057,10 +1064,10 @@ and simpl_cases : type a . (Raw.pattern * a) list -> (a, unit) matching result =
let aux (x , y) = let aux (x , y) =
let error = let error =
let title () = "Pattern" in let title () = "Pattern" in
(** TODO: The labelled arguments should be flowing from the CLI. *) (* TODO: The labelled arguments should be flowing from the CLI. *)
let content () = let content () =
Printf.sprintf "Pattern : %s" Printf.sprintf "Pattern : %s"
(Parser.Pascaligo.ParserLog.pattern_to_string (ParserLog.pattern_to_string
~offsets:true ~mode:`Point x) in ~offsets:true ~mode:`Point x) in
error title content in error title content in
let%bind x' = let%bind x' =
@ -1071,23 +1078,22 @@ and simpl_cases : type a . (Raw.pattern * a) list -> (a, unit) matching result =
ok @@ ez_match_variant constrs ok @@ ez_match_variant constrs
and simpl_instruction : Raw.instruction -> (_ -> expression result) result = and simpl_instruction : Raw.instruction -> (_ -> expression result) result =
fun t -> fun t -> trace (simplifying_instruction t) @@ simpl_single_instruction t
trace (simplifying_instruction t) @@ simpl_single_instruction t
and simpl_statements : Raw.statements -> (_ -> expression result) result = and simpl_statements : Raw.statements -> (_ -> expression result) result =
fun ss -> fun statements ->
let lst = npseq_to_list ss in let lst = npseq_to_list statements in
let%bind fs = bind_map_list simpl_statement lst in let%bind fs = simpl_statement_list lst in
let aux : _ -> (expression option -> expression result) -> _ = let aux : _ -> (expression option -> expression result) -> _ =
fun prec cur -> fun prec cur ->
let%bind res = cur prec in let%bind res = cur prec
ok @@ Some res in in ok @@ Some res in
ok @@ fun (expr' : _ option) -> ok @@ fun (expr' : _ option) ->
let%bind ret = bind_fold_right_list aux expr' fs in let%bind ret = bind_fold_right_list aux expr' fs in
ok @@ Option.unopt_exn ret ok @@ Option.unopt_exn ret
and simpl_block : Raw.block -> (_ -> expression result) result = fun t -> and simpl_block : Raw.block -> (_ -> expression result) result =
simpl_statements t.statements fun t -> simpl_statements t.statements
and simpl_for_int : Raw.for_int -> (_ -> expression result) result = fun fi -> and simpl_for_int : Raw.for_int -> (_ -> expression result) result = fun fi ->
(* cond part *) (* cond part *)
@ -1263,11 +1269,13 @@ and simpl_for_collect : Raw.for_collect -> (_ -> expression result) result = fun
(* STEP 5 *) (* STEP 5 *)
let rec add_return (expr : expression) = match expr.expression with let rec add_return (expr : expression) = match expr.expression with
| E_sequence (a,b) -> e_sequence a (add_return b) | E_sequence (a,b) -> e_sequence a (add_return b)
| _ -> e_sequence expr (e_variable (Var.of_name "#COMPILER#acc")) in (* TODO fresh *) | _ -> (* TODO fresh *)
e_sequence expr (e_variable (Var.of_name "#COMPILER#acc")) in
let for_body = add_return for_body in let for_body = add_return for_body in
(* STEP 6 *) (* STEP 6 *)
let for_body = let for_body =
let ( arg_access: Types.access_path -> expression ) = e_accessor (e_variable (Var.of_name "arguments")) in (* TODO fresh *) let ( arg_access: Types.access_path -> expression ) =
e_accessor (e_variable (Var.of_name "arguments")) in (* TODO fresh *)
( match fc.collection with ( match fc.collection with
| Map _ -> | Map _ ->
let acc = arg_access [Access_tuple 0 ] in let acc = arg_access [Access_tuple 0 ] in
@ -1290,7 +1298,8 @@ and simpl_for_collect : Raw.for_collect -> (_ -> expression result) result = fun
let fold = e_constant op_name [lambda; collect ; init_record] in let fold = e_constant op_name [lambda; collect ; init_record] in
(* STEP 8 *) (* STEP 8 *)
let assign_back (prev : expression option) (captured_varname : string) : expression option = let assign_back (prev : expression option) (captured_varname : string) : expression option =
let access = e_accessor (e_variable (Var.of_name "#COMPILER#folded_record")) (* TODO fresh *) let access = (* TODO fresh *)
e_accessor (e_variable (Var.of_name "#COMPILER#folded_record"))
[Access_record captured_varname] in [Access_record captured_varname] in
let assign = e_assign captured_varname [] access in let assign = e_assign captured_varname [] access in
match prev with match prev with
@ -1303,6 +1312,74 @@ and simpl_for_collect : Raw.for_collect -> (_ -> expression result) result = fun
| None -> e_skip () | None -> e_skip ()
| Some seq -> e_let_in (Var.of_name "#COMPILER#folded_record", None) false fold seq in (* TODO fresh *) | Some seq -> e_let_in (Var.of_name "#COMPILER#folded_record", None) false fold seq in (* TODO fresh *)
return_statement @@ final_sequence return_statement @@ final_sequence
(*
and simpl_declaration : Raw.declaration -> declaration Location.wrap result =
*)
let simpl_program : Raw.ast -> program result = fun t -> and simpl_declaration_list declarations :
bind_list @@ List.map simpl_declaration @@ nseq_to_list t.decl Ast_simplified.declaration Location.wrap list result =
let open Raw in
let rec hook acc = function
[] -> acc
| [AttrDecl _] ->
(* Detached attributes are erased. TODO: Warning. *)
acc
| AttrDecl _ :: (AttrDecl _ :: _ as declarations) ->
(* Detached attributes are erased. TODO: Warning. *)
hook acc declarations
| AttrDecl decl :: ConstDecl {value; region} :: declarations ->
let new_const =
ConstDecl {value = {value with attributes = Some decl}; region}
in hook acc (new_const :: declarations)
| AttrDecl decl :: FunDecl {value; region} :: declarations ->
let new_fun =
FunDecl {value = {value with attributes = Some decl}; region}
in hook acc (new_fun :: declarations)
| AttrDecl _ :: declarations ->
(* Detached attributes are erased. TODO: Warning. *)
hook acc declarations
| TypeDecl decl :: declarations ->
let decl, loc = r_split decl in
let {name; type_expr} : Raw.type_decl = decl in
let%bind type_expression = simpl_type_expression type_expr in
let new_decl =
Declaration_type (Var.of_name name.value, type_expression) in
let res = Location.wrap ~loc new_decl in
hook (bind_list_cons res acc) declarations
| ConstDecl decl :: declarations ->
let simpl_const_decl =
fun {name;const_type; init; attributes} ->
let%bind expression = simpl_expression init in
let%bind t = simpl_type_expression const_type in
let type_annotation = Some t in
let inline =
match attributes with
None -> false
| Some {value; _} ->
npseq_to_list value.ne_elements
|> List.exists (fun Region.{value; _} -> value = "\"inline\"") in
let new_decl =
Declaration_constant
(Var.of_name name.value, type_annotation, inline, expression)
in ok new_decl in
let%bind res =
bind_map_location simpl_const_decl (Location.lift_region decl)
in hook (bind_list_cons res acc) declarations
| FunDecl fun_decl :: declarations ->
let decl, loc = r_split fun_decl in
let%bind ((name, ty_opt), expr) = simpl_fun_decl ~loc decl in
let inline =
match fun_decl.value.attributes with
None -> false
| Some {value; _} ->
npseq_to_list value.ne_elements
|> List.exists (fun Region.{value; _} -> value = "\"inline\"") in
let new_decl =
Declaration_constant (name, ty_opt, inline, expr) in
let res = Location.wrap ~loc new_decl in
hook (bind_list_cons res acc) declarations
in
hook (ok @@ []) (List.rev declarations)
let simpl_program : Raw.ast -> program result =
fun t -> simpl_declaration_list @@ nseq_to_list t.decl

View File

@ -6,14 +6,6 @@ let all = [
Literals.peephole_expression ; Literals.peephole_expression ;
] ]
let rec bind_chain : ('a -> 'a result) list -> 'a -> 'a result = fun fs x ->
match fs with
| [] -> ok x
| hd :: tl -> (
let aux : 'a -> 'a result = fun x -> bind (bind_chain tl) (hd x) in
bind aux (ok x)
)
let all_program = let all_program =
let all_p = List.map Helpers.map_program all in let all_p = List.map Helpers.map_program all in
bind_chain all_p bind_chain all_p

View File

@ -163,3 +163,11 @@ let rec map_expression : mapper -> expression -> expression result = fun f e ->
let%bind updates = bind_map_list (fun (p,e) -> let%bind e = self e in ok(p,e)) updates in let%bind updates = bind_map_list (fun (p,e) -> let%bind e = self e in ok(p,e)) updates in
return @@ E_update(r,updates) return @@ E_update(r,updates)
) )
let map_sub_level_expression : mapper -> expression -> expression result = fun f e ->
match e.content with
| E_closure {binder ; body} ->
let%bind body = map_expression f body in
let content = E_closure {binder; body} in
ok @@ { e with content }
| _ -> ok e

View File

@ -0,0 +1,26 @@
open Mini_c
open Trace
module Errors = struct
let bad_self_address cst () =
let title = thunk @@
Format.asprintf "Wrong %alocation" Mini_c.PP.expression' cst in
let message = thunk @@
Format.asprintf "%ais only allowed at top-level" Mini_c.PP.expression' cst in
error title message ()
end
open Errors
let self_in_lambdas : expression -> expression result =
fun e ->
match e.content with
| E_closure {binder=_ ; body} ->
let%bind _self_in_lambdas = Helpers.map_expression
(fun e -> match e.content with
| E_constant (C_SELF_ADDRESS, _) as c -> fail (bad_self_address c)
| _ -> ok e)
body in
ok e
| _ -> ok e

View File

@ -250,6 +250,11 @@ let betas : bool ref -> expression -> expression =
fun changed -> fun changed ->
map_expression (beta changed) map_expression (beta changed)
let contract_check =
let all = [Michelson_restrictions.self_in_lambdas] in
let all_e = List.map Helpers.map_sub_level_expression all in
bind_chain all_e
let rec all_expression : expression -> expression = let rec all_expression : expression -> expression =
fun e -> fun e ->
let changed = ref false in let changed = ref false in

View File

@ -92,11 +92,13 @@ let e_chain_id ?loc s : expression = location_wrap ?loc @@ E_literal (Literal_ch
let e'_bytes b : expression' result = let e'_bytes b : expression' result =
let%bind bytes = generic_try (simple_error "bad hex to bytes") (fun () -> Hex.to_bytes (`Hex b)) in let%bind bytes = generic_try (simple_error "bad hex to bytes") (fun () -> Hex.to_bytes (`Hex b)) in
ok @@ E_literal (Literal_bytes bytes) ok @@ E_literal (Literal_bytes bytes)
let e_bytes ?loc b : expression result = let e_bytes_hex ?loc b : expression result =
let%bind e' = e'_bytes b in let%bind e' = e'_bytes b in
ok @@ location_wrap ?loc e' ok @@ location_wrap ?loc e'
let e_bytes_ofbytes ?loc (b: bytes) : expression = let e_bytes_raw ?loc (b: bytes) : expression =
location_wrap ?loc @@ E_literal (Literal_bytes b) location_wrap ?loc @@ E_literal (Literal_bytes b)
let e_bytes_string ?loc (s: string) : expression =
location_wrap ?loc @@ E_literal (Literal_bytes (Hex.to_bytes (Hex.of_string s)))
let e_big_map ?loc lst : expression = location_wrap ?loc @@ E_big_map lst let e_big_map ?loc lst : expression = location_wrap ?loc @@ E_big_map lst
let e_record ?loc map : expression = location_wrap ?loc @@ E_record map let e_record ?loc map : expression = location_wrap ?loc @@ E_record map
let e_tuple ?loc lst : expression = location_wrap ?loc @@ E_tuple lst let e_tuple ?loc lst : expression = location_wrap ?loc @@ E_tuple lst

View File

@ -60,8 +60,9 @@ val e_key_hash : ?loc:Location.t -> string -> expression
val e_chain_id : ?loc:Location.t -> string -> expression val e_chain_id : ?loc:Location.t -> string -> expression
val e_mutez : ?loc:Location.t -> int -> expression val e_mutez : ?loc:Location.t -> int -> expression
val e'_bytes : string -> expression' result val e'_bytes : string -> expression' result
val e_bytes : ?loc:Location.t -> string -> expression result val e_bytes_hex : ?loc:Location.t -> string -> expression result
val e_bytes_ofbytes : ?loc:Location.t -> bytes -> expression val e_bytes_raw : ?loc:Location.t -> bytes -> expression
val e_bytes_string : ?loc:Location.t -> string -> expression
val e_big_map : ?loc:Location.t -> ( expr * expr ) list -> expression val e_big_map : ?loc:Location.t -> ( expr * expr ) list -> expression
(* (*
val e_record : ?loc:Location.t -> ( expr * expr ) list -> expression val e_record : ?loc:Location.t -> ( expr * expr ) list -> expression

View File

@ -1,17 +1,19 @@
const x: int = 1; attributes ["inline"]; const x : int = 1; attributes ["inline"]
function foo (const a : int) : int is function foo (const a : int) : int is
block { begin
const test: int = 2 + a; attributes ["inline"]; const test : int = 2 + a;
} with test; attributes ["inline"];
end with test;
attributes ["inline"]; attributes ["inline"];
const y: int = 1; attributes ["inline"; "other"]; const y : int = 1; attributes ["inline"; "other"]
function bar (const b : int) : int is function bar (const b : int) : int is
block { begin
function test (const z : int) : int is begin function test (const z : int) : int is
begin
const r : int = 2 + b + z const r : int = 2 + b + z
end with r; end with r;
attributes ["inline"; "foo"; "bar"]; attributes ["inline"; "foo"; "bar"]
} with test(b); end with test(b)

View File

@ -1,13 +1,10 @@
let x = 1 [@@inline] let x = 1 [@@inline]
let foo (a: int): int = ( let foo (a: int): int =
let test = 2 + a [@@inline] in (let test = 2 + a [@@inline] in test) [@@inline]
test
) [@@inline]
let y = 1 [@@inline][@@other] let y = 1 [@@inline][@@other]
let bar (b: int): int = ( let bar (b: int): int =
let test = fun (z: int) -> 2 + b + z [@@inline][@@foo][@@bar] in let test = fun (z: int) -> 2 + b + z [@@inline][@@foo][@@bar]
test b in test b
)

View File

@ -0,0 +1,11 @@
let id_string (p: string) : string option =
let packed: bytes = Bytes.pack p in
((Bytes.unpack packed): string option)
let id_int (p: int) : int option =
let packed: bytes = Bytes.pack p in
((Bytes.unpack packed): int option)
let id_address (p: address) : address option =
let packed: bytes = Bytes.pack p in
((Bytes.unpack packed): address option)

Some files were not shown because too many files have changed in this diff Show More