2019-05-13 00:56:22 +04:00
|
|
|
%{
|
|
|
|
(* START HEADER *)
|
|
|
|
|
|
|
|
[@@@warning "-42"]
|
|
|
|
|
|
|
|
open Region
|
|
|
|
open AST
|
|
|
|
|
|
|
|
(* END HEADER *)
|
|
|
|
%}
|
|
|
|
|
|
|
|
(* See [ParToken.mly] for the definition of tokens. *)
|
|
|
|
|
|
|
|
(* Entry points *)
|
|
|
|
|
|
|
|
%start contract interactive_expr
|
|
|
|
%type <AST.t> contract
|
|
|
|
%type <AST.expr> interactive_expr
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
|
|
(* RULES *)
|
|
|
|
|
2019-07-25 18:11:33 +04:00
|
|
|
(* The rule [sep_or_term(item,sep)] ("separated or terminated list")
|
|
|
|
parses a non-empty list of items separated by [sep], and optionally
|
|
|
|
terminated by [sep]. *)
|
2019-05-13 00:56:22 +04:00
|
|
|
|
2019-07-25 18:11:33 +04:00
|
|
|
sep_or_term_list(item,sep):
|
|
|
|
nsepseq(item,sep) {
|
|
|
|
$1, None
|
2019-05-13 00:56:22 +04:00
|
|
|
}
|
2019-07-25 18:11:33 +04:00
|
|
|
| nseq(item sep {$1,$2}) {
|
|
|
|
let (first,sep), tail = $1 in
|
|
|
|
let rec trans (seq, prev_sep as acc) = function
|
|
|
|
[] -> acc
|
|
|
|
| (item,next_sep)::others ->
|
|
|
|
trans ((prev_sep,item)::seq, next_sep) others in
|
|
|
|
let list, term = trans ([],sep) tail
|
|
|
|
in (first, List.rev list), Some term }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
(* Compound constructs *)
|
|
|
|
|
|
|
|
par(X):
|
|
|
|
LPAR X RPAR {
|
|
|
|
let region = cover $1 $3
|
|
|
|
and value = {
|
|
|
|
lpar = $1;
|
|
|
|
inside = $2;
|
|
|
|
rpar = $3}
|
|
|
|
in {region; value}
|
|
|
|
}
|
|
|
|
|
|
|
|
brackets(X):
|
|
|
|
LBRACKET X RBRACKET {
|
|
|
|
let region = cover $1 $3
|
|
|
|
and value = {
|
|
|
|
lbracket = $1;
|
|
|
|
inside = $2;
|
|
|
|
rbracket = $3}
|
|
|
|
in {region; value}
|
|
|
|
}
|
|
|
|
|
|
|
|
(* Sequences
|
|
|
|
|
|
|
|
Series of instances of the same syntactical category have often to
|
|
|
|
be parsed, like lists of expressions, patterns etc. The simplest of
|
|
|
|
all is the possibly empty sequence (series), parsed below by
|
|
|
|
[seq]. The non-empty sequence is parsed by [nseq]. Note that the
|
|
|
|
latter returns a pair made of the first parsed item (the parameter
|
|
|
|
[X]) and the rest of the sequence (possibly empty). This way, the
|
|
|
|
OCaml typechecker can keep track of this information along the
|
|
|
|
static control-flow graph. The rule [sepseq] parses possibly empty
|
|
|
|
sequences of items separated by some token (e.g., a comma), and
|
|
|
|
rule [nsepseq] is for non-empty such sequences. See module [Utils]
|
|
|
|
for the types corresponding to the semantic actions of those rules.
|
|
|
|
*)
|
|
|
|
|
|
|
|
(* Possibly empty sequence of items *)
|
|
|
|
|
|
|
|
seq(X):
|
|
|
|
(**) { [] }
|
|
|
|
| X seq(X) { $1::$2 }
|
|
|
|
|
|
|
|
(* Non-empty sequence of items *)
|
|
|
|
|
|
|
|
nseq(X):
|
|
|
|
X seq(X) { $1,$2 }
|
|
|
|
|
|
|
|
(* Non-empty separated sequence of items *)
|
|
|
|
|
|
|
|
nsepseq(X,Sep):
|
|
|
|
X { $1, [] }
|
|
|
|
| X Sep nsepseq(X,Sep) { let h,t = $3 in $1, ($2,h)::t }
|
|
|
|
|
|
|
|
(* Possibly empy separated sequence of items *)
|
|
|
|
|
|
|
|
sepseq(X,Sep):
|
|
|
|
(**) { None }
|
|
|
|
| nsepseq(X,Sep) { Some $1 }
|
|
|
|
|
|
|
|
(* Inlines *)
|
|
|
|
|
|
|
|
%inline var : Ident { $1 }
|
|
|
|
%inline type_name : Ident { $1 }
|
|
|
|
%inline fun_name : Ident { $1 }
|
|
|
|
%inline field_name : Ident { $1 }
|
|
|
|
%inline struct_name : Ident { $1 }
|
|
|
|
|
|
|
|
(* Main *)
|
|
|
|
|
|
|
|
contract:
|
|
|
|
nseq(declaration) EOF {
|
|
|
|
{decl = $1; eof = $2}
|
|
|
|
}
|
|
|
|
|
|
|
|
declaration:
|
2019-10-16 17:39:08 +04:00
|
|
|
type_decl { TypeDecl $1 }
|
|
|
|
| const_decl { ConstDecl $1 }
|
|
|
|
| fun_decl { FunDecl $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
(* Type declarations *)
|
|
|
|
|
|
|
|
type_decl:
|
|
|
|
Type type_name Is type_expr option(SEMI) {
|
|
|
|
let stop =
|
|
|
|
match $5 with
|
|
|
|
Some region -> region
|
|
|
|
| None -> type_expr_to_region $4 in
|
|
|
|
let region = cover $1 stop in
|
|
|
|
let value = {
|
|
|
|
kwd_type = $1;
|
|
|
|
name = $2;
|
|
|
|
kwd_is = $3;
|
|
|
|
type_expr = $4;
|
|
|
|
terminator = $5}
|
2019-09-27 17:33:25 +04:00
|
|
|
in {region; value}
|
|
|
|
}
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
type_expr:
|
2019-10-15 23:03:46 +04:00
|
|
|
sum_type { TSum $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
| record_type { TRecord $1 }
|
2019-10-15 23:03:46 +04:00
|
|
|
| cartesian { $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
cartesian:
|
2019-10-15 23:03:46 +04:00
|
|
|
function_type TIMES nsepseq(function_type,TIMES) {
|
|
|
|
let value = Utils.nsepseq_cons $1 $2 $3 in
|
|
|
|
let region = nsepseq_to_region type_expr_to_region value
|
|
|
|
in TProd {region; value}
|
|
|
|
}
|
|
|
|
| function_type { ($1 : type_expr) }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
function_type:
|
|
|
|
core_type {
|
|
|
|
$1
|
|
|
|
}
|
|
|
|
| core_type ARROW function_type {
|
2019-10-15 23:03:46 +04:00
|
|
|
let start = type_expr_to_region $1
|
|
|
|
and stop = type_expr_to_region $3 in
|
|
|
|
let region = cover start stop in
|
|
|
|
TFun {region; value = $1,$2,$3} }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
core_type:
|
|
|
|
type_name {
|
2019-11-06 20:23:49 +04:00
|
|
|
TVar $1
|
2019-05-13 00:56:22 +04:00
|
|
|
}
|
|
|
|
| type_name type_tuple {
|
|
|
|
let region = cover $1.region $2.region
|
|
|
|
in TApp {region; value = $1,$2}
|
|
|
|
}
|
|
|
|
| Map type_tuple {
|
|
|
|
let region = cover $1 $2.region in
|
|
|
|
let type_constr = {value="map"; region=$1}
|
|
|
|
in TApp {region; value = type_constr, $2}
|
|
|
|
}
|
2019-10-08 14:22:22 +04:00
|
|
|
| BigMap type_tuple {
|
|
|
|
let region = cover $1 $2.region in
|
|
|
|
let type_constr = {value="big_map"; region=$1}
|
|
|
|
in TApp {region; value = type_constr, $2}
|
|
|
|
}
|
2019-05-13 00:56:22 +04:00
|
|
|
| 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}
|
|
|
|
}
|
|
|
|
| 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}
|
|
|
|
|
|
|
|
type_tuple:
|
|
|
|
par(nsepseq(type_expr,COMMA)) { $1 }
|
|
|
|
|
|
|
|
sum_type:
|
|
|
|
option(VBAR) nsepseq(variant,VBAR) {
|
|
|
|
let region = nsepseq_to_region (fun x -> x.region) $2
|
2019-11-06 20:23:49 +04:00
|
|
|
in {region; value=$2} }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
variant:
|
|
|
|
Constr Of cartesian {
|
2019-10-15 23:03:46 +04:00
|
|
|
let region = cover $1.region (type_expr_to_region $3)
|
2019-11-06 20:23:49 +04:00
|
|
|
and value = {constr = $1; arg = Some ($2, $3)}
|
2019-05-17 18:29:22 +04:00
|
|
|
in {region; value}
|
|
|
|
}
|
|
|
|
| Constr {
|
2019-11-06 20:23:49 +04:00
|
|
|
{region=$1.region; value= {constr=$1; arg=None}} }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
record_type:
|
2019-07-25 18:11:33 +04:00
|
|
|
Record sep_or_term_list(field_decl,SEMI) End {
|
2019-10-23 02:35:29 +04:00
|
|
|
let ne_elements, terminator = $2 in
|
2019-07-25 18:11:33 +04:00
|
|
|
let region = cover $1 $3
|
2019-10-23 02:35:29 +04:00
|
|
|
and value = {
|
2019-05-13 00:56:22 +04:00
|
|
|
opening = Kwd $1;
|
2019-10-23 02:35:29 +04:00
|
|
|
ne_elements;
|
2019-05-13 00:56:22 +04:00
|
|
|
terminator;
|
2019-07-25 18:11:33 +04:00
|
|
|
closing = End $3}
|
2019-05-13 00:56:22 +04:00
|
|
|
in {region; value}
|
|
|
|
}
|
2019-07-25 18:11:33 +04:00
|
|
|
| Record LBRACKET sep_or_term_list(field_decl,SEMI) RBRACKET {
|
2019-10-23 02:35:29 +04:00
|
|
|
let ne_elements, terminator = $3 in
|
2019-07-25 18:11:33 +04:00
|
|
|
let region = cover $1 $4
|
2019-10-23 02:35:29 +04:00
|
|
|
and value = {
|
2019-05-13 00:56:22 +04:00
|
|
|
opening = KwdBracket ($1,$2);
|
2019-10-23 02:35:29 +04:00
|
|
|
ne_elements;
|
2019-05-13 00:56:22 +04:00
|
|
|
terminator;
|
2019-07-25 18:11:33 +04:00
|
|
|
closing = RBracket $4}
|
2019-05-13 00:56:22 +04:00
|
|
|
in {region; value} }
|
|
|
|
|
|
|
|
field_decl:
|
|
|
|
field_name COLON type_expr {
|
|
|
|
let stop = type_expr_to_region $3 in
|
|
|
|
let region = cover $1.region stop
|
|
|
|
and value = {field_name = $1; colon = $2; field_type = $3}
|
|
|
|
in {region; value} }
|
|
|
|
|
2019-11-18 19:10:48 +04:00
|
|
|
fun_expr:
|
|
|
|
Function option(fun_name) parameters COLON type_expr Is
|
2019-05-13 00:56:22 +04:00
|
|
|
block
|
2019-11-18 19:10:48 +04:00
|
|
|
With expr {
|
|
|
|
let stop = expr_to_region $9 in
|
2019-05-13 00:56:22 +04:00
|
|
|
let region = cover $1 stop
|
|
|
|
and value = {
|
|
|
|
kwd_function = $1;
|
|
|
|
name = $2;
|
|
|
|
param = $3;
|
|
|
|
colon = $4;
|
|
|
|
ret_type = $5;
|
|
|
|
kwd_is = $6;
|
Refactoring of comments (for [dune build @doc]).
Refactoring of parsing command-line arguments
* The type [options] is now abstract and implemented as an
object type to avoid struggling with scoping and type
inference when record types share some common field names.
Refactoring of ParserLog for PascaLIGO and CameLIGO
* The immediate motivation behind that refactoring was to
remove the use of a couple of global references. A
consequence is that we have a nicer and more compact code, by
threading a state. The files [pascaligo/Tests/pp.ligo] and
[ligodity/Tests/pp.mligo].
* Another consequence is that the choice of making strings from
AST nodes depends on the CLI (offsets? mode?). After this
refactoring, that choice is hardcoded in the simplifiers in a
few places (TODO), waiting for a general solution that would
have all CL options flow through the compiler.
* I removed the use of vendors [x_option.ml], [x_map.ml] and
[x_list.ml] when handling optional values. (Less dependencies
this way.)
Refactoring of the ASTs
* I removed the node [local_decl], which was set to [[]]
already in a previous commit (which removed local
declarations as being redundant, as statements could already
be instructions or declarations).
* I changed [StrLit] to [String] in the AST of CameLIGO and
ReasonLIGO.
* I also changed the type [fun_expr] so now either a block is
present, and therefore followed by the [with] keyword, or it
is not. (Before, the presence of a block was not enforced in
the type with the presence of the keyword.)
Notes
* [LexerMain.ml] and [ParserMain.ml] for CameLIGO and PascaLIGO
are almost identical and differ in the same way (language
name and file extension), which suggests that they should be
in the [shared] folder and instanciated as a functor in the
future (TODO).
* I removed the blank characters at the end of many lines in
the parser of ReasonLIGO.
2019-12-13 15:21:52 +04:00
|
|
|
block_with = Some ($7, $8);
|
|
|
|
return = $9}
|
|
|
|
in {region;value} }
|
2019-11-18 19:10:48 +04:00
|
|
|
| Function option(fun_name) parameters COLON type_expr Is
|
|
|
|
expr {
|
|
|
|
let stop = expr_to_region $7 in
|
2019-10-18 07:50:41 +04:00
|
|
|
let region = cover $1 stop
|
|
|
|
and value = {
|
|
|
|
kwd_function = $1;
|
|
|
|
name = $2;
|
|
|
|
param = $3;
|
|
|
|
colon = $4;
|
|
|
|
ret_type = $5;
|
|
|
|
kwd_is = $6;
|
Refactoring of comments (for [dune build @doc]).
Refactoring of parsing command-line arguments
* The type [options] is now abstract and implemented as an
object type to avoid struggling with scoping and type
inference when record types share some common field names.
Refactoring of ParserLog for PascaLIGO and CameLIGO
* The immediate motivation behind that refactoring was to
remove the use of a couple of global references. A
consequence is that we have a nicer and more compact code, by
threading a state. The files [pascaligo/Tests/pp.ligo] and
[ligodity/Tests/pp.mligo].
* Another consequence is that the choice of making strings from
AST nodes depends on the CLI (offsets? mode?). After this
refactoring, that choice is hardcoded in the simplifiers in a
few places (TODO), waiting for a general solution that would
have all CL options flow through the compiler.
* I removed the use of vendors [x_option.ml], [x_map.ml] and
[x_list.ml] when handling optional values. (Less dependencies
this way.)
Refactoring of the ASTs
* I removed the node [local_decl], which was set to [[]]
already in a previous commit (which removed local
declarations as being redundant, as statements could already
be instructions or declarations).
* I changed [StrLit] to [String] in the AST of CameLIGO and
ReasonLIGO.
* I also changed the type [fun_expr] so now either a block is
present, and therefore followed by the [with] keyword, or it
is not. (Before, the presence of a block was not enforced in
the type with the presence of the keyword.)
Notes
* [LexerMain.ml] and [ParserMain.ml] for CameLIGO and PascaLIGO
are almost identical and differ in the same way (language
name and file extension), which suggests that they should be
in the [shared] folder and instanciated as a functor in the
future (TODO).
* I removed the blank characters at the end of many lines in
the parser of ReasonLIGO.
2019-12-13 15:21:52 +04:00
|
|
|
block_with = None;
|
|
|
|
return = $7}
|
2019-10-19 21:46:24 +04:00
|
|
|
in {region;value}}
|
2019-05-13 00:56:22 +04:00
|
|
|
|
2019-11-18 19:10:48 +04:00
|
|
|
|
|
|
|
|
|
|
|
(* Function declarations *)
|
|
|
|
|
|
|
|
fun_decl:
|
|
|
|
fun_expr option(SEMI) {
|
|
|
|
let stop =
|
|
|
|
match $2 with
|
|
|
|
Some region -> region
|
|
|
|
| None -> $1.region in
|
|
|
|
let region = cover $1.region stop
|
|
|
|
and value = {
|
Refactoring of comments (for [dune build @doc]).
Refactoring of parsing command-line arguments
* The type [options] is now abstract and implemented as an
object type to avoid struggling with scoping and type
inference when record types share some common field names.
Refactoring of ParserLog for PascaLIGO and CameLIGO
* The immediate motivation behind that refactoring was to
remove the use of a couple of global references. A
consequence is that we have a nicer and more compact code, by
threading a state. The files [pascaligo/Tests/pp.ligo] and
[ligodity/Tests/pp.mligo].
* Another consequence is that the choice of making strings from
AST nodes depends on the CLI (offsets? mode?). After this
refactoring, that choice is hardcoded in the simplifiers in a
few places (TODO), waiting for a general solution that would
have all CL options flow through the compiler.
* I removed the use of vendors [x_option.ml], [x_map.ml] and
[x_list.ml] when handling optional values. (Less dependencies
this way.)
Refactoring of the ASTs
* I removed the node [local_decl], which was set to [[]]
already in a previous commit (which removed local
declarations as being redundant, as statements could already
be instructions or declarations).
* I changed [StrLit] to [String] in the AST of CameLIGO and
ReasonLIGO.
* I also changed the type [fun_expr] so now either a block is
present, and therefore followed by the [with] keyword, or it
is not. (Before, the presence of a block was not enforced in
the type with the presence of the keyword.)
Notes
* [LexerMain.ml] and [ParserMain.ml] for CameLIGO and PascaLIGO
are almost identical and differ in the same way (language
name and file extension), which suggests that they should be
in the [shared] folder and instanciated as a functor in the
future (TODO).
* I removed the blank characters at the end of many lines in
the parser of ReasonLIGO.
2019-12-13 15:21:52 +04:00
|
|
|
fun_expr = $1;
|
|
|
|
terminator = $2}
|
|
|
|
in {region; value} }
|
2019-11-18 19:10:48 +04:00
|
|
|
|
|
|
|
open_fun_decl:
|
|
|
|
fun_expr {
|
|
|
|
let region = $1.region
|
|
|
|
and value = {
|
Refactoring of comments (for [dune build @doc]).
Refactoring of parsing command-line arguments
* The type [options] is now abstract and implemented as an
object type to avoid struggling with scoping and type
inference when record types share some common field names.
Refactoring of ParserLog for PascaLIGO and CameLIGO
* The immediate motivation behind that refactoring was to
remove the use of a couple of global references. A
consequence is that we have a nicer and more compact code, by
threading a state. The files [pascaligo/Tests/pp.ligo] and
[ligodity/Tests/pp.mligo].
* Another consequence is that the choice of making strings from
AST nodes depends on the CLI (offsets? mode?). After this
refactoring, that choice is hardcoded in the simplifiers in a
few places (TODO), waiting for a general solution that would
have all CL options flow through the compiler.
* I removed the use of vendors [x_option.ml], [x_map.ml] and
[x_list.ml] when handling optional values. (Less dependencies
this way.)
Refactoring of the ASTs
* I removed the node [local_decl], which was set to [[]]
already in a previous commit (which removed local
declarations as being redundant, as statements could already
be instructions or declarations).
* I changed [StrLit] to [String] in the AST of CameLIGO and
ReasonLIGO.
* I also changed the type [fun_expr] so now either a block is
present, and therefore followed by the [with] keyword, or it
is not. (Before, the presence of a block was not enforced in
the type with the presence of the keyword.)
Notes
* [LexerMain.ml] and [ParserMain.ml] for CameLIGO and PascaLIGO
are almost identical and differ in the same way (language
name and file extension), which suggests that they should be
in the [shared] folder and instanciated as a functor in the
future (TODO).
* I removed the blank characters at the end of many lines in
the parser of ReasonLIGO.
2019-12-13 15:21:52 +04:00
|
|
|
fun_expr = $1;
|
|
|
|
terminator = None}
|
|
|
|
in {region; value} }
|
2019-11-18 19:10:48 +04:00
|
|
|
|
2019-05-13 00:56:22 +04:00
|
|
|
parameters:
|
|
|
|
par(nsepseq(param_decl,SEMI)) { $1 }
|
|
|
|
|
|
|
|
param_decl:
|
|
|
|
Var var COLON param_type {
|
|
|
|
let stop = type_expr_to_region $4 in
|
|
|
|
let region = cover $1 stop
|
|
|
|
and value = {
|
|
|
|
kwd_var = $1;
|
|
|
|
var = $2;
|
|
|
|
colon = $3;
|
|
|
|
param_type = $4}
|
|
|
|
in ParamVar {region; value}
|
|
|
|
}
|
|
|
|
| Const var COLON param_type {
|
|
|
|
let stop = type_expr_to_region $4 in
|
|
|
|
let region = cover $1 stop
|
|
|
|
and value = {
|
|
|
|
kwd_const = $1;
|
|
|
|
var = $2;
|
|
|
|
colon = $3;
|
|
|
|
param_type = $4}
|
|
|
|
in ParamConst {region; value}}
|
|
|
|
|
|
|
|
param_type:
|
2019-10-15 23:03:46 +04:00
|
|
|
cartesian { $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
block:
|
2019-07-25 18:11:33 +04:00
|
|
|
Begin sep_or_term_list(statement,SEMI) End {
|
|
|
|
let statements, terminator = $2 in
|
|
|
|
let region = cover $1 $3
|
2019-05-13 00:56:22 +04:00
|
|
|
and value = {
|
|
|
|
opening = Begin $1;
|
2019-07-25 18:11:33 +04:00
|
|
|
statements;
|
2019-05-13 00:56:22 +04:00
|
|
|
terminator;
|
2019-07-25 18:11:33 +04:00
|
|
|
closing = End $3}
|
2019-05-13 00:56:22 +04:00
|
|
|
in {region; value}
|
|
|
|
}
|
2019-07-25 18:11:33 +04:00
|
|
|
| Block LBRACE sep_or_term_list(statement,SEMI) RBRACE {
|
|
|
|
let statements, terminator = $3 in
|
|
|
|
let region = cover $1 $4
|
2019-05-13 00:56:22 +04:00
|
|
|
and value = {
|
|
|
|
opening = Block ($1,$2);
|
2019-07-25 18:11:33 +04:00
|
|
|
statements;
|
2019-05-13 00:56:22 +04:00
|
|
|
terminator;
|
2019-07-25 18:11:33 +04:00
|
|
|
closing = Block $4}
|
2019-05-13 00:56:22 +04:00
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
statement:
|
|
|
|
instruction { Instr $1 }
|
|
|
|
| open_data_decl { Data $1 }
|
|
|
|
|
|
|
|
open_data_decl:
|
|
|
|
open_const_decl { LocalConst $1 }
|
|
|
|
| open_var_decl { LocalVar $1 }
|
2019-11-18 19:10:48 +04:00
|
|
|
| open_fun_decl { LocalFun $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
open_const_decl:
|
2019-10-13 21:51:01 +04:00
|
|
|
Const unqualified_decl(EQ) {
|
2019-05-13 00:56:22 +04:00
|
|
|
let name, colon, const_type, equal, init, stop = $2 in
|
|
|
|
let region = cover $1 stop
|
|
|
|
and value = {
|
|
|
|
kwd_const = $1;
|
|
|
|
name;
|
|
|
|
colon;
|
|
|
|
const_type;
|
|
|
|
equal;
|
|
|
|
init;
|
|
|
|
terminator = None}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
open_var_decl:
|
|
|
|
Var unqualified_decl(ASS) {
|
|
|
|
let name, colon, var_type, assign, init, stop = $2 in
|
|
|
|
let region = cover $1 stop
|
|
|
|
and value = {
|
|
|
|
kwd_var = $1;
|
|
|
|
name;
|
|
|
|
colon;
|
|
|
|
var_type;
|
|
|
|
assign;
|
|
|
|
init;
|
|
|
|
terminator = None}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
unqualified_decl(OP):
|
2019-07-30 13:27:32 +04:00
|
|
|
var COLON type_expr OP expr {
|
|
|
|
let region = expr_to_region $5
|
|
|
|
in $1, $2, $3, $4, $5, region}
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
const_decl:
|
|
|
|
open_const_decl SEMI {
|
|
|
|
let const_decl : AST.const_decl = $1.value in
|
|
|
|
{$1 with value = {const_decl with terminator = Some $2}}
|
|
|
|
}
|
|
|
|
| open_const_decl { $1 }
|
|
|
|
|
|
|
|
|
|
|
|
instruction:
|
|
|
|
conditional { Cond $1 }
|
|
|
|
| case_instr { CaseInstr $1 }
|
|
|
|
| assignment { Assign $1 }
|
|
|
|
| loop { Loop $1 }
|
|
|
|
| proc_call { ProcCall $1 }
|
|
|
|
| Skip { Skip $1 }
|
|
|
|
| record_patch { RecordPatch $1 }
|
|
|
|
| map_patch { MapPatch $1 }
|
|
|
|
| set_patch { SetPatch $1 }
|
|
|
|
| map_remove { MapRemove $1 }
|
|
|
|
| set_remove { SetRemove $1 }
|
|
|
|
|
|
|
|
set_remove:
|
|
|
|
Remove expr From Set path {
|
|
|
|
let region = cover $1 (path_to_region $5) in
|
|
|
|
let value = {
|
|
|
|
kwd_remove = $1;
|
|
|
|
element = $2;
|
|
|
|
kwd_from = $3;
|
|
|
|
kwd_set = $4;
|
|
|
|
set = $5}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
map_remove:
|
|
|
|
Remove expr From Map path {
|
|
|
|
let region = cover $1 (path_to_region $5) in
|
|
|
|
let value = {
|
|
|
|
kwd_remove = $1;
|
|
|
|
key = $2;
|
|
|
|
kwd_from = $3;
|
|
|
|
kwd_map = $4;
|
|
|
|
map = $5}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
set_patch:
|
2019-10-23 02:35:29 +04:00
|
|
|
Patch path With ne_injection(Set,expr) {
|
2019-05-13 00:56:22 +04:00
|
|
|
let region = cover $1 $4.region in
|
|
|
|
let value = {
|
|
|
|
kwd_patch = $1;
|
|
|
|
path = $2;
|
|
|
|
kwd_with = $3;
|
|
|
|
set_inj = $4}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
map_patch:
|
2019-10-23 02:35:29 +04:00
|
|
|
Patch path With ne_injection(Map,binding) {
|
2019-05-13 00:56:22 +04:00
|
|
|
let region = cover $1 $4.region in
|
|
|
|
let value = {
|
|
|
|
kwd_patch = $1;
|
|
|
|
path = $2;
|
|
|
|
kwd_with = $3;
|
|
|
|
map_inj = $4}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
injection(Kind,element):
|
2019-07-25 18:11:33 +04:00
|
|
|
Kind sep_or_term_list(element,SEMI) End {
|
|
|
|
let elements, terminator = $2 in
|
|
|
|
let region = cover $1 $3
|
2019-05-13 00:56:22 +04:00
|
|
|
and value = {
|
|
|
|
opening = Kwd $1;
|
2019-07-25 18:11:33 +04:00
|
|
|
elements = Some elements;
|
2019-05-13 00:56:22 +04:00
|
|
|
terminator;
|
2019-07-25 18:11:33 +04:00
|
|
|
closing = End $3}
|
2019-05-13 00:56:22 +04:00
|
|
|
in {region; value}
|
|
|
|
}
|
|
|
|
| Kind End {
|
|
|
|
let region = cover $1 $2
|
|
|
|
and value = {
|
|
|
|
opening = Kwd $1;
|
|
|
|
elements = None;
|
|
|
|
terminator = None;
|
|
|
|
closing = End $2}
|
|
|
|
in {region; value}
|
|
|
|
}
|
2019-07-25 18:11:33 +04:00
|
|
|
| Kind LBRACKET sep_or_term_list(element,SEMI) RBRACKET {
|
|
|
|
let elements, terminator = $3 in
|
|
|
|
let region = cover $1 $4
|
2019-05-13 00:56:22 +04:00
|
|
|
and value = {
|
|
|
|
opening = KwdBracket ($1,$2);
|
2019-07-25 18:11:33 +04:00
|
|
|
elements = Some elements;
|
2019-05-13 00:56:22 +04:00
|
|
|
terminator;
|
2019-07-25 18:11:33 +04:00
|
|
|
closing = RBracket $4}
|
2019-05-13 00:56:22 +04:00
|
|
|
in {region; value}
|
|
|
|
}
|
|
|
|
| Kind LBRACKET RBRACKET {
|
|
|
|
let region = cover $1 $3
|
|
|
|
and value = {
|
|
|
|
opening = KwdBracket ($1,$2);
|
|
|
|
elements = None;
|
|
|
|
terminator = None;
|
|
|
|
closing = RBracket $3}
|
|
|
|
in {region; value}}
|
|
|
|
|
2019-10-23 02:35:29 +04:00
|
|
|
ne_injection(Kind,element):
|
|
|
|
Kind sep_or_term_list(element,SEMI) End {
|
|
|
|
let ne_elements, terminator = $2 in
|
|
|
|
let region = cover $1 $3
|
|
|
|
and value = {
|
|
|
|
opening = Kwd $1;
|
|
|
|
ne_elements;
|
|
|
|
terminator;
|
|
|
|
closing = End $3}
|
|
|
|
in {region; value}
|
|
|
|
}
|
|
|
|
| Kind LBRACKET sep_or_term_list(element,SEMI) RBRACKET {
|
|
|
|
let ne_elements, terminator = $3 in
|
|
|
|
let region = cover $1 $4
|
|
|
|
and value = {
|
|
|
|
opening = KwdBracket ($1,$2);
|
|
|
|
ne_elements;
|
|
|
|
terminator;
|
|
|
|
closing = RBracket $4}
|
|
|
|
in {region; value}
|
|
|
|
}
|
|
|
|
|
2019-05-13 00:56:22 +04:00
|
|
|
binding:
|
|
|
|
expr ARROW expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {
|
|
|
|
source = $1;
|
|
|
|
arrow = $2;
|
|
|
|
image = $3}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
record_patch:
|
2019-10-23 02:35:29 +04:00
|
|
|
Patch path With ne_injection(Record,field_assignment) {
|
2019-05-13 00:56:22 +04:00
|
|
|
let region = cover $1 $4.region in
|
|
|
|
let value = {
|
|
|
|
kwd_patch = $1;
|
|
|
|
path = $2;
|
|
|
|
kwd_with = $3;
|
|
|
|
record_inj = $4}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
proc_call:
|
|
|
|
fun_call { $1 }
|
|
|
|
|
|
|
|
conditional:
|
|
|
|
If expr Then if_clause option(SEMI) Else if_clause {
|
|
|
|
let region = cover $1 (if_clause_to_region $7) in
|
2019-10-18 15:41:02 +04:00
|
|
|
let value : conditional = {
|
2019-05-13 00:56:22 +04:00
|
|
|
kwd_if = $1;
|
|
|
|
test = $2;
|
|
|
|
kwd_then = $3;
|
|
|
|
ifso = $4;
|
|
|
|
terminator = $5;
|
|
|
|
kwd_else = $6;
|
|
|
|
ifnot = $7}
|
|
|
|
in {region; value} }
|
|
|
|
|
|
|
|
if_clause:
|
2019-10-17 20:33:58 +04:00
|
|
|
instruction { ClauseInstr $1 }
|
|
|
|
| clause_block { ClauseBlock $1 }
|
|
|
|
|
|
|
|
clause_block:
|
|
|
|
block {
|
|
|
|
LongBlock $1 }
|
2019-07-30 13:27:32 +04:00
|
|
|
| LBRACE sep_or_term_list(statement,SEMI) RBRACE {
|
2019-10-17 20:33:58 +04:00
|
|
|
let region = cover $1 $3 in
|
|
|
|
let value = {
|
|
|
|
lbrace = $1;
|
|
|
|
inside = $2;
|
|
|
|
rbrace = $3} in
|
|
|
|
ShortBlock {value; region} }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
case_instr:
|
2019-10-24 11:58:33 +04:00
|
|
|
case(if_clause) { $1 if_clause_to_region }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
case(rhs):
|
|
|
|
Case expr Of option(VBAR) cases(rhs) End {
|
|
|
|
fun rhs_to_region ->
|
|
|
|
let region = cover $1 $6 in
|
|
|
|
let value = {
|
|
|
|
kwd_case = $1;
|
|
|
|
expr = $2;
|
|
|
|
opening = Kwd $3;
|
|
|
|
lead_vbar = $4;
|
|
|
|
cases = $5 rhs_to_region;
|
|
|
|
closing = End $6}
|
|
|
|
in {region; value}
|
|
|
|
}
|
|
|
|
| Case expr Of LBRACKET option(VBAR) cases(rhs) RBRACKET {
|
|
|
|
fun rhs_to_region ->
|
|
|
|
let region = cover $1 $7 in
|
|
|
|
let value = {
|
|
|
|
kwd_case = $1;
|
|
|
|
expr = $2;
|
|
|
|
opening = KwdBracket ($3,$4);
|
|
|
|
lead_vbar = $5;
|
|
|
|
cases = $6 rhs_to_region;
|
|
|
|
closing = RBracket $7}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
cases(rhs):
|
|
|
|
nsepseq(case_clause(rhs),VBAR) {
|
|
|
|
fun rhs_to_region ->
|
|
|
|
let mk_clause pre_clause = pre_clause rhs_to_region in
|
|
|
|
let value = Utils.nsepseq_map mk_clause $1 in
|
|
|
|
let region = nsepseq_to_region (fun x -> x.region) value
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
case_clause(rhs):
|
|
|
|
pattern ARROW rhs {
|
|
|
|
fun rhs_to_region ->
|
|
|
|
let start = pattern_to_region $1 in
|
|
|
|
let region = cover start (rhs_to_region $3)
|
|
|
|
and value = {pattern=$1; arrow=$2; rhs=$3}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
assignment:
|
|
|
|
lhs ASS rhs {
|
|
|
|
let stop = rhs_to_region $3 in
|
|
|
|
let region = cover (lhs_to_region $1) stop
|
|
|
|
and value = {lhs = $1; assign = $2; rhs = $3}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
rhs:
|
2019-10-07 18:24:56 +04:00
|
|
|
expr { $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
lhs:
|
|
|
|
path { Path $1 }
|
|
|
|
| map_lookup { MapPath $1 }
|
|
|
|
|
|
|
|
loop:
|
|
|
|
while_loop { $1 }
|
|
|
|
| for_loop { $1 }
|
|
|
|
|
|
|
|
while_loop:
|
|
|
|
While expr block {
|
|
|
|
let region = cover $1 $3.region
|
|
|
|
and value = {
|
|
|
|
kwd_while = $1;
|
|
|
|
cond = $2;
|
|
|
|
block = $3}
|
|
|
|
in While {region; value}}
|
|
|
|
|
|
|
|
for_loop:
|
2019-10-13 21:51:01 +04:00
|
|
|
For var_assign To expr block {
|
|
|
|
let region = cover $1 $5.region in
|
2019-05-13 00:56:22 +04:00
|
|
|
let value = {
|
|
|
|
kwd_for = $1;
|
|
|
|
assign = $2;
|
2019-10-13 21:51:01 +04:00
|
|
|
kwd_to = $3;
|
|
|
|
bound = $4;
|
|
|
|
block = $5}
|
2019-05-13 00:56:22 +04:00
|
|
|
in For (ForInt {region; value})
|
|
|
|
}
|
2019-11-06 23:12:25 +04:00
|
|
|
| For var option(arrow_clause)
|
2019-10-16 03:11:54 +04:00
|
|
|
In collection expr block {
|
2019-11-06 23:12:25 +04:00
|
|
|
let region = cover $1 $7.region in
|
2019-05-13 00:56:22 +04:00
|
|
|
let value = {
|
2019-10-16 03:11:54 +04:00
|
|
|
kwd_for = $1;
|
|
|
|
var = $2;
|
|
|
|
bind_to = $3;
|
2019-11-06 23:12:25 +04:00
|
|
|
kwd_in = $4;
|
|
|
|
collection = $5;
|
|
|
|
expr = $6;
|
|
|
|
block = $7}
|
2019-05-13 00:56:22 +04:00
|
|
|
in For (ForCollect {region; value})}
|
|
|
|
|
2019-10-16 03:11:54 +04:00
|
|
|
collection:
|
|
|
|
Map { Map $1 }
|
|
|
|
| Set { Set $1 }
|
|
|
|
| List { List $1 }
|
|
|
|
|
2019-05-13 00:56:22 +04:00
|
|
|
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}}
|
|
|
|
|
|
|
|
arrow_clause:
|
|
|
|
ARROW var { $1,$2 }
|
|
|
|
|
|
|
|
(* Expressions *)
|
|
|
|
|
|
|
|
interactive_expr:
|
|
|
|
expr EOF { $1 }
|
|
|
|
|
|
|
|
expr:
|
|
|
|
case(expr) { ECase ($1 expr_to_region) }
|
2019-10-18 15:41:02 +04:00
|
|
|
| cond_expr { $1 }
|
2019-07-31 12:19:24 +04:00
|
|
|
| disj_expr { $1 }
|
2019-11-18 19:10:48 +04:00
|
|
|
| fun_expr { EFun $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
2019-10-18 15:41:02 +04:00
|
|
|
cond_expr:
|
|
|
|
If expr Then expr option(SEMI) Else expr {
|
|
|
|
let region = cover $1 (expr_to_region $7) in
|
|
|
|
let value : cond_expr = {
|
|
|
|
kwd_if = $1;
|
|
|
|
test = $2;
|
|
|
|
kwd_then = $3;
|
|
|
|
ifso = $4;
|
|
|
|
terminator = $5;
|
|
|
|
kwd_else = $6;
|
|
|
|
ifnot = $7}
|
|
|
|
in ECond {region; value} }
|
|
|
|
|
2019-05-13 00:56:22 +04:00
|
|
|
disj_expr:
|
|
|
|
disj_expr Or conj_expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
2019-10-18 15:41:02 +04:00
|
|
|
and value = {arg1=$1; op=$2; arg2=$3} in
|
2019-05-13 00:56:22 +04:00
|
|
|
ELogic (BoolExpr (Or {region; value}))
|
|
|
|
}
|
|
|
|
| conj_expr { $1 }
|
|
|
|
|
|
|
|
conj_expr:
|
|
|
|
conj_expr And set_membership {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
2019-10-18 15:41:02 +04:00
|
|
|
and value = {arg1=$1; op=$2; arg2=$3}
|
2019-05-13 00:56:22 +04:00
|
|
|
in ELogic (BoolExpr (And {region; value}))
|
|
|
|
}
|
|
|
|
| set_membership { $1 }
|
|
|
|
|
|
|
|
set_membership:
|
|
|
|
core_expr Contains set_membership {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop in
|
|
|
|
let value = {
|
|
|
|
set = $1;
|
|
|
|
kwd_contains = $2;
|
|
|
|
element = $3}
|
|
|
|
in ESet (SetMem {region; value})
|
|
|
|
}
|
|
|
|
| comp_expr { $1 }
|
|
|
|
|
|
|
|
comp_expr:
|
|
|
|
comp_expr LT cat_expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in ELogic (CompExpr (Lt {region; value}))
|
|
|
|
}
|
2019-10-13 21:51:01 +04:00
|
|
|
| comp_expr LE cat_expr {
|
2019-05-13 00:56:22 +04:00
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in ELogic (CompExpr (Leq {region; value}))
|
|
|
|
}
|
|
|
|
| comp_expr GT cat_expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in ELogic (CompExpr (Gt {region; value}))
|
|
|
|
}
|
2019-10-13 21:51:01 +04:00
|
|
|
| comp_expr GE cat_expr {
|
2019-05-13 00:56:22 +04:00
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in ELogic (CompExpr (Geq {region; value}))
|
|
|
|
}
|
2019-10-13 21:51:01 +04:00
|
|
|
| comp_expr EQ cat_expr {
|
2019-05-13 00:56:22 +04:00
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in ELogic (CompExpr (Equal {region; value}))
|
|
|
|
}
|
2019-10-13 21:51:01 +04:00
|
|
|
| comp_expr NE cat_expr {
|
2019-05-13 00:56:22 +04:00
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in ELogic (CompExpr (Neq {region; value}))
|
|
|
|
}
|
|
|
|
| cat_expr { $1 }
|
|
|
|
|
|
|
|
cat_expr:
|
|
|
|
cons_expr CAT cat_expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in EString (Cat {region; value})
|
|
|
|
}
|
|
|
|
| cons_expr { $1 }
|
|
|
|
|
|
|
|
cons_expr:
|
|
|
|
add_expr CONS cons_expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
2019-11-06 20:23:49 +04:00
|
|
|
in EList (ECons {region; value})
|
2019-05-13 00:56:22 +04:00
|
|
|
}
|
|
|
|
| add_expr { $1 }
|
|
|
|
|
|
|
|
add_expr:
|
|
|
|
add_expr PLUS mult_expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in EArith (Add {region; value})
|
|
|
|
}
|
|
|
|
| add_expr MINUS mult_expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in EArith (Sub {region; value})
|
|
|
|
}
|
|
|
|
| mult_expr { $1 }
|
|
|
|
|
|
|
|
mult_expr:
|
|
|
|
mult_expr TIMES unary_expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in EArith (Mult {region; value})
|
|
|
|
}
|
|
|
|
| mult_expr SLASH unary_expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in EArith (Div {region; value})
|
|
|
|
}
|
|
|
|
| mult_expr Mod unary_expr {
|
|
|
|
let start = expr_to_region $1
|
|
|
|
and stop = expr_to_region $3 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = {arg1 = $1; op = $2; arg2 = $3}
|
|
|
|
in EArith (Mod {region; value})
|
|
|
|
}
|
|
|
|
| unary_expr { $1 }
|
|
|
|
|
|
|
|
unary_expr:
|
|
|
|
MINUS core_expr {
|
|
|
|
let stop = expr_to_region $2 in
|
|
|
|
let region = cover $1 stop
|
|
|
|
and value = {op = $1; arg = $2}
|
|
|
|
in EArith (Neg {region; value})
|
|
|
|
}
|
|
|
|
| Not core_expr {
|
|
|
|
let stop = expr_to_region $2 in
|
|
|
|
let region = cover $1 stop
|
|
|
|
and value = {op = $1; arg = $2} in
|
|
|
|
ELogic (BoolExpr (Not {region; value}))
|
|
|
|
}
|
|
|
|
| core_expr { $1 }
|
|
|
|
|
|
|
|
core_expr:
|
|
|
|
Int { EArith (Int $1) }
|
|
|
|
| Nat { EArith (Nat $1) }
|
2019-11-06 20:23:49 +04:00
|
|
|
| Mutez { EArith (Mutez $1) }
|
2019-05-13 00:56:22 +04:00
|
|
|
| var { EVar $1 }
|
|
|
|
| String { EString (String $1) }
|
|
|
|
| Bytes { EBytes $1 }
|
2019-11-06 20:23:49 +04:00
|
|
|
| False { ELogic (BoolExpr (False $1)) }
|
|
|
|
| True { ELogic (BoolExpr (True $1)) }
|
|
|
|
| Unit { EUnit $1 }
|
2019-07-30 13:27:32 +04:00
|
|
|
| annot_expr { EAnnot $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
| tuple_expr { ETuple $1 }
|
|
|
|
| list_expr { EList $1 }
|
|
|
|
| C_None { EConstr (NoneExpr $1) }
|
2019-11-14 23:12:41 +04:00
|
|
|
| fun_call_or_par_or_projection { $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
| map_expr { EMap $1 }
|
|
|
|
| set_expr { ESet $1 }
|
|
|
|
| record_expr { ERecord $1 }
|
|
|
|
| Constr arguments {
|
|
|
|
let region = cover $1.region $2.region in
|
2019-06-11 19:10:27 +04:00
|
|
|
EConstr (ConstrApp {region; value = $1, Some $2})
|
|
|
|
}
|
|
|
|
| Constr {
|
|
|
|
EConstr (ConstrApp {region=$1.region; value = $1,None})
|
2019-05-13 00:56:22 +04:00
|
|
|
}
|
|
|
|
| C_Some arguments {
|
|
|
|
let region = cover $1 $2.region in
|
|
|
|
EConstr (SomeApp {region; value = $1,$2})}
|
|
|
|
|
2019-11-14 23:12:41 +04:00
|
|
|
|
|
|
|
fun_call_or_par_or_projection:
|
|
|
|
| par(expr) option(arguments) {
|
|
|
|
let parenthesized = EPar $1 in
|
|
|
|
match $2 with
|
|
|
|
| None -> parenthesized
|
|
|
|
| Some args -> (
|
|
|
|
let region_1 = $1.region in
|
|
|
|
let region = cover region_1 args.region in
|
|
|
|
ECall {region; value = parenthesized,args}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
| projection option(arguments) {
|
|
|
|
let project = EProj $1 in
|
|
|
|
match $2 with
|
|
|
|
| None -> project
|
|
|
|
| Some args -> (
|
|
|
|
let region_1 = $1.region in
|
|
|
|
let region = cover region_1 args.region in
|
|
|
|
ECall {region; value = project,args}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
| fun_call { ECall $1 }
|
|
|
|
|
2019-07-30 13:27:32 +04:00
|
|
|
annot_expr:
|
|
|
|
LPAR disj_expr COLON type_expr RPAR {
|
|
|
|
let start = expr_to_region $2
|
|
|
|
and stop = type_expr_to_region $4 in
|
|
|
|
let region = cover start stop
|
|
|
|
and value = ($2 , $4)
|
|
|
|
in {region; value}
|
|
|
|
}
|
|
|
|
|
2019-05-13 00:56:22 +04:00
|
|
|
set_expr:
|
|
|
|
injection(Set,expr) { SetInj $1 }
|
|
|
|
|
|
|
|
map_expr:
|
2019-07-26 18:23:12 +04:00
|
|
|
map_lookup { MapLookUp $1 }
|
|
|
|
| injection(Map,binding) { MapInj $1 }
|
2019-10-21 15:04:28 +04:00
|
|
|
| injection(BigMap,binding) { BigMapInj $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
map_lookup:
|
|
|
|
path brackets(expr) {
|
|
|
|
let region = cover (path_to_region $1) $2.region in
|
|
|
|
let value = {path=$1; index=$2}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
path:
|
|
|
|
var { Name $1 }
|
|
|
|
| projection { Path $1 }
|
|
|
|
|
|
|
|
projection:
|
|
|
|
struct_name DOT nsepseq(selection,DOT) {
|
|
|
|
let stop = nsepseq_to_region selection_to_region $3 in
|
|
|
|
let region = cover $1.region stop
|
|
|
|
and value = {
|
|
|
|
struct_name = $1;
|
|
|
|
selector = $2;
|
|
|
|
field_path = $3}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
selection:
|
|
|
|
field_name { FieldName $1 }
|
|
|
|
| Int { Component $1 }
|
|
|
|
|
|
|
|
record_expr:
|
2019-07-25 18:11:33 +04:00
|
|
|
Record sep_or_term_list(field_assignment,SEMI) End {
|
2019-11-06 20:23:49 +04:00
|
|
|
let ne_elements, terminator = $2 in
|
2019-07-25 18:11:33 +04:00
|
|
|
let region = cover $1 $3
|
2019-11-06 20:23:49 +04:00
|
|
|
and value : field_assign AST.reg ne_injection = {
|
2019-05-13 00:56:22 +04:00
|
|
|
opening = Kwd $1;
|
2019-11-06 20:23:49 +04:00
|
|
|
ne_elements;
|
2019-05-13 00:56:22 +04:00
|
|
|
terminator;
|
2019-07-25 18:11:33 +04:00
|
|
|
closing = End $3}
|
2019-05-13 00:56:22 +04:00
|
|
|
in {region; value}
|
|
|
|
}
|
2019-07-25 18:11:33 +04:00
|
|
|
| Record LBRACKET sep_or_term_list(field_assignment,SEMI) RBRACKET {
|
2019-11-06 20:23:49 +04:00
|
|
|
let ne_elements, terminator = $3 in
|
2019-07-25 18:11:33 +04:00
|
|
|
let region = cover $1 $4
|
2019-11-06 20:23:49 +04:00
|
|
|
and value : field_assign AST.reg ne_injection = {
|
2019-05-13 00:56:22 +04:00
|
|
|
opening = KwdBracket ($1,$2);
|
2019-11-06 20:23:49 +04:00
|
|
|
ne_elements;
|
2019-05-13 00:56:22 +04:00
|
|
|
terminator;
|
2019-07-25 18:11:33 +04:00
|
|
|
closing = RBracket $4}
|
2019-05-13 00:56:22 +04:00
|
|
|
in {region; value} }
|
|
|
|
|
|
|
|
field_assignment:
|
2019-10-13 21:51:01 +04:00
|
|
|
field_name EQ expr {
|
2019-05-13 00:56:22 +04:00
|
|
|
let region = cover $1.region (expr_to_region $3)
|
|
|
|
and value = {
|
|
|
|
field_name = $1;
|
|
|
|
equal = $2;
|
|
|
|
field_expr = $3}
|
|
|
|
in {region; value}}
|
|
|
|
|
|
|
|
fun_call:
|
|
|
|
fun_name arguments {
|
|
|
|
let region = cover $1.region $2.region
|
2019-11-14 23:12:41 +04:00
|
|
|
in {region; value = (EVar $1),$2}}
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
tuple_expr:
|
2019-10-15 23:03:46 +04:00
|
|
|
par(tuple_comp) { $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
2019-10-15 23:03:46 +04:00
|
|
|
tuple_comp:
|
|
|
|
expr COMMA nsepseq(expr,COMMA) {
|
|
|
|
Utils.nsepseq_cons $1 $2 $3}
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
arguments:
|
2019-10-15 23:03:46 +04:00
|
|
|
par(nsepseq(expr,COMMA)) { $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
list_expr:
|
2019-11-06 20:23:49 +04:00
|
|
|
injection(List,expr) { EListComp $1 }
|
|
|
|
| Nil { ENil $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
(* Patterns *)
|
|
|
|
|
|
|
|
pattern:
|
2019-10-13 01:42:26 +04:00
|
|
|
core_pattern CONS nsepseq(core_pattern,CONS) {
|
|
|
|
let value = Utils.nsepseq_cons $1 $2 $3 in
|
|
|
|
let region = nsepseq_to_region pattern_to_region value
|
2019-11-06 20:23:49 +04:00
|
|
|
in PList (PCons {region; value}) }
|
2019-10-13 01:42:26 +04:00
|
|
|
| core_pattern { $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
core_pattern:
|
2019-06-13 18:57:40 +04:00
|
|
|
var { PVar $1 }
|
|
|
|
| WILD { PWild $1 }
|
|
|
|
| Int { PInt $1 }
|
2019-10-15 23:03:46 +04:00
|
|
|
| Nat { PNat $1 }
|
2019-10-13 01:42:26 +04:00
|
|
|
| Bytes { PBytes $1 }
|
2019-06-13 18:57:40 +04:00
|
|
|
| String { PString $1 }
|
|
|
|
| list_pattern { PList $1 }
|
|
|
|
| tuple_pattern { PTuple $1 }
|
|
|
|
| constr_pattern { PConstr $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
2019-06-13 18:57:40 +04:00
|
|
|
list_pattern:
|
2019-11-06 20:23:49 +04:00
|
|
|
injection(List,core_pattern) { PListComp $1 }
|
|
|
|
| Nil { PNil $1 }
|
|
|
|
| par(cons_pattern) { PParCons $1 }
|
2019-05-13 00:56:22 +04:00
|
|
|
|
|
|
|
cons_pattern:
|
|
|
|
core_pattern CONS pattern { $1,$2,$3 }
|
|
|
|
|
2019-06-13 18:57:40 +04:00
|
|
|
tuple_pattern:
|
2019-05-13 00:56:22 +04:00
|
|
|
par(nsepseq(core_pattern,COMMA)) { $1 }
|
|
|
|
|
2019-06-13 18:57:40 +04:00
|
|
|
constr_pattern:
|
2019-11-06 20:23:49 +04:00
|
|
|
Unit { PUnit $1 }
|
|
|
|
| False { PFalse $1 }
|
|
|
|
| True { PTrue $1 }
|
|
|
|
| C_None { PNone $1 }
|
|
|
|
| C_Some par(core_pattern) {
|
|
|
|
let region = cover $1 $2.region
|
|
|
|
in PSomeApp {region; value = $1,$2}
|
|
|
|
}
|
|
|
|
| Constr tuple_pattern {
|
2019-06-13 18:57:40 +04:00
|
|
|
let region = cover $1.region $2.region
|
2019-11-06 20:23:49 +04:00
|
|
|
in PConstrApp {region; value = $1, Some $2}
|
2019-06-13 18:57:40 +04:00
|
|
|
}
|
|
|
|
| Constr {
|
2019-11-06 20:23:49 +04:00
|
|
|
PConstrApp {region=$1.region; value = $1, None} }
|