diff --git a/src/passes/1-parser/ligodity/.Parser.mly.tag b/src/passes/1-parser/ligodity/.Parser.mly.tag index c009b4efc..100f7bb69 100644 --- a/src/passes/1-parser/ligodity/.Parser.mly.tag +++ b/src/passes/1-parser/ligodity/.Parser.mly.tag @@ -1 +1 @@ ---explain --external-tokens Token --base Parser ParToken.mly +--explain --external-tokens LexToken --base Parser ParToken.mly diff --git a/src/passes/1-parser/ligodity/.links b/src/passes/1-parser/ligodity/.links index 1f30004d4..f0fdfb646 100644 --- a/src/passes/1-parser/ligodity/.links +++ b/src/passes/1-parser/ligodity/.links @@ -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 diff --git a/src/passes/1-parser/ligodity/LexerMain.ml b/src/passes/1-parser/ligodity/LexerMain.ml index 12f864562..a708432d0 100644 --- a/src/passes/1-parser/ligodity/LexerMain.ml +++ b/src/passes/1-parser/ligodity/LexerMain.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 diff --git a/src/passes/1-parser/ligodity/Parser.mly b/src/passes/1-parser/ligodity/Parser.mly index bb04220f6..0c8a5fbac 100644 --- a/src/passes/1-parser/ligodity/Parser.mly +++ b/src/passes/1-parser/ligodity/Parser.mly @@ -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 } - } \ No newline at end of file + } diff --git a/src/passes/1-parser/ligodity/ParserLog.ml b/src/passes/1-parser/ligodity/ParserLog.ml index 7f62ec5a6..5b594e969 100644 --- a/src/passes/1-parser/ligodity/ParserLog.ml +++ b/src/passes/1-parser/ligodity/ParserLog.ml @@ -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"; diff --git a/src/passes/1-parser/ligodity/ParserMain.ml b/src/passes/1-parser/ligodity/ParserMain.ml index 3d7ed2f3e..1a8913c70 100644 --- a/src/passes/1-parser/ligodity/ParserMain.ml +++ b/src/passes/1-parser/ligodity/ParserMain.ml @@ -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 diff --git a/src/passes/1-parser/pascaligo/.links b/src/passes/1-parser/pascaligo/.links index eff63d2f8..f0fdfb646 100644 --- a/src/passes/1-parser/pascaligo/.links +++ b/src/passes/1-parser/pascaligo/.links @@ -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 diff --git a/src/passes/1-parser/pascaligo/Doc/pascaligo.md b/src/passes/1-parser/pascaligo/Doc/pascaligo.md index 5f1b54a96..e9802ebab 100644 --- a/src/passes/1-parser/pascaligo/Doc/pascaligo.md +++ b/src/passes/1-parser/pascaligo/Doc/pascaligo.md @@ -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. + + + 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 + -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 + + + - 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". + + + + -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 + + + + + + + + + + -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) + + + + + + + + -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 + -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: + + - 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: + + + + + + - 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.) + + ## 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. + - Nested code blocks are not supported yet. diff --git a/src/passes/1-parser/pascaligo/ParserMain.ml b/src/passes/1-parser/pascaligo/ParserMain.ml index 8cb9daa03..14ee99307 100644 --- a/src/passes/1-parser/pascaligo/ParserMain.ml +++ b/src/passes/1-parser/pascaligo/ParserMain.ml @@ -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 diff --git a/src/passes/1-parser/pascaligo/SParserMain.ml b/src/passes/1-parser/pascaligo/SParserMain.ml index d6b91d0f1..64a2bcd96 100644 --- a/src/passes/1-parser/pascaligo/SParserMain.ml +++ b/src/passes/1-parser/pascaligo/SParserMain.ml @@ -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 diff --git a/src/passes/1-parser/shared/EvalOpt.ml b/src/passes/1-parser/shared/EvalOpt.ml index 25e5d3e02..44bb9adc8 100644 --- a/src/passes/1-parser/shared/EvalOpt.ml +++ b/src/passes/1-parser/shared/EvalOpt.ml @@ -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 diff --git a/src/passes/1-parser/shared/EvalOpt.mli b/src/passes/1-parser/shared/EvalOpt.mli index 1173ece56..3b4c3497a 100644 --- a/src/passes/1-parser/shared/EvalOpt.mli +++ b/src/passes/1-parser/shared/EvalOpt.mli @@ -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