diff --git a/AST.ml b/AST.ml index 26c5d9f6d..5dd703a37 100644 --- a/AST.ml +++ b/AST.ml @@ -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 diff --git a/AST.mli b/AST.mli index 9b617322f..d7bbcfdd8 100644 --- a/AST.mli +++ b/AST.mli @@ -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 *) diff --git a/Parser.mly b/Parser.mly index d61bffdbb..2c05c414f 100644 --- a/Parser.mly +++ b/Parser.mly @@ -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 = { diff --git a/Tests/crowdfunding.ligo b/Tests/crowdfunding.ligo index e3fff9e67..243b8fcd0 100644 --- a/Tests/crowdfunding.ligo +++ b/Tests/crowdfunding.ligo @@ -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)