I added and alternate syntax for blocks of instructions.

The syntax: block { ... }
The other syntax: begin ... end
This implies adding a new keyword to LIGO: "block".
This commit is contained in:
Christian Rinderknecht 2019-03-25 16:38:07 +01:00
parent ea4af374f9
commit 457a0085f7
No known key found for this signature in database
GPG Key ID: 9446816CFD267040
8 changed files with 115 additions and 70 deletions

56
AST.ml
View File

@ -41,6 +41,7 @@ let sepseq_to_region to_region = function
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_case = Region.t type kwd_case = Region.t
type kwd_const = Region.t type kwd_const = Region.t
type kwd_contains = Region.t type kwd_contains = Region.t
@ -204,7 +205,7 @@ and record_type = {
opening : kwd_record; opening : kwd_record;
field_decls : field_decls; field_decls : field_decls;
terminator : semi option; terminator : semi option;
close : kwd_end closing : kwd_end
} }
and field_decls = (field_decl reg, semi) nsepseq and field_decls = (field_decl reg, semi) nsepseq
@ -297,12 +298,20 @@ and param_var = {
} }
and block = { and block = {
opening : kwd_begin; opening : block_opening;
instr : instructions; instr : instructions;
terminator : semi option; terminator : semi option;
close : kwd_end closing : block_closing
} }
and block_opening =
Block of kwd_block * lbrace
| Begin of kwd_begin
and block_closing =
Block of rbrace
| End of kwd_end
and local_decl = and local_decl =
LocalLam of lambda_decl LocalLam of lambda_decl
| LocalConst of const_decl reg | LocalConst of const_decl reg
@ -372,7 +381,7 @@ and map_injection = {
opening : kwd_map; opening : kwd_map;
bindings : (binding reg, semi) nsepseq; bindings : (binding reg, semi) nsepseq;
terminator : semi option; terminator : semi option;
close : kwd_end closing : kwd_end
} }
and binding = { and binding = {
@ -508,7 +517,7 @@ and set_injection = {
opening : kwd_set; opening : kwd_set;
elements : (expr, semi) nsepseq; elements : (expr, semi) nsepseq;
terminator : semi option; terminator : semi option;
close : kwd_end closing : kwd_end
} }
and map_expr = and map_expr =
@ -585,7 +594,7 @@ and record_injection = {
opening : kwd_record; opening : kwd_record;
fields : (field_assign reg, semi) nsepseq; fields : (field_assign reg, semi) nsepseq;
terminator : semi option; terminator : semi option;
close : kwd_end closing : kwd_end
} }
and field_assign = { and field_assign = {
@ -875,11 +884,11 @@ and print_sum_type {value; _} =
print_nsepseq "|" print_variant value print_nsepseq "|" print_variant value
and print_record_type {value; _} = and print_record_type {value; _} =
let {opening; field_decls; terminator; close} = value in let {opening; field_decls; terminator; closing} = value in
print_token opening "record"; print_token opening "record";
print_field_decls field_decls; print_field_decls field_decls;
print_terminator terminator; print_terminator terminator;
print_token close "end" print_token closing "end"
and print_type_app {value; _} = and print_type_app {value; _} =
let type_name, type_tuple = value in let type_name, type_tuple = value in
@ -998,11 +1007,20 @@ and print_param_var {value; _} =
print_type_expr param_type print_type_expr param_type
and print_block {value; _} = and print_block {value; _} =
let {opening; instr; terminator; close} = value in let {opening; instr; terminator; closing} = value in
print_token opening "begin"; print_block_opening opening;
print_instructions instr; print_instructions instr;
print_terminator terminator; print_terminator terminator;
print_token close "end" print_block_closing closing
and print_block_opening = function
Block (kwd_block, lbrace) -> print_token kwd_block "block";
print_token lbrace "{"
| Begin kwd_begin -> print_token kwd_begin "begin"
and print_block_closing = function
Block rbrace -> print_token rbrace "}"
| End kwd_end -> print_token kwd_end "end"
and print_local_decls sequence = and print_local_decls sequence =
List.iter print_local_decl sequence List.iter print_local_decl sequence
@ -1260,11 +1278,11 @@ and print_record_expr = function
| RecordProj e -> print_record_projection e | RecordProj e -> print_record_projection e
and print_record_injection {value; _} = and print_record_injection {value; _} =
let {opening; fields; terminator; close} = value in let {opening; fields; terminator; closing} = value in
print_token opening "record"; print_token opening "record";
print_nsepseq ";" print_field_assign fields; print_nsepseq ";" print_field_assign fields;
print_terminator terminator; print_terminator terminator;
print_token close "end" print_token closing "end"
and print_field_assign {value; _} = and print_field_assign {value; _} =
let {field_name; equal; field_expr} = value in let {field_name; equal; field_expr} = value in
@ -1319,18 +1337,18 @@ and print_set_remove node =
print_path set print_path set
and print_map_injection {value; _} = and print_map_injection {value; _} =
let {opening; bindings; terminator; close} = value in let {opening; bindings; terminator; closing} = value in
print_token opening "map"; print_token opening "map";
print_nsepseq ";" print_binding bindings; print_nsepseq ";" print_binding bindings;
print_terminator terminator; print_terminator terminator;
print_token close "end" print_token closing "end"
and print_set_injection {value; _} = and print_set_injection {value; _} =
let {opening; elements; terminator; close} = value in let {opening; elements; terminator; closing} = value in
print_token opening "set"; print_token opening "set";
print_nsepseq ";" print_expr elements; print_nsepseq ";" print_expr elements;
print_terminator terminator; print_terminator terminator;
print_token close "end" print_token closing "end"
and print_binding {value; _} = and print_binding {value; _} =
let {source; arrow; image} = value in let {source; arrow; image} = value in

21
AST.mli
View File

@ -25,6 +25,7 @@ val sepseq_to_region : ('a -> Region.t) -> ('a,'sep) sepseq -> 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_case = Region.t type kwd_case = Region.t
type kwd_const = Region.t type kwd_const = Region.t
type kwd_contains = Region.t type kwd_contains = Region.t
@ -188,7 +189,7 @@ and record_type = {
opening : kwd_record; opening : kwd_record;
field_decls : field_decls; field_decls : field_decls;
terminator : semi option; terminator : semi option;
close : kwd_end closing : kwd_end
} }
and field_decls = (field_decl reg, semi) nsepseq and field_decls = (field_decl reg, semi) nsepseq
@ -281,12 +282,20 @@ and param_var = {
} }
and block = { and block = {
opening : kwd_begin; opening : block_opening;
instr : instructions; instr : instructions;
terminator : semi option; terminator : semi option;
close : kwd_end closing : block_closing
} }
and block_opening =
Block of kwd_block * lbrace
| Begin of kwd_begin
and block_closing =
Block of rbrace
| End of kwd_end
and local_decl = and local_decl =
LocalLam of lambda_decl LocalLam of lambda_decl
| LocalConst of const_decl reg | LocalConst of const_decl reg
@ -356,7 +365,7 @@ and map_injection = {
opening : kwd_map; opening : kwd_map;
bindings : (binding reg, semi) nsepseq; bindings : (binding reg, semi) nsepseq;
terminator : semi option; terminator : semi option;
close : kwd_end closing : kwd_end
} }
and binding = { and binding = {
@ -492,7 +501,7 @@ and set_injection = {
opening : kwd_set; opening : kwd_set;
elements : (expr, semi) nsepseq; elements : (expr, semi) nsepseq;
terminator : semi option; terminator : semi option;
close : kwd_end closing : kwd_end
} }
and map_expr = and map_expr =
@ -569,7 +578,7 @@ and record_injection = {
opening : kwd_record; opening : kwd_record;
fields : (field_assign reg, semi) nsepseq; fields : (field_assign reg, semi) nsepseq;
terminator : semi option; terminator : semi option;
close : kwd_end closing : kwd_end
} }
and field_assign = { and field_assign = {

View File

@ -67,6 +67,7 @@ type t =
| And of Region.t (* "and" *) | And of Region.t (* "and" *)
| Begin of Region.t (* "begin" *) | Begin of Region.t (* "begin" *)
| Block of Region.t (* "block" *)
| Case of Region.t (* "case" *) | Case of Region.t (* "case" *)
| Const of Region.t (* "const" *) | Const of Region.t (* "const" *)
| Contains of Region.t (* "contains" *) | Contains of Region.t (* "contains" *)

View File

@ -66,6 +66,7 @@ type t =
| And of Region.t (* "and" *) | And of Region.t (* "and" *)
| Begin of Region.t (* "begin" *) | Begin of Region.t (* "begin" *)
| Block of Region.t (* "block" *)
| Case of Region.t (* "case" *) | Case of Region.t (* "case" *)
| Const of Region.t (* "const" *) | Const of Region.t (* "const" *)
| Contains of Region.t (* "contains" *) | Contains of Region.t (* "contains" *)
@ -190,6 +191,7 @@ let proj_token = function
| And region -> region, "And" | And region -> region, "And"
| Begin region -> region, "Begin" | Begin region -> region, "Begin"
| Block region -> region, "Block"
| Case region -> region, "Case" | Case region -> region, "Case"
| Const region -> region, "Const" | Const region -> region, "Const"
| Contains region -> region, "Contains" | Contains region -> region, "Contains"
@ -279,6 +281,7 @@ let to_lexeme = function
| And _ -> "and" | And _ -> "and"
| Begin _ -> "begin" | Begin _ -> "begin"
| Block _ -> "block"
| Case _ -> "case" | Case _ -> "case"
| Const _ -> "const" | Const _ -> "const"
| Contains _ -> "contains" | Contains _ -> "contains"
@ -338,6 +341,7 @@ let to_region token = proj_token token |> fst
let keywords = [ let keywords = [
(fun reg -> And reg); (fun reg -> And reg);
(fun reg -> Begin reg); (fun reg -> Begin reg);
(fun reg -> Block reg);
(fun reg -> Case reg); (fun reg -> Case reg);
(fun reg -> Const reg); (fun reg -> Const reg);
(fun reg -> Contains reg); (fun reg -> Contains reg);
@ -565,6 +569,7 @@ let is_ident = function
let is_kwd = function let is_kwd = function
And _ And _
| Begin _ | Begin _
| Block _
| Case _ | Case _
| Const _ | Const _
| Contains _ | Contains _

View File

@ -459,7 +459,7 @@ let byte_seq = byte | byte (byte | '_')* byte
let bytes = "0x" (byte_seq? as seq) let bytes = "0x" (byte_seq? as seq)
let esc = "\\n" | "\\\"" | "\\\\" | "\\b" let esc = "\\n" | "\\\"" | "\\\\" | "\\b"
| "\\r" | "\\t" | "\\x" byte | "\\r" | "\\t" | "\\x" byte
let symbol = ';' | ',' | '(' | ')'| '[' | ']' let symbol = ';' | ',' | '(' | ')'| '[' | ']' | '{' | '}'
| '#' | '|' | "->" | ":=" | '=' | ':' | '#' | '|' | "->" | ":=" | '=' | ':'
| '<' | "<=" | '>' | ">=" | "=/=" | '<' | "<=" | '>' | ">=" | "=/="
| '+' | '-' | '*' | '.' | '_' | '^' | '+' | '-' | '*' | '.' | '_' | '^'

View File

@ -17,6 +17,8 @@
%token <Region.t> COMMA (* "," *) %token <Region.t> COMMA (* "," *)
%token <Region.t> LPAR (* "(" *) %token <Region.t> LPAR (* "(" *)
%token <Region.t> RPAR (* ")" *) %token <Region.t> RPAR (* ")" *)
%token <Region.t> LBRACE (* "{" *)
%token <Region.t> RBRACE (* "}" *)
%token <Region.t> LBRACKET (* "[" *) %token <Region.t> LBRACKET (* "[" *)
%token <Region.t> RBRACKET (* "]" *) %token <Region.t> RBRACKET (* "]" *)
%token <Region.t> CONS (* "#" *) %token <Region.t> CONS (* "#" *)
@ -42,6 +44,7 @@
%token <Region.t> And (* "and" *) %token <Region.t> And (* "and" *)
%token <Region.t> Begin (* "begin" *) %token <Region.t> Begin (* "begin" *)
%token <Region.t> Block (* "block" *)
%token <Region.t> Case (* "case" *) %token <Region.t> Case (* "case" *)
%token <Region.t> Const (* "const" *) %token <Region.t> Const (* "const" *)
%token <Region.t> Contains (* "contains" *) %token <Region.t> Contains (* "contains" *)

View File

@ -21,32 +21,32 @@ open AST
(* RULES *) (* RULES *)
(* The rule [series(Item)] parses a list of [Item] separated by (* The rule [series(Item,TERM)] parses a list of [Item] separated by
semi-colons and optionally terminated by a semi-colon, then the semicolons and optionally terminated by a semicolon, then the
keyword [End]. *) terminal TERM. *)
series(Item): series(Item,TERM):
Item after_item(Item) { $1,$2 } Item after_item(Item,TERM) { $1,$2 }
after_item(Item): after_item(Item,TERM):
SEMI item_or_end(Item) { SEMI item_or_closing(Item,TERM) {
match $2 with match $2 with
`Some (item, items, term, close) -> `Some (item, items, term, closing) ->
($1, item)::items, term, close ($1, item)::items, term, closing
| `End close -> | `Closing closing ->
[], Some $1, close [], Some $1, closing
} }
| End { | TERM {
[], None, $1 [], None, $1
} }
item_or_end(Item): item_or_closing(Item,TERM):
End { TERM {
`End $1 `Closing $1
} }
| series(Item) { | series(Item,TERM) {
let item, (items, term, close) = $1 let item, (items, term, closing) = $1
in `Some (item, items, term, close) in `Some (item, items, term, closing)
} }
(* Compound constructs *) (* Compound constructs *)
@ -198,14 +198,14 @@ variant:
} }
record_type: record_type:
Record series(field_decl) { Record series(field_decl,End) {
let first, (others, terminator, close) = $2 in let first, (others, terminator, closing) = $2 in
let region = cover $1 close let region = cover $1 closing
and value = { and value = {
opening = $1; opening = $1;
field_decls = first, others; field_decls = first, others;
terminator; terminator;
close} closing}
in {region; value} in {region; value}
} }
@ -356,14 +356,24 @@ core_param_type:
} }
block: block:
Begin series(instruction) { Begin series(instruction,End) {
let first, (others, terminator, close) = $2 in let first, (others, terminator, closing) = $2 in
let region = cover $1 close let region = cover $1 closing
and value = { and value = {
opening = $1; opening = Begin $1;
instr = first, others; instr = first, others;
terminator; terminator;
close} closing = End closing}
in {region; value}
}
| Block LBRACE series(instruction,RBRACE) {
let first, (others, terminator, closing) = $3 in
let region = cover $1 closing
and value = {
opening = Block ($1,$2);
instr = first, others;
terminator;
closing = Block closing}
in {region; value} in {region; value}
} }
@ -449,10 +459,9 @@ extended_expr:
| 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} }
instruction: instruction:
single_instr { Single $1 } single_instr { Single $1 }
| block { Block $1 } | block { Block $1 : instruction }
single_instr: single_instr:
conditional { Cond $1 } conditional { Cond $1 }
@ -515,26 +524,26 @@ map_patch:
} }
set_injection: set_injection:
Set series(expr) { Set series(expr,End) {
let first, (others, terminator, close) = $2 in let first, (others, terminator, closing) = $2 in
let region = cover $1 close let region = cover $1 closing
and value = { and value = {
opening = $1; opening = $1;
elements = first, others; elements = first, others;
terminator; terminator;
close} closing}
in {region; value} in {region; value}
} }
map_injection: map_injection:
Map series(binding) { Map series(binding,End) {
let first, (others, terminator, close) = $2 in let first, (others, terminator, closing) = $2 in
let region = cover $1 close let region = cover $1 closing
and value = { and value = {
opening = $1; opening = $1;
bindings = first, others; bindings = first, others;
terminator; terminator;
close} closing}
in {region; value} in {region; value}
} }
@ -885,14 +894,14 @@ record_expr:
| record_projection { RecordProj $1 } | record_projection { RecordProj $1 }
record_injection: record_injection:
Record series(field_assignment) { Record series(field_assignment,End) {
let first, (others, terminator, close) = $2 in let first, (others, terminator, closing) = $2 in
let region = cover $1 close let region = cover $1 closing
and value = { and value = {
opening = $1; opening = $1;
fields = first, others; fields = first, others;
terminator; terminator;
close} closing}
in {region; value} in {region; value}
} }

View File

@ -11,7 +11,7 @@ entrypoint contribute (storage store : store;
const amount : mutez) const amount : mutez)
: store * list (operation) is : store * list (operation) is
var operations : list (operation) := [] var operations : list (operation) := []
begin block {
if now > store.deadline then if now > store.deadline then
fail "Deadline passed"; fail "Deadline passed";
else else
@ -20,14 +20,14 @@ entrypoint contribute (storage store : store;
// None -> patch store.backers with map sender -> amount end // None -> patch store.backers with map sender -> amount end
| _ -> skip | _ -> skip
end end
end with (store, operations) } with (store, operations)
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) := []
begin begin
if sender = owner then if sender = owner then
if now >= store.deadline then if now (Unit) >= store.deadline then
if balance >= store.goal then if balance >= store.goal then
begin begin
store.funded := True; store.funded := True;