Finished the refactoring of the parsers.

This commit is contained in:
Christian Rinderknecht 2019-12-15 20:59:04 +01:00
parent fca439558b
commit a94ee53fd3
4 changed files with 296 additions and 379 deletions

View File

@ -222,8 +222,8 @@ and fun_expr = {
}
and fun_decl = {
fun_expr : fun_expr reg ;
terminator : semi option ;
fun_expr : fun_expr reg;
terminator : semi option
}
and parameters = (param_decl, semi) nsepseq par reg
@ -270,7 +270,7 @@ and statement =
and data_decl =
LocalConst of const_decl reg
| LocalVar of var_decl reg
| LocalFun of fun_decl reg
| LocalFun of fun_decl reg
and var_decl = {
kwd_var : kwd_var;

View File

@ -213,8 +213,8 @@ and fun_expr = {
}
and fun_decl = {
fun_expr : fun_expr reg ;
terminator : semi option ;
fun_expr : fun_expr reg;
terminator : semi option
}
and parameters = (param_decl, semi) nsepseq par reg

View File

@ -107,8 +107,7 @@ sepseq(X,Sep):
(* Main *)
contract:
nseq(declaration) EOF {
{decl = $1; eof = $2} }
nseq(declaration) EOF { {decl=$1; eof=$2} }
declaration:
type_decl { TypeDecl $1 }
@ -124,31 +123,25 @@ type_decl:
Some region -> region
| None -> type_expr_to_region $4 in
let region = cover $1 stop in
let value = {
kwd_type = $1;
name = $2;
kwd_is = $3;
type_expr = $4;
terminator = $5}
let value = {kwd_type = $1;
name = $2;
kwd_is = $3;
type_expr = $4;
terminator = $5}
in {region; value} }
type_expr:
sum_type { TSum $1 }
| record_type { TRecord $1 }
| cartesian { $1 }
sum_type | record_type | cartesian { $1 }
cartesian:
function_type "*" nsepseq(function_type,"*") {
function_type { $1 }
| function_type "*" nsepseq(function_type,"*") {
let value = Utils.nsepseq_cons $1 $2 $3 in
let region = nsepseq_to_region type_expr_to_region value
in TProd {region; value}
}
| function_type { ($1 : type_expr) }
in TProd {region; value} }
function_type:
core_type {
$1
}
core_type { $1 }
| core_type "->" function_type {
let start = type_expr_to_region $1
and stop = type_expr_to_region $3 in
@ -156,9 +149,8 @@ function_type:
TFun {region; value = $1,$2,$3} }
core_type:
type_name {
TVar $1
}
type_name { TVar $1 }
| par(type_expr) { TPar $1 }
| type_name type_tuple {
let region = cover $1.region $2.region
in TApp {region; value = $1,$2}
@ -187,8 +179,6 @@ core_type:
let tuple = {region; value={lpar; inside=inside,[]; rpar}}
in TApp {region=total; value = type_constr, tuple}
}
| par(type_expr) {
TPar $1}
type_tuple:
par(nsepseq(type_expr,",")) { $1 }
@ -196,43 +186,39 @@ type_tuple:
sum_type:
"|"? nsepseq(variant,"|") {
let region = nsepseq_to_region (fun x -> x.region) $2
in {region; value=$2} }
in TSum {region; value=$2} }
variant:
"<constr>" "of" cartesian {
"<constr>" { {$1 with value = {constr=$1; arg=None}} }
| "<constr>" "of" cartesian {
let region = cover $1.region (type_expr_to_region $3)
and value = {constr = $1; arg = Some ($2, $3)}
in {region; value}
}
| "<constr>" {
{region=$1.region; value= {constr=$1; arg=None}} }
and value = {constr=$1; arg = Some ($2,$3)}
in {region; value} }
record_type:
"record" sep_or_term_list(field_decl,";") "end" {
let ne_elements, terminator = $2 in
let region = cover $1 $3
and value = {
opening = Kwd $1;
ne_elements;
terminator;
closing = End $3}
in {region; value}
and value = {opening = Kwd $1;
ne_elements;
terminator;
closing = End $3}
in TRecord {region; value}
}
| "record" "[" sep_or_term_list(field_decl,";") "]" {
let ne_elements, terminator = $3 in
let region = cover $1 $4
and value = {
opening = KwdBracket ($1,$2);
ne_elements;
terminator;
closing = RBracket $4}
in {region; value} }
and value = {opening = KwdBracket ($1,$2);
ne_elements;
terminator;
closing = RBracket $4}
in TRecord {region; value} }
field_decl:
field_name ":" type_expr {
let stop = type_expr_to_region $3 in
let region = cover $1.region stop
and value = {field_name = $1; colon = $2; field_type = $3}
and value = {field_name=$1; colon=$2; field_type=$3}
in {region; value} }
fun_expr:
@ -241,51 +227,42 @@ fun_expr:
"with" expr {
let stop = expr_to_region $9 in
let region = cover $1 stop
and value = {
kwd_function = $1;
name = $2;
param = $3;
colon = $4;
ret_type = $5;
kwd_is = $6;
block_with = Some ($7, $8);
return = $9}
in {region;value} }
and value = {kwd_function = $1;
name = $2;
param = $3;
colon = $4;
ret_type = $5;
kwd_is = $6;
block_with = Some ($7, $8);
return = $9}
in {region; value} }
| "function" fun_name? parameters ":" type_expr "is" expr {
let stop = expr_to_region $7 in
let region = cover $1 stop
and value = {
kwd_function = $1;
name = $2;
param = $3;
colon = $4;
ret_type = $5;
kwd_is = $6;
block_with = None;
return = $7}
in {region;value} }
and value = {kwd_function = $1;
name = $2;
param = $3;
colon = $4;
ret_type = $5;
kwd_is = $6;
block_with = None;
return = $7}
in {region; value} }
(* Function declarations *)
fun_decl:
fun_expr ";"? {
let stop =
match $2 with
Some region -> region
| None -> $1.region in
let region = cover $1.region stop
and value = {
fun_expr = $1;
terminator = $2}
open_fun_decl { $1 }
| fun_expr ";" {
let region = cover $1.region $2
and value = {fun_expr=$1; terminator= Some $2}
in {region; value} }
open_fun_decl:
fun_expr {
let region = $1.region
and value = {
fun_expr = $1;
terminator = None}
and value = {fun_expr=$1; terminator=None}
in {region; value} }
parameters:
@ -295,21 +272,19 @@ param_decl:
"var" var ":" param_type {
let stop = type_expr_to_region $4 in
let region = cover $1 stop
and value = {
kwd_var = $1;
var = $2;
colon = $3;
param_type = $4}
and value = {kwd_var = $1;
var = $2;
colon = $3;
param_type = $4}
in ParamVar {region; value}
}
| "const" var ":" param_type {
let stop = type_expr_to_region $4 in
let region = cover $1 stop
and value = {
kwd_const = $1;
var = $2;
colon = $3;
param_type = $4}
and value = {kwd_const = $1;
var = $2;
colon = $3;
param_type = $4}
in ParamConst {region; value} }
param_type:
@ -319,21 +294,19 @@ block:
"begin" sep_or_term_list(statement,";") "end" {
let statements, terminator = $2 in
let region = cover $1 $3
and value = {
opening = Begin $1;
statements;
terminator;
closing = End $3}
and value = {opening = Begin $1;
statements;
terminator;
closing = End $3}
in {region; value}
}
| "block" "{" sep_or_term_list(statement,";") "}" {
let statements, terminator = $3 in
let region = cover $1 $4
and value = {
opening = Block ($1,$2);
statements;
terminator;
closing = Block $4}
and value = {opening = Block ($1,$2);
statements;
terminator;
closing = Block $4}
in {region; value} }
statement:
@ -349,28 +322,26 @@ open_const_decl:
"const" unqualified_decl("=") {
let name, colon, const_type, equal, init, stop = $2 in
let region = cover $1 stop
and value = {
kwd_const = $1;
name;
colon;
const_type;
equal;
init;
terminator = None}
and value = {kwd_const = $1;
name;
colon;
const_type;
equal;
init;
terminator = None}
in {region; value} }
open_var_decl:
"var" unqualified_decl(":=") {
let name, colon, var_type, assign, init, stop = $2 in
let region = cover $1 stop
and value = {
kwd_var = $1;
name;
colon;
var_type;
assign;
init;
terminator = None}
and value = {kwd_var = $1;
name;
colon;
var_type;
assign;
init;
terminator = None}
in {region; value} }
unqualified_decl(OP):
@ -379,12 +350,9 @@ unqualified_decl(OP):
in $1, $2, $3, $4, $5, region }
const_decl:
open_const_decl ";" {
let const_decl : AST.const_decl = $1.value in
{$1 with value = {const_decl with terminator = Some $2}}
}
| open_const_decl { $1 }
open_const_decl { $1 }
| open_const_decl ";" {
{$1 with value = {$1.value with terminator = Some $2}} }
instruction:
conditional { Cond $1 }
@ -528,7 +496,7 @@ proc_call:
conditional:
"if" expr "then" if_clause ";"? "else" if_clause {
let region = cover $1 (if_clause_to_region $7) in
let value : conditional = {
let value : AST.conditional = {
kwd_if = $1;
test = $2;
kwd_then = $3;
@ -543,14 +511,12 @@ if_clause:
| clause_block { ClauseBlock $1 }
clause_block:
block {
LongBlock $1 }
block { LongBlock $1 }
| "{" sep_or_term_list(statement,";") "}" {
let region = cover $1 $3 in
let value = {
lbrace = $1;
inside = $2;
rbrace = $3} in
let value = {lbrace = $1;
inside = $2;
rbrace = $3} in
ShortBlock {value; region} }
case_instr:
@ -560,25 +526,23 @@ case(rhs):
"case" expr "of" "|"? cases(rhs) "end" {
fun rhs_to_region ->
let region = cover $1 $6 in
let value = {
kwd_case = $1;
expr = $2;
opening = Kwd $3;
lead_vbar = $4;
cases = $5 rhs_to_region;
closing = End $6}
let value = {kwd_case = $1;
expr = $2;
opening = Kwd $3;
lead_vbar = $4;
cases = $5 rhs_to_region;
closing = End $6}
in {region; value}
}
| "case" expr "of" "[" "|"? cases(rhs) "]" {
fun rhs_to_region ->
let region = cover $1 $7 in
let value = {
kwd_case = $1;
expr = $2;
opening = KwdBracket ($3,$4);
lead_vbar = $5;
cases = $6 rhs_to_region;
closing = RBracket $7}
let value = {kwd_case = $1;
expr = $2;
opening = KwdBracket ($3,$4);
lead_vbar = $5;
cases = $6 rhs_to_region;
closing = RBracket $7}
in {region; value} }
cases(rhs):
@ -605,7 +569,7 @@ assignment:
in {region; value} }
rhs:
expr { $1 }
expr { $1 }
lhs:
path { Path $1 }
@ -618,33 +582,28 @@ loop:
while_loop:
"while" expr block {
let region = cover $1 $3.region
and value = {
kwd_while = $1;
cond = $2;
block = $3}
and value = {kwd_while=$1; cond=$2; block=$3}
in While {region; value} }
for_loop:
"for" var_assign "to" expr block {
let region = cover $1 $5.region in
let value = {
kwd_for = $1;
assign = $2;
kwd_to = $3;
bound = $4;
block = $5}
let value = {kwd_for = $1;
assign = $2;
kwd_to = $3;
bound = $4;
block = $5}
in For (ForInt {region; value})
}
| "for" var arrow_clause? "in" collection expr block {
let region = cover $1 $7.region in
let value = {
kwd_for = $1;
var = $2;
bind_to = $3;
kwd_in = $4;
collection = $5;
expr = $6;
block = $7}
let value = {kwd_for = $1;
var = $2;
bind_to = $3;
kwd_in = $4;
collection = $5;
expr = $6;
block = $7}
in For (ForCollect {region; value}) }
collection:
@ -655,7 +614,7 @@ collection:
var_assign:
var ":=" expr {
let region = cover $1.region (expr_to_region $3)
and value = {name = $1; assign = $2; expr = $3}
and value = {name=$1; assign=$2; expr=$3}
in {region; value} }
arrow_clause:
@ -675,7 +634,7 @@ expr:
cond_expr:
"if" expr "then" expr ";"? "else" expr {
let region = cover $1 (expr_to_region $7) in
let value : cond_expr = {
let value : AST.cond_expr = {
kwd_if = $1;
test = $2;
kwd_then = $3;
@ -686,37 +645,31 @@ cond_expr:
in ECond {region; value} }
disj_expr:
disj_expr "or" conj_expr {
conj_expr { $1 }
| disj_expr "or" conj_expr {
let start = expr_to_region $1
and stop = expr_to_region $3 in
let region = cover start stop
and value = {arg1=$1; op=$2; arg2=$3} in
ELogic (BoolExpr (Or {region; value}))
}
| conj_expr { $1 }
ELogic (BoolExpr (Or {region; value})) }
conj_expr:
conj_expr "and" set_membership {
set_membership { $1 }
| conj_expr "and" set_membership {
let start = expr_to_region $1
and stop = expr_to_region $3 in
let region = cover start stop
and value = {arg1=$1; op=$2; arg2=$3}
in ELogic (BoolExpr (And {region; value}))
}
| set_membership { $1 }
in ELogic (BoolExpr (And {region; value})) }
set_membership:
core_expr "contains" set_membership {
comp_expr { $1 }
| core_expr "contains" set_membership {
let start = expr_to_region $1
and stop = expr_to_region $3 in
let region = cover start stop in
let value = {
set = $1;
kwd_contains = $2;
element = $3}
in ESet (SetMem {region; value})
}
| comp_expr { $1 }
let value = {set=$1; kwd_contains=$2; element=$3}
in ESet (SetMem {region; value}) }
comp_expr:
comp_expr "<" cat_expr {
@ -840,23 +793,23 @@ unary_expr:
| core_expr { $1 }
core_expr:
"<int>" { EArith (Int $1) }
| "<nat>" { EArith (Nat $1) }
| "<mutez>" { EArith (Mutez $1) }
| var { EVar $1 }
| "<string>" { EString (String $1) }
| "<bytes>" { EBytes $1 }
| "False" { ELogic (BoolExpr (False $1)) }
| "True" { ELogic (BoolExpr (True $1)) }
| "Unit" { EUnit $1 }
| annot_expr { EAnnot $1 }
| tuple_expr { ETuple $1 }
| list_expr { EList $1 }
| "None" { EConstr (NoneExpr $1) }
| fun_call_or_par_or_projection { $1 }
| map_expr { EMap $1 }
| set_expr { ESet $1 }
| record_expr { ERecord $1 }
"<int>" { EArith (Int $1) }
| "<nat>" { EArith (Nat $1) }
| "<mutez>" { EArith (Mutez $1) }
| var { EVar $1 }
| "<string>" { EString (String $1) }
| "<bytes>" { EBytes $1 }
| "False" { ELogic (BoolExpr (False $1)) }
| "True" { ELogic (BoolExpr (True $1)) }
| "Unit" { EUnit $1 }
| annot_expr { EAnnot $1 }
| tuple_expr { ETuple $1 }
| list_expr { EList $1 }
| "None" { EConstr (NoneExpr $1) }
| fun_call_or_par_or_projection { $1 }
| map_expr { EMap $1 }
| set_expr { ESet $1 }
| record_expr { ERecord $1 }
| "<constr>" arguments {
let region = cover $1.region $2.region in
EConstr (ConstrApp {region; value = $1, Some $2})
@ -871,12 +824,12 @@ core_expr:
fun_call_or_par_or_projection:
par(expr) arguments? {
let parenthesized = EPar $1 in
match $2 with
None -> parenthesized
| Some args ->
let region_1 = $1.region in
let region = cover region_1 args.region in
ECall {region; value = parenthesized,args}
match $2 with
None -> parenthesized
| Some args ->
let region_1 = $1.region in
let region = cover region_1 args.region in
ECall {region; value = parenthesized,args}
}
| projection arguments? {
let project = EProj $1 in
@ -919,10 +872,9 @@ projection:
struct_name "." nsepseq(selection,".") {
let stop = nsepseq_to_region selection_to_region $3 in
let region = cover $1.region stop
and value = {
struct_name = $1;
selector = $2;
field_path = $3}
and value = {struct_name = $1;
selector = $2;
field_path = $3}
in {region; value} }
selection:
@ -953,10 +905,9 @@ record_expr:
field_assignment:
field_name "=" expr {
let region = cover $1.region (expr_to_region $3)
and value = {
field_name = $1;
equal = $2;
field_expr = $3}
and value = {field_name = $1;
equal = $2;
field_expr = $3}
in {region; value} }
fun_call:
@ -968,8 +919,7 @@ tuple_expr:
par(tuple_comp) { $1 }
tuple_comp:
expr "," nsepseq(expr,",") {
Utils.nsepseq_cons $1 $2 $3 }
expr "," nsepseq(expr,",") { Utils.nsepseq_cons $1 $2 $3 }
arguments:
par(nsepseq(expr,",")) { $1 }
@ -981,12 +931,11 @@ list_expr:
(* Patterns *)
pattern:
core_pattern "#" nsepseq(core_pattern,"#") {
core_pattern { $1 }
| core_pattern "#" nsepseq(core_pattern,"#") {
let value = Utils.nsepseq_cons $1 $2 $3 in
let region = nsepseq_to_region pattern_to_region value
in PList (PCons {region; value})
}
| core_pattern { $1 }
in PList (PCons {region; value}) }
core_pattern:
var { PVar $1 }

View File

@ -22,6 +22,8 @@ type 'a sequence_or_record =
| PaRecord of 'a record_elements
| PaSingleExpr of expr
let (<@) f g x = f (g x)
(* END HEADER *)
%}
@ -33,13 +35,14 @@ type 'a sequence_or_record =
%type <AST.t> contract
%type <AST.expr> interactive_expr
(* Solves a shift/reduce problem that happens with record and
sequences. To elaborate: [sequence_or_record_in]
can be reduced to [expr -> Ident], but also to
[field_assignment -> Ident].
*)
%nonassoc Ident
%nonassoc COLON (* Solves a shift/reduce problem that happens with record
and sequences. To elaborate:
- sequence_or_record_in can be reduced to
expr -> Ident, but also to
field_assignment -> Ident.
*)
%nonassoc COLON
%%
(* RULES *)
@ -145,12 +148,11 @@ declaration:
type_decl:
"type" type_name "=" type_expr {
let region = cover $1 (type_expr_to_region $4) in
let value = {
kwd_type = $1;
name = $2;
eq = $3;
type_expr = $4}
let region = cover $1 (type_expr_to_region $4)
and value = {kwd_type = $1;
name = $2;
eq = $3;
type_expr = $4}
in {region; value} }
type_expr:
@ -176,17 +178,17 @@ core_type:
| par(type_expr) { TPar $1 }
| module_name "." type_name {
let module_name = $1.value in
let type_name = $3.value in
let value = module_name ^ "." ^ type_name in
let region = cover $1.region $3.region
let type_name = $3.value in
let value = module_name ^ "." ^ type_name in
let region = cover $1.region $3.region
in TVar {region; value}
}
| type_name par(nsepseq(core_type,",") { $1 }) {
let constr, arg = $1, $2 in
let start = constr.region
and stop = arg.region in
let region = cover start stop in
TApp {region; value = constr,arg} }
let start = constr.region
and stop = arg.region in
let region = cover start stop
in TApp {region; value = constr,arg} }
sum_type:
"|" nsepseq(variant,"|") {
@ -197,7 +199,7 @@ variant:
"<constr>" { {$1 with value={constr=$1; arg=None}} }
| "<constr>" "(" cartesian ")" {
let region = cover $1.region $4
and value = {constr=$1; arg = Some ($2,$3)}
and value = {constr=$1; arg = Some (ghost,$3)}
in {region; value} }
record_type:
@ -212,10 +214,7 @@ type_expr_field:
field_decl:
field_name {
let value = {
field_name = $1;
colon = Region.ghost;
field_type = TVar $1}
let value = {field_name=$1; colon=ghost; field_type = TVar $1}
in {$1 with value}
}
| field_name ":" type_expr_field {
@ -252,7 +251,8 @@ let_binding:
{binders = PRecord $1, []; lhs_type=$2; eq=$3; let_rhs=$4}
}
| par(closed_irrefutable) type_annotation? "=" expr {
{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 {
let hd, tl = $1 in
let start = pattern_to_region hd in
@ -292,14 +292,12 @@ typed_pattern:
let start = pattern_to_region $1 in
let stop = type_expr_to_region $3 in
let region = cover start stop in
let value = {
pattern = $1;
colon = $2;
type_expr = $3}
let value = {pattern=$1; colon=$2; type_expr=$3}
in {region; value} }
pattern:
"[" sub_pattern "," "..." sub_pattern "]" {
core_pattern { $1 }
| "[" sub_pattern "," "..." sub_pattern "]" {
let start = pattern_to_region $2 in
let stop = pattern_to_region $5 in
let region = cover start stop in
@ -311,9 +309,7 @@ pattern:
let start = pattern_to_region hd in
let stop = last fst tl in
let region = cover start stop
in PTuple {value=$1; region}
}
| core_pattern { $1 }
in PTuple {value=$1; region} }
sub_pattern:
par(sub_pattern) { PPar $1 }
@ -336,10 +332,9 @@ record_pattern:
"{" sep_or_term_list(field_pattern,",") "}" {
let ne_elements, terminator = $2 in
let region = cover $1 $3 in
let value = {
compound = Braces ($1,$3);
ne_elements;
terminator}
let value = {compound = Braces ($1,$3);
ne_elements;
terminator}
in {region; value} }
field_pattern:
@ -381,8 +376,7 @@ interactive_expr:
expr EOF { $1 }
expr:
base_cond__open(expr) | switch_expr(base_cond) { $1 }
base_cond__open(expr) | switch_expr(base_cond) { $1 }
base_cond__open(x):
base_expr(x) | conditional(x) { $1 }
@ -391,7 +385,7 @@ base_cond:
base_cond__open(base_cond) { $1 }
type_expr_simple_args:
"(" nsepseq(type_expr_simple, ",") ")" { $1, $2, $3 }
par(nsepseq(type_expr_simple, ",")) { $1 }
type_expr_simple:
core_expr_2 type_expr_simple_args? {
@ -403,29 +397,27 @@ type_expr_simple:
let app a = function
FieldName v -> a ^ "." ^ v.value
| Component {value = c, _; _} -> a ^ "." ^ c in
let path =
let value =
Utils.nsepseq_foldl app struct_name.value field_path
in {value=path; region}
in {region; value}
| EArith Mutez r | EArith Int r | EArith Nat r ->
{r with value = fst r.value}
| EString String s -> s
| ELogic BoolExpr (True t) -> {value="true"; region=t}
| ELogic BoolExpr (False f) -> {value="false"; region=f}
| _ -> failwith "Not supported"
| ELogic BoolExpr (True t) -> {region=t; value="true"}
| ELogic BoolExpr (False f) -> {region=f; value="false"}
| _ -> failwith "Not supported" (* TODO: raise a proper exception *)
in match args with
Some (lpar, args, rpar) ->
let region = cover (expr_to_region $1) rpar
and value = {inside=args; lpar; rpar} in
Some {value; _} ->
let region = cover (expr_to_region $1) value.rpar in
let value = constr, {region; value}
in TApp {region; value}
| None -> TVar constr
}
| "(" nsepseq(type_expr_simple, ",") ")" {
TProd {value=$2; region = cover $1 $3}
TProd {region = cover $1 $3; value=$2}
}
| "(" type_expr_simple "=>" type_expr_simple ")" {
TFun {value=$2,$3,$4; region = cover $1 $5}
}
TFun {region = cover $1 $5; value=$2,$3,$4} }
type_annotation_simple:
":" type_expr_simple { $1,$2 }
@ -433,22 +425,24 @@ type_annotation_simple:
fun_expr:
disj_expr_level es6_func {
let arrow, body = $2 in
let kwd_fun = Region.ghost in
let start = expr_to_region $1 in
let stop = expr_to_region body in
let region = cover start stop in
let rec arg_to_pattern = (function
| EVar val_ -> PVar val_
| EAnnot {value = {inside = EVar v, colon, typ; _}; region} ->
let value = {pattern = PVar v; colon; type_expr = typ}
in PTyped {region; value}
| EPar {value = {inside; lpar; rpar}; region} ->
PPar {value = {inside = arg_to_pattern inside; lpar; rpar}; region}
| EUnit u -> PUnit u
| _ -> failwith "Not supported"
)
in
let fun_args_to_pattern = (function
let kwd_fun = ghost in
let start = expr_to_region $1 in
let stop = expr_to_region body in
let region = cover start stop in
let rec arg_to_pattern = function
EVar v -> PVar v
| EAnnot {region; value = {inside = EVar v, colon, typ; _}} ->
let value = {pattern = PVar v; colon; type_expr = typ}
in PTyped {region; value}
| EPar p ->
let value =
{p.value with inside = arg_to_pattern p.value.inside}
in PPar {p with value}
| EUnit u -> PUnit u
| _ -> failwith "Not supported" in (* TODO: raise a proper exception *)
let fun_args_to_pattern = function
EAnnot {
value = {
inside = ETuple {value=fun_args; _}, _, _;
@ -456,7 +450,7 @@ fun_expr:
_} ->
(* ((foo:x, bar) : type) *)
let bindings =
List.map (fun arg -> arg_to_pattern (snd arg)) (snd fun_args)
List.map (arg_to_pattern <@ snd) (snd fun_args)
in arg_to_pattern (fst fun_args), bindings
| EAnnot {
value = {
@ -464,28 +458,26 @@ fun_expr:
_};
_} ->
(* ((foo:x, bar) : type) *)
(arg_to_pattern fun_arg, [])
(arg_to_pattern fun_arg, [])
| EPar {value = {inside = fun_arg; _ }; _} ->
arg_to_pattern fun_arg, []
| EAnnot e -> arg_to_pattern (EAnnot e), []
| EAnnot e ->
arg_to_pattern (EAnnot e), []
| ETuple {value = fun_args; _} ->
let bindings = List.map (fun arg -> arg_to_pattern (snd arg)) (snd fun_args) in
(arg_to_pattern (fst fun_args), bindings)
let bindings =
List.map (arg_to_pattern <@ snd) (snd fun_args)
in arg_to_pattern (fst fun_args), bindings
| EUnit e ->
arg_to_pattern (EUnit e), []
| _ -> failwith "Not supported"
)
in
| _ -> failwith "Not supported" in (* TODO: raise a proper exception *)
let binders = fun_args_to_pattern $1 in
let f = {
kwd_fun ;
binders ;
lhs_type = None;
arrow ;
body ;
} in
EFun { region; value=f }
}
let f = {kwd_fun;
binders;
lhs_type=None;
arrow;
body}
in EFun {region; value=f} }
base_expr(right_expr):
let_expr(right_expr) | disj_expr_level | fun_expr { $1 }
@ -500,36 +492,26 @@ if_then(right_expr):
"if" parenthesized_expr "{" closed_if "}" {
let the_unit = ghost, ghost in
let ifnot = EUnit {region=ghost; value=the_unit} in
let region = cover $1 $5 in
ECond {
value = {
kwd_if = $1;
test = $2;
kwd_then = $3;
ifso = $4;
kwd_else = Region.ghost;
ifnot;
};
region
}
}
let region = cover $1 $5 in
let value = {kwd_if = $1;
test = $2;
kwd_then = $3;
ifso = $4;
kwd_else = ghost;
ifnot}
in ECond {region; value} }
if_then_else(right_expr):
"if" parenthesized_expr "{" closed_if ";" "}"
"else" "{" right_expr ";" "}" {
let region = cover $1 $11 in
ECond {
value = {
kwd_if = $1;
test = $2;
kwd_then = $3;
ifso = $4;
kwd_else = $6;
ifnot = $9
};
region
}
}
let value = {kwd_if = $1;
test = $2;
kwd_then = $3;
ifso = $4;
kwd_else = $6;
ifnot = $9}
in ECond {region; value} }
base_if_then_else__open(x):
base_expr(x) | if_then_else(x) { $1 }
@ -543,18 +525,18 @@ closed_if:
switch_expr(right_expr):
"switch" switch_expr_ "{" cases(right_expr) "}" {
let start = $1 in
let stop = $5 in
let cases = {
value = $4;
region = nsepseq_to_region (fun x -> x.region) $4} in
let start = $1
and stop = $5 in
let region = cover start stop
and value = {
kwd_match = $1;
expr = $2;
lead_vbar = None;
kwd_with = Region.ghost;
cases}
and cases = {
region = nsepseq_to_region (fun x -> x.region) $4;
value = $4} in
let value = {
kwd_match = $1;
expr = $2;
lead_vbar = None;
kwd_with = ghost;
cases}
in ECase {region; value} }
switch_expr_:
@ -564,8 +546,7 @@ switch_expr_:
cases(right_expr):
nseq(case_clause(right_expr)) {
let hd, tl = $1 in
hd, List.map (fun f -> expr_to_region f.value.rhs, f) tl
}
hd, List.map (fun f -> expr_to_region f.value.rhs, f) tl }
case_clause(right_expr):
"|" pattern "=>" right_expr ";"? {
@ -591,11 +572,11 @@ disj_expr_level:
| conj_expr_level { $1 }
| par(tuple(disj_expr_level)) type_annotation_simple? {
let region = $1.region in
let tuple = ETuple {value=$1.value.inside; region} in
let tuple = ETuple {value=$1.value.inside; region} in
let region =
match $2 with
Some (_,s) -> cover $1.region (type_expr_to_region s)
| None -> region in
| None -> region in
match $2 with
Some (colon, typ) ->
let value = {$1.value with inside = tuple,colon,typ}
@ -616,11 +597,8 @@ disj_expr:
ELogic (BoolExpr (Or $1)) }
conj_expr_level:
conj_expr
| comp_expr_level { $1 }
conj_expr:
bin_op(conj_expr_level, "&&", comp_expr_level) {
comp_expr_level { $1 }
| bin_op(conj_expr_level, "&&", comp_expr_level) {
ELogic (BoolExpr (And $1)) }
comp_expr_level:
@ -678,10 +656,7 @@ call_expr_level:
| None -> expr_to_region $1 in
match $2 with
Some (colon, t) ->
let value = {
lpar=Region.ghost;
inside=$1,colon,t;
rpar=Region.ghost}
let value = {lpar=ghost; inside=$1,colon,t; rpar=ghost}
in EAnnot {region; value}
| None -> $1 }
@ -774,32 +749,28 @@ module_field:
selection:
"[" "<int>" "]" selection {
let r, (h, t) = $4 in
let r, (hd, tl) = $4 in
let result: (selection, dot) Utils.nsepseq =
Component $2, (Region.ghost, h) :: t
Component $2, (ghost, hd) :: tl
in r, result
}
| "." field_name selection {
let r, (h, t) = $3 in
let r, (hd, tl) = $3 in
let result: (selection, dot) Utils.nsepseq =
FieldName $2, ($1, h) :: t
FieldName $2, ($1, hd) :: tl
in r, result
}
| "." field_name {
$1, (FieldName $2, [])
}
| "[" "<int>" "]" {
Region.ghost, (Component $2, []) }
| "." field_name { $1, (FieldName $2, []) }
| "[" "<int>" "]" { ghost, (Component $2, []) }
projection:
struct_name selection {
let start = $1.region in
let stop = nsepseq_to_region selection_to_region (snd $2) in
let region = cover start stop
and value = {
struct_name = $1;
selector = fst $2;
field_path = snd $2}
and value = {struct_name = $1;
selector = fst $2;
field_path = snd $2}
in {region; value}
}
| module_name "." field_name selection {
@ -810,10 +781,9 @@ projection:
let start = $1.region in
let stop = nsepseq_to_region selection_to_region (snd $4) in
let region = cover start stop
and value = {
struct_name;
selector = fst $4;
field_path = snd $4}
and value = {struct_name;
selector = fst $4;
field_path = snd $4}
in {region; value} }
sequence_or_record_in:
@ -832,27 +802,25 @@ sequence_or_record_in:
sequence_or_record:
"{" sequence_or_record_in "}" {
let compound = Braces($1, $3) in
let region = cover $1 $3 in
let region = cover $1 $3 in
match $2 with
PaSequence s ->
let value: expr injection = {
compound;
elements = Some s.s_elts;
terminator = s.s_terminator}
in ESeq {region; value}
let value = {compound;
elements = Some s.s_elts;
terminator = s.s_terminator}
in ESeq {region; value}
| PaRecord r ->
let value: field_assign reg ne_injection = {
compound;
ne_elements = r.r_elts;
terminator = r.r_terminator}
in ERecord {region; value}
let value = {compound;
ne_elements = r.r_elts;
terminator = r.r_terminator}
in ERecord {region; value}
| PaSingleExpr e -> e }
field_assignment:
field_name {
let value = {
field_name = $1;
assignment = Region.ghost;
assignment = ghost;
field_expr = EVar $1 }
in {$1 with value}
}