diff --git a/AST.ml b/AST.ml index 3cf7d59a4..e7240a98d 100644 --- a/AST.ml +++ b/AST.ml @@ -63,6 +63,7 @@ type kwd_patch = Region.t type kwd_procedure = Region.t type kwd_record = Region.t type kwd_remove = Region.t +type kwd_set = Region.t type kwd_skip = Region.t type kwd_step = Region.t type kwd_storage = Region.t @@ -121,6 +122,7 @@ type fun_name = string reg type type_name = string reg type field_name = string reg type map_name = string reg +type set_name = string reg type constr = string reg (* Parentheses *) @@ -470,6 +472,16 @@ and expr = | ETuple of tuple | EPar of expr par reg +and set_expr = + SetInj of set_injection reg + +and set_injection = { + opening : kwd_set; + elements : (expr, semi) nsepseq; + terminator : semi option; + close : kwd_end +} + and map_expr = MapLookUp of map_lookup reg | MapInj of map_injection reg @@ -531,10 +543,6 @@ and list_expr = | List of (expr, comma) nsepseq brackets reg | EmptyList of empty_list reg -and set_expr = - Set of (expr, comma) nsepseq braces reg -| EmptySet of empty_set reg - and constr_expr = SomeApp of (c_Some * arguments) reg | NoneExpr of none_expr reg @@ -574,15 +582,6 @@ and typed_empty_list = { list_type : type_expr } -and empty_set = typed_empty_set par - -and typed_empty_set = { - lbrace : lbrace; - rbrace : rbrace; - colon : colon; - set_type : type_expr -} - and none_expr = typed_none_expr par and typed_none_expr = { @@ -648,6 +647,9 @@ and map_expr_to_region = function MapLookUp {region; _} | MapInj {region; _} -> region +and set_expr_to_region = function + SetInj {region; _} -> region + and logic_expr_to_region = function BoolExpr e -> bool_expr_to_region e | CompExpr e -> comp_expr_to_region e @@ -685,10 +687,6 @@ and list_expr_to_region = function | List {region; _} | EmptyList {region; _} -> region -and set_expr_to_region = function - Set {region; _} -| EmptySet {region; _} -> region - and constr_expr_to_region = function NoneExpr {region; _} | ConstrApp {region; _} @@ -1138,8 +1136,10 @@ and print_expr = function and print_map_expr = function MapLookUp {value; _} -> print_map_lookup value -| MapInj inj -> - print_map_injection inj +| MapInj inj -> print_map_injection inj + +and print_set_expr = function + SetInj inj -> print_set_injection inj and print_map_lookup {path; index} = let {lbracket; inside; rbracket} = index.value in @@ -1206,10 +1206,6 @@ and print_list_expr = function | List e -> print_list e | EmptyList e -> print_empty_list e -and print_set_expr = function - Set e -> print_set e -| EmptySet e -> print_empty_set e - and print_constr_expr = function SomeApp e -> print_some_app e | NoneExpr e -> print_none_expr e @@ -1265,11 +1261,18 @@ and print_map_remove node = and print_map_injection {value; _} = let {opening; bindings; terminator; close} = value in - print_token opening "record"; + print_token opening "map"; print_nsepseq ";" print_binding bindings; print_terminator terminator; print_token close "end" +and print_set_injection {value; _} = + let {opening; elements; terminator; close} = value in + print_token opening "set"; + print_nsepseq ";" print_expr elements; + print_terminator terminator; + print_token close "end" + and print_binding {value; _} = let {source; arrow; image} = value in print_expr source; @@ -1298,22 +1301,6 @@ and print_empty_list {value; _} = print_type_expr list_type; print_token rpar ")" -and print_set {value; _} = - let {lbrace; inside; rbrace} = value in - print_token lbrace "{"; - print_nsepseq "," print_expr inside; - print_token rbrace "}" - -and print_empty_set {value; _} = - let {lpar; inside; rpar} = value in - let {lbrace; rbrace; colon; set_type} = inside in - print_token lpar "("; - print_token lbrace "{"; - print_token rbrace "}"; - print_token colon ":"; - print_type_expr set_type; - print_token rpar ")" - and print_none_expr {value; _} = let {lpar; inside; rpar} = value in let {c_None; colon; opt_type} = inside in diff --git a/AST.mli b/AST.mli index 7cf95ce96..c1d50aa49 100644 --- a/AST.mli +++ b/AST.mli @@ -47,6 +47,7 @@ type kwd_patch = Region.t type kwd_procedure = Region.t type kwd_record = Region.t type kwd_remove = Region.t +type kwd_set = Region.t type kwd_skip = Region.t type kwd_step = Region.t type kwd_storage = Region.t @@ -105,6 +106,7 @@ type fun_name = string reg type type_name = string reg type field_name = string reg type map_name = string reg +type set_name = string reg type constr = string reg (* Parentheses *) @@ -454,6 +456,16 @@ and expr = | ETuple of tuple | EPar of expr par reg +and set_expr = + SetInj of set_injection reg + +and set_injection = { + opening : kwd_set; + elements : (expr, semi) nsepseq; + terminator : semi option; + close : kwd_end +} + and map_expr = MapLookUp of map_lookup reg | MapInj of map_injection reg @@ -515,10 +527,6 @@ and list_expr = | List of (expr, comma) nsepseq brackets reg | EmptyList of empty_list reg -and set_expr = - Set of (expr, comma) nsepseq braces reg -| EmptySet of empty_set reg - and constr_expr = SomeApp of (c_Some * arguments) reg | NoneExpr of none_expr reg @@ -558,15 +566,6 @@ and typed_empty_list = { list_type : type_expr } -and empty_set = typed_empty_set par - -and typed_empty_set = { - lbrace : lbrace; - rbrace : rbrace; - colon : colon; - set_type : type_expr -} - and none_expr = typed_none_expr par and typed_none_expr = { diff --git a/LexToken.mli b/LexToken.mli index 364e2c91c..0f219f215 100644 --- a/LexToken.mli +++ b/LexToken.mli @@ -89,6 +89,7 @@ type t = | Procedure of Region.t (* "procedure" *) | Record of Region.t (* "record" *) | Remove of Region.t (* "remove" *) +| Set of Region.t (* "set" *) | Skip of Region.t (* "skip" *) | Step of Region.t (* "step" *) | Storage of Region.t (* "storage" *) diff --git a/LexToken.mll b/LexToken.mll index 11b6b9e7f..b5f1de1f4 100644 --- a/LexToken.mll +++ b/LexToken.mll @@ -88,6 +88,7 @@ type t = | Procedure of Region.t (* "procedure" *) | Record of Region.t (* "record" *) | Remove of Region.t (* "remove" *) +| Set of Region.t (* "set" *) | Skip of Region.t (* "skip" *) | Step of Region.t (* "step" *) | Storage of Region.t (* "storage" *) @@ -210,6 +211,7 @@ let proj_token = function | Procedure region -> region, "Procedure" | Record region -> region, "Record" | Remove region -> region, "Remove" +| Set region -> region, "Set" | Skip region -> region, "Skip" | Step region -> region, "Step" | Storage region -> region, "Storage" @@ -298,6 +300,7 @@ let to_lexeme = function | Procedure _ -> "procedure" | Record _ -> "record" | Remove _ -> "remove" +| Set _ -> "set" | Skip _ -> "skip" | Step _ -> "step" | Storage _ -> "storage" @@ -355,6 +358,7 @@ let keywords = [ (fun reg -> Procedure reg); (fun reg -> Record reg); (fun reg -> Remove reg); + (fun reg -> Set reg); (fun reg -> Skip reg); (fun reg -> Step reg); (fun reg -> Storage reg); @@ -580,6 +584,7 @@ let is_kwd = function | Procedure _ | Record _ | Remove _ +| Set _ | Skip _ | Step _ | Storage _ diff --git a/ParToken.mly b/ParToken.mly index 59eceea95..9d5efd7c1 100644 --- a/ParToken.mly +++ b/ParToken.mly @@ -67,6 +67,7 @@ %token Procedure (* "procedure" *) %token Record (* "record" *) %token Remove (* "remove" *) +%token Set (* "set" *) %token Skip (* "skip" *) %token Step (* "step" *) %token Storage (* "storage" *) diff --git a/Parser.mly b/Parser.mly index 9fca805fb..dab4effda 100644 --- a/Parser.mly +++ b/Parser.mly @@ -177,8 +177,15 @@ core_type: } | Map type_tuple { let region = cover $1 $2.region in - let value = {value="map"; region=$1} - in TApp {region; value = value, $2} + let type_constr = {value="map"; region=$1} + in TApp {region; value = type_constr, $2} + } +| Set par(type_expr) { + let total = cover $1 $2.region in + let type_constr = {value="set"; region=$1} in + let {region; value = {lpar; inside; rpar}} = $2 in + let tuple = {region; value={lpar; inside=inside,[]; rpar}} + in TApp {region=total; value = type_constr, tuple} } | par(type_expr) { TPar $1 @@ -405,7 +412,9 @@ unqualified_decl(OP): rpar = Region.ghost} in EConstr (NoneExpr {region; value}) | `EMap inj -> - EMap (MapInj inj) + EMap (MapInj inj) + | `ESet inj -> + ESet (SetInj inj) in $1, $2, $3, $4, init, $6, stop } @@ -448,6 +457,7 @@ extended_expr: value = `EList ($1,$2)} } | C_None { {region = $1; value = `ENone $1} } | map_injection { {region = $1.region; value = `EMap $1} } +| set_injection { {region = $1.region; value = `ESet $1} } instruction: @@ -489,6 +499,18 @@ map_patch: in {region; value} } +set_injection: + Set series(expr) { + let first, (others, terminator, close) = $2 in + let region = cover $1 close + and value = { + opening = $1; + elements = first, others; + terminator; + close} + in {region; value} + } + map_injection: Map series(binding) { let first, (others, terminator, close) = $2 in @@ -797,8 +819,6 @@ core_expr: | tuple { ETuple $1 } | list_expr { EList (List $1) } | empty_list { EList (EmptyList $1) } -| set_expr { ESet (Set $1) } -| empty_set { ESet (EmptySet $1) } | none_expr { EConstr (NoneExpr $1) } | fun_call { ECall $1 } | map_expr { EMap $1 } @@ -891,20 +911,6 @@ typed_empty_list: list_type = $4} } -set_expr: - braces(nsepseq(expr,COMMA)) { $1 } - -empty_set: - par(typed_empty_set) { $1 } - -typed_empty_set: - LBRACE RBRACE COLON type_expr { - {lbrace = $1; - rbrace = $2; - colon = $3; - set_type = $4} - } - none_expr: par(typed_none_expr) { $1 } diff --git a/Tests/crowdfunding.ligo b/Tests/crowdfunding.ligo index 4e3c2edba..670ff50ce 100644 --- a/Tests/crowdfunding.ligo +++ b/Tests/crowdfunding.ligo @@ -6,7 +6,8 @@ type store is funded : bool; end -const foo : store = map "X" -> 10; "Y" -> 11 end +const foo : map (string, nat) = map "X" -> 10; "Y" -> 11 end +const bar : set (int) = set 1; 1+1; f(3); end entrypoint contribute (storage store : store; const sender : address;