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