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:
parent
98f9d3e417
commit
fef4337e83
103
AST.ml
103
AST.ml
@ -39,6 +39,7 @@ let sepseq_to_region to_region = function
|
||||
|
||||
(* Keywords of LIGO *)
|
||||
|
||||
type keyword = Region.t
|
||||
type kwd_and = Region.t
|
||||
type kwd_begin = Region.t
|
||||
type kwd_block = Region.t
|
||||
@ -56,8 +57,10 @@ type kwd_function = Region.t
|
||||
type kwd_if = Region.t
|
||||
type kwd_in = Region.t
|
||||
type kwd_is = Region.t
|
||||
type kwd_list = Region.t
|
||||
type kwd_map = Region.t
|
||||
type kwd_mod = Region.t
|
||||
type kwd_nil = Region.t
|
||||
type kwd_not = Region.t
|
||||
type kwd_of = Region.t
|
||||
type kwd_or = Region.t
|
||||
@ -378,10 +381,10 @@ and map_patch = {
|
||||
}
|
||||
|
||||
and map_injection = {
|
||||
opening : kwd_map;
|
||||
bindings : (binding reg, semi) nsepseq;
|
||||
opening : opening;
|
||||
bindings : (binding reg, semi) sepseq;
|
||||
terminator : semi option;
|
||||
closing : kwd_end
|
||||
closing : closing
|
||||
}
|
||||
|
||||
and binding = {
|
||||
@ -518,12 +521,20 @@ and set_expr =
|
||||
SetInj of set_injection reg
|
||||
|
||||
and set_injection = {
|
||||
opening : kwd_set;
|
||||
elements : (expr, semi) nsepseq;
|
||||
opening : opening;
|
||||
elements : (expr, semi) sepseq;
|
||||
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 =
|
||||
MapLookUp of map_lookup reg
|
||||
| MapInj of map_injection reg
|
||||
@ -581,9 +592,22 @@ and string_expr =
|
||||
| String of Lexer.lexeme reg
|
||||
|
||||
and list_expr =
|
||||
Cons of cons bin_op reg
|
||||
| List of (expr, comma) nsepseq brackets reg
|
||||
| EmptyList of empty_list reg
|
||||
Cons of cons bin_op reg
|
||||
| List of list_injection 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 =
|
||||
SomeApp of (c_Some * arguments) reg
|
||||
@ -615,15 +639,6 @@ and record_projection = {
|
||||
|
||||
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 typed_none_expr = {
|
||||
@ -725,9 +740,9 @@ and string_expr_to_region = function
|
||||
| String {region; _} -> region
|
||||
|
||||
and list_expr_to_region = function
|
||||
Cons {region; _}
|
||||
| List {region; _}
|
||||
| EmptyList {region; _} -> region
|
||||
Cons {region; _}
|
||||
| List {region; _}
|
||||
| Nil {region; _} -> region
|
||||
|
||||
and constr_expr_to_region = function
|
||||
NoneExpr {region; _}
|
||||
@ -1283,8 +1298,8 @@ and print_string_expr = function
|
||||
and print_list_expr = function
|
||||
Cons {value = {arg1; op; arg2}; _} ->
|
||||
print_expr arg1; print_token op "#"; print_expr arg2
|
||||
| List e -> print_list e
|
||||
| EmptyList e -> print_empty_list e
|
||||
| List e -> print_list_injection e
|
||||
| Nil e -> print_nil e
|
||||
|
||||
and print_constr_expr = function
|
||||
SomeApp e -> print_some_app e
|
||||
@ -1356,17 +1371,27 @@ and print_set_remove node =
|
||||
|
||||
and print_map_injection {value; _} =
|
||||
let {opening; bindings; terminator; closing} = value in
|
||||
print_token opening "map";
|
||||
print_nsepseq ";" print_binding bindings;
|
||||
print_opening "map" opening;
|
||||
print_sepseq ";" print_binding bindings;
|
||||
print_terminator terminator;
|
||||
print_token closing "end"
|
||||
print_closing closing
|
||||
|
||||
and print_set_injection {value; _} =
|
||||
let {opening; elements; terminator; closing} = value in
|
||||
print_token opening "set";
|
||||
print_nsepseq ";" print_expr elements;
|
||||
let {opening; elements; terminator; closing} : set_injection = value in
|
||||
print_opening "set" opening;
|
||||
print_sepseq ";" print_expr elements;
|
||||
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; _} =
|
||||
let {source; arrow; image} = value in
|
||||
@ -1380,18 +1405,18 @@ and print_tuple {value; _} =
|
||||
print_nsepseq "," print_expr inside;
|
||||
print_token rpar ")"
|
||||
|
||||
and print_list {value; _} =
|
||||
let {lbracket; inside; rbracket} = value in
|
||||
print_token lbracket "[";
|
||||
print_nsepseq "," print_expr inside;
|
||||
print_token rbracket "]"
|
||||
and print_list_injection {value; _} =
|
||||
let {opening; elements; terminator; closing} : list_injection = value in
|
||||
print_opening "list" opening;
|
||||
print_sepseq ";" print_expr elements;
|
||||
print_terminator terminator;
|
||||
print_closing closing
|
||||
|
||||
and print_empty_list {value; _} =
|
||||
and print_nil {value; _} =
|
||||
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 lbracket "[";
|
||||
print_token rbracket "]";
|
||||
print_token nil "nil";
|
||||
print_token colon ":";
|
||||
print_type_expr list_type;
|
||||
print_token rpar ")"
|
||||
|
51
AST.mli
51
AST.mli
@ -23,6 +23,7 @@ val sepseq_to_region : ('a -> Region.t) -> ('a,'sep) sepseq -> Region.t
|
||||
|
||||
(* Keywords of LIGO *)
|
||||
|
||||
type keyword = Region.t
|
||||
type kwd_and = Region.t
|
||||
type kwd_begin = Region.t
|
||||
type kwd_block = Region.t
|
||||
@ -40,8 +41,10 @@ type kwd_function = Region.t
|
||||
type kwd_if = Region.t
|
||||
type kwd_in = Region.t
|
||||
type kwd_is = Region.t
|
||||
type kwd_list = Region.t
|
||||
type kwd_map = Region.t
|
||||
type kwd_mod = Region.t
|
||||
type kwd_nil = Region.t
|
||||
type kwd_not = Region.t
|
||||
type kwd_of = Region.t
|
||||
type kwd_or = Region.t
|
||||
@ -362,10 +365,10 @@ and map_patch = {
|
||||
}
|
||||
|
||||
and map_injection = {
|
||||
opening : kwd_map;
|
||||
bindings : (binding reg, semi) nsepseq;
|
||||
opening : opening;
|
||||
bindings : (binding reg, semi) sepseq;
|
||||
terminator : semi option;
|
||||
closing : kwd_end
|
||||
closing : closing
|
||||
}
|
||||
|
||||
and binding = {
|
||||
@ -502,12 +505,20 @@ and set_expr =
|
||||
SetInj of set_injection reg
|
||||
|
||||
and set_injection = {
|
||||
opening : kwd_set;
|
||||
elements : (expr, semi) nsepseq;
|
||||
opening : opening;
|
||||
elements : (expr, semi) sepseq;
|
||||
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 =
|
||||
MapLookUp of map_lookup reg
|
||||
| MapInj of map_injection reg
|
||||
@ -565,9 +576,22 @@ and string_expr =
|
||||
| String of Lexer.lexeme reg
|
||||
|
||||
and list_expr =
|
||||
Cons of cons bin_op reg
|
||||
| List of (expr, comma) nsepseq brackets reg
|
||||
| EmptyList of empty_list reg
|
||||
Cons of cons bin_op reg
|
||||
| List of list_injection 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 =
|
||||
SomeApp of (c_Some * arguments) reg
|
||||
@ -599,15 +623,6 @@ and record_projection = {
|
||||
|
||||
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 typed_none_expr = {
|
||||
|
@ -82,8 +82,10 @@ type t =
|
||||
| If of Region.t (* "if" *)
|
||||
| In of Region.t (* "in" *)
|
||||
| Is of Region.t (* "is" *)
|
||||
| List of Region.t (* "list" *)
|
||||
| Map of Region.t (* "map" *)
|
||||
| Mod of Region.t (* "mod" *)
|
||||
| Nil of Region.t (* "nil" *)
|
||||
| Not of Region.t (* "not" *)
|
||||
| Of of Region.t (* "of" *)
|
||||
| Or of Region.t (* "or" *)
|
||||
|
82
LexToken.mll
82
LexToken.mll
@ -81,8 +81,10 @@ type t =
|
||||
| If of Region.t (* "if" *)
|
||||
| In of Region.t (* "in" *)
|
||||
| Is of Region.t (* "is" *)
|
||||
| List of Region.t (* "list" *)
|
||||
| Map of Region.t (* "map" *)
|
||||
| Mod of Region.t (* "mod" *)
|
||||
| Nil of Region.t (* "nil" *)
|
||||
| Not of Region.t (* "not" *)
|
||||
| Of of Region.t (* "of" *)
|
||||
| Or of Region.t (* "or" *)
|
||||
@ -206,8 +208,10 @@ let proj_token = function
|
||||
| If region -> region, "If"
|
||||
| In region -> region, "In"
|
||||
| Is region -> region, "Is"
|
||||
| List region -> region, "List"
|
||||
| Map region -> region, "Map"
|
||||
| Mod region -> region, "Mod"
|
||||
| Nil region -> region, "Nil"
|
||||
| Not region -> region, "Not"
|
||||
| Of region -> region, "Of"
|
||||
| Or region -> region, "Or"
|
||||
@ -286,22 +290,23 @@ let to_lexeme = function
|
||||
| Const _ -> "const"
|
||||
| Contains _ -> "contains"
|
||||
| Down _ -> "down"
|
||||
| Fail _ -> "fail"
|
||||
| If _ -> "if"
|
||||
| In _ -> "in"
|
||||
| Is _ -> "is"
|
||||
| Else _ -> "else"
|
||||
| End _ -> "end"
|
||||
| Entrypoint _ -> "entrypoint"
|
||||
| Fail _ -> "fail"
|
||||
| For _ -> "for"
|
||||
| From _ -> "from"
|
||||
| Function _ -> "function"
|
||||
| Type _ -> "type"
|
||||
| If _ -> "if"
|
||||
| In _ -> "in"
|
||||
| Is _ -> "is"
|
||||
| List _ -> "list"
|
||||
| Map _ -> "map"
|
||||
| Mod _ -> "mod"
|
||||
| Nil _ -> "nil"
|
||||
| Not _ -> "not"
|
||||
| Of _ -> "of"
|
||||
| Or _ -> "or"
|
||||
| Var _ -> "var"
|
||||
| End _ -> "end"
|
||||
| Then _ -> "then"
|
||||
| Else _ -> "else"
|
||||
| Map _ -> "map"
|
||||
| Patch _ -> "patch"
|
||||
| Procedure _ -> "procedure"
|
||||
| Record _ -> "record"
|
||||
@ -310,9 +315,10 @@ let to_lexeme = function
|
||||
| Skip _ -> "skip"
|
||||
| Step _ -> "step"
|
||||
| Storage _ -> "storage"
|
||||
| Then _ -> "then"
|
||||
| To _ -> "to"
|
||||
| Mod _ -> "mod"
|
||||
| Not _ -> "not"
|
||||
| Type _ -> "type"
|
||||
| Var _ -> "var"
|
||||
| While _ -> "while"
|
||||
| With _ -> "with"
|
||||
|
||||
@ -346,22 +352,23 @@ let keywords = [
|
||||
(fun reg -> Const reg);
|
||||
(fun reg -> Contains reg);
|
||||
(fun reg -> Down reg);
|
||||
(fun reg -> Fail reg);
|
||||
(fun reg -> If reg);
|
||||
(fun reg -> In reg);
|
||||
(fun reg -> Is reg);
|
||||
(fun reg -> Else reg);
|
||||
(fun reg -> End reg);
|
||||
(fun reg -> Entrypoint reg);
|
||||
(fun reg -> For reg);
|
||||
(fun reg -> From 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 -> 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 -> Procedure reg);
|
||||
(fun reg -> Record reg);
|
||||
@ -370,9 +377,10 @@ let keywords = [
|
||||
(fun reg -> Skip reg);
|
||||
(fun reg -> Step reg);
|
||||
(fun reg -> Storage reg);
|
||||
(fun reg -> Then reg);
|
||||
(fun reg -> To reg);
|
||||
(fun reg -> Mod reg);
|
||||
(fun reg -> Not reg);
|
||||
(fun reg -> Type reg);
|
||||
(fun reg -> Var reg);
|
||||
(fun reg -> While reg);
|
||||
(fun reg -> With reg)
|
||||
]
|
||||
@ -574,22 +582,23 @@ let is_kwd = function
|
||||
| Const _
|
||||
| Contains _
|
||||
| Down _
|
||||
| Fail _
|
||||
| If _
|
||||
| In _
|
||||
| Is _
|
||||
| Else _
|
||||
| End _
|
||||
| Entrypoint _
|
||||
| Fail _
|
||||
| For _
|
||||
| From _
|
||||
| Function _
|
||||
| Type _
|
||||
| If _
|
||||
| In _
|
||||
| Is _
|
||||
| List _
|
||||
| Map _
|
||||
| Mod _
|
||||
| Nil _
|
||||
| Not _
|
||||
| Of _
|
||||
| Or _
|
||||
| Var _
|
||||
| End _
|
||||
| Then _
|
||||
| Else _
|
||||
| Map _
|
||||
| Patch _
|
||||
| Procedure _
|
||||
| Record _
|
||||
@ -598,9 +607,10 @@ let is_kwd = function
|
||||
| Skip _
|
||||
| Step _
|
||||
| Storage _
|
||||
| Then _
|
||||
| To _
|
||||
| Mod _
|
||||
| Not _
|
||||
| Type _
|
||||
| Var _
|
||||
| While _
|
||||
| With _ -> true
|
||||
| _ -> false
|
||||
|
24
ParToken.mly
24
ParToken.mly
@ -49,22 +49,23 @@
|
||||
%token <Region.t> Const (* "const" *)
|
||||
%token <Region.t> Contains (* "contains" *)
|
||||
%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> For (* "for" *)
|
||||
%token <Region.t> Function (* "function" *)
|
||||
%token <Region.t> From (* "from" *)
|
||||
%token <Region.t> If (* "if" *)
|
||||
%token <Region.t> In (* "in" *)
|
||||
%token <Region.t> Is (* "is" *)
|
||||
%token <Region.t> Entrypoint (* "entrypoint" *)
|
||||
%token <Region.t> For (* "for" *)
|
||||
%token <Region.t> Function (* "function" *)
|
||||
%token <Region.t> Type (* "type" *)
|
||||
%token <Region.t> List (* "list" *)
|
||||
%token <Region.t> Map (* "map" *)
|
||||
%token <Region.t> Mod (* "mod" *)
|
||||
%token <Region.t> Nil (* "nil" *)
|
||||
%token <Region.t> Not (* "not" *)
|
||||
%token <Region.t> Of (* "of" *)
|
||||
%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> Procedure (* "procedure" *)
|
||||
%token <Region.t> Record (* "record" *)
|
||||
@ -73,9 +74,10 @@
|
||||
%token <Region.t> Skip (* "skip" *)
|
||||
%token <Region.t> Step (* "step" *)
|
||||
%token <Region.t> Storage (* "storage" *)
|
||||
%token <Region.t> Then (* "then" *)
|
||||
%token <Region.t> To (* "to" *)
|
||||
%token <Region.t> Mod (* "mod" *)
|
||||
%token <Region.t> Not (* "not" *)
|
||||
%token <Region.t> Type (* "type" *)
|
||||
%token <Region.t> Var (* "var" *)
|
||||
%token <Region.t> While (* "while" *)
|
||||
%token <Region.t> With (* "with" *)
|
||||
|
||||
|
149
Parser.mly
149
Parser.mly
@ -177,6 +177,13 @@ core_type:
|
||||
let tuple = {region; value={lpar; inside=inside,[]; rpar}}
|
||||
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) {
|
||||
TPar $1
|
||||
}
|
||||
@ -390,18 +397,17 @@ unqualified_decl(OP):
|
||||
let init =
|
||||
match $5.value with
|
||||
`Expr e -> e
|
||||
| `EList (lbracket, rbracket) ->
|
||||
| `EList kwd_nil ->
|
||||
let region = $5.region
|
||||
and value = {
|
||||
lbracket;
|
||||
rbracket;
|
||||
nil = kwd_nil;
|
||||
colon = Region.ghost;
|
||||
list_type = $3} in
|
||||
let value = {
|
||||
lpar = Region.ghost;
|
||||
inside = value;
|
||||
rpar = Region.ghost} in
|
||||
EList (EmptyList {region; value})
|
||||
EList (Nil {region; value})
|
||||
| `ENone region ->
|
||||
let value = {
|
||||
lpar = Region.ghost;
|
||||
@ -451,13 +457,12 @@ var_decl:
|
||||
}
|
||||
|
||||
extended_expr:
|
||||
expr { {region = expr_to_region $1;
|
||||
value = `Expr $1} }
|
||||
| LBRACKET RBRACKET { {region = cover $1 $2;
|
||||
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} }
|
||||
expr { {region = expr_to_region $1;
|
||||
value = `Expr $1} }
|
||||
| Nil { {region = $1; value = `EList $1} }
|
||||
| C_None { {region = $1; value = `ENone $1} }
|
||||
| map_injection { {region = $1.region; value = `EMap $1} }
|
||||
| set_injection { {region = $1.region; value = `ESet $1} }
|
||||
|
||||
instruction:
|
||||
single_instr { Single $1 }
|
||||
@ -527,11 +532,39 @@ set_injection:
|
||||
Set series(expr,End) {
|
||||
let first, (others, terminator, closing) = $2 in
|
||||
let region = cover $1 closing
|
||||
and value = {
|
||||
opening = $1;
|
||||
elements = first, others;
|
||||
and value : set_injection = {
|
||||
opening = Kwd $1;
|
||||
elements = Some (first, others);
|
||||
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}
|
||||
}
|
||||
|
||||
@ -540,10 +573,38 @@ map_injection:
|
||||
let first, (others, terminator, closing) = $2 in
|
||||
let region = cover $1 closing
|
||||
and value = {
|
||||
opening = $1;
|
||||
bindings = first, others;
|
||||
opening = Kwd $1;
|
||||
bindings = Some (first, others);
|
||||
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}
|
||||
}
|
||||
|
||||
@ -873,7 +934,7 @@ core_expr:
|
||||
| C_Unit { EUnit $1 }
|
||||
| tuple { ETuple $1 }
|
||||
| list_expr { EList (List $1) }
|
||||
| empty_list { EList (EmptyList $1) }
|
||||
| nil { EList (Nil $1) }
|
||||
| none_expr { EConstr (NoneExpr $1) }
|
||||
| fun_call { ECall $1 }
|
||||
| map_expr { EMap $1 }
|
||||
@ -953,17 +1014,53 @@ arguments:
|
||||
tuple { $1 }
|
||||
|
||||
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 }
|
||||
|
||||
typed_empty_list:
|
||||
LBRACKET RBRACKET COLON type_expr {
|
||||
{lbracket = $1;
|
||||
rbracket = $2;
|
||||
colon = $3;
|
||||
list_type = $4}
|
||||
Nil COLON type_expr {
|
||||
{nil = $1;
|
||||
colon = $2;
|
||||
list_type = $3}
|
||||
}
|
||||
|
||||
none_expr:
|
||||
|
@ -10,7 +10,9 @@ entrypoint contribute (storage store : store;
|
||||
const sender : address;
|
||||
const amount : mutez)
|
||||
: 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 {
|
||||
if now > store.deadline then
|
||||
fail "Deadline passed";
|
||||
@ -24,14 +26,14 @@ entrypoint contribute (storage store : store;
|
||||
|
||||
entrypoint withdraw (storage store : store; const sender : address)
|
||||
: store * list (operation) is
|
||||
var operations : list (operation) := []
|
||||
var operations : list (operation) := list end
|
||||
begin
|
||||
if sender = owner then
|
||||
if now (Unit) >= store.deadline then
|
||||
if balance >= store.goal then {
|
||||
store.funded := True;
|
||||
// patch store with record funded = True end;
|
||||
operations := [Transfer (owner, balance)];
|
||||
operations := list [Transfer (owner, balance)];
|
||||
};
|
||||
else fail "Below target"
|
||||
else { fail "Too soon"; }
|
||||
@ -40,7 +42,7 @@ entrypoint withdraw (storage store : store; const sender : address)
|
||||
|
||||
entrypoint claim (storage store : store; const sender : address)
|
||||
: store * list (operation) is
|
||||
var operations : list (operation) := []
|
||||
var operations : list (operation) := list []
|
||||
var amount : mutez := 0
|
||||
begin
|
||||
if now <= store.deadline then
|
||||
@ -54,7 +56,7 @@ entrypoint claim (storage store : store; const sender : address)
|
||||
fail "Cannot refund"
|
||||
else
|
||||
begin
|
||||
operations := [Transfer (sender, amount)];
|
||||
operations := list [Transfer (sender, amount)];
|
||||
remove sender from map store.backers
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user