Support for empty sets and maps. Alternate syntax for maps and lists:

sets, maps and lists are now homogeneous.

Lists by extension now require the "list" keyword, like sets and
maps. Semicolons needed, instead of commas.

New syntax for lists: `list [e_1; e_2; ...; e_n]`.

The empty list can now be denoted either by `list []` or `list end` or
`nil'.

Both `list` and `nil` are new keywords. Lists can also be denoted
without brackets, as sets and maps: `list e_1; e_2; ...; e_n end`.

The extension for maps follows the extension for sets: `map [b_1; b_2;
...; b_n]` or `maps b_1; ...; b_n end`.
This commit is contained in:
Christian Rinderknecht 2019-03-26 10:31:55 +01:00
parent 98f9d3e417
commit fef4337e83
No known key found for this signature in database
GPG Key ID: 9446816CFD267040
7 changed files with 288 additions and 135 deletions

97
AST.ml
View File

@ -39,6 +39,7 @@ let sepseq_to_region to_region = function
(* Keywords of LIGO *) (* Keywords of LIGO *)
type keyword = Region.t
type kwd_and = Region.t type kwd_and = Region.t
type kwd_begin = Region.t type kwd_begin = Region.t
type kwd_block = Region.t type kwd_block = Region.t
@ -56,8 +57,10 @@ type kwd_function = Region.t
type kwd_if = Region.t type kwd_if = Region.t
type kwd_in = Region.t type kwd_in = Region.t
type kwd_is = Region.t type kwd_is = Region.t
type kwd_list = Region.t
type kwd_map = Region.t type kwd_map = Region.t
type kwd_mod = Region.t type kwd_mod = Region.t
type kwd_nil = Region.t
type kwd_not = Region.t type kwd_not = Region.t
type kwd_of = Region.t type kwd_of = Region.t
type kwd_or = Region.t type kwd_or = Region.t
@ -378,10 +381,10 @@ and map_patch = {
} }
and map_injection = { and map_injection = {
opening : kwd_map; opening : opening;
bindings : (binding reg, semi) nsepseq; bindings : (binding reg, semi) sepseq;
terminator : semi option; terminator : semi option;
closing : kwd_end closing : closing
} }
and binding = { and binding = {
@ -518,12 +521,20 @@ and set_expr =
SetInj of set_injection reg SetInj of set_injection reg
and set_injection = { and set_injection = {
opening : kwd_set; opening : opening;
elements : (expr, semi) nsepseq; elements : (expr, semi) sepseq;
terminator : semi option; terminator : semi option;
closing : kwd_end closing : closing
} }
and opening =
Kwd of keyword
| KwdBracket of keyword * lbracket
and closing =
End of kwd_end
| RBracket of rbracket
and map_expr = and map_expr =
MapLookUp of map_lookup reg MapLookUp of map_lookup reg
| MapInj of map_injection reg | MapInj of map_injection reg
@ -582,8 +593,21 @@ and string_expr =
and list_expr = and list_expr =
Cons of cons bin_op reg Cons of cons bin_op reg
| List of (expr, comma) nsepseq brackets reg | List of list_injection reg
| EmptyList of empty_list reg | Nil of nil par reg
and list_injection = {
opening : opening;
elements : (expr, semi) sepseq;
terminator : semi option;
closing : closing
}
and nil = {
nil : kwd_nil;
colon : colon;
list_type : type_expr
}
and constr_expr = and constr_expr =
SomeApp of (c_Some * arguments) reg SomeApp of (c_Some * arguments) reg
@ -615,15 +639,6 @@ and record_projection = {
and tuple = (expr, comma) nsepseq par reg and tuple = (expr, comma) nsepseq par reg
and empty_list = typed_empty_list par
and typed_empty_list = {
lbracket : lbracket;
rbracket : rbracket;
colon : colon;
list_type : type_expr
}
and none_expr = typed_none_expr par and none_expr = typed_none_expr par
and typed_none_expr = { and typed_none_expr = {
@ -727,7 +742,7 @@ and string_expr_to_region = function
and list_expr_to_region = function and list_expr_to_region = function
Cons {region; _} Cons {region; _}
| List {region; _} | List {region; _}
| EmptyList {region; _} -> region | Nil {region; _} -> region
and constr_expr_to_region = function and constr_expr_to_region = function
NoneExpr {region; _} NoneExpr {region; _}
@ -1283,8 +1298,8 @@ and print_string_expr = function
and print_list_expr = function and print_list_expr = function
Cons {value = {arg1; op; arg2}; _} -> Cons {value = {arg1; op; arg2}; _} ->
print_expr arg1; print_token op "#"; print_expr arg2 print_expr arg1; print_token op "#"; print_expr arg2
| List e -> print_list e | List e -> print_list_injection e
| EmptyList e -> print_empty_list e | Nil e -> print_nil e
and print_constr_expr = function and print_constr_expr = function
SomeApp e -> print_some_app e SomeApp e -> print_some_app e
@ -1356,17 +1371,27 @@ and print_set_remove node =
and print_map_injection {value; _} = and print_map_injection {value; _} =
let {opening; bindings; terminator; closing} = value in let {opening; bindings; terminator; closing} = value in
print_token opening "map"; print_opening "map" opening;
print_nsepseq ";" print_binding bindings; print_sepseq ";" print_binding bindings;
print_terminator terminator; print_terminator terminator;
print_token closing "end" print_closing closing
and print_set_injection {value; _} = and print_set_injection {value; _} =
let {opening; elements; terminator; closing} = value in let {opening; elements; terminator; closing} : set_injection = value in
print_token opening "set"; print_opening "set" opening;
print_nsepseq ";" print_expr elements; print_sepseq ";" print_expr elements;
print_terminator terminator; print_terminator terminator;
print_token closing "end" print_closing closing
and print_opening lexeme = function
Kwd kwd -> print_token kwd lexeme
| KwdBracket (kwd, lbracket) ->
print_token kwd lexeme;
print_token lbracket "{"
and print_closing = function
RBracket rbracket -> print_token rbracket "}"
| End kwd_end -> print_token kwd_end "end"
and print_binding {value; _} = and print_binding {value; _} =
let {source; arrow; image} = value in let {source; arrow; image} = value in
@ -1380,18 +1405,18 @@ and print_tuple {value; _} =
print_nsepseq "," print_expr inside; print_nsepseq "," print_expr inside;
print_token rpar ")" print_token rpar ")"
and print_list {value; _} = and print_list_injection {value; _} =
let {lbracket; inside; rbracket} = value in let {opening; elements; terminator; closing} : list_injection = value in
print_token lbracket "["; print_opening "list" opening;
print_nsepseq "," print_expr inside; print_sepseq ";" print_expr elements;
print_token rbracket "]" print_terminator terminator;
print_closing closing
and print_empty_list {value; _} = and print_nil {value; _} =
let {lpar; inside; rpar} = value in let {lpar; inside; rpar} = value in
let {lbracket; rbracket; colon; list_type} = inside in let {nil; colon; list_type} = inside in
print_token lpar "("; print_token lpar "(";
print_token lbracket "["; print_token nil "nil";
print_token rbracket "]";
print_token colon ":"; print_token colon ":";
print_type_expr list_type; print_type_expr list_type;
print_token rpar ")" print_token rpar ")"

49
AST.mli
View File

@ -23,6 +23,7 @@ val sepseq_to_region : ('a -> Region.t) -> ('a,'sep) sepseq -> Region.t
(* Keywords of LIGO *) (* Keywords of LIGO *)
type keyword = Region.t
type kwd_and = Region.t type kwd_and = Region.t
type kwd_begin = Region.t type kwd_begin = Region.t
type kwd_block = Region.t type kwd_block = Region.t
@ -40,8 +41,10 @@ type kwd_function = Region.t
type kwd_if = Region.t type kwd_if = Region.t
type kwd_in = Region.t type kwd_in = Region.t
type kwd_is = Region.t type kwd_is = Region.t
type kwd_list = Region.t
type kwd_map = Region.t type kwd_map = Region.t
type kwd_mod = Region.t type kwd_mod = Region.t
type kwd_nil = Region.t
type kwd_not = Region.t type kwd_not = Region.t
type kwd_of = Region.t type kwd_of = Region.t
type kwd_or = Region.t type kwd_or = Region.t
@ -362,10 +365,10 @@ and map_patch = {
} }
and map_injection = { and map_injection = {
opening : kwd_map; opening : opening;
bindings : (binding reg, semi) nsepseq; bindings : (binding reg, semi) sepseq;
terminator : semi option; terminator : semi option;
closing : kwd_end closing : closing
} }
and binding = { and binding = {
@ -502,12 +505,20 @@ and set_expr =
SetInj of set_injection reg SetInj of set_injection reg
and set_injection = { and set_injection = {
opening : kwd_set; opening : opening;
elements : (expr, semi) nsepseq; elements : (expr, semi) sepseq;
terminator : semi option; terminator : semi option;
closing : kwd_end closing : closing
} }
and opening =
Kwd of keyword
| KwdBracket of keyword * lbracket
and closing =
End of kwd_end
| RBracket of rbracket
and map_expr = and map_expr =
MapLookUp of map_lookup reg MapLookUp of map_lookup reg
| MapInj of map_injection reg | MapInj of map_injection reg
@ -566,8 +577,21 @@ and string_expr =
and list_expr = and list_expr =
Cons of cons bin_op reg Cons of cons bin_op reg
| List of (expr, comma) nsepseq brackets reg | List of list_injection reg
| EmptyList of empty_list reg | Nil of nil par reg
and list_injection = {
opening : opening;
elements : (expr, semi) sepseq;
terminator : semi option;
closing : closing
}
and nil = {
nil : kwd_nil;
colon : colon;
list_type : type_expr
}
and constr_expr = and constr_expr =
SomeApp of (c_Some * arguments) reg SomeApp of (c_Some * arguments) reg
@ -599,15 +623,6 @@ and record_projection = {
and tuple = (expr, comma) nsepseq par reg and tuple = (expr, comma) nsepseq par reg
and empty_list = typed_empty_list par
and typed_empty_list = {
lbracket : lbracket;
rbracket : rbracket;
colon : colon;
list_type : type_expr
}
and none_expr = typed_none_expr par and none_expr = typed_none_expr par
and typed_none_expr = { and typed_none_expr = {

View File

@ -82,8 +82,10 @@ type t =
| If of Region.t (* "if" *) | If of Region.t (* "if" *)
| In of Region.t (* "in" *) | In of Region.t (* "in" *)
| Is of Region.t (* "is" *) | Is of Region.t (* "is" *)
| List of Region.t (* "list" *)
| Map of Region.t (* "map" *) | Map of Region.t (* "map" *)
| Mod of Region.t (* "mod" *) | Mod of Region.t (* "mod" *)
| Nil of Region.t (* "nil" *)
| Not of Region.t (* "not" *) | Not of Region.t (* "not" *)
| Of of Region.t (* "of" *) | Of of Region.t (* "of" *)
| Or of Region.t (* "or" *) | Or of Region.t (* "or" *)

View File

@ -81,8 +81,10 @@ type t =
| If of Region.t (* "if" *) | If of Region.t (* "if" *)
| In of Region.t (* "in" *) | In of Region.t (* "in" *)
| Is of Region.t (* "is" *) | Is of Region.t (* "is" *)
| List of Region.t (* "list" *)
| Map of Region.t (* "map" *) | Map of Region.t (* "map" *)
| Mod of Region.t (* "mod" *) | Mod of Region.t (* "mod" *)
| Nil of Region.t (* "nil" *)
| Not of Region.t (* "not" *) | Not of Region.t (* "not" *)
| Of of Region.t (* "of" *) | Of of Region.t (* "of" *)
| Or of Region.t (* "or" *) | Or of Region.t (* "or" *)
@ -206,8 +208,10 @@ let proj_token = function
| If region -> region, "If" | If region -> region, "If"
| In region -> region, "In" | In region -> region, "In"
| Is region -> region, "Is" | Is region -> region, "Is"
| List region -> region, "List"
| Map region -> region, "Map" | Map region -> region, "Map"
| Mod region -> region, "Mod" | Mod region -> region, "Mod"
| Nil region -> region, "Nil"
| Not region -> region, "Not" | Not region -> region, "Not"
| Of region -> region, "Of" | Of region -> region, "Of"
| Or region -> region, "Or" | Or region -> region, "Or"
@ -286,22 +290,23 @@ let to_lexeme = function
| Const _ -> "const" | Const _ -> "const"
| Contains _ -> "contains" | Contains _ -> "contains"
| Down _ -> "down" | Down _ -> "down"
| Fail _ -> "fail" | Else _ -> "else"
| If _ -> "if" | End _ -> "end"
| In _ -> "in"
| Is _ -> "is"
| Entrypoint _ -> "entrypoint" | Entrypoint _ -> "entrypoint"
| Fail _ -> "fail"
| For _ -> "for" | For _ -> "for"
| From _ -> "from" | From _ -> "from"
| Function _ -> "function" | Function _ -> "function"
| Type _ -> "type" | If _ -> "if"
| In _ -> "in"
| Is _ -> "is"
| List _ -> "list"
| Map _ -> "map"
| Mod _ -> "mod"
| Nil _ -> "nil"
| Not _ -> "not"
| Of _ -> "of" | Of _ -> "of"
| Or _ -> "or" | Or _ -> "or"
| Var _ -> "var"
| End _ -> "end"
| Then _ -> "then"
| Else _ -> "else"
| Map _ -> "map"
| Patch _ -> "patch" | Patch _ -> "patch"
| Procedure _ -> "procedure" | Procedure _ -> "procedure"
| Record _ -> "record" | Record _ -> "record"
@ -310,9 +315,10 @@ let to_lexeme = function
| Skip _ -> "skip" | Skip _ -> "skip"
| Step _ -> "step" | Step _ -> "step"
| Storage _ -> "storage" | Storage _ -> "storage"
| Then _ -> "then"
| To _ -> "to" | To _ -> "to"
| Mod _ -> "mod" | Type _ -> "type"
| Not _ -> "not" | Var _ -> "var"
| While _ -> "while" | While _ -> "while"
| With _ -> "with" | With _ -> "with"
@ -346,22 +352,23 @@ let keywords = [
(fun reg -> Const reg); (fun reg -> Const reg);
(fun reg -> Contains reg); (fun reg -> Contains reg);
(fun reg -> Down reg); (fun reg -> Down reg);
(fun reg -> Fail reg); (fun reg -> Else reg);
(fun reg -> If reg); (fun reg -> End reg);
(fun reg -> In reg);
(fun reg -> Is reg);
(fun reg -> Entrypoint reg); (fun reg -> Entrypoint reg);
(fun reg -> For reg); (fun reg -> For reg);
(fun reg -> From reg); (fun reg -> From reg);
(fun reg -> Function reg); (fun reg -> Function reg);
(fun reg -> Type reg); (fun reg -> Fail reg);
(fun reg -> If reg);
(fun reg -> In reg);
(fun reg -> Is reg);
(fun reg -> List reg);
(fun reg -> Map reg);
(fun reg -> Mod reg);
(fun reg -> Nil reg);
(fun reg -> Not reg);
(fun reg -> Of reg); (fun reg -> Of reg);
(fun reg -> Or reg); (fun reg -> Or reg);
(fun reg -> Var reg);
(fun reg -> End reg);
(fun reg -> Then reg);
(fun reg -> Else reg);
(fun reg -> Map reg);
(fun reg -> Patch reg); (fun reg -> Patch reg);
(fun reg -> Procedure reg); (fun reg -> Procedure reg);
(fun reg -> Record reg); (fun reg -> Record reg);
@ -370,9 +377,10 @@ let keywords = [
(fun reg -> Skip reg); (fun reg -> Skip reg);
(fun reg -> Step reg); (fun reg -> Step reg);
(fun reg -> Storage reg); (fun reg -> Storage reg);
(fun reg -> Then reg);
(fun reg -> To reg); (fun reg -> To reg);
(fun reg -> Mod reg); (fun reg -> Type reg);
(fun reg -> Not reg); (fun reg -> Var reg);
(fun reg -> While reg); (fun reg -> While reg);
(fun reg -> With reg) (fun reg -> With reg)
] ]
@ -574,22 +582,23 @@ let is_kwd = function
| Const _ | Const _
| Contains _ | Contains _
| Down _ | Down _
| Fail _ | Else _
| If _ | End _
| In _
| Is _
| Entrypoint _ | Entrypoint _
| Fail _
| For _ | For _
| From _ | From _
| Function _ | Function _
| Type _ | If _
| In _
| Is _
| List _
| Map _
| Mod _
| Nil _
| Not _
| Of _ | Of _
| Or _ | Or _
| Var _
| End _
| Then _
| Else _
| Map _
| Patch _ | Patch _
| Procedure _ | Procedure _
| Record _ | Record _
@ -598,9 +607,10 @@ let is_kwd = function
| Skip _ | Skip _
| Step _ | Step _
| Storage _ | Storage _
| Then _
| To _ | To _
| Mod _ | Type _
| Not _ | Var _
| While _ | While _
| With _ -> true | With _ -> true
| _ -> false | _ -> false

View File

@ -49,22 +49,23 @@
%token <Region.t> Const (* "const" *) %token <Region.t> Const (* "const" *)
%token <Region.t> Contains (* "contains" *) %token <Region.t> Contains (* "contains" *)
%token <Region.t> Down (* "down" *) %token <Region.t> Down (* "down" *)
%token <Region.t> Else (* "else" *)
%token <Region.t> End (* "end" *)
%token <Region.t> Entrypoint (* "entrypoint" *)
%token <Region.t> Fail (* "fail" *) %token <Region.t> Fail (* "fail" *)
%token <Region.t> For (* "for" *)
%token <Region.t> Function (* "function" *)
%token <Region.t> From (* "from" *) %token <Region.t> From (* "from" *)
%token <Region.t> If (* "if" *) %token <Region.t> If (* "if" *)
%token <Region.t> In (* "in" *) %token <Region.t> In (* "in" *)
%token <Region.t> Is (* "is" *) %token <Region.t> Is (* "is" *)
%token <Region.t> Entrypoint (* "entrypoint" *) %token <Region.t> List (* "list" *)
%token <Region.t> For (* "for" *) %token <Region.t> Map (* "map" *)
%token <Region.t> Function (* "function" *) %token <Region.t> Mod (* "mod" *)
%token <Region.t> Type (* "type" *) %token <Region.t> Nil (* "nil" *)
%token <Region.t> Not (* "not" *)
%token <Region.t> Of (* "of" *) %token <Region.t> Of (* "of" *)
%token <Region.t> Or (* "or" *) %token <Region.t> Or (* "or" *)
%token <Region.t> Var (* "var" *)
%token <Region.t> End (* "end" *)
%token <Region.t> Then (* "then" *)
%token <Region.t> Else (* "else" *)
%token <Region.t> Map (* "map" *)
%token <Region.t> Patch (* "patch" *) %token <Region.t> Patch (* "patch" *)
%token <Region.t> Procedure (* "procedure" *) %token <Region.t> Procedure (* "procedure" *)
%token <Region.t> Record (* "record" *) %token <Region.t> Record (* "record" *)
@ -73,9 +74,10 @@
%token <Region.t> Skip (* "skip" *) %token <Region.t> Skip (* "skip" *)
%token <Region.t> Step (* "step" *) %token <Region.t> Step (* "step" *)
%token <Region.t> Storage (* "storage" *) %token <Region.t> Storage (* "storage" *)
%token <Region.t> Then (* "then" *)
%token <Region.t> To (* "to" *) %token <Region.t> To (* "to" *)
%token <Region.t> Mod (* "mod" *) %token <Region.t> Type (* "type" *)
%token <Region.t> Not (* "not" *) %token <Region.t> Var (* "var" *)
%token <Region.t> While (* "while" *) %token <Region.t> While (* "while" *)
%token <Region.t> With (* "with" *) %token <Region.t> With (* "with" *)

View File

@ -177,6 +177,13 @@ core_type:
let tuple = {region; value={lpar; inside=inside,[]; rpar}} let tuple = {region; value={lpar; inside=inside,[]; rpar}}
in TApp {region=total; value = type_constr, tuple} in TApp {region=total; value = type_constr, tuple}
} }
| List par(type_expr) {
let total = cover $1 $2.region in
let type_constr = {value="list"; 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) { | par(type_expr) {
TPar $1 TPar $1
} }
@ -390,18 +397,17 @@ unqualified_decl(OP):
let init = let init =
match $5.value with match $5.value with
`Expr e -> e `Expr e -> e
| `EList (lbracket, rbracket) -> | `EList kwd_nil ->
let region = $5.region let region = $5.region
and value = { and value = {
lbracket; nil = kwd_nil;
rbracket;
colon = Region.ghost; colon = Region.ghost;
list_type = $3} in list_type = $3} in
let value = { let value = {
lpar = Region.ghost; lpar = Region.ghost;
inside = value; inside = value;
rpar = Region.ghost} in rpar = Region.ghost} in
EList (EmptyList {region; value}) EList (Nil {region; value})
| `ENone region -> | `ENone region ->
let value = { let value = {
lpar = Region.ghost; lpar = Region.ghost;
@ -453,8 +459,7 @@ var_decl:
extended_expr: extended_expr:
expr { {region = expr_to_region $1; expr { {region = expr_to_region $1;
value = `Expr $1} } value = `Expr $1} }
| LBRACKET RBRACKET { {region = cover $1 $2; | Nil { {region = $1; value = `EList $1} }
value = `EList ($1,$2)} }
| C_None { {region = $1; value = `ENone $1} } | C_None { {region = $1; value = `ENone $1} }
| map_injection { {region = $1.region; value = `EMap $1} } | map_injection { {region = $1.region; value = `EMap $1} }
| set_injection { {region = $1.region; value = `ESet $1} } | set_injection { {region = $1.region; value = `ESet $1} }
@ -527,11 +532,39 @@ set_injection:
Set series(expr,End) { Set series(expr,End) {
let first, (others, terminator, closing) = $2 in let first, (others, terminator, closing) = $2 in
let region = cover $1 closing let region = cover $1 closing
and value = { and value : set_injection = {
opening = $1; opening = Kwd $1;
elements = first, others; elements = Some (first, others);
terminator; terminator;
closing} closing = End closing}
in {region; value}
}
| Set End {
let region = cover $1 $2
and value : set_injection = {
opening = Kwd $1;
elements = None;
terminator = None;
closing = End $2}
in {region; value}
}
| Set LBRACKET series(expr,RBRACKET) {
let first, (others, terminator, closing) = $3 in
let region = cover $1 closing
and value : set_injection = {
opening = KwdBracket ($1,$2);
elements = Some (first, others);
terminator;
closing = RBracket closing}
in {region; value}
}
| Set LBRACKET RBRACKET {
let region = cover $1 $3
and value : set_injection = {
opening = KwdBracket ($1,$2);
elements = None;
terminator = None;
closing = RBracket $3}
in {region; value} in {region; value}
} }
@ -540,10 +573,38 @@ map_injection:
let first, (others, terminator, closing) = $2 in let first, (others, terminator, closing) = $2 in
let region = cover $1 closing let region = cover $1 closing
and value = { and value = {
opening = $1; opening = Kwd $1;
bindings = first, others; bindings = Some (first, others);
terminator; terminator;
closing} closing = End closing}
in {region; value}
}
| Map End {
let region = cover $1 $2
and value = {
opening = Kwd $1;
bindings = None;
terminator = None;
closing = End $2}
in {region; value}
}
| Map LBRACKET series(binding,RBRACKET) {
let first, (others, terminator, closing) = $3 in
let region = cover $1 closing
and value = {
opening = KwdBracket ($1,$2);
bindings = Some (first, others);
terminator;
closing = RBracket closing}
in {region; value}
}
| Map LBRACKET RBRACKET {
let region = cover $1 $3
and value = {
opening = KwdBracket ($1,$2);
bindings = None;
terminator = None;
closing = RBracket $3}
in {region; value} in {region; value}
} }
@ -873,7 +934,7 @@ core_expr:
| C_Unit { EUnit $1 } | C_Unit { EUnit $1 }
| tuple { ETuple $1 } | tuple { ETuple $1 }
| list_expr { EList (List $1) } | list_expr { EList (List $1) }
| empty_list { EList (EmptyList $1) } | nil { EList (Nil $1) }
| none_expr { EConstr (NoneExpr $1) } | none_expr { EConstr (NoneExpr $1) }
| fun_call { ECall $1 } | fun_call { ECall $1 }
| map_expr { EMap $1 } | map_expr { EMap $1 }
@ -953,17 +1014,53 @@ arguments:
tuple { $1 } tuple { $1 }
list_expr: list_expr:
brackets(nsepseq(expr,COMMA)) { $1 } List series(expr,End) {
let first, (others, terminator, closing) = $2 in
let region = cover $1 closing
and value : list_injection = {
opening = Kwd $1;
elements = Some (first, others);
terminator;
closing = End closing}
in {region; value}
}
| List End {
let region = cover $1 $2
and value : list_injection = {
opening = Kwd $1;
elements = None;
terminator = None;
closing = End $2}
in {region; value}
}
| List LBRACKET series(expr,RBRACKET) {
let first, (others, terminator, closing) = $3 in
let region = cover $1 closing
and value : list_injection = {
opening = KwdBracket ($1,$2);
elements = Some (first, others);
terminator;
closing = RBracket closing}
in {region; value}
}
| List LBRACKET RBRACKET {
let region = cover $1 $3
and value : list_injection = {
opening = KwdBracket ($1,$2);
elements = None;
terminator = None;
closing = RBracket $3}
in {region; value}
}
empty_list: nil:
par(typed_empty_list) { $1 } par(typed_empty_list) { $1 }
typed_empty_list: typed_empty_list:
LBRACKET RBRACKET COLON type_expr { Nil COLON type_expr {
{lbracket = $1; {nil = $1;
rbracket = $2; colon = $2;
colon = $3; list_type = $3}
list_type = $4}
} }
none_expr: none_expr:

View File

@ -10,7 +10,9 @@ entrypoint contribute (storage store : store;
const sender : address; const sender : address;
const amount : mutez) const amount : mutez)
: store * list (operation) is : store * list (operation) is
var operations : list (operation) := [] var operations : list (operation) := nil
const s : list (int) = list [1; 2; 3]
const t : set (int) = set []
block { block {
if now > store.deadline then if now > store.deadline then
fail "Deadline passed"; fail "Deadline passed";
@ -24,14 +26,14 @@ entrypoint contribute (storage store : store;
entrypoint withdraw (storage store : store; const sender : address) entrypoint withdraw (storage store : store; const sender : address)
: store * list (operation) is : store * list (operation) is
var operations : list (operation) := [] var operations : list (operation) := list end
begin begin
if sender = owner then if sender = owner then
if now (Unit) >= store.deadline then if now (Unit) >= store.deadline then
if balance >= store.goal then { if balance >= store.goal then {
store.funded := True; store.funded := True;
// patch store with record funded = True end; // patch store with record funded = True end;
operations := [Transfer (owner, balance)]; operations := list [Transfer (owner, balance)];
}; };
else fail "Below target" else fail "Below target"
else { fail "Too soon"; } else { fail "Too soon"; }
@ -40,7 +42,7 @@ entrypoint withdraw (storage store : store; const sender : address)
entrypoint claim (storage store : store; const sender : address) entrypoint claim (storage store : store; const sender : address)
: store * list (operation) is : store * list (operation) is
var operations : list (operation) := [] var operations : list (operation) := list []
var amount : mutez := 0 var amount : mutez := 0
begin begin
if now <= store.deadline then if now <= store.deadline then
@ -54,7 +56,7 @@ entrypoint claim (storage store : store; const sender : address)
fail "Cannot refund" fail "Cannot refund"
else else
begin begin
operations := [Transfer (sender, amount)]; operations := list [Transfer (sender, amount)];
remove sender from map store.backers remove sender from map store.backers
end end
end end