I extended left-hand sides of assignments to have qualified paths.

Note: In loops over integers, the initial assignment has still a
variable (the index) as left-hand side.

A qualified path is of the form "x" or "x.y.z" or "x.y.z[t]".
This commit is contained in:
Christian Rinderknecht 2019-03-20 14:57:55 +01:00
parent dc70df99f9
commit 24c0a33c99
4 changed files with 71 additions and 25 deletions

49
AST.ml
View File

@ -388,11 +388,15 @@ and case = {
}
and assignment = {
path : path;
lhs : lhs;
assign : assign;
expr : expr
}
and lhs =
Path of path
| MapPath of map_lookup reg
and loop =
While of while_loop reg
| For of for_loop
@ -409,7 +413,7 @@ and for_loop =
and for_int = {
kwd_for : kwd_for;
assign : assignment reg;
assign : var_assign reg;
down : kwd_down option;
kwd_to : kwd_to;
bound : expr;
@ -417,6 +421,12 @@ and for_int = {
block : block reg
}
and var_assign = {
name : variable;
assign : assign;
expr : expr
}
and for_collect = {
kwd_for : kwd_for;
var : variable;
@ -713,6 +723,10 @@ let local_decl_to_region = function
| LocalConst {region; _}
| LocalVar {region; _} -> region
let lhs_to_region = function
Path path -> path_to_region path
| MapPath {region; _} -> region
(* Printing the tokens with their source regions *)
let printf = Printf.printf
@ -1014,11 +1028,15 @@ and print_case {value; _} =
print_instruction instr
and print_assignment {value; _} =
let {path; assign; expr} = value in
print_path path;
let {lhs; assign; expr} = value in
print_lhs lhs;
print_token assign ":=";
print_expr expr
and print_lhs = function
Path path -> print_path path
| MapPath {value; _} -> print_map_lookup value
and print_loop = function
While {value; _} -> print_while_loop value
| For for_loop -> print_for_loop for_loop
@ -1037,13 +1055,19 @@ and print_for_int ({value; _} : for_int reg) =
let {kwd_for; assign; down; kwd_to;
bound; step; block} = value in
print_token kwd_for "for";
print_assignment assign;
print_var_assign assign;
print_down down;
print_token kwd_to "to";
print_expr bound;
print_step step;
print_block block
and print_var_assign {value; _} =
let {name; assign; expr} = value in
print_var name;
print_token assign ":=";
print_expr expr
and print_down = function
Some kwd_down -> print_token kwd_down "down"
| None -> ()
@ -1086,16 +1110,17 @@ and print_expr = function
| ParExpr e -> print_par_expr e
and print_map_expr = function
MapLookUp {value; _} ->
let {path; index} = value in
let {lbracket; inside; rbracket} = index.value in
print_path path;
print_token lbracket "[";
print_expr inside;
print_token rbracket "]"
MapLookUp {value; _} -> print_map_lookup value
| MapInj inj ->
print_map_injection inj
and print_map_lookup {path; index} =
let {lbracket; inside; rbracket} = index.value in
print_path path;
print_token lbracket "[";
print_expr inside;
print_token rbracket "]"
and print_path = function
Name var -> print_var var
| RecordPath path -> print_record_projection path

15
AST.mli
View File

@ -372,11 +372,15 @@ and case = {
}
and assignment = {
path : path;
lhs : lhs;
assign : assign;
expr : expr
}
and lhs =
Path of path
| MapPath of map_lookup reg
and loop =
While of while_loop reg
| For of for_loop
@ -393,7 +397,7 @@ and for_loop =
and for_int = {
kwd_for : kwd_for;
assign : assignment reg;
assign : var_assign reg;
down : kwd_down option;
kwd_to : kwd_to;
bound : expr;
@ -401,6 +405,12 @@ and for_int = {
block : block reg
}
and var_assign = {
name : variable;
assign : assign;
expr : expr
}
and for_collect = {
kwd_for : kwd_for;
var : variable;
@ -582,6 +592,7 @@ val instr_to_region : instruction -> Region.t
val pattern_to_region : pattern -> Region.t
val local_decl_to_region : local_decl -> Region.t
val path_to_region : path -> Region.t
val lhs_to_region : lhs -> Region.t
(* Printing *)

View File

@ -543,12 +543,16 @@ case:
}
assignment:
path ASS expr {
let region = cover (path_to_region $1) (expr_to_region $3)
and value = {path = $1; assign = $2; expr = $3}
lhs ASS expr {
let region = cover (lhs_to_region $1) (expr_to_region $3)
and value = {lhs = $1; assign = $2; expr = $3}
in {region; value}
}
lhs:
path { Path $1 }
| map_lookup { MapPath $1 }
loop:
while_loop { $1 }
| for_loop { $1 }
@ -564,7 +568,7 @@ while_loop:
}
for_loop:
For assignment Down? To expr option(step_clause) block {
For var_assign Down? To expr option(step_clause) block {
let region = cover $1 $7.region in
let value = {
kwd_for = $1;
@ -589,6 +593,13 @@ for_loop:
in For (ForCollect {region; value})
}
var_assign:
var ASS expr {
let region = cover $1.region (expr_to_region $3)
and value = {name = $1; assign = $2; expr = $3}
in {region; value}
}
step_clause:
Step expr { $1,$2 }
@ -768,13 +779,13 @@ core_expr:
}
map_expr:
map_selection { MapLookUp $1 }
map_lookup { MapLookUp $1 }
path:
var { Name $1 }
| record_projection { RecordPath $1 }
map_selection:
map_lookup:
path brackets(expr) {
let region = cover (path_to_region $1) $2.region in
let value = {

View File

@ -18,9 +18,8 @@ entrypoint contribute (storage store : store;
fail "Deadline passed"
else
case store.backers[sender] of
None ->
// store.backers[sender] := Some (amount)
patch store.backers with map sender -> amount end
None -> store.backers[sender] := Some (amount)
// patch store.backers with map sender -> amount end
| _ -> skip
end
end with (store, operations)
@ -33,7 +32,7 @@ entrypoint withdraw (storage store : store; const sender : address)
if now >= store.deadline then
if balance >= store.goal then
begin
// patch store with record funded = True end;
// patch store with record funded = True end;
store.funded := True;
operations := [Transfer (owner, balance)]
end
@ -59,7 +58,7 @@ entrypoint claim (storage store : store; const sender : address)
else
begin
operations := [Transfer (sender, amount)];
// store.backers[sender] := None
store.backers[sender] := (None : option (nat))
end
end
end with (store, operations)