Merge branch 'feature/pascaligo-anon-functions' into 'dev'
Feature/pascaligo anon functions See merge request ligolang/ligo!201
This commit is contained in:
commit
bbcacc253b
@ -36,7 +36,9 @@ Here's how you define a basic function that accepts two `ints` and returns a sin
|
|||||||
|
|
||||||
```pascaligo
|
```pascaligo
|
||||||
function add(const a: int; const b: int): int is
|
function add(const a: int; const b: int): int is
|
||||||
block { skip } with a + b
|
begin
|
||||||
|
const result: int = a + b;
|
||||||
|
end with result;
|
||||||
```
|
```
|
||||||
|
|
||||||
The function body consists of two parts:
|
The function body consists of two parts:
|
||||||
@ -44,9 +46,14 @@ The function body consists of two parts:
|
|||||||
- `block {<code>}` - logic of the function
|
- `block {<code>}` - logic of the function
|
||||||
- `with <value>` - the return value of the function
|
- `with <value>` - the return value of the function
|
||||||
|
|
||||||
> 💡 `skip` can be used as a placeholder for empty function blocks, when all the neccessary logic fits into `with` at the end. It is also possible to omit `block { skip } with`
|
#### Blockless functions
|
||||||
in the above example, leaving only `a + b`.
|
|
||||||
|
|
||||||
|
Functions that can contain all of their logic into a single instruction/expression, can be defined without the surrounding `block`.
|
||||||
|
Instead, you can inline the necessary logic directly, like this:
|
||||||
|
|
||||||
|
```pascaligo
|
||||||
|
function add(const a: int; const b: int): int is a + b
|
||||||
|
```
|
||||||
|
|
||||||
<!--Cameligo-->
|
<!--Cameligo-->
|
||||||
|
|
||||||
@ -65,3 +72,25 @@ value.
|
|||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
<!--Pascaligo-->
|
||||||
|
```pascaligo
|
||||||
|
const increment : (int -> int) = (function (const i : int) : int is i + 1);
|
||||||
|
// a = 2
|
||||||
|
const a: int = increment(1);
|
||||||
|
```
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
## Anonymous functions
|
||||||
|
|
||||||
|
Functions without a name, also known as anonymous functions are useful in cases when you want to pass the function as an argument or assign it to a key in a record/map.
|
||||||
|
|
||||||
|
Here's how to define an anonymous function assigned to a variable `increment`, with it's appropriate function type signature.
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
<!--Pascaligo-->
|
||||||
|
```pascaligo
|
||||||
|
const increment : (int -> int) = (function (const i : int) : int is i + 1);
|
||||||
|
// a = 2
|
||||||
|
const a: int = increment(1);
|
||||||
|
```
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
4
gitlab-pages/docs/language-basics/src/functions/add.ligo
Normal file
4
gitlab-pages/docs/language-basics/src/functions/add.ligo
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
function add(const a: int; const b: int): int is
|
||||||
|
begin
|
||||||
|
const result: int = a + b;
|
||||||
|
end with result;
|
@ -0,0 +1,3 @@
|
|||||||
|
const increment : (int -> int) = (function (const i : int) : int is i + 1);
|
||||||
|
// a = 2
|
||||||
|
const a: int = increment(1);
|
@ -0,0 +1 @@
|
|||||||
|
function add(const a: int; const b: int): int is a + b
|
@ -43,6 +43,9 @@ Variables, unlike constants, are mutable. They can't be used in a *global scope*
|
|||||||
|
|
||||||
> 💡 Don't worry if you don't understand the function syntax yet. We'll get to it in upcoming sections of the docs.
|
> 💡 Don't worry if you don't understand the function syntax yet. We'll get to it in upcoming sections of the docs.
|
||||||
|
|
||||||
|
> ⚠️ Please be wary that mutation only works within the function scope itself, values outside of the function scope will not be affected.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```pascaligo
|
```pascaligo
|
||||||
// won't work, use const for global values instead
|
// won't work, use const for global values instead
|
||||||
|
@ -18,55 +18,25 @@ const GridBlock = CompLibrary.GridBlock;
|
|||||||
const pre = "```";
|
const pre = "```";
|
||||||
|
|
||||||
const pascaligoExampleSmall = `${pre}pascaligo
|
const pascaligoExampleSmall = `${pre}pascaligo
|
||||||
// variant defining pseudo multi-entrypoint
|
|
||||||
// actions
|
|
||||||
type action is
|
|
||||||
| Increment of int
|
|
||||||
| Decrement of int
|
|
||||||
|
|
||||||
function add
|
|
||||||
(const a: int; const b: int): int is
|
|
||||||
block { skip } with a + b
|
|
||||||
|
|
||||||
function subtract
|
|
||||||
(const a: int; const b: int): int
|
|
||||||
is block { skip } with a - b
|
|
||||||
|
|
||||||
// real entrypoint that re-routes the flow
|
|
||||||
// based on the action provided
|
|
||||||
function main
|
|
||||||
(const p: action; const s: int):
|
|
||||||
(list(operation) * int) is
|
|
||||||
block { skip }
|
|
||||||
with ((nil : list(operation)),
|
|
||||||
case p of
|
|
||||||
| Increment(n) -> add(s, n)
|
|
||||||
| Decrement(n) -> subtract(s, n)
|
|
||||||
end)
|
|
||||||
${pre}`;
|
|
||||||
|
|
||||||
const pascaligoExample = `${pre}pascaligo
|
|
||||||
// variant defining pseudo multi-entrypoint actions
|
// variant defining pseudo multi-entrypoint actions
|
||||||
type action is
|
type action is
|
||||||
| Increment of int
|
| Increment of int
|
||||||
| Decrement of int
|
| Decrement of int
|
||||||
|
|
||||||
function add (const a : int ; const b : int) : int is
|
function add (const a : int ; const b : int) : int is a + b
|
||||||
block { skip } with a + b
|
|
||||||
|
|
||||||
function subtract (const a : int ; const b : int) : int is
|
function subtract (const a : int ; const b : int) : int is a - b
|
||||||
block { skip } with a - b
|
|
||||||
|
|
||||||
// real entrypoint that re-routes the flow based
|
// real entrypoint that re-routes the flow based on the action provided
|
||||||
// on the action provided
|
function main (const p : action ; const s : int) : (list(operation) * int) is
|
||||||
function main (const p : action ; const s : int) :
|
((nil : list(operation)),
|
||||||
(list(operation) * int) is
|
|
||||||
block { skip } with ((nil : list(operation)),
|
|
||||||
case p of
|
case p of
|
||||||
| Increment(n) -> add(s, n)
|
| Increment (n) -> add (s, n)
|
||||||
| Decrement(n) -> subtract(s, n)
|
| Decrement (n) -> subtract (s, n)
|
||||||
end)
|
end)
|
||||||
${pre}`;
|
${pre}`;
|
||||||
|
|
||||||
|
const pascaligoExample = pascaligoExampleSmall;
|
||||||
const cameligoExampleSmall = `${pre}ocaml
|
const cameligoExampleSmall = `${pre}ocaml
|
||||||
type storage = int
|
type storage = int
|
||||||
|
|
||||||
|
@ -210,9 +210,9 @@ and type_tuple = (type_expr, comma) nsepseq par reg
|
|||||||
|
|
||||||
(* Function and procedure declarations *)
|
(* Function and procedure declarations *)
|
||||||
|
|
||||||
and fun_decl = {
|
and fun_expr = {
|
||||||
kwd_function : kwd_function;
|
kwd_function : kwd_function;
|
||||||
name : variable;
|
name : variable option;
|
||||||
param : parameters;
|
param : parameters;
|
||||||
colon : colon;
|
colon : colon;
|
||||||
ret_type : type_expr;
|
ret_type : type_expr;
|
||||||
@ -221,7 +221,11 @@ and fun_decl = {
|
|||||||
block : block reg option;
|
block : block reg option;
|
||||||
kwd_with : kwd_with option;
|
kwd_with : kwd_with option;
|
||||||
return : expr;
|
return : expr;
|
||||||
terminator : semi option
|
}
|
||||||
|
|
||||||
|
and fun_decl = {
|
||||||
|
fun_expr : fun_expr reg ;
|
||||||
|
terminator : semi option ;
|
||||||
}
|
}
|
||||||
|
|
||||||
and parameters = (param_decl, semi) nsepseq par reg
|
and parameters = (param_decl, semi) nsepseq par reg
|
||||||
@ -266,12 +270,12 @@ and statement =
|
|||||||
| Data of data_decl
|
| Data of data_decl
|
||||||
|
|
||||||
and local_decl =
|
and local_decl =
|
||||||
LocalFun of fun_decl reg
|
|
||||||
| LocalData of data_decl
|
| LocalData of data_decl
|
||||||
|
|
||||||
and data_decl =
|
and data_decl =
|
||||||
LocalConst of const_decl reg
|
LocalConst of const_decl reg
|
||||||
| LocalVar of var_decl reg
|
| LocalVar of var_decl reg
|
||||||
|
| LocalFun of fun_decl reg
|
||||||
|
|
||||||
and var_decl = {
|
and var_decl = {
|
||||||
kwd_var : kwd_var;
|
kwd_var : kwd_var;
|
||||||
@ -464,6 +468,7 @@ and expr =
|
|||||||
| EUnit of c_Unit
|
| EUnit of c_Unit
|
||||||
| ETuple of tuple_expr
|
| ETuple of tuple_expr
|
||||||
| EPar of expr par reg
|
| EPar of expr par reg
|
||||||
|
| EFun of fun_expr reg
|
||||||
|
|
||||||
and annot_expr = (expr * type_expr)
|
and annot_expr = (expr * type_expr)
|
||||||
|
|
||||||
@ -644,7 +649,8 @@ let rec expr_to_region = function
|
|||||||
| EUnit region
|
| EUnit region
|
||||||
| ECase {region;_}
|
| ECase {region;_}
|
||||||
| ECond {region; _}
|
| ECond {region; _}
|
||||||
| EPar {region; _} -> region
|
| EPar {region; _}
|
||||||
|
| EFun {region; _} -> region
|
||||||
|
|
||||||
and tuple_expr_to_region {region; _} = region
|
and tuple_expr_to_region {region; _} = region
|
||||||
|
|
||||||
@ -752,7 +758,7 @@ let pattern_to_region = function
|
|||||||
| PTuple {region; _} -> region
|
| PTuple {region; _} -> region
|
||||||
|
|
||||||
let local_decl_to_region = function
|
let local_decl_to_region = function
|
||||||
LocalFun {region; _}
|
| LocalData LocalFun {region; _}
|
||||||
| LocalData LocalConst {region; _}
|
| LocalData LocalConst {region; _}
|
||||||
| LocalData LocalVar {region; _} -> region
|
| LocalData LocalVar {region; _} -> region
|
||||||
|
|
||||||
|
@ -201,9 +201,9 @@ and type_tuple = (type_expr, comma) nsepseq par reg
|
|||||||
|
|
||||||
(* Function declarations *)
|
(* Function declarations *)
|
||||||
|
|
||||||
and fun_decl ={
|
and fun_expr = {
|
||||||
kwd_function : kwd_function;
|
kwd_function : kwd_function;
|
||||||
name : variable;
|
name : variable option;
|
||||||
param : parameters;
|
param : parameters;
|
||||||
colon : colon;
|
colon : colon;
|
||||||
ret_type : type_expr;
|
ret_type : type_expr;
|
||||||
@ -212,7 +212,12 @@ and fun_decl ={
|
|||||||
block : block reg option;
|
block : block reg option;
|
||||||
kwd_with : kwd_with option;
|
kwd_with : kwd_with option;
|
||||||
return : expr;
|
return : expr;
|
||||||
terminator : semi option }
|
}
|
||||||
|
|
||||||
|
and fun_decl = {
|
||||||
|
fun_expr : fun_expr reg ;
|
||||||
|
terminator : semi option ;
|
||||||
|
}
|
||||||
|
|
||||||
and parameters = (param_decl, semi) nsepseq par reg
|
and parameters = (param_decl, semi) nsepseq par reg
|
||||||
|
|
||||||
@ -256,12 +261,12 @@ and statement =
|
|||||||
| Data of data_decl
|
| Data of data_decl
|
||||||
|
|
||||||
and local_decl =
|
and local_decl =
|
||||||
LocalFun of fun_decl reg
|
|
||||||
| LocalData of data_decl
|
| LocalData of data_decl
|
||||||
|
|
||||||
and data_decl =
|
and data_decl =
|
||||||
LocalConst of const_decl reg
|
LocalConst of const_decl reg
|
||||||
| LocalVar of var_decl reg
|
| LocalVar of var_decl reg
|
||||||
|
| LocalFun of fun_decl reg
|
||||||
|
|
||||||
and var_decl = {
|
and var_decl = {
|
||||||
kwd_var : kwd_var;
|
kwd_var : kwd_var;
|
||||||
@ -454,6 +459,7 @@ and expr =
|
|||||||
| EUnit of c_Unit
|
| EUnit of c_Unit
|
||||||
| ETuple of tuple_expr
|
| ETuple of tuple_expr
|
||||||
| EPar of expr par reg
|
| EPar of expr par reg
|
||||||
|
| EFun of fun_expr reg
|
||||||
|
|
||||||
and annot_expr = (expr * type_expr)
|
and annot_expr = (expr * type_expr)
|
||||||
|
|
||||||
|
@ -239,17 +239,11 @@ field_decl:
|
|||||||
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} }
|
||||||
|
|
||||||
(* Function declarations *)
|
fun_expr:
|
||||||
|
Function option(fun_name) parameters COLON type_expr Is
|
||||||
fun_decl:
|
|
||||||
Function fun_name parameters COLON type_expr Is
|
|
||||||
seq(local_decl)
|
|
||||||
block
|
block
|
||||||
With expr option(SEMI) {
|
With expr {
|
||||||
let stop =
|
let stop = expr_to_region $9 in
|
||||||
match $11 with
|
|
||||||
Some region -> region
|
|
||||||
| None -> expr_to_region $10 in
|
|
||||||
let region = cover $1 stop
|
let region = cover $1 stop
|
||||||
and value = {
|
and value = {
|
||||||
kwd_function = $1;
|
kwd_function = $1;
|
||||||
@ -258,18 +252,15 @@ fun_decl:
|
|||||||
colon = $4;
|
colon = $4;
|
||||||
ret_type = $5;
|
ret_type = $5;
|
||||||
kwd_is = $6;
|
kwd_is = $6;
|
||||||
local_decls = $7;
|
local_decls = [];
|
||||||
block = Some $8;
|
block = Some $7;
|
||||||
kwd_with = Some $9;
|
kwd_with = Some $8;
|
||||||
return = $10;
|
return = $9;
|
||||||
terminator = $11}
|
}
|
||||||
in {region;value}}
|
in {region;value}}
|
||||||
| Function fun_name parameters COLON type_expr Is
|
| Function option(fun_name) parameters COLON type_expr Is
|
||||||
expr option(SEMI) {
|
expr {
|
||||||
let stop =
|
let stop = expr_to_region $7 in
|
||||||
match $8 with
|
|
||||||
Some region -> region
|
|
||||||
| None -> expr_to_region $7 in
|
|
||||||
let region = cover $1 stop
|
let region = cover $1 stop
|
||||||
and value = {
|
and value = {
|
||||||
kwd_function = $1;
|
kwd_function = $1;
|
||||||
@ -282,10 +273,36 @@ fun_decl:
|
|||||||
block = None;
|
block = None;
|
||||||
kwd_with = None;
|
kwd_with = None;
|
||||||
return = $7;
|
return = $7;
|
||||||
terminator = $8;
|
|
||||||
}
|
}
|
||||||
in {region;value}}
|
in {region;value}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(* Function declarations *)
|
||||||
|
|
||||||
|
fun_decl:
|
||||||
|
fun_expr option(SEMI) {
|
||||||
|
let stop =
|
||||||
|
match $2 with
|
||||||
|
Some region -> region
|
||||||
|
| None -> $1.region in
|
||||||
|
let region = cover $1.region stop
|
||||||
|
and value = {
|
||||||
|
fun_expr = $1;
|
||||||
|
terminator = $2;
|
||||||
|
}
|
||||||
|
in {region;value}}
|
||||||
|
|
||||||
|
open_fun_decl:
|
||||||
|
fun_expr {
|
||||||
|
let region = $1.region
|
||||||
|
and value = {
|
||||||
|
fun_expr = $1;
|
||||||
|
terminator = None;
|
||||||
|
}
|
||||||
|
in {region;value}}
|
||||||
|
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
par(nsepseq(param_decl,SEMI)) { $1 }
|
par(nsepseq(param_decl,SEMI)) { $1 }
|
||||||
|
|
||||||
@ -341,6 +358,7 @@ statement:
|
|||||||
open_data_decl:
|
open_data_decl:
|
||||||
open_const_decl { LocalConst $1 }
|
open_const_decl { LocalConst $1 }
|
||||||
| open_var_decl { LocalVar $1 }
|
| open_var_decl { LocalVar $1 }
|
||||||
|
| open_fun_decl { LocalFun $1 }
|
||||||
|
|
||||||
open_const_decl:
|
open_const_decl:
|
||||||
Const unqualified_decl(EQ) {
|
Const unqualified_decl(EQ) {
|
||||||
@ -370,14 +388,6 @@ open_var_decl:
|
|||||||
terminator = None}
|
terminator = None}
|
||||||
in {region; value}}
|
in {region; value}}
|
||||||
|
|
||||||
local_decl:
|
|
||||||
fun_decl { LocalFun $1 }
|
|
||||||
| data_decl { LocalData $1 }
|
|
||||||
|
|
||||||
data_decl:
|
|
||||||
const_decl { LocalConst $1 }
|
|
||||||
| var_decl { LocalVar $1 }
|
|
||||||
|
|
||||||
unqualified_decl(OP):
|
unqualified_decl(OP):
|
||||||
var COLON type_expr OP expr {
|
var COLON type_expr OP expr {
|
||||||
let region = expr_to_region $5
|
let region = expr_to_region $5
|
||||||
@ -390,12 +400,6 @@ const_decl:
|
|||||||
}
|
}
|
||||||
| open_const_decl { $1 }
|
| open_const_decl { $1 }
|
||||||
|
|
||||||
var_decl:
|
|
||||||
open_var_decl SEMI {
|
|
||||||
let var_decl : AST.var_decl = $1.value in
|
|
||||||
{$1 with value = {var_decl with terminator = Some $2}}
|
|
||||||
}
|
|
||||||
| open_var_decl { $1 }
|
|
||||||
|
|
||||||
instruction:
|
instruction:
|
||||||
conditional { Cond $1 }
|
conditional { Cond $1 }
|
||||||
@ -683,6 +687,7 @@ expr:
|
|||||||
case(expr) { ECase ($1 expr_to_region) }
|
case(expr) { ECase ($1 expr_to_region) }
|
||||||
| cond_expr { $1 }
|
| cond_expr { $1 }
|
||||||
| disj_expr { $1 }
|
| disj_expr { $1 }
|
||||||
|
| fun_expr { EFun $1 }
|
||||||
|
|
||||||
cond_expr:
|
cond_expr:
|
||||||
If expr Then expr option(SEMI) Else expr {
|
If expr Then expr option(SEMI) Else expr {
|
||||||
|
@ -156,12 +156,13 @@ and print_type_tuple buffer {value; _} =
|
|||||||
print_nsepseq buffer "," print_type_expr inside;
|
print_nsepseq buffer "," print_type_expr inside;
|
||||||
print_token buffer rpar ")"
|
print_token buffer rpar ")"
|
||||||
|
|
||||||
and print_fun_decl buffer {value; _} =
|
and print_fun_expr buffer {value; _} =
|
||||||
let {kwd_function; name; param; colon;
|
let {kwd_function; name; param; colon;
|
||||||
ret_type; kwd_is; local_decls;
|
ret_type; kwd_is; local_decls;
|
||||||
block; kwd_with; return; terminator} = value in
|
block; kwd_with; return;} = value in
|
||||||
|
let anonymous_name = Region.wrap_ghost "#anonymous" in
|
||||||
print_token buffer kwd_function "function";
|
print_token buffer kwd_function "function";
|
||||||
print_var buffer name;
|
print_var buffer @@ Simple_utils.Option.unopt ~default:anonymous_name name;
|
||||||
print_parameters buffer param;
|
print_parameters buffer param;
|
||||||
print_token buffer colon ":";
|
print_token buffer colon ":";
|
||||||
print_type_expr buffer ret_type;
|
print_type_expr buffer ret_type;
|
||||||
@ -173,7 +174,11 @@ and print_fun_decl buffer {value; _} =
|
|||||||
print_token buffer kwd_with "with";
|
print_token buffer kwd_with "with";
|
||||||
| None -> ();
|
| None -> ();
|
||||||
print_expr buffer return;
|
print_expr buffer return;
|
||||||
print_terminator buffer terminator
|
|
||||||
|
and print_fun_decl buffer {value; _} =
|
||||||
|
let {fun_expr ; terminator;} = value in
|
||||||
|
print_fun_expr buffer fun_expr;
|
||||||
|
print_terminator buffer terminator;
|
||||||
|
|
||||||
and print_parameters buffer {value; _} =
|
and print_parameters buffer {value; _} =
|
||||||
let {lpar; inside; rpar} = value in
|
let {lpar; inside; rpar} = value in
|
||||||
@ -225,12 +230,12 @@ and print_local_decls buffer sequence =
|
|||||||
List.iter (print_local_decl buffer) sequence
|
List.iter (print_local_decl buffer) sequence
|
||||||
|
|
||||||
and print_local_decl buffer = function
|
and print_local_decl buffer = function
|
||||||
LocalFun decl -> print_fun_decl buffer decl
|
|
||||||
| LocalData decl -> print_data_decl buffer decl
|
| LocalData decl -> print_data_decl buffer decl
|
||||||
|
|
||||||
and print_data_decl buffer = function
|
and print_data_decl buffer = function
|
||||||
LocalConst decl -> print_const_decl buffer decl
|
LocalConst decl -> print_const_decl buffer decl
|
||||||
| LocalVar decl -> print_var_decl buffer decl
|
| LocalVar decl -> print_var_decl buffer decl
|
||||||
|
| LocalFun decl -> print_fun_decl buffer decl
|
||||||
|
|
||||||
and print_var_decl buffer {value; _} =
|
and print_var_decl buffer {value; _} =
|
||||||
let {kwd_var; name; colon; var_type;
|
let {kwd_var; name; colon; var_type;
|
||||||
@ -402,6 +407,7 @@ and print_expr buffer = function
|
|||||||
| EUnit r -> print_token buffer r "Unit"
|
| EUnit r -> print_token buffer r "Unit"
|
||||||
| ETuple e -> print_tuple_expr buffer e
|
| ETuple e -> print_tuple_expr buffer e
|
||||||
| EPar e -> print_par_expr buffer e
|
| EPar e -> print_par_expr buffer e
|
||||||
|
| EFun e -> print_fun_expr buffer e
|
||||||
|
|
||||||
and print_annot_expr buffer (expr , type_expr) =
|
and print_annot_expr buffer (expr , type_expr) =
|
||||||
print_expr buffer expr;
|
print_expr buffer expr;
|
||||||
@ -795,7 +801,7 @@ and pp_declaration buffer ~pad:(_,pc as pad) = function
|
|||||||
pp_const_decl buffer ~pad value
|
pp_const_decl buffer ~pad value
|
||||||
| FunDecl {value; region} ->
|
| FunDecl {value; region} ->
|
||||||
pp_loc_node buffer ~pad "FunDecl" region;
|
pp_loc_node buffer ~pad "FunDecl" region;
|
||||||
pp_fun_decl buffer ~pad value
|
pp_fun_expr buffer ~pad value.fun_expr.value
|
||||||
|
|
||||||
and pp_const_decl buffer ~pad:(_,pc) decl =
|
and pp_const_decl buffer ~pad:(_,pc) decl =
|
||||||
pp_ident buffer ~pad:(mk_pad 3 0 pc) decl.name;
|
pp_ident buffer ~pad:(mk_pad 3 0 pc) decl.name;
|
||||||
@ -861,12 +867,13 @@ and pp_type_tuple buffer ~pad:(_,pc) {value; _} =
|
|||||||
pp_type_expr buffer ~pad:(mk_pad len rank pc)
|
pp_type_expr buffer ~pad:(mk_pad len rank pc)
|
||||||
in List.iteri (List.length components |> apply) components
|
in List.iteri (List.length components |> apply) components
|
||||||
|
|
||||||
and pp_fun_decl buffer ~pad:(_,pc) decl =
|
and pp_fun_expr buffer ~pad:(_,pc) decl =
|
||||||
let fields =
|
let fields =
|
||||||
if decl.local_decls = [] then 5 else 6 in
|
if decl.local_decls = [] then 5 else 6 in
|
||||||
let () =
|
let () =
|
||||||
let pad = mk_pad fields 0 pc in
|
let pad = mk_pad fields 0 pc in
|
||||||
pp_ident buffer ~pad decl.name in
|
let anonymous_name = Region.wrap_ghost "#anonymous" in
|
||||||
|
pp_ident buffer ~pad @@ Simple_utils.Option.unopt ~default:anonymous_name decl.name in
|
||||||
let () =
|
let () =
|
||||||
let pad = mk_pad fields 1 pc in
|
let pad = mk_pad fields 1 pc in
|
||||||
pp_node buffer ~pad "<parameters>";
|
pp_node buffer ~pad "<parameters>";
|
||||||
@ -1294,9 +1301,6 @@ and pp_local_decls buffer ~pad:(_,pc) decls =
|
|||||||
in List.iteri (List.length decls |> apply) decls
|
in List.iteri (List.length decls |> apply) decls
|
||||||
|
|
||||||
and pp_local_decl buffer ~pad:(_,pc as pad) = function
|
and pp_local_decl buffer ~pad:(_,pc as pad) = function
|
||||||
LocalFun {value; region} ->
|
|
||||||
pp_loc_node buffer ~pad "LocalFun" region;
|
|
||||||
pp_fun_decl buffer ~pad value
|
|
||||||
| LocalData data ->
|
| LocalData data ->
|
||||||
pp_node buffer ~pad "LocalData";
|
pp_node buffer ~pad "LocalData";
|
||||||
pp_data_decl buffer ~pad:(mk_pad 1 0 pc) data
|
pp_data_decl buffer ~pad:(mk_pad 1 0 pc) data
|
||||||
@ -1308,6 +1312,9 @@ and pp_data_decl buffer ~pad = function
|
|||||||
| LocalVar {value; region} ->
|
| LocalVar {value; region} ->
|
||||||
pp_loc_node buffer ~pad "LocalVar" region;
|
pp_loc_node buffer ~pad "LocalVar" region;
|
||||||
pp_var_decl buffer ~pad value
|
pp_var_decl buffer ~pad value
|
||||||
|
| LocalFun {value; region} ->
|
||||||
|
pp_loc_node buffer ~pad "LocalFun" region;
|
||||||
|
pp_fun_expr buffer ~pad value.fun_expr.value
|
||||||
|
|
||||||
and pp_var_decl buffer ~pad:(_,pc) decl =
|
and pp_var_decl buffer ~pad:(_,pc) decl =
|
||||||
pp_ident buffer ~pad:(mk_pad 3 0 pc) decl.name;
|
pp_ident buffer ~pad:(mk_pad 3 0 pc) decl.name;
|
||||||
@ -1368,6 +1375,9 @@ and pp_expr buffer ~pad:(_,pc as pad) = function
|
|||||||
| EPar {value; region} ->
|
| EPar {value; region} ->
|
||||||
pp_loc_node buffer ~pad "EPar" region;
|
pp_loc_node buffer ~pad "EPar" region;
|
||||||
pp_expr buffer ~pad:(mk_pad 1 0 pc) value.inside
|
pp_expr buffer ~pad:(mk_pad 1 0 pc) value.inside
|
||||||
|
| EFun {value; region} ->
|
||||||
|
pp_loc_node buffer ~pad "EFun" region;
|
||||||
|
pp_fun_expr ~pad buffer value;
|
||||||
|
|
||||||
and pp_list_expr buffer ~pad:(_,pc as pad) = function
|
and pp_list_expr buffer ~pad:(_,pc as pad) = function
|
||||||
ECons {value; region} ->
|
ECons {value; region} ->
|
||||||
|
@ -117,6 +117,22 @@ module Errors = struct
|
|||||||
] in
|
] in
|
||||||
error ~data title message
|
error ~data title message
|
||||||
|
|
||||||
|
let unexpected_anonymous_function loc =
|
||||||
|
let title () = "unexpected anonymous function" in
|
||||||
|
let message () = "you provided a function declaration without name" in
|
||||||
|
let data = [
|
||||||
|
("loc" , fun () -> Format.asprintf "%a" Location.pp @@ loc)
|
||||||
|
] in
|
||||||
|
error ~data title message
|
||||||
|
|
||||||
|
let unexpected_named_function loc =
|
||||||
|
let title () = "unexpected named function" in
|
||||||
|
let message () = "you provided a function expression with a name (remove it)" in
|
||||||
|
let data = [
|
||||||
|
("loc" , fun () -> Format.asprintf "%a" Location.pp @@ loc)
|
||||||
|
] in
|
||||||
|
error ~data title message
|
||||||
|
|
||||||
(* Logging *)
|
(* Logging *)
|
||||||
|
|
||||||
let simplifying_instruction t =
|
let simplifying_instruction t =
|
||||||
@ -410,6 +426,13 @@ let rec simpl_expression (t:Raw.expr) : expr result =
|
|||||||
let%bind index = simpl_expression lu.index.value.inside in
|
let%bind index = simpl_expression lu.index.value.inside in
|
||||||
return @@ e_look_up ~loc path index
|
return @@ e_look_up ~loc path index
|
||||||
)
|
)
|
||||||
|
| EFun f -> (
|
||||||
|
let (f , loc) = r_split f in
|
||||||
|
let%bind ((name_opt , _ty_opt) , f') = simpl_fun_expression ~loc f in
|
||||||
|
match name_opt with
|
||||||
|
| None -> return @@ f'
|
||||||
|
| Some _ -> fail @@ unexpected_named_function loc
|
||||||
|
)
|
||||||
|
|
||||||
and simpl_logic_expression (t:Raw.logic_expr) : expression result =
|
and simpl_logic_expression (t:Raw.logic_expr) : expression result =
|
||||||
let return x = ok x in
|
let return x = ok x in
|
||||||
@ -497,10 +520,6 @@ and simpl_local_declaration : Raw.local_decl -> _ result = fun t ->
|
|||||||
match t with
|
match t with
|
||||||
| LocalData d ->
|
| LocalData d ->
|
||||||
simpl_data_declaration d
|
simpl_data_declaration d
|
||||||
| LocalFun f ->
|
|
||||||
let (f , loc) = r_split f in
|
|
||||||
let%bind (name , e) = simpl_fun_declaration ~loc f in
|
|
||||||
return_let_in ~loc name e
|
|
||||||
|
|
||||||
and simpl_data_declaration : Raw.data_decl -> _ result = fun t ->
|
and simpl_data_declaration : Raw.data_decl -> _ result = fun t ->
|
||||||
match t with
|
match t with
|
||||||
@ -516,6 +535,11 @@ and simpl_data_declaration : Raw.data_decl -> _ result = fun t ->
|
|||||||
let%bind t = simpl_type_expression x.const_type in
|
let%bind t = simpl_type_expression x.const_type in
|
||||||
let%bind expression = simpl_expression x.init in
|
let%bind expression = simpl_expression x.init in
|
||||||
return_let_in ~loc (name , Some t) expression
|
return_let_in ~loc (name , Some t) expression
|
||||||
|
| LocalFun f ->
|
||||||
|
let (f , loc) = r_split f in
|
||||||
|
let%bind ((name_opt , ty_opt) , e) = simpl_fun_expression ~loc f.fun_expr.value in
|
||||||
|
let%bind name = trace_option (unexpected_anonymous_function loc) name_opt in
|
||||||
|
return_let_in ~loc (name , ty_opt) e
|
||||||
|
|
||||||
and simpl_param : Raw.param_decl -> (type_name * type_expression) result =
|
and simpl_param : Raw.param_decl -> (type_name * type_expression) result =
|
||||||
fun t ->
|
fun t ->
|
||||||
@ -531,11 +555,11 @@ and simpl_param : Raw.param_decl -> (type_name * type_expression) result =
|
|||||||
let%bind type_expression = simpl_type_expression c.param_type in
|
let%bind type_expression = simpl_type_expression c.param_type in
|
||||||
ok (type_name , type_expression)
|
ok (type_name , type_expression)
|
||||||
|
|
||||||
and simpl_fun_declaration :
|
and simpl_fun_expression :
|
||||||
loc:_ -> Raw.fun_decl -> ((name * type_expression option) * expression) result =
|
loc:_ -> Raw.fun_expr -> ((name option * type_expression option) * expression) result =
|
||||||
fun ~loc x ->
|
fun ~loc x ->
|
||||||
let open! Raw in
|
let open! Raw in
|
||||||
let {name;param;ret_type;local_decls;block;return} : fun_decl = x in
|
let {name;param;ret_type;local_decls;block;return} : fun_expr = x in
|
||||||
let statements =
|
let statements =
|
||||||
match block with
|
match block with
|
||||||
| Some block -> npseq_to_list block.value.statements
|
| Some block -> npseq_to_list block.value.statements
|
||||||
@ -544,7 +568,7 @@ and simpl_fun_declaration :
|
|||||||
(match param.value.inside with
|
(match param.value.inside with
|
||||||
a, [] -> (
|
a, [] -> (
|
||||||
let%bind input = simpl_param a in
|
let%bind input = simpl_param a in
|
||||||
let name = name.value in
|
let name = Option.map (fun (x : _ reg) -> x.value) name in
|
||||||
let (binder , input_type) = input in
|
let (binder , input_type) = input in
|
||||||
let%bind local_declarations =
|
let%bind local_declarations =
|
||||||
bind_map_list simpl_local_declaration local_decls in
|
bind_map_list simpl_local_declaration local_decls in
|
||||||
@ -591,7 +615,8 @@ and simpl_fun_declaration :
|
|||||||
let expression =
|
let expression =
|
||||||
e_lambda ~loc binder (Some input_type) (Some output_type) result in
|
e_lambda ~loc binder (Some input_type) (Some output_type) result in
|
||||||
let type_annotation = Some (T_function (input_type, output_type)) in
|
let type_annotation = Some (T_function (input_type, output_type)) in
|
||||||
ok ((name.value , type_annotation) , expression)
|
let name = Option.map (fun (x : _ reg) -> x.value) name in
|
||||||
|
ok ((name , type_annotation) , expression)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
and simpl_declaration : Raw.declaration -> declaration Location.wrap result =
|
and simpl_declaration : Raw.declaration -> declaration Location.wrap result =
|
||||||
@ -614,7 +639,8 @@ and simpl_declaration : Raw.declaration -> declaration Location.wrap result =
|
|||||||
bind_map_location simpl_const_decl (Location.lift_region x)
|
bind_map_location simpl_const_decl (Location.lift_region x)
|
||||||
| FunDecl x -> (
|
| FunDecl x -> (
|
||||||
let (x , loc) = r_split x in
|
let (x , loc) = r_split x in
|
||||||
let%bind ((name , ty_opt) , expr) = simpl_fun_declaration ~loc x in
|
let%bind ((name_opt , ty_opt) , expr) = simpl_fun_expression ~loc x.fun_expr.value in
|
||||||
|
let%bind name = trace_option (unexpected_anonymous_function loc) name_opt in
|
||||||
ok @@ Location.wrap ~loc (Declaration_constant (name , ty_opt , expr))
|
ok @@ Location.wrap ~loc (Declaration_constant (name , ty_opt , expr))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@ type storage_ is big_map(int, int) * unit
|
|||||||
type foo is big_map(int, int)
|
type foo is big_map(int, int)
|
||||||
|
|
||||||
function main(const p : unit; const s : storage_) : list(operation) * storage_ is
|
function main(const p : unit; const s : storage_) : list(operation) * storage_ is
|
||||||
var toto : option (int) := Some(0);
|
|
||||||
block {
|
block {
|
||||||
|
var toto : option (int) := Some(0);
|
||||||
toto := s.0[23];
|
toto := s.0[23];
|
||||||
s.0[2] := 444;
|
s.0[2] := 444;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
function foo (const i : int) : int is
|
function foo (const i : int) : int is
|
||||||
|
block {
|
||||||
function bar (const j : int) : int is
|
function bar (const j : int) : int is
|
||||||
block { skip } with i + j ;
|
i + j ;
|
||||||
block { skip } with bar (i)
|
} with bar (i)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
function foobar(const i : int) : int is
|
function foobar(const i : int) : int is
|
||||||
|
block {
|
||||||
const j : int = 3 ;
|
const j : int = 3 ;
|
||||||
function toto(const k : int) : int is
|
function toto(const k : int) : int is
|
||||||
block { skip } with i + j + k ;
|
i + j + k ;
|
||||||
block { skip } with toto(42)
|
} with toto(42)
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
// https://gitlab.com/ligolang/ligo/commit/faf3bbc06106de98189f1c1673bd57e78351dc7e
|
// https://gitlab.com/ligolang/ligo/commit/faf3bbc06106de98189f1c1673bd57e78351dc7e
|
||||||
|
|
||||||
function foobar(const i : int) : int is
|
function foobar(const i : int) : int is
|
||||||
|
block {
|
||||||
const j : int = 3 ;
|
const j : int = 3 ;
|
||||||
const k : int = 4 ;
|
const k : int = 4 ;
|
||||||
function toto(const l : int) : int is
|
function toto(const l : int) : int is
|
||||||
block { skip } with i + j + k + l;
|
i + j + k + l;
|
||||||
block { skip } with toto(42)
|
|
||||||
|
} with toto(42)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
function toto (const i : int) : int is
|
function toto (const i : int) : int is
|
||||||
|
block {
|
||||||
function tata (const j : int) : int is
|
function tata (const j : int) : int is
|
||||||
block { skip } with i + j ;
|
i + j ;
|
||||||
function titi (const j : int) : int is
|
function titi (const j : int) : int is
|
||||||
block { skip } with i + j ;
|
i + j ;
|
||||||
block { skip } with tata(i) + titi(i)
|
} with tata(i) + titi(i)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// Test if conditional in PascaLIGO
|
// Test if conditional in PascaLIGO
|
||||||
|
|
||||||
function main (const i : int) : int is
|
function main (const i : int) : int is
|
||||||
var result : int := 23 ;
|
|
||||||
begin
|
begin
|
||||||
|
var result : int := 23 ;
|
||||||
if i = 2 then
|
if i = 2 then
|
||||||
result := 42
|
result := 42
|
||||||
else
|
else
|
||||||
@ -10,7 +10,7 @@ function main (const i : int) : int is
|
|||||||
end with result
|
end with result
|
||||||
|
|
||||||
function foo (const b : bool) : int is
|
function foo (const b : bool) : int is
|
||||||
var x : int := 41 ;
|
|
||||||
begin
|
begin
|
||||||
|
var x : int := 41 ;
|
||||||
x := 1 + (if b then x else main(x)) ;
|
x := 1 + (if b then x else main(x)) ;
|
||||||
end with x
|
end with x
|
@ -3,20 +3,17 @@ type pii is (int*int)
|
|||||||
type ppi is record x:pii; y:pii end
|
type ppi is record x:pii; y:pii end
|
||||||
type ppp is (ppi*ppi)
|
type ppp is (ppi*ppi)
|
||||||
|
|
||||||
function main (const toto : unit) : int is
|
function main (const toto : unit) : int is block {
|
||||||
var a : ppp :=
|
var a : ppp := (
|
||||||
(
|
record
|
||||||
record
|
x = (0,1);
|
||||||
x = (0,1);
|
y = (10,11);
|
||||||
y = (10,11);
|
end ,
|
||||||
end
|
record
|
||||||
,
|
x = (100,101);
|
||||||
record
|
y = (110,111);
|
||||||
x = (100,101);
|
end
|
||||||
y = (110,111);
|
) ;
|
||||||
end
|
|
||||||
)
|
|
||||||
begin
|
|
||||||
a.0.x.0 := 2;
|
a.0.x.0 := 2;
|
||||||
const b:int = a.0.x.0;
|
const b:int = a.0.x.0;
|
||||||
end with b
|
} with b
|
||||||
|
@ -12,8 +12,8 @@ function main (const p : param; const s : unit) : list(operation) * unit is
|
|||||||
with ((nil : list(operation)), s)
|
with ((nil : list(operation)), s)
|
||||||
|
|
||||||
function foobar (const i : int) : int is
|
function foobar (const i : int) : int is
|
||||||
var p : param := Zero (42n) ;
|
|
||||||
block {
|
block {
|
||||||
|
var p : param := Zero (42n) ;
|
||||||
if i > 0 then block {
|
if i > 0 then block {
|
||||||
i := i + 1 ;
|
i := i + 1 ;
|
||||||
if i > 10 then block {
|
if i > 10 then block {
|
||||||
|
1
src/test/contracts/function-anon.ligo
Normal file
1
src/test/contracts/function-anon.ligo
Normal file
@ -0,0 +1 @@
|
|||||||
|
const x : int = (function (const i : int) : int is i + 1)(41)
|
@ -1,9 +1,9 @@
|
|||||||
// Test a PascaLIGO function with more complex logic than function.ligo
|
// Test a PascaLIGO function with more complex logic than function.ligo
|
||||||
|
|
||||||
function main (const i : int) : int is
|
function main (const i : int) : int is
|
||||||
|
begin
|
||||||
var j : int := 0 ;
|
var j : int := 0 ;
|
||||||
var k : int := 1 ;
|
var k : int := 1 ;
|
||||||
begin
|
|
||||||
j := k + i ;
|
j := k + i ;
|
||||||
k := i + j ;
|
k := i + j ;
|
||||||
end with (k + j)
|
end with (k + j)
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
// Test a PascaLIGO function which takes another PascaLIGO function as an argument
|
// Test a PascaLIGO function which takes another PascaLIGO function as an argument
|
||||||
function foobar (const i : int) : int is
|
function foobar (const i : int) : int is
|
||||||
|
block {
|
||||||
function foo (const i : int) : int is
|
function foo (const i : int) : int is
|
||||||
block { skip } with i ;
|
i ;
|
||||||
function bar (const f : int -> int) : int is
|
function bar (const f : int -> int) : int is
|
||||||
block { skip } with f ( i ) ;
|
f ( i ) ;
|
||||||
block { skip } with bar (foo) ;
|
} with bar (foo) ;
|
||||||
|
|
||||||
// higher order function with more than one argument
|
// higher order function with more than one argument
|
||||||
function higher2(const i: int; const f: int -> int): int is
|
function higher2(const i: int; const f: int -> int): int is
|
||||||
@ -13,27 +14,26 @@ function higher2(const i: int; const f: int -> int): int is
|
|||||||
} with ii
|
} with ii
|
||||||
|
|
||||||
function foobar2 (const i : int) : int is
|
function foobar2 (const i : int) : int is
|
||||||
|
block {
|
||||||
function foo2 (const i : int) : int is
|
function foo2 (const i : int) : int is
|
||||||
block { skip } with i;
|
i;
|
||||||
block { skip } with higher2(i,foo2)
|
} with higher2(i,foo2)
|
||||||
|
|
||||||
const a : int = 0;
|
const a : int = 0;
|
||||||
function foobar3 (const i : int) : int is
|
function foobar3 (const i : int) : int is
|
||||||
|
block {
|
||||||
function foo2 (const i : int) : int is
|
function foo2 (const i : int) : int is
|
||||||
block { skip } with (a+i);
|
(a+i);
|
||||||
block { skip } with higher2(i,foo2)
|
} with higher2(i,foo2)
|
||||||
|
|
||||||
function f (const i : int) : int is
|
function f (const i : int) : int is
|
||||||
block { skip }
|
i
|
||||||
with i
|
|
||||||
|
|
||||||
function g (const i : int) : int is
|
function g (const i : int) : int is
|
||||||
block { skip }
|
f(i)
|
||||||
with f(i)
|
|
||||||
|
|
||||||
function foobar4 (const i : int) : int is
|
function foobar4 (const i : int) : int is
|
||||||
block { skip }
|
g(g(i))
|
||||||
with g(g(i))
|
|
||||||
|
|
||||||
function higher3(const i: int; const f: int -> int; const g: int -> int): int is
|
function higher3(const i: int; const f: int -> int; const g: int -> int): int is
|
||||||
block {
|
block {
|
||||||
@ -41,9 +41,10 @@ function higher3(const i: int; const f: int -> int; const g: int -> int): int is
|
|||||||
} with ii
|
} with ii
|
||||||
|
|
||||||
function foobar5 (const i : int) : int is
|
function foobar5 (const i : int) : int is
|
||||||
|
block {
|
||||||
const a : int = 0;
|
const a : int = 0;
|
||||||
function foo (const i : int) : int is
|
function foo (const i : int) : int is
|
||||||
block { skip } with (a+i);
|
(a+i);
|
||||||
function goo (const i : int) : int is
|
function goo (const i : int) : int is
|
||||||
block { skip } with foo(i);
|
foo(i);
|
||||||
block { skip } with higher3(i,foo,goo)
|
} with higher3(i,foo,goo)
|
||||||
|
@ -2,5 +2,6 @@ function f (const x : unit) : unit is
|
|||||||
begin skip end with unit
|
begin skip end with unit
|
||||||
|
|
||||||
function main (const p : unit ; const s : unit) : unit is
|
function main (const p : unit ; const s : unit) : unit is
|
||||||
|
begin
|
||||||
var y : unit := f(unit) ;
|
var y : unit := f(unit) ;
|
||||||
begin skip end with y
|
end with y
|
||||||
|
@ -25,15 +25,16 @@ const bl : foobar = list
|
|||||||
end
|
end
|
||||||
|
|
||||||
function iter_op (const s : list(int)) : int is
|
function iter_op (const s : list(int)) : int is
|
||||||
|
begin
|
||||||
var r : int := 0 ;
|
var r : int := 0 ;
|
||||||
function aggregate (const i : int) : unit is
|
function aggregate (const i : int) : unit is
|
||||||
begin
|
begin
|
||||||
r := r + i ;
|
r := r + i ;
|
||||||
end with unit
|
end with unit ;
|
||||||
begin
|
|
||||||
list_iter(s , aggregate) ;
|
list_iter(s , aggregate) ;
|
||||||
end with r
|
end with r
|
||||||
|
|
||||||
function map_op (const s : list(int)) : list(int) is
|
function map_op (const s : list(int)) : list(int) is
|
||||||
|
block {
|
||||||
function increment (const i : int) : int is block { skip } with i + 1
|
function increment (const i : int) : int is block { skip } with i + 1
|
||||||
block { skip } with list_map(s , increment)
|
} with list_map(s , increment)
|
||||||
|
@ -48,23 +48,25 @@ function get_ (const m : foobar) : option(int) is
|
|||||||
end with map_get(42 , m)
|
end with map_get(42 , m)
|
||||||
|
|
||||||
function iter_op (const m : foobar) : unit is
|
function iter_op (const m : foobar) : unit is
|
||||||
|
block {
|
||||||
function aggregate (const i : int ; const j : int) : unit is block
|
function aggregate (const i : int ; const j : int) : unit is block
|
||||||
{ if (i=j) then skip else failwith("fail") } with unit ;
|
{ if (i=j) then skip else failwith("fail") } with unit ;
|
||||||
block {skip}
|
|
||||||
// map_iter(m , aggregate) ;
|
// map_iter(m , aggregate) ;
|
||||||
with map_iter(m, aggregate) ;
|
} with map_iter(m, aggregate) ;
|
||||||
|
|
||||||
function map_op (const m : foobar) : foobar is
|
function map_op (const m : foobar) : foobar is
|
||||||
|
block {
|
||||||
function increment (const i : int ; const j : int) : int is block { skip } with j + 1 ;
|
function increment (const i : int ; const j : int) : int is block { skip } with j + 1 ;
|
||||||
block { skip } with map_map(m , increment) ;
|
} with map_map(m , increment) ;
|
||||||
|
|
||||||
function fold_op (const m : foobar) : int is
|
function fold_op (const m : foobar) : int is
|
||||||
|
block {
|
||||||
function aggregate (const i : int ; const j : (int * int)) : int is block { skip } with i + j.0 + j.1 ;
|
function aggregate (const i : int ; const j : (int * int)) : int is block { skip } with i + j.0 + j.1 ;
|
||||||
block { skip } with map_fold(m , 10 , aggregate)
|
} with map_fold(m , 10 , aggregate)
|
||||||
|
|
||||||
function deep_op (var m : foobar) : foobar is
|
function deep_op (var m : foobar) : foobar is
|
||||||
var coco : (int*foobar) := (0, m);
|
block {
|
||||||
block {
|
var coco : (int*foobar) := (0, m);
|
||||||
remove 42 from map coco.1 ;
|
remove 42 from map coco.1 ;
|
||||||
coco.1[32] := 16 ;
|
coco.1[32] := 16 ;
|
||||||
} with coco.1
|
} with coco.1
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
// Test the pattern matching functionality of PascaLIGO
|
// Test the pattern matching functionality of PascaLIGO
|
||||||
|
|
||||||
function match_bool (const i : int) : int is
|
function match_bool (const i : int) : int is
|
||||||
var result : int := 23 ;
|
|
||||||
begin
|
begin
|
||||||
|
var result : int := 23 ;
|
||||||
case i = 2 of
|
case i = 2 of
|
||||||
| True -> result := 42
|
| True -> result := 42
|
||||||
| False -> result := 0
|
| False -> result := 0
|
||||||
@ -10,8 +10,8 @@ function match_bool (const i : int) : int is
|
|||||||
end with result
|
end with result
|
||||||
|
|
||||||
function match_option (const o : option(int)) : int is
|
function match_option (const o : option(int)) : int is
|
||||||
var result : int := 23 ;
|
|
||||||
begin
|
begin
|
||||||
|
var result : int := 23 ;
|
||||||
case o of
|
case o of
|
||||||
| None -> skip
|
| None -> skip
|
||||||
| Some (s) -> result := s
|
| Some (s) -> result := s
|
||||||
@ -19,21 +19,18 @@ function match_option (const o : option(int)) : int is
|
|||||||
end with result
|
end with result
|
||||||
|
|
||||||
function match_expr_bool (const i : int) : int is
|
function match_expr_bool (const i : int) : int is
|
||||||
begin skip end with
|
|
||||||
case i = 2 of
|
case i = 2 of
|
||||||
| True -> 42
|
| True -> 42
|
||||||
| False -> 0
|
| False -> 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function match_expr_option (const o : option(int)) : int is
|
function match_expr_option (const o : option(int)) : int is
|
||||||
begin skip end with
|
|
||||||
case o of
|
case o of
|
||||||
| None -> 42
|
| None -> 42
|
||||||
| Some (s) -> s
|
| Some (s) -> s
|
||||||
end
|
end
|
||||||
|
|
||||||
function match_expr_list (const l : list(int)) : int is
|
function match_expr_list (const l : list(int)) : int is
|
||||||
begin skip end with
|
|
||||||
case l of
|
case l of
|
||||||
| nil -> -1
|
| nil -> -1
|
||||||
| hd # tl -> hd
|
| hd # tl -> hd
|
||||||
|
@ -6,10 +6,8 @@ const s : foobar = Some(42)
|
|||||||
const n : foobar = None
|
const n : foobar = None
|
||||||
|
|
||||||
function assign (var m : int) : foobar is
|
function assign (var m : int) : foobar is
|
||||||
|
block {
|
||||||
var coco : foobar := None;
|
var coco : foobar := None;
|
||||||
block
|
|
||||||
{
|
|
||||||
coco := Some(m);
|
coco := Some(m);
|
||||||
coco := None;
|
coco := None;
|
||||||
}
|
} with coco
|
||||||
with coco
|
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
// Test set iteration in PascaLIGO
|
// Test set iteration in PascaLIGO
|
||||||
|
|
||||||
function iter_op (const s : set(int)) : int is
|
function iter_op (const s : set(int)) : int is
|
||||||
|
begin
|
||||||
var r : int := 0 ;
|
var r : int := 0 ;
|
||||||
function aggregate (const i : int) : unit is
|
function aggregate (const i : int) : unit is
|
||||||
begin
|
begin
|
||||||
r := r + i ;
|
r := r + i ;
|
||||||
end with unit
|
end with unit ;
|
||||||
begin
|
|
||||||
set_iter(s , aggregate) ;
|
set_iter(s , aggregate) ;
|
||||||
end with r
|
end with r
|
||||||
|
|
||||||
function fold_op (const s : set(int)) : int is
|
function fold_op (const s : set(int)) : int is
|
||||||
|
block {
|
||||||
function aggregate (const i : int ; const j : int) : int is
|
function aggregate (const i : int ; const j : int) : int is
|
||||||
block { skip } with i + j
|
i + j
|
||||||
block { skip } with set_fold(s , 15 , aggregate)
|
} with set_fold(s , 15 , aggregate)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
function foo (const i : int) : int is
|
function foo (const i : int) : int is
|
||||||
|
block {
|
||||||
function bar (const i : int) : int is
|
function bar (const i : int) : int is
|
||||||
block { skip } with i ;
|
i ;
|
||||||
block { skip } with bar (0)
|
} with bar (0)
|
||||||
|
@ -7,10 +7,10 @@ end
|
|||||||
type mpi is map(string,int)
|
type mpi is map(string,int)
|
||||||
|
|
||||||
function main (const toto : tpi) : int is
|
function main (const toto : tpi) : int is
|
||||||
|
begin
|
||||||
var a : tpi := toto;
|
var a : tpi := toto;
|
||||||
var b : rpi := record x = 0; y=1 ; end;
|
var b : rpi := record x = 0; y=1 ; end;
|
||||||
var m : mpi := map "y" -> 1; end;
|
var m : mpi := map "y" -> 1; end;
|
||||||
begin
|
|
||||||
a.0 := 2;
|
a.0 := 2;
|
||||||
b.x := a.0;
|
b.x := a.0;
|
||||||
m["x"] := b.x;
|
m["x"] := b.x;
|
||||||
|
@ -3,15 +3,13 @@ type action is
|
|||||||
| Increment of int
|
| Increment of int
|
||||||
| Decrement of int
|
| Decrement of int
|
||||||
|
|
||||||
function add (const a : int ; const b : int) : int is
|
function add (const a : int ; const b : int) : int is a + b
|
||||||
block { skip } with a + b
|
|
||||||
|
|
||||||
function subtract (const a : int ; const b : int) : int is
|
function subtract (const a : int ; const b : int) : int is a - b
|
||||||
block { skip } with a - b
|
|
||||||
|
|
||||||
// real entrypoint that re-routes the flow based on the action provided
|
// real entrypoint that re-routes the flow based on the action provided
|
||||||
function main (const p : action ; const s : int) : (list(operation) * int) is
|
function main (const p : action ; const s : int) : (list(operation) * int) is
|
||||||
block {skip} with ((nil : list(operation)),
|
((nil : list(operation)),
|
||||||
case p of
|
case p of
|
||||||
| Increment (n) -> add (s, n)
|
| Increment (n) -> add (s, n)
|
||||||
| Decrement (n) -> subtract (s, n)
|
| Decrement (n) -> subtract (s, n)
|
||||||
|
@ -52,6 +52,13 @@ let complex_function () : unit result =
|
|||||||
let make_expect = fun n -> (3 * n + 2) in
|
let make_expect = fun n -> (3 * n + 2) in
|
||||||
expect_eq_n_int program "main" make_expect
|
expect_eq_n_int program "main" make_expect
|
||||||
|
|
||||||
|
let anon_function () : unit result =
|
||||||
|
let%bind program = type_file "./contracts/function-anon.ligo" in
|
||||||
|
let%bind () =
|
||||||
|
expect_eq_evaluate program "x" (e_int 42)
|
||||||
|
in
|
||||||
|
ok ()
|
||||||
|
|
||||||
let application () : unit result =
|
let application () : unit result =
|
||||||
let%bind program = type_file "./contracts/application.ligo" in
|
let%bind program = type_file "./contracts/application.ligo" in
|
||||||
let%bind () =
|
let%bind () =
|
||||||
@ -1196,6 +1203,7 @@ let main = test_suite "Integration (End to End)" [
|
|||||||
test "assign" assign ;
|
test "assign" assign ;
|
||||||
test "declaration local" declaration_local ;
|
test "declaration local" declaration_local ;
|
||||||
test "complex function" complex_function ;
|
test "complex function" complex_function ;
|
||||||
|
test "anon function" anon_function ;
|
||||||
test "various applications" application ;
|
test "various applications" application ;
|
||||||
test "closure" closure ;
|
test "closure" closure ;
|
||||||
test "shared function" shared_function ;
|
test "shared function" shared_function ;
|
||||||
|
2
vendors/ligo-utils/simple-utils/region.ml
vendored
2
vendors/ligo-utils/simple-utils/region.ml
vendored
@ -108,6 +108,8 @@ let make ~(start: Pos.t) ~(stop: Pos.t) =
|
|||||||
|
|
||||||
let ghost = make ~start:Pos.ghost ~stop:Pos.ghost
|
let ghost = make ~start:Pos.ghost ~stop:Pos.ghost
|
||||||
|
|
||||||
|
let wrap_ghost value = {value ; region = ghost}
|
||||||
|
|
||||||
let min = make ~start:Pos.min ~stop:Pos.min
|
let min = make ~start:Pos.min ~stop:Pos.min
|
||||||
|
|
||||||
(* Comparisons *)
|
(* Comparisons *)
|
||||||
|
5
vendors/ligo-utils/simple-utils/region.mli
vendored
5
vendors/ligo-utils/simple-utils/region.mli
vendored
@ -96,6 +96,11 @@ val make : start:Pos.t -> stop:Pos.t -> t
|
|||||||
|
|
||||||
val ghost : t (* Two [Pos.ghost] positions *)
|
val ghost : t (* Two [Pos.ghost] positions *)
|
||||||
|
|
||||||
|
(* This wraps a value with a ghost region. *)
|
||||||
|
|
||||||
|
val wrap_ghost : 'a -> 'a reg
|
||||||
|
|
||||||
|
|
||||||
(* Occasionnally, we may need a minimum region. It is here made of two
|
(* Occasionnally, we may need a minimum region. It is here made of two
|
||||||
minimal positions. *)
|
minimal positions. *)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user