I extended the grammar with optional semicolons and vertical bars.
This commit is contained in:
parent
ec6cefb1ff
commit
09f790680f
151
AST.ml
151
AST.ml
@ -89,7 +89,7 @@ type rbracket = Region.t
|
||||
type cons = Region.t
|
||||
type vbar = Region.t
|
||||
type arrow = Region.t
|
||||
type asgnmnt = Region.t
|
||||
type ass = Region.t
|
||||
type equal = Region.t
|
||||
type colon = Region.t
|
||||
type bool_or = Region.t
|
||||
@ -143,11 +143,11 @@ type 'a braces = (lbrace * 'a * rbrace) reg
|
||||
(* The Abstract Syntax Tree *)
|
||||
|
||||
type t = {
|
||||
types : type_decl list;
|
||||
types : type_decl reg list;
|
||||
constants : const_decl reg list;
|
||||
parameter : parameter_decl;
|
||||
storage : storage_decl;
|
||||
operations : operations_decl;
|
||||
parameter : parameter_decl reg;
|
||||
storage : storage_decl reg;
|
||||
operations : operations_decl reg;
|
||||
lambdas : lambda_decl list;
|
||||
block : block reg;
|
||||
eof : eof
|
||||
@ -155,15 +155,35 @@ type t = {
|
||||
|
||||
and ast = t
|
||||
|
||||
and parameter_decl = (kwd_parameter * variable * colon * type_expr) reg
|
||||
and parameter_decl = {
|
||||
kwd_parameter : kwd_parameter;
|
||||
name : variable;
|
||||
colon : colon;
|
||||
param_type : type_expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and storage_decl = (kwd_storage * type_expr) reg
|
||||
and storage_decl = {
|
||||
kwd_storage : kwd_storage;
|
||||
store_type : type_expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and operations_decl = (kwd_operations * type_expr) reg
|
||||
and operations_decl = {
|
||||
kwd_operations : kwd_operations;
|
||||
op_type : type_expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
(* Type declarations *)
|
||||
|
||||
and type_decl = (kwd_type * type_name * kwd_is * type_expr) reg
|
||||
and type_decl = {
|
||||
kwd_type : kwd_type;
|
||||
name : type_name;
|
||||
kwd_is : kwd_is;
|
||||
type_expr : type_expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and type_expr =
|
||||
Prod of cartesian
|
||||
@ -201,7 +221,8 @@ and fun_decl = {
|
||||
local_decls : local_decl list;
|
||||
block : block reg;
|
||||
kwd_with : kwd_with;
|
||||
return : expr
|
||||
return : expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and proc_decl = {
|
||||
@ -210,22 +231,24 @@ and proc_decl = {
|
||||
param : parameters;
|
||||
kwd_is : kwd_is;
|
||||
local_decls : local_decl list;
|
||||
block : block reg
|
||||
block : block reg;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and parameters = (param_decl, semi) nsepseq par
|
||||
|
||||
and param_const = (kwd_const * variable * colon * type_expr) reg
|
||||
|
||||
and param_var = (kwd_var * variable * colon * type_expr) reg
|
||||
|
||||
and param_decl =
|
||||
ParamConst of param_const
|
||||
| ParamVar of param_var
|
||||
|
||||
and param_const = (kwd_const * variable * colon * type_expr) reg
|
||||
|
||||
and param_var = (kwd_var * variable * colon * type_expr) reg
|
||||
|
||||
and block = {
|
||||
opening : kwd_begin;
|
||||
instr : instructions;
|
||||
terminator : semi option;
|
||||
close : kwd_end
|
||||
}
|
||||
|
||||
@ -240,15 +263,18 @@ and const_decl = {
|
||||
colon : colon;
|
||||
vtype : type_expr;
|
||||
equal : equal;
|
||||
init : expr
|
||||
init : expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and var_decl = {
|
||||
kwd_var : kwd_var;
|
||||
name : variable;
|
||||
colon : colon;
|
||||
vtype : type_expr;
|
||||
asgnmnt : asgnmnt;
|
||||
init : expr
|
||||
ass : ass;
|
||||
init : expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and instructions = (instruction, semi) nsepseq reg
|
||||
@ -260,7 +286,7 @@ and instruction =
|
||||
and single_instr =
|
||||
Cond of conditional reg
|
||||
| Match of match_instr reg
|
||||
| Asgnmnt of asgnmnt_instr
|
||||
| Ass of ass_instr
|
||||
| Loop of loop
|
||||
| ProcCall of fun_call
|
||||
| Null of kwd_null
|
||||
@ -279,6 +305,7 @@ and match_instr = {
|
||||
kwd_match : kwd_match;
|
||||
expr : expr;
|
||||
kwd_with : kwd_with;
|
||||
lead_vbar : vbar option;
|
||||
cases : cases;
|
||||
kwd_end : kwd_end
|
||||
}
|
||||
@ -287,7 +314,7 @@ and cases = (case, vbar) nsepseq reg
|
||||
|
||||
and case = (pattern * arrow * instruction) reg
|
||||
|
||||
and asgnmnt_instr = (variable * asgnmnt * expr) reg
|
||||
and ass_instr = (variable * ass * expr) reg
|
||||
|
||||
and loop =
|
||||
While of while_loop
|
||||
@ -301,7 +328,7 @@ and for_loop =
|
||||
|
||||
and for_int = {
|
||||
kwd_for : kwd_for;
|
||||
asgnmnt : asgnmnt_instr;
|
||||
ass : ass_instr;
|
||||
down : kwd_down option;
|
||||
kwd_to : kwd_to;
|
||||
bound : expr;
|
||||
@ -454,7 +481,7 @@ let expr_to_region = function
|
||||
let instr_to_region = function
|
||||
Single Cond {region;_}
|
||||
| Single Match {region; _}
|
||||
| Single Asgnmnt {region; _}
|
||||
| Single Ass {region; _}
|
||||
| Single Loop While {region; _}
|
||||
| Single Loop For ForInt {region; _}
|
||||
| Single Loop For ForCollect {region; _}
|
||||
@ -487,7 +514,7 @@ let local_decl_to_region = function
|
||||
(* Printing the tokens with their source regions *)
|
||||
|
||||
type visitor = {
|
||||
asgnmnt_instr : asgnmnt_instr -> unit;
|
||||
ass_instr : ass_instr -> unit;
|
||||
bind_to : (region * variable) option -> unit;
|
||||
block : block reg -> unit;
|
||||
bytes : (string * MBytes.t) reg -> unit;
|
||||
@ -522,11 +549,11 @@ type visitor = {
|
||||
match_instr : match_instr -> unit;
|
||||
none_expr : none_expr -> unit;
|
||||
nsepseq : 'a.string -> ('a -> unit) -> ('a, region) nsepseq -> unit;
|
||||
operations_decl : (region * type_expr) reg -> unit;
|
||||
operations_decl : operations_decl reg -> unit;
|
||||
par_expr : expr par -> unit;
|
||||
par_type : type_expr par -> unit;
|
||||
param_decl : param_decl -> unit;
|
||||
parameter_decl : (region * variable * region * type_expr) reg -> unit;
|
||||
parameter_decl : parameter_decl reg -> unit;
|
||||
parameters : parameters -> unit;
|
||||
param_const : param_const -> unit;
|
||||
param_var : param_var -> unit;
|
||||
@ -542,14 +569,15 @@ type visitor = {
|
||||
single_instr : single_instr -> unit;
|
||||
some_app : (region * arguments) reg -> unit;
|
||||
step : (region * expr) option -> unit;
|
||||
storage_decl : (region * type_expr) reg -> unit;
|
||||
storage_decl : storage_decl reg -> unit;
|
||||
string : string reg -> unit;
|
||||
sugar : (core_pattern, region) sepseq brackets -> unit;
|
||||
sum_type : (variant, region) nsepseq reg -> unit;
|
||||
terminator : semi option -> unit;
|
||||
token : region -> string -> unit;
|
||||
tuple : arguments -> unit;
|
||||
type_app : (type_name * type_tuple) reg -> unit;
|
||||
type_decl : (region * variable * region * type_expr) reg -> unit;
|
||||
type_decl : type_decl reg -> unit;
|
||||
type_expr : type_expr -> unit;
|
||||
type_tuple : type_tuple -> unit;
|
||||
local_decl : local_decl -> unit;
|
||||
@ -603,7 +631,8 @@ and print_int _visitor {region; value = lexeme, abstract} =
|
||||
(compact region) lexeme
|
||||
(Z.to_string abstract)
|
||||
|
||||
(* main print function *)
|
||||
(* Main printing function *)
|
||||
|
||||
and print_tokens (v: visitor) ast =
|
||||
List.iter v.type_decl ast.types;
|
||||
v.parameter_decl ast.parameter;
|
||||
@ -614,28 +643,28 @@ and print_tokens (v: visitor) ast =
|
||||
v.token ast.eof "EOF"
|
||||
|
||||
and print_parameter_decl (v: visitor) {value=node; _} =
|
||||
let kwd_parameter, variable, colon, type_expr = node in
|
||||
v.token kwd_parameter "parameter";
|
||||
v.var variable;
|
||||
v.token colon ":";
|
||||
v.type_expr type_expr
|
||||
v.token node.kwd_parameter "parameter";
|
||||
v.var node.name;
|
||||
v.token node.colon ":";
|
||||
v.type_expr node.param_type;
|
||||
v.terminator node.terminator
|
||||
|
||||
and print_storage_decl (v: visitor) {value=node; _} =
|
||||
let kwd_storage, type_expr = node in
|
||||
v.token kwd_storage "storage";
|
||||
v.type_expr type_expr
|
||||
v.token node.kwd_storage "storage";
|
||||
v.type_expr node.store_type;
|
||||
v.terminator node.terminator
|
||||
|
||||
and print_operations_decl (v: visitor) {value=node; _} =
|
||||
let kwd_operations, type_expr = node in
|
||||
v.token kwd_operations "operations";
|
||||
v.type_expr type_expr
|
||||
v.token node.kwd_operations "operations";
|
||||
v.type_expr node.op_type;
|
||||
v.terminator node.terminator
|
||||
|
||||
and print_type_decl (v: visitor) {value=node; _} =
|
||||
let kwd_type, type_name, kwd_is, type_expr = node in
|
||||
v.token kwd_type "type";
|
||||
v.var type_name;
|
||||
v.token kwd_is "is";
|
||||
v.type_expr type_expr
|
||||
v.token node.kwd_type "type";
|
||||
v.var node.name;
|
||||
v.token node.kwd_is "is";
|
||||
v.type_expr node.type_expr;
|
||||
v.terminator node.terminator
|
||||
|
||||
and print_type_expr (v: visitor) = function
|
||||
Prod cartesian -> v.cartesian cartesian
|
||||
@ -703,7 +732,8 @@ and print_fun_decl (v: visitor) {value=node; _} =
|
||||
v.local_decls node.local_decls;
|
||||
v.block node.block;
|
||||
v.token node.kwd_with "with";
|
||||
v.expr node.return
|
||||
v.expr node.return;
|
||||
v.terminator node.terminator
|
||||
|
||||
and print_proc_decl (v: visitor) {value=node; _} =
|
||||
v.token node.kwd_procedure "procedure";
|
||||
@ -711,7 +741,8 @@ and print_proc_decl (v: visitor) {value=node; _} =
|
||||
v.parameters node.param;
|
||||
v.token node.kwd_is "is";
|
||||
v.local_decls node.local_decls;
|
||||
v.block node.block
|
||||
v.block node.block;
|
||||
v.terminator node.terminator
|
||||
|
||||
and print_parameters (v: visitor) {value=node; _} =
|
||||
let lpar, sequence, rpar = node in
|
||||
@ -740,6 +771,7 @@ and print_param_var (v: visitor) {value=node; _} =
|
||||
and print_block (v: visitor) {value=node; _} =
|
||||
v.token node.opening "begin";
|
||||
v.instructions node.instr;
|
||||
v.terminator node.terminator;
|
||||
v.token node.close "end"
|
||||
|
||||
and print_local_decls (v: visitor) sequence =
|
||||
@ -756,15 +788,17 @@ and print_const_decl (v: visitor) {value=node; _} =
|
||||
v.token node.colon ":";
|
||||
v.type_expr node.vtype;
|
||||
v.token node.equal "=";
|
||||
v.expr node.init
|
||||
v.expr node.init;
|
||||
v.terminator node.terminator
|
||||
|
||||
and print_var_decl (v: visitor) {value=node; _} =
|
||||
v.token node.kwd_var "var";
|
||||
v.var node.name;
|
||||
v.token node.colon ":";
|
||||
v.type_expr node.vtype;
|
||||
v.token node.asgnmnt ":=";
|
||||
v.expr node.init
|
||||
v.token node.ass ":=";
|
||||
v.expr node.init;
|
||||
v.terminator node.terminator
|
||||
|
||||
and print_instructions (v: visitor) {value=sequence; _} =
|
||||
v.nsepseq ";" v.instruction sequence
|
||||
@ -776,7 +810,7 @@ and print_instruction (v: visitor) = function
|
||||
and print_single_instr (v: visitor) = function
|
||||
Cond {value; _} -> v.conditional value
|
||||
| Match {value; _} -> v.match_instr value
|
||||
| Asgnmnt instr -> v.asgnmnt_instr instr
|
||||
| Ass instr -> v.ass_instr instr
|
||||
| Loop loop -> v.loop loop
|
||||
| ProcCall fun_call -> v.fun_call fun_call
|
||||
| Null kwd_null -> v.token kwd_null "null"
|
||||
@ -810,10 +844,10 @@ and print_case (v: visitor) {value=node; _} =
|
||||
v.token arrow "->";
|
||||
v.instruction instruction
|
||||
|
||||
and print_asgnmnt_instr (v: visitor) {value=node; _} =
|
||||
let variable, asgnmnt, expr = node in
|
||||
and print_ass_instr (v: visitor) {value=node; _} =
|
||||
let variable, ass, expr = node in
|
||||
v.var variable;
|
||||
v.token asgnmnt ":=";
|
||||
v.token ass ":=";
|
||||
v.expr expr
|
||||
|
||||
and print_loop (v: visitor) = function
|
||||
@ -832,7 +866,7 @@ and print_for_loop (v: visitor) = function
|
||||
|
||||
and print_for_int (v: visitor) ({value=node; _} : for_int reg) =
|
||||
v.token node.kwd_for "for";
|
||||
v.asgnmnt_instr node.asgnmnt;
|
||||
v.ass_instr node.ass;
|
||||
v.down node.down;
|
||||
v.token node.kwd_to "to";
|
||||
v.expr node.bound;
|
||||
@ -1042,6 +1076,10 @@ and print_ptuple (v: visitor) {value=node; _} =
|
||||
v.nsepseq "," v.core_pattern sequence;
|
||||
v.token rpar ")"
|
||||
|
||||
and print_terminator (v: visitor) = function
|
||||
Some semi -> v.token semi ";"
|
||||
| None -> ()
|
||||
|
||||
let rec visitor () : visitor = {
|
||||
nsepseq = print_nsepseq;
|
||||
sepseq = print_sepseq;
|
||||
@ -1086,7 +1124,7 @@ let rec visitor () : visitor = {
|
||||
match_instr = print_match_instr (visitor ());
|
||||
cases = print_cases (visitor ());
|
||||
case = print_case (visitor ());
|
||||
asgnmnt_instr = print_asgnmnt_instr (visitor ());
|
||||
ass_instr = print_ass_instr (visitor ());
|
||||
loop = print_loop (visitor ());
|
||||
while_loop = print_while_loop (visitor ());
|
||||
for_loop = print_for_loop (visitor ());
|
||||
@ -1114,7 +1152,8 @@ let rec visitor () : visitor = {
|
||||
list_pattern = print_list_pattern (visitor ());
|
||||
sugar = print_sugar (visitor ());
|
||||
raw = print_raw (visitor ());
|
||||
ptuple = print_ptuple (visitor ())
|
||||
ptuple = print_ptuple (visitor ());
|
||||
terminator = print_terminator (visitor ())
|
||||
}
|
||||
|
||||
let print_tokens = print_tokens (visitor ())
|
||||
|
68
AST.mli
68
AST.mli
@ -73,7 +73,7 @@ type rbracket = Region.t
|
||||
type cons = Region.t
|
||||
type vbar = Region.t
|
||||
type arrow = Region.t
|
||||
type asgnmnt = Region.t
|
||||
type ass = Region.t
|
||||
type equal = Region.t
|
||||
type colon = Region.t
|
||||
type bool_or = Region.t
|
||||
@ -127,11 +127,11 @@ type 'a braces = (lbrace * 'a * rbrace) reg
|
||||
(* The Abstract Syntax Tree *)
|
||||
|
||||
type t = {
|
||||
types : type_decl list;
|
||||
types : type_decl reg list;
|
||||
constants : const_decl reg list;
|
||||
parameter : parameter_decl;
|
||||
storage : storage_decl;
|
||||
operations : operations_decl;
|
||||
parameter : parameter_decl reg;
|
||||
storage : storage_decl reg;
|
||||
operations : operations_decl reg;
|
||||
lambdas : lambda_decl list;
|
||||
block : block reg;
|
||||
eof : eof
|
||||
@ -139,15 +139,35 @@ type t = {
|
||||
|
||||
and ast = t
|
||||
|
||||
and parameter_decl = (kwd_parameter * variable * colon * type_expr) reg
|
||||
and parameter_decl = {
|
||||
kwd_parameter : kwd_parameter;
|
||||
name : variable;
|
||||
colon : colon;
|
||||
param_type : type_expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and storage_decl = (kwd_storage * type_expr) reg
|
||||
and storage_decl = {
|
||||
kwd_storage : kwd_storage;
|
||||
store_type : type_expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and operations_decl = (kwd_operations * type_expr) reg
|
||||
and operations_decl = {
|
||||
kwd_operations : kwd_operations;
|
||||
op_type : type_expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
(* Type declarations *)
|
||||
|
||||
and type_decl = (kwd_type * type_name * kwd_is * type_expr) reg
|
||||
and type_decl = {
|
||||
kwd_type : kwd_type;
|
||||
name : type_name;
|
||||
kwd_is : kwd_is;
|
||||
type_expr : type_expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and type_expr =
|
||||
Prod of cartesian
|
||||
@ -185,7 +205,8 @@ and fun_decl = {
|
||||
local_decls : local_decl list;
|
||||
block : block reg;
|
||||
kwd_with : kwd_with;
|
||||
return : expr
|
||||
return : expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and proc_decl = {
|
||||
@ -194,18 +215,24 @@ and proc_decl = {
|
||||
param : parameters;
|
||||
kwd_is : kwd_is;
|
||||
local_decls : local_decl list;
|
||||
block : block reg
|
||||
block : block reg;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and parameters = (param_decl, semi) nsepseq par
|
||||
|
||||
and param_decl =
|
||||
ParamConst of (kwd_const * variable * colon * type_expr) reg
|
||||
| ParamVar of (kwd_var * variable * colon * type_expr) reg
|
||||
ParamConst of param_const
|
||||
| ParamVar of param_var
|
||||
|
||||
and param_const = (kwd_const * variable * colon * type_expr) reg
|
||||
|
||||
and param_var = (kwd_var * variable * colon * type_expr) reg
|
||||
|
||||
and block = {
|
||||
opening : kwd_begin;
|
||||
instr : instructions;
|
||||
terminator : semi option;
|
||||
close : kwd_end
|
||||
}
|
||||
|
||||
@ -220,7 +247,8 @@ and const_decl = {
|
||||
colon : colon;
|
||||
vtype : type_expr;
|
||||
equal : equal;
|
||||
init : expr
|
||||
init : expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and var_decl = {
|
||||
@ -228,8 +256,9 @@ and var_decl = {
|
||||
name : variable;
|
||||
colon : colon;
|
||||
vtype : type_expr;
|
||||
asgnmnt : asgnmnt;
|
||||
init : expr
|
||||
ass : ass;
|
||||
init : expr;
|
||||
terminator : semi option
|
||||
}
|
||||
|
||||
and instructions = (instruction, semi) nsepseq reg
|
||||
@ -241,7 +270,7 @@ and instruction =
|
||||
and single_instr =
|
||||
Cond of conditional reg
|
||||
| Match of match_instr reg
|
||||
| Asgnmnt of asgnmnt_instr
|
||||
| Ass of ass_instr
|
||||
| Loop of loop
|
||||
| ProcCall of fun_call
|
||||
| Null of kwd_null
|
||||
@ -260,6 +289,7 @@ and match_instr = {
|
||||
kwd_match : kwd_match;
|
||||
expr : expr;
|
||||
kwd_with : kwd_with;
|
||||
lead_vbar : vbar option;
|
||||
cases : cases;
|
||||
kwd_end : kwd_end
|
||||
}
|
||||
@ -268,7 +298,7 @@ and cases = (case, vbar) nsepseq reg
|
||||
|
||||
and case = (pattern * arrow * instruction) reg
|
||||
|
||||
and asgnmnt_instr = (variable * asgnmnt * expr) reg
|
||||
and ass_instr = (variable * ass * expr) reg
|
||||
|
||||
and loop =
|
||||
While of while_loop
|
||||
@ -282,7 +312,7 @@ and for_loop =
|
||||
|
||||
and for_int = {
|
||||
kwd_for : kwd_for;
|
||||
asgnmnt : asgnmnt_instr;
|
||||
ass : ass_instr;
|
||||
down : kwd_down option;
|
||||
kwd_to : kwd_to;
|
||||
bound : expr;
|
||||
|
@ -47,7 +47,7 @@ type t =
|
||||
| CONS of Region.t (* "<:" *)
|
||||
| VBAR of Region.t (* "|" *)
|
||||
| ARROW of Region.t (* "->" *)
|
||||
| ASGNMNT of Region.t (* ":=" *)
|
||||
| ASS of Region.t (* ":=" *)
|
||||
| EQUAL of Region.t (* "=" *)
|
||||
| COLON of Region.t (* ":" *)
|
||||
| OR of Region.t (* "||" *)
|
||||
|
10
LexToken.mll
10
LexToken.mll
@ -46,7 +46,7 @@ type t =
|
||||
| CONS of Region.t
|
||||
| VBAR of Region.t
|
||||
| ARROW of Region.t
|
||||
| ASGNMNT of Region.t
|
||||
| ASS of Region.t
|
||||
| EQUAL of Region.t
|
||||
| COLON of Region.t
|
||||
| OR of Region.t
|
||||
@ -165,7 +165,7 @@ let proj_token = function
|
||||
| CONS region -> region, "CONS"
|
||||
| VBAR region -> region, "VBAR"
|
||||
| ARROW region -> region, "ARROW"
|
||||
| ASGNMNT region -> region, "ASGNMNT"
|
||||
| ASS region -> region, "ASS"
|
||||
| EQUAL region -> region, "EQUAL"
|
||||
| COLON region -> region, "COLON"
|
||||
| OR region -> region, "OR"
|
||||
@ -249,7 +249,7 @@ let to_lexeme = function
|
||||
| CONS _ -> "<:"
|
||||
| VBAR _ -> "|"
|
||||
| ARROW _ -> "->"
|
||||
| ASGNMNT _ -> ":="
|
||||
| ASS _ -> ":="
|
||||
| EQUAL _ -> "="
|
||||
| COLON _ -> ":"
|
||||
| OR _ -> "||"
|
||||
@ -493,7 +493,7 @@ let mk_sym lexeme region =
|
||||
| "<:" -> CONS region
|
||||
| "|" -> VBAR region
|
||||
| "->" -> ARROW region
|
||||
| ":=" -> ASGNMNT region
|
||||
| ":=" -> ASS region
|
||||
| "=" -> EQUAL region
|
||||
| ":" -> COLON region
|
||||
| "||" -> OR region
|
||||
@ -596,7 +596,7 @@ let is_sym = function
|
||||
| CONS _
|
||||
| VBAR _
|
||||
| ARROW _
|
||||
| ASGNMNT _
|
||||
| ASS _
|
||||
| EQUAL _
|
||||
| COLON _
|
||||
| OR _
|
||||
|
@ -24,7 +24,7 @@
|
||||
%token <Region.t> CONS (* "<:" *)
|
||||
%token <Region.t> VBAR (* "|" *)
|
||||
%token <Region.t> ARROW (* "->" *)
|
||||
%token <Region.t> ASGNMNT (* ":=" *)
|
||||
%token <Region.t> ASS (* ":=" *)
|
||||
%token <Region.t> EQUAL (* "=" *)
|
||||
%token <Region.t> COLON (* ":" *)
|
||||
%token <Region.t> OR (* "||" *)
|
||||
|
190
Parser.mly
190
Parser.mly
@ -110,33 +110,65 @@ program:
|
||||
}
|
||||
|
||||
parameter_decl:
|
||||
Parameter var COLON type_expr {
|
||||
let stop = type_expr_to_region $4
|
||||
in {region = cover $1 stop;
|
||||
value = $1,$2,$3,$4}
|
||||
Parameter var COLON type_expr option(SEMI) {
|
||||
let stop =
|
||||
match $5 with
|
||||
None -> type_expr_to_region $4
|
||||
| Some region -> region in
|
||||
let region = cover $1 stop in
|
||||
let value = {
|
||||
kwd_parameter = $1;
|
||||
name = $2;
|
||||
colon = $3;
|
||||
param_type = $4;
|
||||
terminator = $5}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
storage_decl:
|
||||
Storage type_expr {
|
||||
let stop = type_expr_to_region $2
|
||||
in {region = cover $1 stop;
|
||||
value = $1,$2}
|
||||
Storage type_expr option(SEMI) {
|
||||
let stop =
|
||||
match $3 with
|
||||
None -> type_expr_to_region $2
|
||||
| Some region -> region in
|
||||
let region = cover $1 stop in
|
||||
let value = {
|
||||
kwd_storage = $1;
|
||||
store_type = $2;
|
||||
terminator = $3}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
operations_decl:
|
||||
Operations type_expr {
|
||||
let stop = type_expr_to_region $2
|
||||
in {region = cover $1 stop;
|
||||
value = $1,$2}
|
||||
Operations type_expr option(SEMI) {
|
||||
let stop =
|
||||
match $3 with
|
||||
None -> type_expr_to_region $2
|
||||
| Some region -> region in
|
||||
let region = cover $1 stop in
|
||||
let value = {
|
||||
kwd_operations = $1;
|
||||
op_type = $2;
|
||||
terminator = $3}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
(* Type declarations *)
|
||||
|
||||
type_decl:
|
||||
Type type_name Is type_expr {
|
||||
{region = cover $1 (type_expr_to_region $4);
|
||||
value = $1,$2,$3,$4}
|
||||
}
|
||||
Type type_name Is type_expr option(SEMI) {
|
||||
let stop =
|
||||
match $5 with
|
||||
None -> type_expr_to_region $4
|
||||
| Some region -> region in
|
||||
let region = cover $1 stop in
|
||||
let value = {
|
||||
kwd_type = $1;
|
||||
name = $2;
|
||||
kwd_is = $3;
|
||||
type_expr = $4;
|
||||
terminator = $5}
|
||||
in {region; value}}
|
||||
|
||||
type_expr:
|
||||
cartesian { Prod $1 }
|
||||
@ -202,10 +234,13 @@ fun_decl:
|
||||
Function fun_name parameters COLON type_expr Is
|
||||
seq(local_decl)
|
||||
block
|
||||
With expr {
|
||||
let region = cover $1 (expr_to_region $10) in
|
||||
let value =
|
||||
{
|
||||
With expr option(SEMI) {
|
||||
let stop =
|
||||
match $11 with
|
||||
None -> expr_to_region $10
|
||||
| Some region -> region in
|
||||
let region = cover $1 stop in
|
||||
let value = {
|
||||
kwd_function = $1;
|
||||
name = $2;
|
||||
param = $3;
|
||||
@ -216,25 +251,28 @@ fun_decl:
|
||||
block = $8;
|
||||
kwd_with = $9;
|
||||
return = $10;
|
||||
}
|
||||
terminator = $11}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
proc_decl:
|
||||
Procedure fun_name parameters Is
|
||||
seq(local_decl)
|
||||
block
|
||||
{
|
||||
let region = cover $1 $6.region in
|
||||
let value =
|
||||
block option(SEMI)
|
||||
{
|
||||
let stop =
|
||||
match $7 with
|
||||
None -> $6.region
|
||||
| Some region -> region in
|
||||
let region = cover $1 stop in
|
||||
let value = {
|
||||
kwd_procedure = $1;
|
||||
name = $2;
|
||||
param = $3;
|
||||
kwd_is = $4;
|
||||
local_decls = $5;
|
||||
block = $6;
|
||||
}
|
||||
terminator = $7}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
@ -255,27 +293,52 @@ param_decl:
|
||||
|
||||
block:
|
||||
Begin
|
||||
instructions
|
||||
End
|
||||
{
|
||||
let region = cover $1 $3 in
|
||||
let value =
|
||||
instruction after_instr
|
||||
{
|
||||
let instrs, terminator, close = $3 in
|
||||
let region = cover $1 close in
|
||||
let value = {
|
||||
opening = $1;
|
||||
instr = $2;
|
||||
close = $3;
|
||||
}
|
||||
instr = (let value = $2, instrs in
|
||||
let region = nsepseq_to_region instr_to_region value
|
||||
in {value; region});
|
||||
terminator;
|
||||
close}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
after_instr:
|
||||
SEMI instr_or_end {
|
||||
match $2 with
|
||||
`Some (instr, instrs, term, close) ->
|
||||
($1, instr)::instrs, term, close
|
||||
| `End close ->
|
||||
[], Some $1, close
|
||||
}
|
||||
| End {
|
||||
[], None, $1
|
||||
}
|
||||
|
||||
instr_or_end:
|
||||
End {
|
||||
`End $1 }
|
||||
| instruction after_instr {
|
||||
let instrs, term, close = $2 in
|
||||
`Some ($1, instrs, term, close)
|
||||
}
|
||||
|
||||
local_decl:
|
||||
lambda_decl { LocalLam $1 }
|
||||
| const_decl { LocalConst $1 }
|
||||
| var_decl { LocalVar $1 }
|
||||
|
||||
const_decl:
|
||||
Const var COLON type_expr EQUAL expr {
|
||||
let region = cover $1 (expr_to_region $6) in
|
||||
Const var COLON type_expr EQUAL expr option(SEMI) {
|
||||
let stop =
|
||||
match $7 with
|
||||
None -> expr_to_region $6
|
||||
| Some region -> region in
|
||||
let region = cover $1 stop in
|
||||
let value = {
|
||||
kwd_const = $1;
|
||||
name = $2;
|
||||
@ -283,30 +346,28 @@ const_decl:
|
||||
vtype = $4;
|
||||
equal = $5;
|
||||
init = $6;
|
||||
}
|
||||
terminator = $7}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
var_decl:
|
||||
Var var COLON type_expr ASGNMNT expr {
|
||||
let region = cover $1 (expr_to_region $6) in
|
||||
Var var COLON type_expr ASS expr option(SEMI) {
|
||||
let stop =
|
||||
match $7 with
|
||||
None -> expr_to_region $6
|
||||
| Some region -> region in
|
||||
let region = cover $1 stop in
|
||||
let value = {
|
||||
kwd_var = $1;
|
||||
name = $2;
|
||||
colon = $3;
|
||||
vtype = $4;
|
||||
asgnmnt = $5;
|
||||
ass = $5;
|
||||
init = $6;
|
||||
}
|
||||
terminator = $7}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
instructions:
|
||||
nsepseq(instruction,SEMI) {
|
||||
let region = nsepseq_to_region instr_to_region $1
|
||||
in {region; value=$1}
|
||||
}
|
||||
|
||||
instruction:
|
||||
single_instr { Single $1 }
|
||||
| block { Block $1 }
|
||||
@ -314,14 +375,12 @@ instruction:
|
||||
single_instr:
|
||||
conditional { Cond $1 }
|
||||
| match_instr { Match $1 }
|
||||
| asgnmnt { Asgnmnt $1 }
|
||||
| ass { Ass $1 }
|
||||
| loop { Loop $1 }
|
||||
| proc_call { ProcCall $1 }
|
||||
| Null { Null $1 }
|
||||
| Fail expr {
|
||||
let region = cover $1 (expr_to_region $2)
|
||||
in Fail {region; value = $1,$2}
|
||||
}
|
||||
| Fail expr { let region = cover $1 (expr_to_region $2)
|
||||
in Fail {region; value = $1,$2} }
|
||||
|
||||
proc_call:
|
||||
fun_call { $1 }
|
||||
@ -329,29 +388,26 @@ proc_call:
|
||||
conditional:
|
||||
If expr Then instruction Else instruction {
|
||||
let region = cover $1 (instr_to_region $6) in
|
||||
let value =
|
||||
{
|
||||
let value = {
|
||||
kwd_if = $1;
|
||||
test = $2;
|
||||
kwd_then = $3;
|
||||
ifso = $4;
|
||||
kwd_else = $5;
|
||||
ifnot = $6;
|
||||
}
|
||||
ifnot = $6}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
match_instr:
|
||||
Match expr With cases End {
|
||||
let region = cover $1 $5 in
|
||||
let value =
|
||||
{
|
||||
Match expr With option(VBAR) cases End {
|
||||
let region = cover $1 $6 in
|
||||
let value = {
|
||||
kwd_match = $1;
|
||||
expr = $2;
|
||||
kwd_with = $3;
|
||||
cases = $4;
|
||||
kwd_end = $5;
|
||||
}
|
||||
lead_vbar = $4;
|
||||
cases = $5;
|
||||
kwd_end = $6}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
@ -367,8 +423,8 @@ case:
|
||||
in {region; value = $1,$2,$3}
|
||||
}
|
||||
|
||||
asgnmnt:
|
||||
var ASGNMNT expr {
|
||||
ass:
|
||||
var ASS expr {
|
||||
let region = cover $1.region (expr_to_region $3)
|
||||
in {region; value = $1,$2,$3}
|
||||
}
|
||||
@ -384,12 +440,12 @@ while_loop:
|
||||
}
|
||||
|
||||
for_loop:
|
||||
For asgnmnt Down? To expr option(step_clause) block {
|
||||
For ass Down? To expr option(step_clause) block {
|
||||
let region = cover $1 $7.region in
|
||||
let value =
|
||||
{
|
||||
kwd_for = $1;
|
||||
asgnmnt = $2;
|
||||
ass = $2;
|
||||
down = $3;
|
||||
kwd_to = $4;
|
||||
bound = $5;
|
||||
|
10
Tests/a.li
10
Tests/a.li
@ -1,9 +1,9 @@
|
||||
type t is int * string
|
||||
type u is t
|
||||
type v is record foo: key; bar: mutez; baz: address end
|
||||
type w is K of v * u
|
||||
type w is K of (U of int) (*v * u*)
|
||||
|
||||
parameter p : v # Line comment
|
||||
parameter p : v // Line comment
|
||||
storage w
|
||||
operations u
|
||||
|
||||
@ -19,11 +19,11 @@ procedure g (const l : list (int)) is
|
||||
begin
|
||||
match l with
|
||||
[] -> null
|
||||
| h<:t -> q (h+2)
|
||||
| h#t -> q (h+2)
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
g (Unit) (*;
|
||||
fail K (3, "foo")*)
|
||||
g (Unit);
|
||||
fail K "in extremis"
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user