Gardening.
This commit is contained in:
parent
0c7bfbdecd
commit
ff9584c7b7
@ -1 +1 @@
|
||||
--explain --external-tokens Token --base Parser ParToken.mly
|
||||
--explain --external-tokens LexToken --base Parser ParToken.mly
|
||||
|
@ -4,18 +4,17 @@ $HOME/git/ligo/vendors/ligo-utils/simple-utils/pos.mli
|
||||
$HOME/git/ligo/vendors/ligo-utils/simple-utils/pos.ml
|
||||
$HOME/git/ligo/vendors/ligo-utils/simple-utils/region.mli
|
||||
$HOME/git/ligo/vendors/ligo-utils/simple-utils/region.ml
|
||||
$HOME/git/ligo/src/parser/shared/Lexer.mli
|
||||
$HOME/git/ligo/src/parser/shared/Lexer.mll
|
||||
$HOME/git/ligo/src/parser/shared/Error.mli
|
||||
$HOME/git/ligo/src/parser/shared/EvalOpt.ml
|
||||
$HOME/git/ligo/src/parser/shared/EvalOpt.mli
|
||||
$HOME/git/ligo/src/parser/shared/FQueue.ml
|
||||
$HOME/git/ligo/src/parser/shared/FQueue.mli
|
||||
$HOME/git/ligo/src/parser/shared/LexerLog.mli
|
||||
$HOME/git/ligo/src/parser/shared/LexerLog.ml
|
||||
$HOME/git/ligo/src/parser/shared/Markup.ml
|
||||
$HOME/git/ligo/src/parser/shared/Markup.mli
|
||||
$HOME/git/ligo/src/parser/shared/Utils.mli
|
||||
$HOME/git/ligo/src/parser/shared/Utils.ml
|
||||
$HOME/git/ligo/src/parser/shared/Version.ml
|
||||
../shared/Lexer.mli
|
||||
../shared/Lexer.mll
|
||||
../shared/Error.mli
|
||||
../shared/EvalOpt.ml
|
||||
../shared/EvalOpt.mli
|
||||
../shared/FQueue.ml
|
||||
../shared/FQueue.mli
|
||||
../shared/LexerLog.mli
|
||||
../shared/LexerLog.ml
|
||||
../shared/Markup.ml
|
||||
../shared/Markup.mli
|
||||
../shared/Utils.mli
|
||||
../shared/Utils.ml
|
||||
Stubs/Simple_utils.ml
|
||||
|
@ -6,7 +6,7 @@ let () = Printexc.record_backtrace true
|
||||
|
||||
(* Running the lexer on the source *)
|
||||
|
||||
let options = EvalOpt.read "Ligodity" ".mligo"
|
||||
let options = EvalOpt.read "CameLIGO" ".mligo"
|
||||
|
||||
open EvalOpt
|
||||
|
||||
|
@ -49,7 +49,7 @@ par(X):
|
||||
rpar = $3}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
|
||||
brackets(X):
|
||||
LBRACKET X RBRACKET {
|
||||
let region = cover $1 $3
|
||||
@ -109,7 +109,7 @@ sepseq(item,sep):
|
||||
(* Non-empty comma-separated values (at least two values) *)
|
||||
|
||||
tuple(item):
|
||||
item COMMA nsepseq(item,COMMA) {
|
||||
item COMMA nsepseq(item,COMMA) {
|
||||
let h,t = $3 in $1,($2,h)::t
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ tuple(item):
|
||||
|
||||
list(item):
|
||||
LBRACKET sep_or_term_list(item,SEMI) RBRACKET {
|
||||
let elements, terminator = $2 in
|
||||
let elements, terminator = $2 in
|
||||
{ value =
|
||||
{
|
||||
opening = LBracket $1;
|
||||
@ -136,7 +136,7 @@ list(item):
|
||||
terminator = None;
|
||||
closing = RBracket $2
|
||||
};
|
||||
region = cover $1 $2
|
||||
region = cover $1 $2
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,10 +150,10 @@ declarations:
|
||||
| declaration declarations { Utils.(nseq_foldl (swap nseq_cons) $2 $1)}
|
||||
|
||||
declaration:
|
||||
LetEntry entry_binding {
|
||||
LetEntry entry_binding {
|
||||
let start = $1 in
|
||||
let stop = expr_to_region $2.let_rhs in
|
||||
let region = cover start stop in
|
||||
let region = cover start stop in
|
||||
LetEntry { value = ($1, $2); region}, []
|
||||
}
|
||||
| type_decl { TypeDecl $1, [] }
|
||||
@ -162,7 +162,7 @@ declaration:
|
||||
(* Type declarations *)
|
||||
|
||||
type_decl:
|
||||
Type type_name EQ type_expr {
|
||||
Type type_name EQ type_expr {
|
||||
let region = cover $1 (type_expr_to_region $4) in
|
||||
let value = {
|
||||
kwd_type = $1;
|
||||
@ -179,19 +179,19 @@ type_expr:
|
||||
| record_type { TRecord $1 }
|
||||
|
||||
cartesian:
|
||||
nsepseq(fun_type, TIMES) {
|
||||
nsepseq(fun_type, TIMES) {
|
||||
let region = nsepseq_to_region type_expr_to_region $1
|
||||
in {region; value=$1}
|
||||
}
|
||||
|
||||
fun_type:
|
||||
core_type {
|
||||
$1
|
||||
core_type {
|
||||
$1
|
||||
}
|
||||
| core_type ARROW fun_type {
|
||||
| core_type ARROW fun_type {
|
||||
let region = cover (type_expr_to_region $1)
|
||||
(type_expr_to_region $3)
|
||||
in
|
||||
in
|
||||
TFun {region; value = ($1, $2, $3)}
|
||||
}
|
||||
|
||||
@ -202,16 +202,16 @@ core_type:
|
||||
| module_name DOT type_name {
|
||||
let module_name = $1.value in
|
||||
let type_name = $3.value in
|
||||
let value = module_name ^ "." ^ type_name in
|
||||
let value = module_name ^ "." ^ type_name in
|
||||
let region = cover $1.region $3.region
|
||||
in
|
||||
in
|
||||
TAlias {region; value}
|
||||
}
|
||||
| core_type type_constr {
|
||||
let arg_val = $1 in
|
||||
let constr = $2 in
|
||||
let start = type_expr_to_region $1 in
|
||||
let stop = $2.region in
|
||||
let start = type_expr_to_region $1 in
|
||||
let stop = $2.region in
|
||||
let region = cover start stop in
|
||||
let lpar, rpar = ghost, ghost in
|
||||
let value = {lpar; inside=arg_val,[]; rpar} in
|
||||
@ -219,12 +219,12 @@ core_type:
|
||||
TApp Region.{value = constr, arg; region}
|
||||
}
|
||||
| type_tuple type_constr {
|
||||
let total = cover $1.region $2.region in
|
||||
let total = cover $1.region $2.region in
|
||||
TApp {region=total; value = $2, $1 }
|
||||
}
|
||||
}
|
||||
| par(cartesian) {
|
||||
let Region.{value={inside=prod; _}; _} = $1 in
|
||||
TPar {$1 with value={$1.value with inside = TProd prod}} }
|
||||
TPar {$1 with value={$1.value with inside = TProd prod}} }
|
||||
|
||||
type_constr:
|
||||
type_name { $1 }
|
||||
@ -233,7 +233,7 @@ type_tuple:
|
||||
par(tuple(type_expr)) { $1 }
|
||||
|
||||
sum_type:
|
||||
ioption(VBAR) nsepseq(variant,VBAR) {
|
||||
ioption(VBAR) nsepseq(variant,VBAR) {
|
||||
let region = nsepseq_to_region (fun x -> x.region) $2
|
||||
in {region; value = $2}
|
||||
}
|
||||
@ -256,7 +256,7 @@ record_type:
|
||||
elements = Some elements;
|
||||
terminator;
|
||||
closing = RBrace $3}
|
||||
in {region; value}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
field_decl:
|
||||
@ -264,7 +264,7 @@ field_decl:
|
||||
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}
|
||||
in {region; value}
|
||||
}
|
||||
|
||||
(* Entry points *)
|
||||
@ -284,7 +284,7 @@ entry_binding:
|
||||
|
||||
let_declaration:
|
||||
Let let_binding {
|
||||
let kwd_let = $1 in
|
||||
let kwd_let = $1 in
|
||||
let binding, region = $2 in
|
||||
{value = kwd_let, binding; region}
|
||||
}
|
||||
@ -299,10 +299,10 @@ let_binding:
|
||||
let region = cover start stop in
|
||||
({bindings= (ident_pattern :: hd :: tl); lhs_type=$3; eq=$4; let_rhs}, region)
|
||||
}
|
||||
| irrefutable type_annotation? EQ expr {
|
||||
| irrefutable type_annotation? EQ expr {
|
||||
let pattern = $1 in
|
||||
let start = pattern_to_region $1 in
|
||||
let stop = expr_to_region $4 in
|
||||
let stop = expr_to_region $4 in
|
||||
let region = cover start stop in
|
||||
({bindings = [pattern]; lhs_type=$2; eq=$3; let_rhs=$4}, region)
|
||||
}
|
||||
@ -313,11 +313,11 @@ type_annotation:
|
||||
(* Patterns *)
|
||||
|
||||
irrefutable:
|
||||
tuple(sub_irrefutable) {
|
||||
let h, t = $1 in
|
||||
tuple(sub_irrefutable) {
|
||||
let h, t = $1 in
|
||||
let start = pattern_to_region h in
|
||||
let stop = last (fun (region, _) -> region) t in
|
||||
let region = cover start stop in
|
||||
let region = cover start stop in
|
||||
PTuple { value = $1; region }
|
||||
}
|
||||
| sub_irrefutable { $1 }
|
||||
@ -335,14 +335,14 @@ closed_irrefutable:
|
||||
| typed_pattern { PTyped $1 }
|
||||
|
||||
typed_pattern:
|
||||
irrefutable COLON type_expr {
|
||||
let start = pattern_to_region $1 in
|
||||
irrefutable COLON type_expr {
|
||||
let start = pattern_to_region $1 in
|
||||
let stop = type_expr_to_region $3 in
|
||||
let region = cover start stop in
|
||||
{
|
||||
value = {
|
||||
pattern = $1;
|
||||
colon = $2;
|
||||
pattern = $1;
|
||||
colon = $2;
|
||||
type_expr = $3
|
||||
};
|
||||
region
|
||||
@ -350,18 +350,18 @@ typed_pattern:
|
||||
}
|
||||
|
||||
pattern:
|
||||
sub_pattern CONS tail {
|
||||
sub_pattern CONS tail {
|
||||
let start = pattern_to_region $1 in
|
||||
let stop = pattern_to_region $3 in
|
||||
let stop = pattern_to_region $3 in
|
||||
let region = cover start stop in
|
||||
let val_ = {value = $1, $2, $3; region} in
|
||||
PList (PCons val_)
|
||||
PList (PCons val_)
|
||||
}
|
||||
| tuple(sub_pattern) {
|
||||
let h, t = $1 in
|
||||
| tuple(sub_pattern) {
|
||||
let h, t = $1 in
|
||||
let start = pattern_to_region h in
|
||||
let stop = last (fun (region, _) -> region) t in
|
||||
let region = cover start stop in
|
||||
let region = cover start stop in
|
||||
PTuple { value = $1; region }
|
||||
}
|
||||
| core_pattern { $1 }
|
||||
@ -379,7 +379,7 @@ core_pattern:
|
||||
| False { PFalse $1 }
|
||||
| Str { PString $1 }
|
||||
| par(ptuple) { PPar $1 }
|
||||
| list(tail) { PList (Sugar $1) }
|
||||
| list(tail) { PList (Sugar $1) }
|
||||
| constr_pattern { PConstr $1 }
|
||||
| record_pattern { PRecord $1 }
|
||||
|
||||
@ -393,7 +393,7 @@ record_pattern:
|
||||
terminator;
|
||||
closing = RBrace $3}
|
||||
in
|
||||
{region; value}
|
||||
{region; value}
|
||||
}
|
||||
|
||||
field_pattern:
|
||||
@ -405,29 +405,29 @@ field_pattern:
|
||||
}
|
||||
|
||||
constr_pattern:
|
||||
Constr sub_pattern {
|
||||
Constr sub_pattern {
|
||||
let region = cover $1.region (pattern_to_region $2) in
|
||||
{ value = $1, Some $2; region } }
|
||||
| Constr { { value = $1, None; region = $1.region } }
|
||||
|
||||
ptuple:
|
||||
tuple(tail) {
|
||||
let h, t = $1 in
|
||||
tuple(tail) {
|
||||
let h, t = $1 in
|
||||
let start = pattern_to_region h in
|
||||
let stop = last (fun (region, _) -> region) t in
|
||||
let region = cover start stop in
|
||||
PTuple { value = $1; region }
|
||||
let region = cover start stop in
|
||||
PTuple { value = $1; region }
|
||||
}
|
||||
|
||||
unit:
|
||||
LPAR RPAR {
|
||||
LPAR RPAR {
|
||||
let the_unit = ghost, ghost in
|
||||
let region = cover $1 $2 in
|
||||
{ value = the_unit; region }
|
||||
}
|
||||
|
||||
tail:
|
||||
sub_pattern CONS tail {
|
||||
sub_pattern CONS tail {
|
||||
let start = pattern_to_region $1 in
|
||||
let end_ = pattern_to_region $3 in
|
||||
let region = cover start end_ in
|
||||
@ -456,11 +456,11 @@ base_expr(right_expr):
|
||||
| fun_expr(right_expr)
|
||||
| disj_expr_level { $1 }
|
||||
| tuple(disj_expr_level) {
|
||||
let h, t = $1 in
|
||||
let h, t = $1 in
|
||||
let start = expr_to_region h in
|
||||
let stop = last (fun (region, _) -> region) t in
|
||||
let region = cover start stop in
|
||||
ETuple { value = $1; region }
|
||||
let region = cover start stop in
|
||||
ETuple { value = $1; region }
|
||||
}
|
||||
|
||||
conditional(right_expr):
|
||||
@ -476,27 +476,27 @@ if_then(right_expr):
|
||||
let ifnot = EUnit {region=ghost; value=the_unit} in
|
||||
{
|
||||
value = {
|
||||
kwd_if = $1;
|
||||
test = $2;
|
||||
kwd_then = $3;
|
||||
kwd_if = $1;
|
||||
test = $2;
|
||||
kwd_then = $3;
|
||||
ifso = $4;
|
||||
kwd_else = ghost;
|
||||
kwd_else = ghost;
|
||||
ifnot
|
||||
};
|
||||
region
|
||||
region
|
||||
}
|
||||
}
|
||||
|
||||
if_then_else(right_expr):
|
||||
If expr Then closed_if Else right_expr {
|
||||
let region = cover $1 (expr_to_region $6) in
|
||||
{
|
||||
{
|
||||
value = {
|
||||
kwd_if = $1;
|
||||
test = $2;
|
||||
kwd_then = $3;
|
||||
kwd_if = $1;
|
||||
test = $2;
|
||||
kwd_then = $3;
|
||||
ifso = $4;
|
||||
kwd_else = $5;
|
||||
kwd_else = $5;
|
||||
ifnot = $6
|
||||
};
|
||||
region
|
||||
@ -520,21 +520,21 @@ match_expr(right_expr):
|
||||
let start = $1 in
|
||||
let stop = match $5 with (* TODO: move to separate function *)
|
||||
| {region; _}, [] -> region
|
||||
| _, tl -> last (fun (region,_) -> region) tl
|
||||
| _, tl -> last (fun (region,_) -> region) tl
|
||||
in
|
||||
let region = cover start stop in
|
||||
{ value = {
|
||||
kwd_match = $1;
|
||||
expr = $2;
|
||||
kwd_match = $1;
|
||||
expr = $2;
|
||||
opening = With $3;
|
||||
lead_vbar = $4;
|
||||
lead_vbar = $4;
|
||||
cases = {
|
||||
value = cases;
|
||||
value = cases;
|
||||
region = nsepseq_to_region (fun {region; _} -> region) $5
|
||||
};
|
||||
closing = End ghost
|
||||
};
|
||||
region
|
||||
};
|
||||
region
|
||||
}
|
||||
}
|
||||
| MatchNat expr With VBAR? cases(right_expr) {
|
||||
@ -544,27 +544,27 @@ match_expr(right_expr):
|
||||
let start = $1 in
|
||||
let stop = match $5 with (* TODO: move to separate function *)
|
||||
| {region; _}, [] -> region
|
||||
| _, tl -> last (fun (region,_) -> region) tl
|
||||
| _, tl -> last (fun (region,_) -> region) tl
|
||||
in
|
||||
let region = cover start stop in
|
||||
{
|
||||
{
|
||||
value = {
|
||||
kwd_match = $1;
|
||||
expr = cast;
|
||||
kwd_match = $1;
|
||||
expr = cast;
|
||||
opening = With $3;
|
||||
lead_vbar = $4;
|
||||
lead_vbar = $4;
|
||||
cases = {
|
||||
value = cases;
|
||||
value = cases;
|
||||
region = nsepseq_to_region (fun {region; _} -> region) $5
|
||||
};
|
||||
closing = End ghost
|
||||
};
|
||||
region
|
||||
};
|
||||
region
|
||||
}
|
||||
}
|
||||
|
||||
cases(right_expr):
|
||||
case_clause(right_expr) {
|
||||
case_clause(right_expr) {
|
||||
let start = pattern_to_region $1.pattern in
|
||||
let stop = expr_to_region $1.rhs in
|
||||
let region = cover start stop in
|
||||
@ -573,25 +573,25 @@ cases(right_expr):
|
||||
| cases(base_cond) VBAR case_clause(right_expr) {
|
||||
let start = match $1 with
|
||||
| {region; _}, [] -> region
|
||||
| _, tl -> last (fun (region,_) -> region) tl
|
||||
| _, tl -> last (fun (region,_) -> region) tl
|
||||
in
|
||||
let stop = expr_to_region $3.rhs in
|
||||
let region = cover start stop in
|
||||
let h,t = $1 in { value = $3; region}, ($2, h)::t
|
||||
}
|
||||
let h,t = $1 in { value = $3; region}, ($2, h)::t
|
||||
}
|
||||
|
||||
case_clause(right_expr):
|
||||
pattern ARROW right_expr {
|
||||
pattern ARROW right_expr {
|
||||
{
|
||||
pattern = $1;
|
||||
arrow = $2;
|
||||
rhs=$3
|
||||
pattern = $1;
|
||||
arrow = $2;
|
||||
rhs=$3
|
||||
}
|
||||
}
|
||||
|
||||
let_expr(right_expr):
|
||||
Let let_binding In right_expr {
|
||||
let kwd_let = $1 in
|
||||
let kwd_let = $1 in
|
||||
let (binding, _) = $2 in
|
||||
let kwd_in = $3 in
|
||||
let body = $4 in
|
||||
@ -603,7 +603,7 @@ let_expr(right_expr):
|
||||
fun_expr(right_expr):
|
||||
Fun nseq(irrefutable) ARROW right_expr {
|
||||
let kwd_fun = $1 in
|
||||
let bindings = $2 in
|
||||
let bindings = $2 in
|
||||
let arrow = $3 in
|
||||
let body = $4 in
|
||||
let stop = expr_to_region $4 in
|
||||
@ -624,7 +624,7 @@ disj_expr_level:
|
||||
| conj_expr_level { $1 }
|
||||
|
||||
bin_op(arg1,op,arg2):
|
||||
arg1 op arg2 {
|
||||
arg1 op arg2 {
|
||||
let start = expr_to_region $1 in
|
||||
let stop = expr_to_region $3 in
|
||||
let region = cover start stop in
|
||||
@ -720,16 +720,16 @@ unary_expr_level:
|
||||
let start = $1 in
|
||||
let end_ = expr_to_region $2 in
|
||||
let region = cover start end_
|
||||
and value = {op = $1; arg = $2}
|
||||
in EArith (Neg {region; value})
|
||||
and value = {op = $1; arg = $2}
|
||||
in EArith (Neg {region; value})
|
||||
}
|
||||
| Not call_expr_level {
|
||||
let start = $1 in
|
||||
let end_ = expr_to_region $2 in
|
||||
let region = cover start end_
|
||||
and value = {op = $1; arg = $2} in
|
||||
and value = {op = $1; arg = $2} in
|
||||
ELogic (BoolExpr (Not ({region; value})))
|
||||
}
|
||||
}
|
||||
| call_expr_level { $1 }
|
||||
|
||||
call_expr_level:
|
||||
@ -738,11 +738,11 @@ call_expr_level:
|
||||
| core_expr { $1 }
|
||||
|
||||
constr_expr:
|
||||
Constr core_expr? {
|
||||
Constr core_expr? {
|
||||
let start = $1.region in
|
||||
let stop = match $2 with
|
||||
let stop = match $2 with
|
||||
| Some c -> expr_to_region c
|
||||
| None -> start
|
||||
| None -> start
|
||||
in
|
||||
let region = cover start stop in
|
||||
{ value = $1,$2; region}
|
||||
@ -751,7 +751,7 @@ constr_expr:
|
||||
call_expr:
|
||||
core_expr nseq(core_expr) {
|
||||
let start = expr_to_region $1 in
|
||||
let stop = match $2 with
|
||||
let stop = match $2 with
|
||||
| e, [] -> expr_to_region e
|
||||
| _, l -> last expr_to_region l
|
||||
in
|
||||
@ -777,50 +777,49 @@ core_expr:
|
||||
EAnnot {$1 with value=$1.value.inside} }
|
||||
|
||||
module_field:
|
||||
module_name DOT field_name {
|
||||
module_name DOT field_name {
|
||||
let region = cover $1.region $3.region in
|
||||
{ value = $1.value ^ "." ^ $3.value; region }
|
||||
{ value = $1.value ^ "." ^ $3.value; region }
|
||||
}
|
||||
|
||||
projection:
|
||||
struct_name DOT nsepseq(selection,DOT) {
|
||||
let start = $1.region in
|
||||
let stop = nsepseq_to_region (function
|
||||
| FieldName f -> f.region
|
||||
| Component c -> c.region) $3
|
||||
let start = $1.region in
|
||||
let stop = nsepseq_to_region (function
|
||||
| FieldName f -> f.region
|
||||
| Component c -> c.region) $3
|
||||
in
|
||||
let region = cover start stop in
|
||||
{ value =
|
||||
{ value =
|
||||
{
|
||||
struct_name = $1;
|
||||
selector = $2;
|
||||
struct_name = $1;
|
||||
selector = $2;
|
||||
field_path = $3
|
||||
};
|
||||
region
|
||||
}
|
||||
}
|
||||
| module_name DOT field_name DOT nsepseq(selection,DOT) {
|
||||
let open Region in
|
||||
let module_name = $1 in
|
||||
let field_name = $3 in
|
||||
let value = module_name.value ^ "." ^ field_name.value in
|
||||
let struct_name = {$1 with value} in
|
||||
let start = $1.region in
|
||||
let stop = nsepseq_to_region (function
|
||||
| FieldName f -> f.region
|
||||
let stop = nsepseq_to_region (function
|
||||
| FieldName f -> f.region
|
||||
| Component c -> c.region) $5
|
||||
in
|
||||
in
|
||||
let region = cover start stop in
|
||||
{
|
||||
{
|
||||
value = {
|
||||
struct_name;
|
||||
selector = $4;
|
||||
struct_name;
|
||||
selector = $4;
|
||||
field_path = $5
|
||||
};
|
||||
region
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
selection:
|
||||
field_name { FieldName $1 }
|
||||
| par(Int) { Component $1 }
|
||||
@ -829,36 +828,36 @@ record_expr:
|
||||
LBRACE sep_or_term_list(field_assignment,SEMI) RBRACE {
|
||||
let elements, terminator = $2 in
|
||||
let region = cover $1 $3 in
|
||||
{value =
|
||||
{value =
|
||||
{
|
||||
opening = LBrace $1;
|
||||
elements = Some elements;
|
||||
terminator;
|
||||
closing = RBrace $3
|
||||
};
|
||||
};
|
||||
region}
|
||||
}
|
||||
|
||||
field_assignment:
|
||||
field_name EQ expr {
|
||||
let start = $1.region in
|
||||
let stop = expr_to_region $3 in
|
||||
let start = $1.region in
|
||||
let stop = expr_to_region $3 in
|
||||
let region = cover start stop in
|
||||
{ value =
|
||||
{ value =
|
||||
{
|
||||
field_name = $1;
|
||||
assignment = $2;
|
||||
field_name = $1;
|
||||
assignment = $2;
|
||||
field_expr = $3
|
||||
};
|
||||
region
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sequence:
|
||||
Begin sep_or_term_list(expr,SEMI) End {
|
||||
let elements, terminator = $2 in
|
||||
let start = $1 in
|
||||
let stop = $3 in
|
||||
let start = $1 in
|
||||
let stop = $3 in
|
||||
let region = cover start stop in
|
||||
{
|
||||
value = {
|
||||
@ -869,4 +868,4 @@ sequence:
|
||||
};
|
||||
region
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
[@@@warning "-42"]
|
||||
|
||||
open AST
|
||||
open! Region
|
||||
|
||||
@ -351,7 +353,6 @@ and print_fun_expr {value; _} =
|
||||
print_expr body
|
||||
|
||||
and print_conditional {value; _} =
|
||||
let open Region in
|
||||
let {kwd_if; test; kwd_then; ifso; kwd_else; ifnot} = value
|
||||
in print_token ghost "(";
|
||||
print_token kwd_if "if";
|
||||
|
@ -6,7 +6,7 @@ let () = Printexc.record_backtrace true
|
||||
|
||||
(* Reading the command-line options *)
|
||||
|
||||
let options = EvalOpt.read "Ligodity" ".mligo"
|
||||
let options = EvalOpt.read "CameLIGO" ".mligo"
|
||||
|
||||
open EvalOpt
|
||||
|
||||
|
@ -4,17 +4,17 @@ $HOME/git/ligo/vendors/ligo-utils/simple-utils/pos.mli
|
||||
$HOME/git/ligo/vendors/ligo-utils/simple-utils/pos.ml
|
||||
$HOME/git/ligo/vendors/ligo-utils/simple-utils/region.mli
|
||||
$HOME/git/ligo/vendors/ligo-utils/simple-utils/region.ml
|
||||
$HOME/git/ligo/src/parser/shared/Lexer.mli
|
||||
$HOME/git/ligo/src/parser/shared/Lexer.mll
|
||||
$HOME/git/ligo/src/parser/shared/Error.mli
|
||||
$HOME/git/ligo/src/parser/shared/EvalOpt.ml
|
||||
$HOME/git/ligo/src/parser/shared/EvalOpt.mli
|
||||
$HOME/git/ligo/src/parser/shared/FQueue.ml
|
||||
$HOME/git/ligo/src/parser/shared/FQueue.mli
|
||||
$HOME/git/ligo/src/parser/shared/LexerLog.mli
|
||||
$HOME/git/ligo/src/parser/shared/LexerLog.ml
|
||||
$HOME/git/ligo/src/parser/shared/Markup.ml
|
||||
$HOME/git/ligo/src/parser/shared/Markup.mli
|
||||
$HOME/git/ligo/src/parser/shared/Utils.mli
|
||||
$HOME/git/ligo/src/parser/shared/Utils.ml
|
||||
../shared/Lexer.mli
|
||||
../shared/Lexer.mll
|
||||
../shared/Error.mli
|
||||
../shared/EvalOpt.ml
|
||||
../shared/EvalOpt.mli
|
||||
../shared/FQueue.ml
|
||||
../shared/FQueue.mli
|
||||
../shared/LexerLog.mli
|
||||
../shared/LexerLog.ml
|
||||
../shared/Markup.ml
|
||||
../shared/Markup.mli
|
||||
../shared/Utils.mli
|
||||
../shared/Utils.ml
|
||||
Stubs/Simple_utils.ml
|
||||
|
@ -119,9 +119,9 @@ use the non-operation `skip`.
|
||||
end
|
||||
end with f
|
||||
|
||||
Like Pascal, PascaLIGO offers procedures, as well as functions. The
|
||||
difference follows the divide between expressions and instructions:
|
||||
function calls are expressions, procedure calls are instructions.
|
||||
<!-- Like Pascal, PascaLIGO offers procedures, as well as functions. The -->
|
||||
<!-- difference follows the divide between expressions and instructions: -->
|
||||
<!-- function calls are expressions, procedure calls are instructions. -->
|
||||
|
||||
In order for a function to be a candidate to be an entrypoint to the
|
||||
contract, it needs to return a specific type: `list (operation) *
|
||||
@ -554,7 +554,7 @@ given the declarations (in verbose style)
|
||||
|
||||
then the value of `r.f` is `4`.
|
||||
|
||||
### Predefined functions, procedures and instructions
|
||||
### Predefined functions instructions
|
||||
|
||||
Beyond a few operators, PascaLIGO features some predefined values and
|
||||
functions.
|
||||
@ -590,54 +590,54 @@ string: if `offset + length` is greater than the length of `string`,
|
||||
the result is `None`, otherwise `Some (substring)`. See section
|
||||
"Options".
|
||||
|
||||
#### Lists
|
||||
<!-- #### Lists -->
|
||||
|
||||
PascaLIGO offers two kinds of iterators on lists.
|
||||
<!-- PascaLIGO offers two kinds of iterators on lists. -->
|
||||
|
||||
The first applies a given function to all the items of a given list,
|
||||
each call returning the predefined value `Unit`. If the function name
|
||||
is `f` and the list is `l`, this is expressed as
|
||||
<!-- The first applies a given function to all the items of a given list, -->
|
||||
<!-- each call returning the predefined value `Unit`. If the function name -->
|
||||
<!-- is `f` and the list is `l`, this is expressed as -->
|
||||
|
||||
list_iter (l, f);
|
||||
<!-- list_iter (l, f); -->
|
||||
|
||||
Note: `list_iter` is a predefined _procedure_. Procedures are
|
||||
functions that return `Unit` and whose calls are instructions, not
|
||||
expressions. The same holds for the iterated function `f` here. See
|
||||
section "Declarations/Procedures".
|
||||
<!-- Note: `list_iter` is a predefined _procedure_. Procedures are -->
|
||||
<!-- functions that return `Unit` and whose calls are instructions, not -->
|
||||
<!-- expressions. The same holds for the iterated function `f` here. See -->
|
||||
<!-- section "Declarations/Procedures". -->
|
||||
|
||||
For an iterator like `list_iter` to be useful, it needs to be able to
|
||||
perform a side effect, which user-defined procedures and functions
|
||||
cannot do. Like so:
|
||||
<!-- For an iterator like `list_iter` to be useful, it needs to be able to -->
|
||||
<!-- perform a side effect, which user-defined procedures and functions -->
|
||||
<!-- cannot do. Like so: -->
|
||||
|
||||
function iter (const delta : int; const l : list (int)) : int is
|
||||
var acc : int := 0
|
||||
procedure aggregate (const i : int) is
|
||||
begin
|
||||
acc := acc + i
|
||||
end
|
||||
begin
|
||||
aggregate (delta); // Has no effect on acc
|
||||
list_iter (l, aggregate) // Has an effect on acc
|
||||
end with acc
|
||||
<!-- function iter (const delta : int; const l : list (int)) : int is -->
|
||||
<!-- var acc : int := 0 -->
|
||||
<!-- procedure aggregate (const i : int) is -->
|
||||
<!-- begin -->
|
||||
<!-- acc := acc + i -->
|
||||
<!-- end -->
|
||||
<!-- begin -->
|
||||
<!-- aggregate (delta); // Has no effect on acc -->
|
||||
<!-- list_iter (l, aggregate) // Has an effect on acc -->
|
||||
<!-- end with acc -->
|
||||
|
||||
The other predefined iterator on lists is `list_map`. It is useful
|
||||
when we need to apply a function to all the items of a list and gather
|
||||
them into another list, in the same order as the original items. (In
|
||||
mathematical terms, `list_map` builds the list of the images through
|
||||
the function.) For instance, the function `iter`
|
||||
<!-- The other predefined iterator on lists is `list_map`. It is useful -->
|
||||
<!-- when we need to apply a function to all the items of a list and gather -->
|
||||
<!-- them into another list, in the same order as the original items. (In -->
|
||||
<!-- mathematical terms, `list_map` builds the list of the images through -->
|
||||
<!-- the function.) For instance, the function `iter` -->
|
||||
|
||||
function iter (const l : list (int)) : list (int) is
|
||||
function incr (const i : int) : int is
|
||||
begin
|
||||
skip
|
||||
end with i+1
|
||||
begin
|
||||
skip
|
||||
end with list_map (l, incr)
|
||||
<!-- function iter (const l : list (int)) : list (int) is -->
|
||||
<!-- function incr (const i : int) : int is -->
|
||||
<!-- begin -->
|
||||
<!-- skip -->
|
||||
<!-- end with i+1 -->
|
||||
<!-- begin -->
|
||||
<!-- skip -->
|
||||
<!-- end with list_map (l, incr) -->
|
||||
|
||||
will take a list of integers as a parameter and return a list with the
|
||||
integers all incremented, e.g., `iter (list [1;2;3])` evaluates in
|
||||
`list [2;3;4]`.
|
||||
<!-- will take a list of integers as a parameter and return a list with the -->
|
||||
<!-- integers all incremented, e.g., `iter (list [1;2;3])` evaluates in -->
|
||||
<!-- `list [2;3;4]`. -->
|
||||
|
||||
#### Sets
|
||||
|
||||
@ -709,18 +709,13 @@ functions to update sets.
|
||||
|
||||
has value `3`.
|
||||
|
||||
|
||||
- The iterator `set_iter` is similar to `list_iter`: it takes a set
|
||||
and a procedure (or function returning `Unit`) and applies it in
|
||||
turn to all the elements of the set.
|
||||
|
||||
- Another form of complete iteration on sets is performed by
|
||||
loops. See section "Loops".
|
||||
- Complete iteration on sets is performed by loops. See section
|
||||
"Loops".
|
||||
|
||||
#### Maps
|
||||
|
||||
Currently, maps have less support than sets. PascaLIGO offers the
|
||||
following functions and procedures on maps:
|
||||
following functions on maps:
|
||||
|
||||
- Adding bindings to a map is only possible if the map is mutable,
|
||||
that is, if it was declared with the annotation `var`, like so, in
|
||||
@ -768,19 +763,8 @@ following functions and procedures on maps:
|
||||
where `sender` is a key and `backers` is a map. If the key is
|
||||
absent in the map, this instruction is a non-operation.
|
||||
|
||||
- The iterator `map_iter` is similar to `list_iter`: it takes a set
|
||||
and a procedure (or function returning `Unit`) and applies it in
|
||||
turn to all the bindings of the map. The type of the iterated
|
||||
procedure/function is expected to be `key * value -> unit`.
|
||||
|
||||
- The iterator `map_map` is similar to `list_map`: it takes a map
|
||||
and a function and builds a new map by applying the function to
|
||||
all the bindings. In particular, this means that the expected
|
||||
return type of the iterated function must be the type of the
|
||||
values in the map.
|
||||
|
||||
- Another form of complete iteration on maps is performed by
|
||||
loops. See section "Loops".
|
||||
- Complete iteration on maps is performed by loops. See section
|
||||
"Loops".
|
||||
|
||||
#### Failures
|
||||
|
||||
@ -800,17 +784,17 @@ can chose.
|
||||
## Declarations
|
||||
|
||||
There are several kinds of declarations: types, mutable variables,
|
||||
constants, functions, procedures, fields. Depending on the syntactic
|
||||
context, only some of those declarations will be allowed. Declarations
|
||||
may be separated by a semicolon. (Because each declaration starts with a
|
||||
constants, functions, fields. Depending on the syntactic context, only
|
||||
some of those declarations will be allowed. Declarations may be
|
||||
separated by a semicolon. (Because each declaration starts with a
|
||||
keyword they can be parsed without separators.)
|
||||
|
||||
|
||||
### Types
|
||||
|
||||
Type declarations are found only at top-level, that is, outside any
|
||||
function or procedure. They associate a type name to a type
|
||||
expression. The general syntax is
|
||||
function. They associate a type name to a type expression. The general
|
||||
syntax is
|
||||
|
||||
type some_type_name is some_type_expression
|
||||
|
||||
@ -959,27 +943,39 @@ is valid and changes the value of the mutable variable `counter` to be
|
||||
`3n`. This is the semantics found in all imperative languages.
|
||||
|
||||
IMPORTANT: Mutable variables cannot be declared at top-level, but only
|
||||
in the scope of function and procedure bodies. This is to avoid global
|
||||
side effects that hide the control flow and makes static analysis
|
||||
extremely difficult.
|
||||
in the scope of function bodies. This is to avoid global side effects
|
||||
that hide the control flow and makes static analysis extremely
|
||||
difficult.
|
||||
|
||||
### Functions
|
||||
|
||||
Function declarations can occur both at top-level and inside functions
|
||||
and procedures (in the tradition of Pascal). We saw an example
|
||||
earlier:
|
||||
Function declarations can occur both at top-level and inside
|
||||
functions, in the tradition of Pascal. For example,
|
||||
|
||||
function iter (const l : list (int)) : list (int) is
|
||||
function incr (const i : int) : int is
|
||||
function incr_list (const l : list (int)) : list (int) is
|
||||
function incr_int (const i : int) : int is
|
||||
begin
|
||||
skip
|
||||
end with i+1
|
||||
const item : int = 0
|
||||
begin
|
||||
skip
|
||||
end with list_map (l, incr)
|
||||
var temp : list (int) := nil;
|
||||
for item in l
|
||||
begin
|
||||
temp := incr_int (item) # temp
|
||||
end;
|
||||
var new_l : list (int) := nil;
|
||||
for item in temp
|
||||
begin
|
||||
new_l := item # new_l
|
||||
end
|
||||
end with new_l
|
||||
|
||||
Here, the function `incr` is declared inside the declaration of the
|
||||
function `iter`. The general shape of a function declaration is
|
||||
Here, the function `incr_int` is declared inside the declaration of
|
||||
the function `incr_list`, which take a list of integers and a list
|
||||
containing the same integers plus one.
|
||||
|
||||
The general shape of a function declaration is
|
||||
|
||||
function my_name ( ... (* parameters here *)) : return_type is
|
||||
... // local declarations here
|
||||
@ -1042,7 +1038,7 @@ copies. Let us copy an example seen above:
|
||||
|
||||
function iter (const delta : int; const l : list (int)) : int is
|
||||
var acc : int := 0
|
||||
procedure aggregate (const i : int) is
|
||||
function aggregate (const i : int) : unit is
|
||||
begin
|
||||
acc := acc + i // acc is part of the copied environment
|
||||
end
|
||||
@ -1058,41 +1054,41 @@ value in return.
|
||||
IMPORTANT: _Functions cannot be recursive in PascaLIGO_, that is why
|
||||
loops or iterators are needed.
|
||||
|
||||
### Procedures
|
||||
<!-- ### Procedures -->
|
||||
|
||||
WARNING: Procedures are not implemented in the current version of LIGO, they
|
||||
will appear in a future version with these semantics but cannot currently be
|
||||
used.
|
||||
<!-- WARNING: Procedures are not implemented in the current version of LIGO, they -->
|
||||
<!-- will appear in a future version with these semantics but cannot currently be -->
|
||||
<!-- used. -->
|
||||
|
||||
Procedures are a special kind of functions that return `Unit`. They
|
||||
are declared as follows:
|
||||
<!-- Procedures are a special kind of functions that return `Unit`. They -->
|
||||
<!-- are declared as follows: -->
|
||||
|
||||
procedure my_name ( ... (* parameters here *)) is
|
||||
... // local declarations here
|
||||
begin
|
||||
... // instructions here
|
||||
end
|
||||
<!-- procedure my_name ( ... (* parameters here *)) is -->
|
||||
<!-- ... // local declarations here -->
|
||||
<!-- begin -->
|
||||
<!-- ... // instructions here -->
|
||||
<!-- end -->
|
||||
|
||||
Since function calls (see section "Functions") leave the environment
|
||||
invariant, one may wonder what use there is to procedures. As we have
|
||||
seen in the section about "Lists" and their iterators, the exception
|
||||
to this rule are predefined iterators, like `list_iter`. They actually
|
||||
allow the iterated function to perform side effects. Here is the
|
||||
example again:
|
||||
<!-- Since function calls (see section "Functions") leave the environment -->
|
||||
<!-- invariant, one may wonder what use there is to procedures. As we have -->
|
||||
<!-- seen in the section about "Lists" and their iterators, the exception -->
|
||||
<!-- to this rule are predefined iterators, like `list_iter`. They actually -->
|
||||
<!-- allow the iterated function to perform side effects. Here is the -->
|
||||
<!-- example again: -->
|
||||
|
||||
function iter (const delta : int; const l : list (int)) : int is
|
||||
var acc : int := 0
|
||||
procedure aggregate (const i : int) is
|
||||
begin
|
||||
acc := acc + i
|
||||
end
|
||||
begin
|
||||
aggregate (delta); // Has no effect on acc
|
||||
list_iter (l, aggregate) // Has an effect on acc
|
||||
end with acc
|
||||
<!-- function iter (const delta : int; const l : list (int)) : int is -->
|
||||
<!-- var acc : int := 0 -->
|
||||
<!-- procedure aggregate (const i : int) is -->
|
||||
<!-- begin -->
|
||||
<!-- acc := acc + i -->
|
||||
<!-- end -->
|
||||
<!-- begin -->
|
||||
<!-- aggregate (delta); // Has no effect on acc -->
|
||||
<!-- list_iter (l, aggregate) // Has an effect on acc -->
|
||||
<!-- end with acc -->
|
||||
|
||||
(For the keen reader, this is because the iterated function is inlined
|
||||
by the compiler.)
|
||||
<!-- (For the keen reader, this is because the iterated function is inlined -->
|
||||
<!-- by the compiler.) -->
|
||||
|
||||
## Instructions
|
||||
|
||||
@ -1154,7 +1150,7 @@ To iterate on a set `s`, we would write, for instance,
|
||||
... // instructions
|
||||
end
|
||||
|
||||
where `e` is bound in turn in increasing orde to each element of the
|
||||
where `e` is bound in turn in increasing order to each element of the
|
||||
set `s`. For example, given the declarations
|
||||
|
||||
const s : set (int) = set 3; 1; 2 end
|
||||
@ -1329,7 +1325,7 @@ PascaLIGO has an explicit keyword for the non-operation: `skip`. Using
|
||||
|
||||
- The `for` loop is not supported yet.
|
||||
|
||||
- Procedures are not supported yet.
|
||||
<!-- - Procedures are not supported yet. -->
|
||||
|
||||
- Nested code blocks are not supported yet.
|
||||
|
||||
|
@ -6,7 +6,7 @@ let () = Printexc.record_backtrace true
|
||||
|
||||
(* Reading the command-line options *)
|
||||
|
||||
let options = EvalOpt.read "Pascaligo" ".ligo"
|
||||
let options = EvalOpt.read "PascaLIGO" ".ligo"
|
||||
|
||||
open EvalOpt
|
||||
|
||||
|
@ -8,7 +8,7 @@ let () = Printexc.record_backtrace true
|
||||
|
||||
(* Reading the command-line options *)
|
||||
|
||||
let options = EvalOpt.read ()
|
||||
let options = EvalOpt.read "PascaLIGO" ".ligo"
|
||||
|
||||
open EvalOpt
|
||||
|
||||
|
@ -174,7 +174,7 @@ let check extension =
|
||||
|
||||
let read language extension =
|
||||
try
|
||||
Getopt.parse_cmdline (specs language extension) anonymous;
|
||||
Getopt.parse_cmdline (specs language extension) anonymous;
|
||||
(verb_str :=
|
||||
let apply e a =
|
||||
if a <> "" then Printf.sprintf "%s, %s" e a else e
|
||||
|
@ -47,6 +47,9 @@ type options = {
|
||||
cmd : command
|
||||
}
|
||||
|
||||
(* Parsing the command-line options on stdin *)
|
||||
(* Parsing the command-line options on stdin. The first parameter is
|
||||
the name of the concrete syntax, e.g., "pascaligo", and the second
|
||||
is the file extension, e.g., ".ligo".
|
||||
*)
|
||||
|
||||
val read : string -> string -> options
|
||||
|
Loading…
Reference in New Issue
Block a user