2019-02-26 01:29:29 +04:00
|
|
|
(* Abstract Syntax Tree (AST) for Ligo *)
|
2019-03-07 15:24:57 +04:00
|
|
|
|
|
|
|
(* To disable warning about multiply-defined record labels. *)
|
|
|
|
|
|
|
|
[@@@warning "-30-42"]
|
|
|
|
|
|
|
|
(* Utilities *)
|
|
|
|
|
2019-02-26 01:29:29 +04:00
|
|
|
open Utils
|
|
|
|
|
|
|
|
(* Regions
|
|
|
|
|
|
|
|
The AST carries all the regions where tokens have been found by the
|
|
|
|
lexer, plus additional regions corresponding to whole subtrees
|
|
|
|
(like entire expressions, patterns etc.). These regions are needed
|
|
|
|
for error reporting and source-to-source transformations. To make
|
|
|
|
these pervasive regions more legible, we define singleton types for
|
|
|
|
the symbols, keywords etc. with suggestive names like "kwd_and"
|
|
|
|
denoting the _region_ of the occurrence of the keyword "and".
|
|
|
|
*)
|
|
|
|
|
|
|
|
type 'a reg = 'a Region.reg
|
|
|
|
|
|
|
|
let rec last to_region = function
|
|
|
|
[] -> Region.ghost
|
|
|
|
| [x] -> to_region x
|
|
|
|
| _::t -> last to_region t
|
|
|
|
|
|
|
|
let nseq_to_region to_region (hd,tl) =
|
|
|
|
Region.cover (to_region hd) (last to_region tl)
|
|
|
|
|
|
|
|
let nsepseq_to_region to_region (hd,tl) =
|
2019-03-07 15:24:57 +04:00
|
|
|
let reg (_, item) = to_region item in
|
2019-02-26 01:29:29 +04:00
|
|
|
Region.cover (to_region hd) (last reg tl)
|
|
|
|
|
|
|
|
let sepseq_to_region to_region = function
|
|
|
|
None -> Region.ghost
|
|
|
|
| Some seq -> nsepseq_to_region to_region seq
|
|
|
|
|
|
|
|
(* Keywords of Ligo *)
|
|
|
|
|
|
|
|
type kwd_begin = Region.t
|
|
|
|
type kwd_const = Region.t
|
|
|
|
type kwd_down = Region.t
|
2019-02-28 18:46:34 +04:00
|
|
|
type kwd_fail = Region.t
|
2019-02-26 01:29:29 +04:00
|
|
|
type kwd_if = Region.t
|
|
|
|
type kwd_in = Region.t
|
|
|
|
type kwd_is = Region.t
|
|
|
|
type kwd_for = Region.t
|
|
|
|
type kwd_function = Region.t
|
|
|
|
type kwd_parameter = Region.t
|
|
|
|
type kwd_storage = Region.t
|
|
|
|
type kwd_type = Region.t
|
|
|
|
type kwd_of = Region.t
|
|
|
|
type kwd_operations = Region.t
|
|
|
|
type kwd_var = Region.t
|
|
|
|
type kwd_end = Region.t
|
|
|
|
type kwd_then = Region.t
|
|
|
|
type kwd_else = Region.t
|
|
|
|
type kwd_match = Region.t
|
|
|
|
type kwd_procedure = Region.t
|
|
|
|
type kwd_null = Region.t
|
|
|
|
type kwd_record = Region.t
|
|
|
|
type kwd_step = Region.t
|
|
|
|
type kwd_to = Region.t
|
|
|
|
type kwd_mod = Region.t
|
|
|
|
type kwd_not = Region.t
|
|
|
|
type kwd_while = Region.t
|
|
|
|
type kwd_with = Region.t
|
|
|
|
|
|
|
|
(* Data constructors *)
|
|
|
|
|
|
|
|
type c_False = Region.t
|
|
|
|
type c_None = Region.t
|
|
|
|
type c_Some = Region.t
|
|
|
|
type c_True = Region.t
|
|
|
|
type c_Unit = Region.t
|
|
|
|
|
|
|
|
(* Symbols *)
|
|
|
|
|
|
|
|
type semi = Region.t
|
|
|
|
type comma = Region.t
|
|
|
|
type lpar = Region.t
|
|
|
|
type rpar = Region.t
|
|
|
|
type lbrace = Region.t
|
|
|
|
type rbrace = Region.t
|
|
|
|
type lbracket = Region.t
|
|
|
|
type rbracket = Region.t
|
|
|
|
type cons = Region.t
|
|
|
|
type vbar = Region.t
|
|
|
|
type arrow = Region.t
|
2019-03-07 20:06:02 +04:00
|
|
|
type ass = Region.t
|
2019-02-26 01:29:29 +04:00
|
|
|
type equal = Region.t
|
|
|
|
type colon = Region.t
|
|
|
|
type bool_or = Region.t
|
|
|
|
type bool_and = Region.t
|
|
|
|
type lt = Region.t
|
|
|
|
type leq = Region.t
|
|
|
|
type gt = Region.t
|
|
|
|
type geq = Region.t
|
|
|
|
type neq = Region.t
|
|
|
|
type plus = Region.t
|
|
|
|
type minus = Region.t
|
|
|
|
type slash = Region.t
|
|
|
|
type times = Region.t
|
|
|
|
type dot = Region.t
|
|
|
|
type wild = Region.t
|
|
|
|
type cat = Region.t
|
|
|
|
|
|
|
|
(* Virtual tokens *)
|
|
|
|
|
|
|
|
type eof = Region.t
|
|
|
|
|
|
|
|
(* Literals *)
|
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
type 'x variable = string reg
|
|
|
|
type 'x fun_name = string reg
|
|
|
|
type 'x type_name = string reg
|
|
|
|
type 'x field_name = string reg
|
|
|
|
type 'x map_name = string reg
|
|
|
|
type 'x constr = string reg
|
2019-02-26 01:29:29 +04:00
|
|
|
|
|
|
|
(* Comma-separated non-empty lists *)
|
|
|
|
|
|
|
|
type 'a csv = ('a, comma) nsepseq
|
|
|
|
|
|
|
|
(* Bar-separated non-empty lists *)
|
|
|
|
|
|
|
|
type 'a bsv = ('a, vbar) nsepseq
|
|
|
|
|
|
|
|
(* Parentheses *)
|
|
|
|
|
|
|
|
type 'a par = (lpar * 'a * rpar) reg
|
|
|
|
|
|
|
|
(* Brackets compounds *)
|
|
|
|
|
|
|
|
type 'a brackets = (lbracket * 'a * rbracket) reg
|
|
|
|
|
|
|
|
(* Braced compounds *)
|
|
|
|
|
|
|
|
type 'a braces = (lbrace * 'a * rbrace) reg
|
|
|
|
|
|
|
|
(* The Abstract Syntax Tree *)
|
|
|
|
|
2019-03-05 23:37:32 +04:00
|
|
|
type ttrue = TTrue
|
|
|
|
type tfalse = TFalse
|
|
|
|
type ('a, 'type_expr_typecheck) gadt_if =
|
|
|
|
Present : 'a -> ('a, ttrue) gadt_if
|
2019-03-05 21:13:09 +04:00
|
|
|
|
2019-03-05 23:37:32 +04:00
|
|
|
(* It is possible to further ensure well-typedness at the meta level
|
|
|
|
by using the following constraint:
|
|
|
|
|
|
|
|
type ttrue = [`True]
|
|
|
|
type tfalse = [`False]
|
|
|
|
|
|
|
|
type 'x x_sig = 'x
|
|
|
|
constraint 'x = < ty: 'ty;
|
|
|
|
type_expr_typecheck: [< `True | `False] >
|
|
|
|
|
|
|
|
we could also use a single selector for type_expr, as long as
|
|
|
|
the fields are monotonic:
|
|
|
|
|
|
|
|
type z = [`Z]
|
|
|
|
type 'i s = [`S of 'i]
|
|
|
|
type 'is type_level_int = [< `S of 'i | `Z]
|
|
|
|
constraint 'i = 'prev type_level_int
|
|
|
|
|
|
|
|
type parse_phase = z
|
|
|
|
type typecheck_phase = z s
|
|
|
|
type further_phase = z s s
|
|
|
|
|
|
|
|
type 'x x_sig = 'x
|
|
|
|
constraint 'x = < ty: 'ty;
|
|
|
|
type_expr: 'type_expr >
|
|
|
|
|
|
|
|
These schemes provide more guidance but the simple one below is
|
|
|
|
sufficient.
|
|
|
|
*)
|
|
|
|
type 'x x_sig = 'x
|
|
|
|
constraint 'x = < annot: 'type_annotation;
|
|
|
|
type_expr_typecheck: 'bool1 >
|
|
|
|
|
|
|
|
type 'x ast = {
|
2019-03-05 21:16:21 +04:00
|
|
|
types : 'x type_decl reg list;
|
|
|
|
constants : 'x const_decl reg list;
|
|
|
|
parameter : 'x parameter_decl reg;
|
|
|
|
storage : 'x storage_decl reg;
|
|
|
|
operations : 'x operations_decl reg;
|
|
|
|
lambdas : 'x lambda_decl list;
|
|
|
|
block : 'x block reg;
|
2019-03-05 21:13:09 +04:00
|
|
|
eof : eof
|
2019-03-05 12:53:58 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x parameter_decl = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_parameter : kwd_parameter;
|
2019-03-05 21:16:21 +04:00
|
|
|
name : 'x variable;
|
2019-03-05 21:13:09 +04:00
|
|
|
colon : colon;
|
2019-03-05 21:16:21 +04:00
|
|
|
param_type : 'x type_expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
terminator : semi option
|
2019-03-07 20:06:02 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x storage_decl = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_storage : kwd_storage;
|
2019-03-05 21:16:21 +04:00
|
|
|
store_type : 'x type_expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
terminator : semi option
|
2019-03-07 20:06:02 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x operations_decl = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_operations : kwd_operations;
|
2019-03-05 21:16:21 +04:00
|
|
|
op_type : 'x type_expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
terminator : semi option
|
2019-03-07 20:06:02 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
|
|
|
(* Type declarations *)
|
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x type_decl = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_type : kwd_type;
|
2019-03-05 21:16:21 +04:00
|
|
|
name : 'x type_name;
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_is : kwd_is;
|
2019-03-05 21:16:21 +04:00
|
|
|
type_expr : 'x type_expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
terminator : semi option
|
2019-03-07 20:06:02 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x type_expr =
|
2019-03-05 23:37:32 +04:00
|
|
|
Prod of ('x cartesian, ttrue) gadt_if
|
|
|
|
| Sum of (('x variant, vbar) nsepseq reg, ttrue) gadt_if
|
|
|
|
| Record of ('x record_type, ttrue) gadt_if
|
|
|
|
| TypeApp of (('x type_name * 'x type_tuple) reg, ttrue) gadt_if
|
|
|
|
| ParType of ('x type_expr par, ttrue) gadt_if
|
|
|
|
| TAlias of ('x variable, ttrue) gadt_if
|
|
|
|
|
|
|
|
| Function of (('x type_expr list) * 'x type_expr, 'type_expr_typecheck) gadt_if
|
|
|
|
| Mutable of ('x type_expr, 'type_expr_typecheck) gadt_if
|
|
|
|
| Unit of (unit, 'type_expr_typecheck) gadt_if
|
|
|
|
constraint 'x = < type_expr_typecheck: 'type_expr_typecheck;
|
|
|
|
.. >
|
|
|
|
constraint 'x = 'x x_sig
|
|
|
|
|
|
|
|
(*
|
|
|
|
and 'x type_expr = ('x cartesian,
|
|
|
|
('x variant, vbar) nsepseq reg,
|
|
|
|
'x record_type,
|
|
|
|
('x type_name * 'x type_tuple) reg,
|
|
|
|
'x type_expr par,
|
|
|
|
'x variable,
|
|
|
|
|
|
|
|
('x type_expr list) * 'x type_expr,
|
|
|
|
'x type_expr,
|
|
|
|
unit,
|
|
|
|
|
|
|
|
'type_expr_parse,
|
|
|
|
'type_expr_typecheck) type_expr_gadt
|
|
|
|
constraint 'x = < type_expr_parse: 'type_expr_parse;
|
|
|
|
type_expr_typecheck: 'type_expr_typecheck;
|
|
|
|
.. >
|
|
|
|
constraint 'x = 'x x_sig
|
|
|
|
|
|
|
|
and ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'type_expr_parse, 'type_expr_typecheck) type_expr_gadt =
|
|
|
|
Prod : 'a -> ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, ttrue, ttrue) type_expr_gadt
|
|
|
|
| Sum : 'b -> ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, ttrue, ttrue) type_expr_gadt
|
|
|
|
| Record : 'c -> ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, ttrue, ttrue) type_expr_gadt
|
|
|
|
| TypeApp : 'd -> ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, ttrue, ttrue) type_expr_gadt
|
|
|
|
| ParType : 'e -> ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, ttrue, ttrue) type_expr_gadt
|
|
|
|
| TAlias : 'f -> ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, ttrue, ttrue) type_expr_gadt
|
|
|
|
|
|
|
|
| Function : 'g -> ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, tfalse, ttrue) type_expr_gadt
|
|
|
|
| Mutable : 'h -> ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, tfalse, ttrue) type_expr_gadt
|
|
|
|
| Unit : 'i -> ('a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, tfalse, ttrue) type_expr_gadt
|
|
|
|
*)
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x cartesian = ('x type_expr, times) nsepseq reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x variant = ('x constr * kwd_of * 'x cartesian) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x record_type = (kwd_record * 'x field_decls * kwd_end) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x field_decls = ('x field_decl, semi) nsepseq
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x field_decl = ('x variable * colon * 'x type_expr) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x type_tuple = ('x type_name, comma) nsepseq par
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
|
|
|
(* Function and procedure declarations *)
|
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x lambda_decl =
|
|
|
|
FunDecl of 'x fun_decl reg
|
|
|
|
| ProcDecl of 'x proc_decl reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-03-05 21:13:09 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x fun_decl = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_function : kwd_function;
|
2019-03-05 21:16:21 +04:00
|
|
|
name : 'x variable;
|
|
|
|
param : 'x parameters;
|
2019-03-05 21:13:09 +04:00
|
|
|
colon : colon;
|
2019-03-05 21:16:21 +04:00
|
|
|
ret_type : 'x type_expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_is : kwd_is;
|
2019-03-05 21:16:21 +04:00
|
|
|
local_decls : 'x local_decl list;
|
|
|
|
block : 'x block reg;
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_with : kwd_with;
|
2019-03-05 21:16:21 +04:00
|
|
|
return : 'x expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
terminator : semi option
|
2019-03-05 12:53:58 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x proc_decl = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_procedure : kwd_procedure;
|
2019-03-05 21:16:21 +04:00
|
|
|
name : 'x variable;
|
|
|
|
param : 'x parameters;
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_is : kwd_is;
|
2019-03-05 21:16:21 +04:00
|
|
|
local_decls : 'x local_decl list;
|
|
|
|
block : 'x block reg;
|
2019-03-05 21:13:09 +04:00
|
|
|
terminator : semi option
|
2019-03-05 12:53:58 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x parameters = ('x param_decl, semi) nsepseq par
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x param_decl =
|
|
|
|
ParamConst of 'x param_const
|
|
|
|
| ParamVar of 'x param_var
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x param_const = (kwd_const * 'x variable * colon * 'x type_expr) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-03-07 20:06:02 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x param_var = (kwd_var * 'x variable * colon * 'x type_expr) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-03-07 20:06:02 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x block = {
|
2019-03-05 21:13:09 +04:00
|
|
|
opening : kwd_begin;
|
2019-03-05 21:16:21 +04:00
|
|
|
instr : 'x instructions;
|
2019-03-05 21:13:09 +04:00
|
|
|
terminator : semi option;
|
|
|
|
close : kwd_end
|
2019-03-05 12:53:58 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x local_decl =
|
|
|
|
LocalLam of 'x lambda_decl
|
|
|
|
| LocalConst of 'x const_decl reg
|
|
|
|
| LocalVar of 'x var_decl reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-03-05 21:13:09 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x const_decl = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_const : kwd_const;
|
2019-03-05 21:16:21 +04:00
|
|
|
name : 'x variable;
|
2019-03-05 21:13:09 +04:00
|
|
|
colon : colon;
|
2019-03-05 21:16:21 +04:00
|
|
|
vtype : 'x type_expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
equal : equal;
|
2019-03-05 21:16:21 +04:00
|
|
|
init : 'x expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
terminator : semi option
|
2019-03-05 14:15:02 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-03-07 20:06:02 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x var_decl = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_var : kwd_var;
|
2019-03-05 21:16:21 +04:00
|
|
|
name : 'x variable;
|
2019-03-05 21:13:09 +04:00
|
|
|
colon : colon;
|
2019-03-05 21:16:21 +04:00
|
|
|
vtype : 'x type_expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
ass : ass;
|
2019-03-05 21:16:21 +04:00
|
|
|
init : 'x expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
terminator : semi option
|
2019-03-05 12:53:58 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x instructions = ('x instruction, semi) nsepseq reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x instruction =
|
|
|
|
Single of 'x single_instr
|
|
|
|
| Block of 'x block reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x single_instr =
|
|
|
|
Cond of 'x conditional reg
|
|
|
|
| Match of 'x match_instr reg
|
|
|
|
| Ass of 'x ass_instr
|
|
|
|
| Loop of 'x loop
|
|
|
|
| ProcCall of 'x fun_call
|
2019-02-26 01:29:29 +04:00
|
|
|
| Null of kwd_null
|
2019-03-05 21:16:21 +04:00
|
|
|
| Fail of (kwd_fail * 'x expr) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-03-05 21:13:09 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x conditional = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_if : kwd_if;
|
2019-03-05 21:16:21 +04:00
|
|
|
test : 'x expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_then : kwd_then;
|
2019-03-05 21:16:21 +04:00
|
|
|
ifso : 'x instruction;
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_else : kwd_else;
|
2019-03-05 21:16:21 +04:00
|
|
|
ifnot : 'x instruction
|
2019-03-05 12:53:58 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x match_instr = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_match : kwd_match;
|
2019-03-05 21:16:21 +04:00
|
|
|
expr : 'x expr;
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_with : kwd_with;
|
|
|
|
lead_vbar : vbar option;
|
2019-03-05 21:16:21 +04:00
|
|
|
cases : 'x cases;
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_end : kwd_end
|
2019-03-05 12:53:58 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x cases = ('x case, vbar) nsepseq reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x case = ('x pattern * arrow * 'x instruction) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x ass_instr = ('x variable * ass * 'x expr) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x loop =
|
|
|
|
While of 'x while_loop
|
|
|
|
| For of 'x for_loop
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x while_loop = (kwd_while * 'x expr * 'x block reg) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x for_loop =
|
|
|
|
ForInt of 'x for_int reg
|
|
|
|
| ForCollect of 'x for_collect reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x for_int = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_for : kwd_for;
|
2019-03-05 21:16:21 +04:00
|
|
|
ass : 'x ass_instr;
|
2019-03-05 21:13:09 +04:00
|
|
|
down : kwd_down option;
|
|
|
|
kwd_to : kwd_to;
|
2019-03-05 21:16:21 +04:00
|
|
|
bound : 'x expr;
|
|
|
|
step : (kwd_step * 'x expr) option;
|
|
|
|
block : 'x block reg
|
2019-03-05 12:53:58 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x for_collect = {
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_for : kwd_for;
|
2019-03-05 21:16:21 +04:00
|
|
|
var : 'x variable;
|
|
|
|
bind_to : (arrow * 'x variable) option;
|
2019-03-05 21:13:09 +04:00
|
|
|
kwd_in : kwd_in;
|
2019-03-05 21:16:21 +04:00
|
|
|
expr : 'x expr;
|
|
|
|
block : 'x block reg
|
2019-03-05 12:53:58 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
|
|
|
(* Expressions *)
|
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x expr =
|
|
|
|
Or of ('x expr * bool_or * 'x expr) reg
|
|
|
|
| And of ('x expr * bool_and * 'x expr) reg
|
|
|
|
| Lt of ('x expr * lt * 'x expr) reg
|
|
|
|
| Leq of ('x expr * leq * 'x expr) reg
|
|
|
|
| Gt of ('x expr * gt * 'x expr) reg
|
|
|
|
| Geq of ('x expr * geq * 'x expr) reg
|
|
|
|
| Equal of ('x expr * equal * 'x expr) reg
|
|
|
|
| Neq of ('x expr * neq * 'x expr) reg
|
|
|
|
| Cat of ('x expr * cat * 'x expr) reg
|
|
|
|
| Cons of ('x expr * cons * 'x expr) reg
|
|
|
|
| Add of ('x expr * plus * 'x expr) reg
|
|
|
|
| Sub of ('x expr * minus * 'x expr) reg
|
|
|
|
| Mult of ('x expr * times * 'x expr) reg
|
|
|
|
| Div of ('x expr * slash * 'x expr) reg
|
|
|
|
| Mod of ('x expr * kwd_mod * 'x expr) reg
|
|
|
|
| Neg of (minus * 'x expr) reg
|
|
|
|
| Not of (kwd_not * 'x expr) reg
|
2019-02-26 01:29:29 +04:00
|
|
|
| Int of (Lexer.lexeme * Z.t) reg
|
|
|
|
| Var of Lexer.lexeme reg
|
|
|
|
| String of Lexer.lexeme reg
|
|
|
|
| Bytes of (Lexer.lexeme * MBytes.t) reg
|
|
|
|
| False of c_False
|
|
|
|
| True of c_True
|
|
|
|
| Unit of c_Unit
|
2019-03-05 21:16:21 +04:00
|
|
|
| Tuple of 'x tuple
|
|
|
|
| List of ('x expr, comma) nsepseq brackets
|
|
|
|
| EmptyList of 'x empty_list
|
|
|
|
| Set of ('x expr, comma) nsepseq braces
|
|
|
|
| EmptySet of 'x empty_set
|
|
|
|
| NoneExpr of 'x none_expr
|
|
|
|
| FunCall of 'x fun_call
|
|
|
|
| ConstrApp of 'x constr_app
|
|
|
|
| SomeApp of (c_Some * 'x arguments) reg
|
|
|
|
| MapLookUp of 'x map_lookup reg
|
|
|
|
| ParExpr of 'x expr par
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x tuple = ('x expr, comma) nsepseq par
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x empty_list =
|
|
|
|
(lbracket * rbracket * colon * 'x type_expr) par
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x empty_set =
|
|
|
|
(lbrace * rbrace * colon * 'x type_expr) par
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x none_expr =
|
|
|
|
(c_None * colon * 'x type_expr) par
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x fun_call = ('x fun_name * 'x arguments) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x arguments = 'x tuple
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x constr_app = ('x constr * 'x arguments) reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x map_lookup = {
|
|
|
|
map_name : 'x variable;
|
2019-02-26 01:29:29 +04:00
|
|
|
selector : dot;
|
2019-03-05 21:16:21 +04:00
|
|
|
index : 'x expr brackets
|
2019-03-05 12:53:58 +04:00
|
|
|
}
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
|
|
|
(* Patterns *)
|
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x pattern = ('x core_pattern, cons) nsepseq reg
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x core_pattern =
|
2019-02-26 01:29:29 +04:00
|
|
|
PVar of Lexer.lexeme reg
|
|
|
|
| PWild of wild
|
|
|
|
| PInt of (Lexer.lexeme * Z.t) reg
|
|
|
|
| PBytes of (Lexer.lexeme * MBytes.t) reg
|
|
|
|
| PString of Lexer.lexeme reg
|
|
|
|
| PUnit of c_Unit
|
|
|
|
| PFalse of c_False
|
|
|
|
| PTrue of c_True
|
|
|
|
| PNone of c_None
|
2019-03-05 21:16:21 +04:00
|
|
|
| PSome of (c_Some * 'x core_pattern par) reg
|
|
|
|
| PList of 'x list_pattern
|
|
|
|
| PTuple of ('x core_pattern, comma) nsepseq par
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
and 'x list_pattern =
|
|
|
|
Sugar of ('x core_pattern, comma) sepseq brackets
|
|
|
|
| Raw of ('x core_pattern * cons * 'x pattern) par
|
2019-03-05 23:37:32 +04:00
|
|
|
constraint 'x = 'x x_sig
|
|
|
|
|
|
|
|
(* Variations on the AST *)
|
|
|
|
|
|
|
|
type parse_phase = <
|
|
|
|
annot: unit;
|
|
|
|
type_expr_typecheck: tfalse;
|
|
|
|
>
|
|
|
|
|
|
|
|
type typecheck_phase = <
|
|
|
|
annot: typecheck_phase type_expr;
|
|
|
|
type_expr_typecheck: ttrue;
|
|
|
|
>
|
|
|
|
|
|
|
|
type t = parse_phase ast
|
2019-02-26 01:29:29 +04:00
|
|
|
|
|
|
|
(* Projecting regions *)
|
|
|
|
|
2019-03-07 15:24:57 +04:00
|
|
|
open! Region
|
2019-02-26 01:29:29 +04:00
|
|
|
|
2019-03-05 23:37:32 +04:00
|
|
|
let type_expr_to_region : parse_phase type_expr -> region = function
|
|
|
|
Prod (Present node) -> node.region
|
|
|
|
| Sum (Present node) -> node.region
|
|
|
|
| Record (Present node) -> node.region
|
|
|
|
| TypeApp (Present node) -> node.region
|
|
|
|
| ParType (Present node) -> node.region
|
|
|
|
| TAlias (Present node) -> node.region
|
|
|
|
| _ -> .
|
2019-02-26 01:29:29 +04:00
|
|
|
|
|
|
|
let expr_to_region = function
|
|
|
|
Or {region; _}
|
|
|
|
| And {region; _}
|
|
|
|
| Lt {region; _}
|
|
|
|
| Leq {region; _}
|
|
|
|
| Gt {region; _}
|
|
|
|
| Geq {region; _}
|
|
|
|
| Equal {region; _}
|
|
|
|
| Neq {region; _}
|
|
|
|
| Cat {region; _}
|
|
|
|
| Cons {region; _}
|
|
|
|
| Add {region; _}
|
|
|
|
| Sub {region; _}
|
|
|
|
| Mult {region; _}
|
|
|
|
| Div {region; _}
|
|
|
|
| Mod {region; _}
|
|
|
|
| Neg {region; _}
|
|
|
|
| Not {region; _}
|
|
|
|
| Int {region; _}
|
|
|
|
| Var {region; _}
|
|
|
|
| String {region; _}
|
|
|
|
| Bytes {region; _}
|
|
|
|
| False region
|
|
|
|
| True region
|
|
|
|
| Unit region
|
|
|
|
| Tuple {region; _}
|
|
|
|
| List {region; _}
|
|
|
|
| EmptyList {region; _}
|
|
|
|
| Set {region; _}
|
|
|
|
| EmptySet {region; _}
|
|
|
|
| NoneExpr {region; _}
|
|
|
|
| FunCall {region; _}
|
|
|
|
| ConstrApp {region; _}
|
|
|
|
| SomeApp {region; _}
|
|
|
|
| MapLookUp {region; _}
|
|
|
|
| ParExpr {region; _} -> region
|
|
|
|
|
|
|
|
let instr_to_region = function
|
|
|
|
Single Cond {region;_}
|
|
|
|
| Single Match {region; _}
|
2019-03-07 20:06:02 +04:00
|
|
|
| Single Ass {region; _}
|
2019-02-26 01:29:29 +04:00
|
|
|
| Single Loop While {region; _}
|
|
|
|
| Single Loop For ForInt {region; _}
|
|
|
|
| Single Loop For ForCollect {region; _}
|
|
|
|
| Single ProcCall {region; _}
|
|
|
|
| Single Null region
|
2019-02-28 18:46:34 +04:00
|
|
|
| Single Fail {region; _}
|
2019-02-26 01:29:29 +04:00
|
|
|
| Block {region; _} -> region
|
|
|
|
|
|
|
|
let core_pattern_to_region = function
|
|
|
|
PVar {region; _}
|
|
|
|
| PWild region
|
|
|
|
| PInt {region; _}
|
|
|
|
| PBytes {region; _}
|
|
|
|
| PString {region; _}
|
|
|
|
| PUnit region
|
|
|
|
| PFalse region
|
|
|
|
| PTrue region
|
|
|
|
| PNone region
|
|
|
|
| PSome {region; _}
|
|
|
|
| PList Sugar {region; _}
|
|
|
|
| PList Raw {region; _}
|
|
|
|
| PTuple {region; _} -> region
|
|
|
|
|
2019-02-28 18:46:34 +04:00
|
|
|
let local_decl_to_region = function
|
|
|
|
LocalLam FunDecl {region; _}
|
|
|
|
| LocalLam ProcDecl {region; _}
|
|
|
|
| LocalConst {region; _}
|
|
|
|
| LocalVar {region; _} -> region
|
|
|
|
|
2019-02-26 01:29:29 +04:00
|
|
|
(* Printing the tokens with their source regions *)
|
|
|
|
|
2019-03-05 21:16:21 +04:00
|
|
|
type 'x visitor = {
|
|
|
|
ass_instr : 'x ass_instr -> unit;
|
|
|
|
bind_to : (region * 'x variable) option -> unit;
|
|
|
|
block : 'x block reg -> unit;
|
2019-03-07 15:24:57 +04:00
|
|
|
bytes : (string * MBytes.t) reg -> unit;
|
2019-03-05 21:16:21 +04:00
|
|
|
cartesian : 'x cartesian -> unit;
|
|
|
|
case : 'x case -> unit;
|
|
|
|
cases : 'x cases -> unit;
|
|
|
|
conditional : 'x conditional -> unit;
|
|
|
|
const_decl : 'x const_decl reg -> unit;
|
|
|
|
constr : 'x constr -> unit;
|
|
|
|
constr_app : 'x constr_app -> unit;
|
|
|
|
core_pattern : 'x core_pattern -> unit;
|
2019-03-07 15:24:57 +04:00
|
|
|
down : region option -> unit;
|
2019-03-05 21:16:21 +04:00
|
|
|
empty_list : 'x empty_list -> unit;
|
|
|
|
empty_set : 'x empty_set -> unit;
|
|
|
|
expr : 'x expr -> unit;
|
|
|
|
fail : (kwd_fail * 'x expr) -> unit;
|
|
|
|
field_decl : 'x field_decl -> unit;
|
|
|
|
field_decls : 'x field_decls -> unit;
|
|
|
|
for_collect : 'x for_collect reg -> unit;
|
|
|
|
for_int : 'x for_int reg -> unit;
|
|
|
|
for_loop : 'x for_loop -> unit;
|
|
|
|
fun_call : 'x fun_call -> unit;
|
|
|
|
fun_decl : 'x fun_decl reg -> unit;
|
|
|
|
instruction : 'x instruction -> unit;
|
|
|
|
instructions : 'x instructions -> unit;
|
2019-03-07 15:24:57 +04:00
|
|
|
int : (string * Z.t) reg -> unit;
|
2019-03-05 21:16:21 +04:00
|
|
|
lambda_decl : 'x lambda_decl -> unit;
|
|
|
|
list : ('x expr, region) nsepseq brackets -> unit;
|
|
|
|
list_pattern : 'x list_pattern -> unit;
|
|
|
|
loop : 'x loop -> unit;
|
|
|
|
map_lookup : 'x map_lookup reg -> unit;
|
|
|
|
match_instr : 'x match_instr -> unit;
|
|
|
|
none_expr : 'x none_expr -> unit;
|
2019-03-07 15:24:57 +04:00
|
|
|
nsepseq : 'a.string -> ('a -> unit) -> ('a, region) nsepseq -> unit;
|
2019-03-05 21:16:21 +04:00
|
|
|
operations_decl : 'x operations_decl reg -> unit;
|
|
|
|
par_expr : 'x expr par -> unit;
|
|
|
|
par_type : 'x type_expr par -> unit;
|
|
|
|
param_decl : 'x param_decl -> unit;
|
|
|
|
parameter_decl : 'x parameter_decl reg -> unit;
|
|
|
|
parameters : 'x parameters -> unit;
|
|
|
|
param_const : 'x param_const -> unit;
|
|
|
|
param_var : 'x param_var -> unit;
|
|
|
|
pattern : 'x pattern -> unit;
|
|
|
|
patterns : 'x core_pattern par -> unit;
|
|
|
|
proc_decl : 'x proc_decl reg -> unit;
|
|
|
|
psome : (region * 'x core_pattern par) reg -> unit;
|
|
|
|
ptuple : ('x core_pattern, region) nsepseq par -> unit;
|
|
|
|
raw : ('x core_pattern * region * 'x pattern) par -> unit;
|
|
|
|
record_type : 'x record_type -> unit;
|
2019-03-07 15:24:57 +04:00
|
|
|
sepseq : 'a.string -> ('a -> unit) -> ('a, region) sepseq -> unit;
|
2019-03-05 21:16:21 +04:00
|
|
|
set : ('x expr, region) nsepseq braces -> unit;
|
|
|
|
single_instr : 'x single_instr -> unit;
|
|
|
|
some_app : (region * 'x arguments) reg -> unit;
|
|
|
|
step : (region * 'x expr) option -> unit;
|
|
|
|
storage_decl : 'x storage_decl reg -> unit;
|
2019-03-07 15:24:57 +04:00
|
|
|
string : string reg -> unit;
|
2019-03-05 21:16:21 +04:00
|
|
|
sugar : ('x core_pattern, region) sepseq brackets -> unit;
|
|
|
|
sum_type : ('x variant, region) nsepseq reg -> unit;
|
2019-03-07 20:06:02 +04:00
|
|
|
terminator : semi option -> unit;
|
2019-03-07 15:24:57 +04:00
|
|
|
token : region -> string -> unit;
|
2019-03-05 21:16:21 +04:00
|
|
|
tuple : 'x arguments -> unit;
|
|
|
|
type_app : ('x type_name * 'x type_tuple) reg -> unit;
|
|
|
|
type_decl : 'x type_decl reg -> unit;
|
|
|
|
type_expr : 'x type_expr -> unit;
|
|
|
|
type_tuple : 'x type_tuple -> unit;
|
|
|
|
local_decl : 'x local_decl -> unit;
|
|
|
|
local_decls : 'x local_decl list -> unit;
|
|
|
|
var : 'x variable -> unit;
|
|
|
|
var_decl : 'x var_decl reg -> unit;
|
|
|
|
variant : 'x variant -> unit;
|
|
|
|
while_loop : 'x while_loop -> unit
|
2019-03-07 15:24:57 +04:00
|
|
|
}
|