Merge branch 'dev' of gitlab.com:ligolang/ligo into rinderknecht@pprint
This commit is contained in:
commit
96f9c032c0
@ -5,12 +5,12 @@ title: Records and Maps
|
|||||||
|
|
||||||
import Syntax from '@theme/Syntax';
|
import Syntax from '@theme/Syntax';
|
||||||
|
|
||||||
So far we have seen pretty basic data types. LIGO also offers more
|
So far, we have seen pretty basic data types. LIGO also offers more
|
||||||
complex built-in constructs, such as *records* and *maps*.
|
complex built-in constructs, such as *records* and *maps*.
|
||||||
|
|
||||||
## Records
|
## Records
|
||||||
|
|
||||||
Records are one way data of different types can be packed into a
|
Records are one-way data of different types can be packed into a
|
||||||
single type. A record is made of a set of *fields*, which are made of
|
single type. A record is made of a set of *fields*, which are made of
|
||||||
a *field name* and a *field type*. Given a value of a record type, the
|
a *field name* and a *field type*. Given a value of a record type, the
|
||||||
value bound to a field can be accessed by giving its field name to a
|
value bound to a field can be accessed by giving its field name to a
|
||||||
@ -18,8 +18,6 @@ special operator (`.`).
|
|||||||
|
|
||||||
Let us first consider and example of record type declaration.
|
Let us first consider and example of record type declaration.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Syntax syntax="pascaligo">
|
<Syntax syntax="pascaligo">
|
||||||
|
|
||||||
```pascaligo group=records1
|
```pascaligo group=records1
|
||||||
@ -55,10 +53,8 @@ type user = {
|
|||||||
|
|
||||||
</Syntax>
|
</Syntax>
|
||||||
|
|
||||||
|
|
||||||
And here is how a record value is defined:
|
And here is how a record value is defined:
|
||||||
|
|
||||||
|
|
||||||
<Syntax syntax="pascaligo">
|
<Syntax syntax="pascaligo">
|
||||||
|
|
||||||
```pascaligo group=records1
|
```pascaligo group=records1
|
||||||
@ -142,7 +138,7 @@ points on a plane.
|
|||||||
|
|
||||||
In PascaLIGO, the shape of that expression is
|
In PascaLIGO, the shape of that expression is
|
||||||
`<record variable> with <record value>`.
|
`<record variable> with <record value>`.
|
||||||
The record variable is the record to update and the
|
The record variable is the record to update, and the
|
||||||
record value is the update itself.
|
record value is the update itself.
|
||||||
|
|
||||||
```pascaligo group=records2
|
```pascaligo group=records2
|
||||||
@ -160,13 +156,13 @@ following command of the shell:
|
|||||||
```shell
|
```shell
|
||||||
ligo run-function
|
ligo run-function
|
||||||
gitlab-pages/docs/language-basics/src/maps-records/record_update.ligo
|
gitlab-pages/docs/language-basics/src/maps-records/record_update.ligo
|
||||||
translate "(record [x=2;y=3;z=1], record [dx=3;dy=4])"
|
xy_translate "(record [x=2;y=3;z=1], record [dx=3;dy=4])"
|
||||||
# Outputs: {z = 1 , y = 7 , x = 5}
|
# Outputs: {z = 1 , y = 7 , x = 5}
|
||||||
```
|
```
|
||||||
|
|
||||||
You have to understand that `p` has not been changed by the functional
|
You have to understand that `p` has not been changed by the functional
|
||||||
update: a namless new version of it has been created and returned by
|
update: a nameless new version of it has been created and returned by
|
||||||
the blockless function.
|
the block-less function.
|
||||||
|
|
||||||
</Syntax>
|
</Syntax>
|
||||||
<Syntax syntax="cameligo">
|
<Syntax syntax="cameligo">
|
||||||
@ -186,6 +182,7 @@ let xy_translate (p, vec : point * vector) : point =
|
|||||||
|
|
||||||
You can call the function `xy_translate` defined above by running the
|
You can call the function `xy_translate` defined above by running the
|
||||||
following command of the shell:
|
following command of the shell:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
ligo run-function
|
ligo run-function
|
||||||
gitlab-pages/docs/language-basics/src/maps-records/record_update.mligo
|
gitlab-pages/docs/language-basics/src/maps-records/record_update.mligo
|
||||||
@ -218,6 +215,7 @@ let xy_translate = ((p, vec) : (point, vector)) : point =>
|
|||||||
|
|
||||||
You can call the function `xy_translate` defined above by running the
|
You can call the function `xy_translate` defined above by running the
|
||||||
following command of the shell:
|
following command of the shell:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
ligo run-function
|
ligo run-function
|
||||||
gitlab-pages/docs/language-basics/src/maps-records/record_update.religo
|
gitlab-pages/docs/language-basics/src/maps-records/record_update.religo
|
||||||
@ -326,12 +324,21 @@ let change_color_preference = (account : account, color : color): account =>
|
|||||||
Note that all the records in the path will get updated. In this example that's
|
Note that all the records in the path will get updated. In this example that's
|
||||||
`account` and `preferences`.
|
`account` and `preferences`.
|
||||||
|
|
||||||
|
You can call the function `change_color_preference` defined above by running the
|
||||||
|
following command:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ligo run-function gitlab-pages/docs/language-basics/src/maps-records/record_nested_update.ligo
|
||||||
|
change_color_preference "(record [id=1001; preferences=record [color=Blue; other=1]], Green)"
|
||||||
|
# Outputs: record[id -> 1001 , preferences -> record[color -> Green(unit) , other -> 1]]
|
||||||
|
```
|
||||||
|
|
||||||
<Syntax syntax="pascaligo">
|
<Syntax syntax="pascaligo">
|
||||||
|
|
||||||
### Record Patches
|
### Record Patches
|
||||||
|
|
||||||
Another way to understand what it means to update a record value is to
|
Another way to understand what it means to update a record value is to
|
||||||
make sure that any further reference to the value afterwards will
|
make sure that any further reference to the value afterward will
|
||||||
exhibit the modification. This is called a `patch` and this is only
|
exhibit the modification. This is called a `patch` and this is only
|
||||||
possible in PascaLIGO, because a patch is an *instruction*, therefore
|
possible in PascaLIGO, because a patch is an *instruction*, therefore
|
||||||
we can only use it in a block. Similarly to a *functional update*, a
|
we can only use it in a block. Similarly to a *functional update*, a
|
||||||
@ -355,6 +362,7 @@ function xy_translate (var p : point; const vec : vector) : point is
|
|||||||
|
|
||||||
You can call the function `xy_translate` defined above by running the
|
You can call the function `xy_translate` defined above by running the
|
||||||
following command of the shell:
|
following command of the shell:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
ligo run-function
|
ligo run-function
|
||||||
gitlab-pages/docs/language-basics/src/maps-records/record_patch.ligo
|
gitlab-pages/docs/language-basics/src/maps-records/record_patch.ligo
|
||||||
@ -378,6 +386,7 @@ function xy_translate (var p : point; const vec : vector) : point is
|
|||||||
|
|
||||||
You can call the new function `xy_translate` defined above by running the
|
You can call the new function `xy_translate` defined above by running the
|
||||||
following command of the shell:
|
following command of the shell:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
ligo run-function
|
ligo run-function
|
||||||
gitlab-pages/docs/language-basics/src/maps-records/record_patch2.ligo
|
gitlab-pages/docs/language-basics/src/maps-records/record_patch2.ligo
|
||||||
@ -401,6 +410,7 @@ function xy_translate (var p : point; const vec : vector) : point is
|
|||||||
|
|
||||||
You can call the new function `xy_translate` defined above by running the
|
You can call the new function `xy_translate` defined above by running the
|
||||||
following command of the shell:
|
following command of the shell:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
ligo run-function
|
ligo run-function
|
||||||
gitlab-pages/docs/language-basics/src/maps-records/record_simu.ligo
|
gitlab-pages/docs/language-basics/src/maps-records/record_simu.ligo
|
||||||
@ -425,8 +435,6 @@ sense.
|
|||||||
Here is how a custom map from addresses to a pair of integers is
|
Here is how a custom map from addresses to a pair of integers is
|
||||||
defined.
|
defined.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Syntax syntax="pascaligo">
|
<Syntax syntax="pascaligo">
|
||||||
|
|
||||||
```pascaligo group=maps
|
```pascaligo group=maps
|
||||||
@ -680,8 +688,8 @@ let assign = (m : register) : register =>
|
|||||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), Some ((4,9)), m);
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), Some ((4,9)), m);
|
||||||
```
|
```
|
||||||
|
|
||||||
Notice the optional value `Some (4,9)` instead of `(4,9)`. If we had
|
Notice the optional value `Some (4,9)` instead of `(4,9)`. If we used
|
||||||
use `None` instead, that would have meant that the binding is removed.
|
`None` instead that would have meant that the binding is removed.
|
||||||
|
|
||||||
As a particular case, we can only add a key and its associated value.
|
As a particular case, we can only add a key and its associated value.
|
||||||
|
|
||||||
@ -693,7 +701,6 @@ let add = (m : register) : register =>
|
|||||||
|
|
||||||
</Syntax>
|
</Syntax>
|
||||||
|
|
||||||
|
|
||||||
To remove a binding from a map, we need its key.
|
To remove a binding from a map, we need its key.
|
||||||
|
|
||||||
|
|
||||||
@ -748,8 +755,8 @@ There are three kinds of functional iterations over LIGO maps: the
|
|||||||
|
|
||||||
The first, the *iterated operation*, is an iteration over the map with
|
The first, the *iterated operation*, is an iteration over the map with
|
||||||
no return value: its only use is to produce side-effects. This can be
|
no return value: its only use is to produce side-effects. This can be
|
||||||
useful if for example you would like to check that each value inside
|
useful if, for example you would like to check that each value inside
|
||||||
of a map is within a certain range, and fail with an error otherwise.
|
of a map is within a certain range and fail with an error otherwise.
|
||||||
|
|
||||||
The predefined functional iterator implementing the iterated operation
|
The predefined functional iterator implementing the iterated operation
|
||||||
over maps is called `Map.iter`. In the following example, the register
|
over maps is called `Map.iter`. In the following example, the register
|
||||||
@ -985,7 +992,7 @@ let moves : register =
|
|||||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))]
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))]
|
||||||
```
|
```
|
||||||
|
|
||||||
The predefind function `Big_map.literal` constructs a big map from a
|
The predefined function `Big_map.literal` constructs a big map from a
|
||||||
list of key-value pairs `(<key>, <value>)`. Note also the semicolon
|
list of key-value pairs `(<key>, <value>)`. Note also the semicolon
|
||||||
separating individual map entries. The annotated value `("<string>
|
separating individual map entries. The annotated value `("<string>
|
||||||
value>" : address)` means that we cast a string into an address.
|
value>" : address)` means that we cast a string into an address.
|
||||||
@ -1000,7 +1007,7 @@ let moves : register =
|
|||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
||||||
```
|
```
|
||||||
|
|
||||||
The predefind function `Big_map.literal` constructs a big map from a
|
The predefined function `Big_map.literal` constructs a big map from a
|
||||||
list of key-value pairs `(<key>, <value>)`. Note also the semicolon
|
list of key-value pairs `(<key>, <value>)`. Note also the semicolon
|
||||||
separating individual map entries. The annotated value `("<string>
|
separating individual map entries. The annotated value `("<string>
|
||||||
value>" : address)` means that we cast a string into an address.
|
value>" : address)` means that we cast a string into an address.
|
||||||
|
@ -275,7 +275,7 @@ let compile_parameter =
|
|||||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||||
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
||||||
let env = Ast_typed.program_environment typed_prg in
|
let env = Ast_typed.program_environment Environment.default typed_prg in
|
||||||
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||||
(* fails if the given entry point is not a valid contract *)
|
(* fails if the given entry point is not a valid contract *)
|
||||||
Compile.Of_michelson.build_contract michelson_prg in
|
Compile.Of_michelson.build_contract michelson_prg in
|
||||||
@ -302,7 +302,7 @@ let interpret =
|
|||||||
| Some init_file ->
|
| Some init_file ->
|
||||||
let%bind typed_prg,state = Compile.Utils.type_file init_file syntax Env in
|
let%bind typed_prg,state = Compile.Utils.type_file init_file syntax Env in
|
||||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||||
let env = Ast_typed.program_environment typed_prg in
|
let env = Ast_typed.program_environment Environment.default typed_prg in
|
||||||
ok (mini_c_prg,state,env)
|
ok (mini_c_prg,state,env)
|
||||||
| None -> ok ([],Typer.Solver.initial_state,Environment.default) in
|
| None -> ok ([],Typer.Solver.initial_state,Environment.default) in
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ let compile_storage =
|
|||||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||||
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
||||||
let env = Ast_typed.program_environment typed_prg in
|
let env = Ast_typed.program_environment Environment.default typed_prg in
|
||||||
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||||
(* fails if the given entry point is not a valid contract *)
|
(* fails if the given entry point is not a valid contract *)
|
||||||
Compile.Of_michelson.build_contract michelson_prg in
|
Compile.Of_michelson.build_contract michelson_prg in
|
||||||
@ -368,7 +368,7 @@ let dry_run =
|
|||||||
let f source_file entry_point storage input amount balance sender source predecessor_timestamp syntax display_format =
|
let f source_file entry_point storage input amount balance sender source predecessor_timestamp syntax display_format =
|
||||||
toplevel ~display_format @@
|
toplevel ~display_format @@
|
||||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax (Contract entry_point) in
|
||||||
let env = Ast_typed.program_environment typed_prg in
|
let env = Ast_typed.program_environment Environment.default typed_prg in
|
||||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||||
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
let%bind michelson_prg = Compile.Of_mini_c.aggregate_and_compile_contract mini_c_prg entry_point in
|
||||||
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
let%bind (_contract: Tezos_utils.Michelson.michelson) =
|
||||||
@ -398,7 +398,7 @@ let run_function =
|
|||||||
let f source_file entry_point parameter amount balance sender source predecessor_timestamp syntax display_format =
|
let f source_file entry_point parameter amount balance sender source predecessor_timestamp syntax display_format =
|
||||||
toplevel ~display_format @@
|
toplevel ~display_format @@
|
||||||
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax Env in
|
let%bind typed_prg,state = Compile.Utils.type_file source_file syntax Env in
|
||||||
let env = Ast_typed.program_environment typed_prg in
|
let env = Ast_typed.program_environment Environment.default typed_prg in
|
||||||
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
let%bind mini_c_prg = Compile.Of_typed.compile typed_prg in
|
||||||
|
|
||||||
|
|
||||||
|
@ -202,4 +202,121 @@ let%expect_test _ =
|
|||||||
IF_LEFT
|
IF_LEFT
|
||||||
{ DUP ; CDR ; NIL operation ; PAIR ; DIP { DROP } }
|
{ DUP ; CDR ; NIL operation ; PAIR ; DIP { DROP } }
|
||||||
{ DUP ; CDR ; NIL operation ; PAIR ; DIP { DROP } } ;
|
{ DUP ; CDR ; NIL operation ; PAIR ; DIP { DROP } } ;
|
||||||
|
DIP { DROP 2 } } } |}]
|
||||||
|
|
||||||
|
let%expect_test _ =
|
||||||
|
run_ligo_good [ "compile-contract" ; (contract "double_fold_converter.religo") ; "main" ] ;
|
||||||
|
[%expect {|
|
||||||
|
{ parameter
|
||||||
|
(list (pair (address %from_)
|
||||||
|
(list %txs (pair (address %to_) (pair (nat %token_id) (nat %amount)))))) ;
|
||||||
|
storage (big_map nat address) ;
|
||||||
|
code { DUP ;
|
||||||
|
CDR ;
|
||||||
|
DIG 1 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 2 ;
|
||||||
|
CAR ;
|
||||||
|
ITER { SWAP ;
|
||||||
|
PAIR ;
|
||||||
|
DUP ;
|
||||||
|
CDR ;
|
||||||
|
DUP ;
|
||||||
|
CAR ;
|
||||||
|
SENDER ;
|
||||||
|
DIG 1 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 2 ;
|
||||||
|
COMPARE ;
|
||||||
|
NEQ ;
|
||||||
|
IF { PUSH string "NOT_OWNER" ; FAILWITH } { PUSH unit Unit } ;
|
||||||
|
DIG 1 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 2 ;
|
||||||
|
DIG 4 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 5 ;
|
||||||
|
CAR ;
|
||||||
|
PAIR ;
|
||||||
|
DIG 3 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 4 ;
|
||||||
|
CDR ;
|
||||||
|
ITER { SWAP ;
|
||||||
|
PAIR ;
|
||||||
|
DUP ;
|
||||||
|
CAR ;
|
||||||
|
DIG 1 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 2 ;
|
||||||
|
CDR ;
|
||||||
|
DIG 1 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 2 ;
|
||||||
|
CAR ;
|
||||||
|
DIG 2 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 3 ;
|
||||||
|
CDR ;
|
||||||
|
DIG 2 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 3 ;
|
||||||
|
CDR ;
|
||||||
|
CAR ;
|
||||||
|
DIG 3 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 4 ;
|
||||||
|
CAR ;
|
||||||
|
DIG 4 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 5 ;
|
||||||
|
CDR ;
|
||||||
|
CDR ;
|
||||||
|
PAIR ;
|
||||||
|
PAIR ;
|
||||||
|
DIG 2 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 3 ;
|
||||||
|
DIG 1 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 2 ;
|
||||||
|
CDR ;
|
||||||
|
GET ;
|
||||||
|
IF_NONE
|
||||||
|
{ PUSH string "TOKEN_UNDEFINED" ; FAILWITH }
|
||||||
|
{ DIG 2 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 3 ;
|
||||||
|
DIG 1 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 2 ;
|
||||||
|
COMPARE ;
|
||||||
|
EQ ;
|
||||||
|
IF { DUP } { PUSH string "INSUFFICIENT_BALANCE" ; FAILWITH } ;
|
||||||
|
DIP { DROP } } ;
|
||||||
|
DIG 2 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 3 ;
|
||||||
|
DIG 4 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 5 ;
|
||||||
|
DIG 3 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 4 ;
|
||||||
|
CAR ;
|
||||||
|
CDR ;
|
||||||
|
SOME ;
|
||||||
|
DIG 4 ;
|
||||||
|
DUP ;
|
||||||
|
DUG 5 ;
|
||||||
|
CDR ;
|
||||||
|
UPDATE ;
|
||||||
|
PAIR ;
|
||||||
|
DIP { DROP 7 } } ;
|
||||||
|
DUP ;
|
||||||
|
CAR ;
|
||||||
|
DIP { DROP 5 } } ;
|
||||||
|
DUP ;
|
||||||
|
NIL operation ;
|
||||||
|
PAIR ;
|
||||||
DIP { DROP 2 } } } |}]
|
DIP { DROP 2 } } } |}]
|
@ -1,4 +1,8 @@
|
|||||||
open Ast_typed
|
open Ast_typed
|
||||||
open Stage_common.Constant
|
open Stage_common.Constant
|
||||||
|
|
||||||
let environment = env_sum_type ~type_name:t_bool @@ [(Constructor "true",{ctor_type=t_unit ();michelson_annotation=None;ctor_decl_pos=0});(Constructor "false",{ctor_type=t_unit ();michelson_annotation=None;ctor_decl_pos=1})]
|
let environment = Ast_typed.Environment.add_ez_sum_type ~type_name:t_bool @@
|
||||||
|
[
|
||||||
|
(Constructor "true" ,{ctor_type=t_unit ();michelson_annotation=None;ctor_decl_pos=0});
|
||||||
|
(Constructor "false",{ctor_type=t_unit ();michelson_annotation=None;ctor_decl_pos=1});
|
||||||
|
]
|
||||||
|
@ -368,19 +368,23 @@ and eval : Ast_typed.expression -> env -> value result
|
|||||||
|
|
||||||
let dummy : Ast_typed.program -> string result =
|
let dummy : Ast_typed.program -> string result =
|
||||||
fun prg ->
|
fun prg ->
|
||||||
let%bind (res,_) = bind_fold_list
|
let aux (pp,top_env) el =
|
||||||
(fun (pp,top_env) el ->
|
match Location.unwrap el with
|
||||||
let (Ast_typed.Declaration_constant {binder; expr ; inline=_ ; _}) = Location.unwrap el in
|
| Ast_typed.Declaration_constant {binder; expr ; inline=_ ; _} ->
|
||||||
let%bind v =
|
let%bind v =
|
||||||
(*TODO This TRY-CATCH is here until we properly implement effects*)
|
(*TODO This TRY-CATCH is here until we properly implement effects*)
|
||||||
try
|
try
|
||||||
eval expr top_env
|
eval expr top_env
|
||||||
with Temporary_hack s -> ok @@ V_Failure s
|
with Temporary_hack s ->
|
||||||
(*TODO This TRY-CATCH is here until we properly implement effects*)
|
ok (V_Failure s)
|
||||||
in
|
(*TODO This TRY-CATCH is here until we properly implement effects*)
|
||||||
let pp' = pp^"\n val "^(Var.to_name binder)^" = "^(Ligo_interpreter.PP.pp_value v) in
|
in
|
||||||
let top_env' = Env.extend top_env (binder, v) in
|
let pp' = pp^"\n val "^(Var.to_name binder)^" = "^(Ligo_interpreter.PP.pp_value v) in
|
||||||
ok @@ (pp',top_env')
|
let top_env' = Env.extend top_env (binder, v) in
|
||||||
)
|
ok @@ (pp',top_env')
|
||||||
|
| Ast_typed.Declaration_type _ ->
|
||||||
|
ok (pp , top_env)
|
||||||
|
in
|
||||||
|
let%bind (res,_) = bind_fold_list aux
|
||||||
("",Env.empty_env) prg in
|
("",Env.empty_env) prg in
|
||||||
ok @@ res
|
ok @@ res
|
||||||
|
@ -42,14 +42,6 @@ them. please report this to the developers." in
|
|||||||
] in
|
] in
|
||||||
error ~data title content
|
error ~data title content
|
||||||
|
|
||||||
let unsupported_iterator location =
|
|
||||||
let title () = "unsupported iterator" in
|
|
||||||
let content () = "only lambda are supported as iterators" in
|
|
||||||
let data = [
|
|
||||||
row_loc location ;
|
|
||||||
] in
|
|
||||||
error ~data title content
|
|
||||||
|
|
||||||
let not_functional_main location =
|
let not_functional_main location =
|
||||||
let title () = "not functional main" in
|
let title () = "not functional main" in
|
||||||
let content () = "main should be a function" in
|
let content () = "main should be a function" in
|
||||||
@ -382,9 +374,6 @@ let rec transpile_literal : AST.literal -> value = fun l -> match l with
|
|||||||
| Literal_unit -> D_unit
|
| Literal_unit -> D_unit
|
||||||
| Literal_void -> D_none
|
| Literal_void -> D_none
|
||||||
|
|
||||||
and transpile_environment_element_type : AST.environment_element -> type_expression result = fun ele ->
|
|
||||||
transpile_type ele.type_value
|
|
||||||
|
|
||||||
and tree_of_sum : AST.type_expression -> (AST.constructor' * AST.type_expression) Append_tree.t result = fun t ->
|
and tree_of_sum : AST.type_expression -> (AST.constructor' * AST.type_expression) Append_tree.t result = fun t ->
|
||||||
let%bind map_tv = get_t_sum t in
|
let%bind map_tv = get_t_sum t in
|
||||||
let kt_list = List.map (fun (k,({ctor_type;_}:AST.ctor_content)) -> (k,ctor_type)) (kv_list_of_cmap map_tv) in
|
let kt_list = List.map (fun (k,({ctor_type;_}:AST.ctor_content)) -> (k,ctor_type)) (kv_list_of_cmap map_tv) in
|
||||||
@ -405,11 +394,7 @@ and transpile_annotated_expression (ae:AST.expression) : expression result =
|
|||||||
return (E_let_in ((let_binder, rhs'.type_expression), inline, rhs', result'))
|
return (E_let_in ((let_binder, rhs'.type_expression), inline, rhs', result'))
|
||||||
| E_literal l -> return @@ E_literal (transpile_literal l)
|
| E_literal l -> return @@ E_literal (transpile_literal l)
|
||||||
| E_variable name -> (
|
| E_variable name -> (
|
||||||
let%bind ele =
|
return @@ E_variable (name)
|
||||||
trace_option (corner_case ~loc:__LOC__ "name not in environment") @@
|
|
||||||
AST.Environment.get_opt name ae.environment in
|
|
||||||
let%bind tv = transpile_environment_element_type ele in
|
|
||||||
return ~tv @@ E_variable (name)
|
|
||||||
)
|
)
|
||||||
| E_application {lamb; args} ->
|
| E_application {lamb; args} ->
|
||||||
let%bind a = transpile_annotated_expression lamb in
|
let%bind a = transpile_annotated_expression lamb in
|
||||||
@ -449,7 +434,6 @@ and transpile_annotated_expression (ae:AST.expression) : expression result =
|
|||||||
return ~tv ae
|
return ~tv ae
|
||||||
)
|
)
|
||||||
| E_record m -> (
|
| E_record m -> (
|
||||||
(*list_of_lmap to record_to_list*)
|
|
||||||
let node = Append_tree.of_list @@ Ast_typed.Helpers.list_of_record_or_tuple m in
|
let node = Append_tree.of_list @@ Ast_typed.Helpers.list_of_record_or_tuple m in
|
||||||
let aux a b : expression result =
|
let aux a b : expression result =
|
||||||
let%bind a = a in
|
let%bind a = a in
|
||||||
@ -511,28 +495,14 @@ and transpile_annotated_expression (ae:AST.expression) : expression result =
|
|||||||
return @@ E_record_update (record, path, update)
|
return @@ E_record_update (record, path, update)
|
||||||
| E_constant {cons_name=name; arguments=lst} -> (
|
| E_constant {cons_name=name; arguments=lst} -> (
|
||||||
let iterator_generator iterator_name =
|
let iterator_generator iterator_name =
|
||||||
let lambda_to_iterator_body (f : AST.expression) (l : AST.lambda) =
|
|
||||||
let%bind body' = transpile_annotated_expression l.result in
|
|
||||||
let%bind (input , _) = AST.get_t_function f.type_expression in
|
|
||||||
let%bind input' = transpile_type input in
|
|
||||||
ok ((l.binder , input') , body')
|
|
||||||
in
|
|
||||||
let expression_to_iterator_body (f : AST.expression) =
|
let expression_to_iterator_body (f : AST.expression) =
|
||||||
match f.expression_content with
|
let%bind (input , output) = AST.get_t_function f.type_expression in
|
||||||
| E_lambda l -> lambda_to_iterator_body f l
|
let%bind f' = transpile_annotated_expression f in
|
||||||
| E_variable v -> (
|
let%bind input' = transpile_type input in
|
||||||
let%bind elt =
|
let%bind output' = transpile_type output in
|
||||||
trace_option (corner_case ~loc:__LOC__ "missing var") @@
|
let binder = Var.fresh ~name:"iterated" () in
|
||||||
AST.Environment.get_opt v f.environment in
|
let application = Mini_c.Combinators.e_application f' output' (Mini_c.Combinators.e_var binder input') in
|
||||||
match elt.definition with
|
ok ((binder , input'), application)
|
||||||
| ED_declaration { expr = f ; free_variables = _ } -> (
|
|
||||||
match f.expression_content with
|
|
||||||
| E_lambda l -> lambda_to_iterator_body f l
|
|
||||||
| _ -> fail @@ unsupported_iterator f.location
|
|
||||||
)
|
|
||||||
| _ -> fail @@ unsupported_iterator f.location
|
|
||||||
)
|
|
||||||
| _ -> fail @@ unsupported_iterator f.location
|
|
||||||
in
|
in
|
||||||
fun (lst : AST.expression list) -> match (lst , iterator_name) with
|
fun (lst : AST.expression list) -> match (lst , iterator_name) with
|
||||||
| [f ; i] , C_ITER | [f ; i] , C_MAP -> (
|
| [f ; i] , C_ITER | [f ; i] , C_MAP -> (
|
||||||
@ -781,25 +751,29 @@ and transpile_recursive {fun_name; fun_type; lambda} =
|
|||||||
let body = Expression.make (E_iterator (C_LOOP_LEFT, ((lambda.binder, loop_type),body), expr)) output_type in
|
let body = Expression.make (E_iterator (C_LOOP_LEFT, ((lambda.binder, loop_type),body), expr)) output_type in
|
||||||
ok @@ Expression.make (E_closure {binder;body}) fun_type
|
ok @@ Expression.make (E_closure {binder;body}) fun_type
|
||||||
|
|
||||||
let transpile_declaration env (d:AST.declaration) : toplevel_statement result =
|
let transpile_declaration env (d:AST.declaration) : toplevel_statement option result =
|
||||||
match d with
|
match d with
|
||||||
| Declaration_constant { binder ; expr ; inline ; post_env=_ } ->
|
| Declaration_constant { binder ; expr ; inline } ->
|
||||||
let%bind expression = transpile_annotated_expression expr in
|
let%bind expression = transpile_annotated_expression expr in
|
||||||
let tv = Combinators.Expression.get_type expression in
|
let tv = Combinators.Expression.get_type expression in
|
||||||
let env' = Environment.add (binder, tv) env in
|
let env' = Environment.add (binder, tv) env in
|
||||||
ok @@ ((binder, inline, expression), environment_wrap env env')
|
ok @@ Some ((binder, inline, expression), environment_wrap env env')
|
||||||
|
| _ -> ok None
|
||||||
|
|
||||||
let transpile_program (lst : AST.program) : program result =
|
let transpile_program (lst : AST.program) : program result =
|
||||||
let aux (prev:(toplevel_statement list * Environment.t) result) cur =
|
let aux (prev:(toplevel_statement list * Environment.t) result) cur =
|
||||||
let%bind (hds, env) = prev in
|
let%bind (hds, env) = prev in
|
||||||
let%bind ((_, env') as cur') = transpile_declaration env cur in
|
match%bind transpile_declaration env cur with
|
||||||
ok (hds @ [ cur' ], env'.post_environment)
|
| Some ((_ , env') as cur') -> ok (hds @ [ cur' ] , env'.post_environment)
|
||||||
|
| None -> ok (hds , env)
|
||||||
in
|
in
|
||||||
let%bind (statements, _) = List.fold_left aux (ok ([], Environment.empty)) (temp_unwrap_loc_list lst) in
|
let%bind (statements, _) = List.fold_left aux (ok ([], Environment.empty)) (temp_unwrap_loc_list lst) in
|
||||||
ok statements
|
ok statements
|
||||||
|
|
||||||
(* check whether the storage contains a big_map, if yes, check that
|
(* check whether the storage contains a big_map, if yes, check that
|
||||||
it appears on the left hand side of a pair *)
|
it appears on the left hand side of a pair
|
||||||
|
TODO : checking should appears in check_pass.
|
||||||
|
*)
|
||||||
let check_storage f ty loc : (anon_function * _) result =
|
let check_storage f ty loc : (anon_function * _) result =
|
||||||
let rec aux (t:type_expression) on_big_map =
|
let rec aux (t:type_expression) on_big_map =
|
||||||
match t.type_content with
|
match t.type_content with
|
||||||
|
@ -42,19 +42,19 @@ open Errors
|
|||||||
|
|
||||||
let rec untranspile (v : value) (t : AST.type_expression) : AST.expression result =
|
let rec untranspile (v : value) (t : AST.type_expression) : AST.expression result =
|
||||||
let open! AST in
|
let open! AST in
|
||||||
let return e = ok (make_a_e_empty e t) in
|
let return e = ok (make_e e t) in
|
||||||
match t.type_content with
|
match t.type_content with
|
||||||
| T_variable (name) when Var.equal name Stage_common.Constant.t_bool -> (
|
| T_variable (name) when Var.equal name Stage_common.Constant.t_bool -> (
|
||||||
let%bind b =
|
let%bind b =
|
||||||
trace_strong (wrong_mini_c_value "bool" v) @@
|
trace_strong (wrong_mini_c_value "bool" v) @@
|
||||||
get_bool v in
|
get_bool v in
|
||||||
return (e_bool b Environment.empty)
|
return (e_bool b)
|
||||||
)
|
)
|
||||||
| t when (compare t (t_bool ()).type_content) = 0-> (
|
| t when (compare t (t_bool ()).type_content) = 0-> (
|
||||||
let%bind b =
|
let%bind b =
|
||||||
trace_strong (wrong_mini_c_value "bool" v) @@
|
trace_strong (wrong_mini_c_value "bool" v) @@
|
||||||
get_bool v in
|
get_bool v in
|
||||||
return (e_bool b Environment.empty)
|
return (e_bool b)
|
||||||
)
|
)
|
||||||
| T_constant type_constant -> (
|
| T_constant type_constant -> (
|
||||||
match type_constant with
|
match type_constant with
|
||||||
@ -152,10 +152,10 @@ let rec untranspile (v : value) (t : AST.type_expression) : AST.expression resul
|
|||||||
trace_strong (wrong_mini_c_value "option" v) @@
|
trace_strong (wrong_mini_c_value "option" v) @@
|
||||||
get_option v in
|
get_option v in
|
||||||
match opt with
|
match opt with
|
||||||
| None -> ok (e_a_empty_none o)
|
| None -> ok (e_a_none o)
|
||||||
| Some s ->
|
| Some s ->
|
||||||
let%bind s' = untranspile s o in
|
let%bind s' = untranspile s o in
|
||||||
ok (e_a_empty_some s')
|
ok (e_a_some s')
|
||||||
)
|
)
|
||||||
| TC_map {k=k_ty;v=v_ty}-> (
|
| TC_map {k=k_ty;v=v_ty}-> (
|
||||||
let%bind map =
|
let%bind map =
|
||||||
|
@ -29,7 +29,7 @@ let rec type_declaration env state : I.declaration -> (environment * O.typer_sta
|
|||||||
trace (constant_declaration_error binder expression tv'_opt) @@
|
trace (constant_declaration_error binder expression tv'_opt) @@
|
||||||
type_expression env state expression in
|
type_expression env state expression in
|
||||||
let post_env = Environment.add_ez_declaration binder expr env in
|
let post_env = Environment.add_ez_declaration binder expr env in
|
||||||
ok (post_env, state' , Some (O.Declaration_constant { binder ; expr ; inline ; post_env} ))
|
ok (post_env, state' , Some (O.Declaration_constant { binder ; expr ; inline} ))
|
||||||
)
|
)
|
||||||
|
|
||||||
and type_match : environment -> O.typer_state -> O.type_expression -> I.matching_expr -> I.expression -> Location.t -> (O.matching_expr * O.typer_state) result =
|
and type_match : environment -> O.typer_state -> O.type_expression -> I.matching_expr -> I.expression -> Location.t -> (O.matching_expr * O.typer_state) result =
|
||||||
@ -196,7 +196,7 @@ and type_expression : environment -> O.typer_state -> ?tv_opt:O.type_expression
|
|||||||
let%bind new_state = aggregate_constraints state constraints in
|
let%bind new_state = aggregate_constraints state constraints in
|
||||||
let tv = t_variable type_name () in
|
let tv = t_variable type_name () in
|
||||||
let location = ae.location in
|
let location = ae.location in
|
||||||
let expr' = make_e ~location expr tv e in
|
let expr' = make_e ~location expr tv in
|
||||||
ok @@ (expr' , new_state) in
|
ok @@ (expr' , new_state) in
|
||||||
let return_wrapped expr state (constraints , expr_type) = return expr state constraints expr_type in
|
let return_wrapped expr state (constraints , expr_type) = return expr state constraints expr_type in
|
||||||
let main_error =
|
let main_error =
|
||||||
|
@ -494,27 +494,25 @@ let rec type_program (p:I.program) : (O.program * O.typer_state) result =
|
|||||||
let%bind ed' = (bind_map_location (type_declaration e (Solver.placeholder_for_state_of_new_typer ()))) d in
|
let%bind ed' = (bind_map_location (type_declaration e (Solver.placeholder_for_state_of_new_typer ()))) d in
|
||||||
let loc : 'a . 'a Location.wrap -> _ -> _ = fun x v -> Location.wrap ~loc:x.location v in
|
let loc : 'a . 'a Location.wrap -> _ -> _ = fun x v -> Location.wrap ~loc:x.location v in
|
||||||
let (e', _placeholder_for_state_of_new_typer , d') = Location.unwrap ed' in
|
let (e', _placeholder_for_state_of_new_typer , d') = Location.unwrap ed' in
|
||||||
match d' with
|
ok (e', loc ed' d' :: acc)
|
||||||
| None -> ok (e', acc)
|
|
||||||
| Some d' -> ok (e', loc ed' d' :: acc)
|
|
||||||
in
|
in
|
||||||
let%bind (_, lst) =
|
let%bind (_, lst) =
|
||||||
trace (fun () -> program_error p ()) @@
|
trace (fun () -> program_error p ()) @@
|
||||||
bind_fold_list aux (DEnv.default, []) p in
|
bind_fold_list aux (DEnv.default, []) p in
|
||||||
ok @@ (List.rev lst , (Solver.placeholder_for_state_of_new_typer ()))
|
ok @@ (List.rev lst , (Solver.placeholder_for_state_of_new_typer ()))
|
||||||
|
|
||||||
and type_declaration env (_placeholder_for_state_of_new_typer : O.typer_state) : I.declaration -> (environment * O.typer_state * O.declaration option) result = function
|
and type_declaration env (_placeholder_for_state_of_new_typer : O.typer_state) : I.declaration -> (environment * O.typer_state * O.declaration) result = function
|
||||||
| Declaration_type (type_name , type_expression) ->
|
| Declaration_type (type_binder , type_expr) ->
|
||||||
let%bind tv = evaluate_type env type_expression in
|
let%bind tv = evaluate_type env type_expr in
|
||||||
let env' = Environment.add_type (type_name) tv env in
|
let env' = Environment.add_type (type_binder) tv env in
|
||||||
ok (env', (Solver.placeholder_for_state_of_new_typer ()) , None)
|
ok (env', (Solver.placeholder_for_state_of_new_typer ()) , (O.Declaration_type { type_binder ; type_expr = tv } ))
|
||||||
| Declaration_constant (binder , tv_opt , inline, expression) -> (
|
| Declaration_constant (binder , tv_opt , inline, expression) -> (
|
||||||
let%bind tv'_opt = bind_map_option (evaluate_type env) tv_opt in
|
let%bind tv'_opt = bind_map_option (evaluate_type env) tv_opt in
|
||||||
let%bind expr =
|
let%bind expr =
|
||||||
trace (constant_declaration_error binder expression tv'_opt) @@
|
trace (constant_declaration_error binder expression tv'_opt) @@
|
||||||
type_expression' ?tv_opt:tv'_opt env expression in
|
type_expression' ?tv_opt:tv'_opt env expression in
|
||||||
let post_env = Environment.add_ez_declaration binder expr env in
|
let post_env = Environment.add_ez_declaration binder expr env in
|
||||||
ok (post_env, (Solver.placeholder_for_state_of_new_typer ()) , Some (O.Declaration_constant { binder ; expr ; inline ; post_env}))
|
ok (post_env, (Solver.placeholder_for_state_of_new_typer ()) , (O.Declaration_constant { binder ; expr ; inline}))
|
||||||
)
|
)
|
||||||
|
|
||||||
and type_match : (environment -> I.expression -> O.expression result) -> environment -> O.type_expression -> I.matching_expr -> I.expression -> Location.t -> O.matching_expr result =
|
and type_match : (environment -> I.expression -> O.expression result) -> environment -> O.type_expression -> I.matching_expr -> I.expression -> Location.t -> O.matching_expr result =
|
||||||
@ -674,6 +672,7 @@ and type_expression : environment -> O.typer_state -> ?tv_opt:O.type_expression
|
|||||||
= fun e _placeholder_for_state_of_new_typer ?tv_opt ae ->
|
= fun e _placeholder_for_state_of_new_typer ?tv_opt ae ->
|
||||||
let%bind res = type_expression' e ?tv_opt ae in
|
let%bind res = type_expression' e ?tv_opt ae in
|
||||||
ok (res, (Solver.placeholder_for_state_of_new_typer ()))
|
ok (res, (Solver.placeholder_for_state_of_new_typer ()))
|
||||||
|
|
||||||
and type_expression' : environment -> ?tv_opt:O.type_expression -> I.expression -> O.expression result = fun e ?tv_opt ae ->
|
and type_expression' : environment -> ?tv_opt:O.type_expression -> I.expression -> O.expression result = fun e ?tv_opt ae ->
|
||||||
let module L = Logger.Stateful() in
|
let module L = Logger.Stateful() in
|
||||||
let return expr tv =
|
let return expr tv =
|
||||||
@ -682,7 +681,7 @@ and type_expression' : environment -> ?tv_opt:O.type_expression -> I.expression
|
|||||||
| None -> ok ()
|
| None -> ok ()
|
||||||
| Some tv' -> O.assert_type_expression_eq (tv' , tv) in
|
| Some tv' -> O.assert_type_expression_eq (tv' , tv) in
|
||||||
let location = ae.location in
|
let location = ae.location in
|
||||||
ok @@ make_e ~location expr tv e in
|
ok @@ make_e ~location expr tv in
|
||||||
let main_error =
|
let main_error =
|
||||||
let title () = "typing expression" in
|
let title () = "typing expression" in
|
||||||
let content () = "" in
|
let content () = "" in
|
||||||
@ -736,7 +735,7 @@ and type_expression' : environment -> ?tv_opt:O.type_expression -> I.expression
|
|||||||
generic_try (bad_record_access property ae prev.type_expression ae.location)
|
generic_try (bad_record_access property ae prev.type_expression ae.location)
|
||||||
@@ (fun () -> let ({field_type;_} : O.field_content) = O.LMap.find (convert_label property) r_tv in field_type) in
|
@@ (fun () -> let ({field_type;_} : O.field_content) = O.LMap.find (convert_label property) r_tv in field_type) in
|
||||||
let location = ae.location in
|
let location = ae.location in
|
||||||
ok @@ make_e ~location (E_record_accessor {record=prev; path=convert_label property}) tv e
|
ok @@ make_e ~location (E_record_accessor {record=prev; path=convert_label property}) tv
|
||||||
in
|
in
|
||||||
let%bind ae =
|
let%bind ae =
|
||||||
trace (simple_info "accessing") @@ aux e' path in
|
trace (simple_info "accessing") @@ aux e' path in
|
||||||
@ -832,7 +831,7 @@ and type_expression' : environment -> ?tv_opt:O.type_expression -> I.expression
|
|||||||
let e' = Environment.add_ez_binder lname input_type e in
|
let e' = Environment.add_ez_binder lname input_type e in
|
||||||
let%bind body = type_expression' ?tv_opt:(Some tv_out) e' result in
|
let%bind body = type_expression' ?tv_opt:(Some tv_out) e' result in
|
||||||
let output_type = body.type_expression in
|
let output_type = body.type_expression in
|
||||||
let lambda' = make_e (E_lambda {binder = lname ; result=body}) (t_function input_type output_type ()) e' in
|
let lambda' = make_e (E_lambda {binder = lname ; result=body}) (t_function input_type output_type ()) in
|
||||||
let lst' = [lambda'; v_col; v_initr] in
|
let lst' = [lambda'; v_col; v_initr] in
|
||||||
let tv_lst = List.map get_type_expression lst' in
|
let tv_lst = List.map get_type_expression lst' in
|
||||||
let%bind (opname', tv) =
|
let%bind (opname', tv) =
|
||||||
@ -853,7 +852,7 @@ and type_expression' : environment -> ?tv_opt:O.type_expression -> I.expression
|
|||||||
let e' = Environment.add_ez_binder lname input_type e in
|
let e' = Environment.add_ez_binder lname input_type e in
|
||||||
let%bind body = type_expression' e' result in
|
let%bind body = type_expression' e' result in
|
||||||
let output_type = body.type_expression in
|
let output_type = body.type_expression in
|
||||||
let lambda' = make_e (E_lambda {binder = lname ; result=body}) (t_function input_type output_type ()) e' in
|
let lambda' = make_e (E_lambda {binder = lname ; result=body}) (t_function input_type output_type ()) in
|
||||||
let lst' = [lambda';v_initr] in
|
let lst' = [lambda';v_initr] in
|
||||||
let tv_lst = List.map get_type_expression lst' in
|
let tv_lst = List.map get_type_expression lst' in
|
||||||
let%bind (opname',tv) = type_constant opname tv_lst tv_opt in
|
let%bind (opname',tv) = type_constant opname tv_lst tv_opt in
|
||||||
|
@ -39,7 +39,7 @@ module Errors : sig
|
|||||||
end
|
end
|
||||||
|
|
||||||
val type_program : I.program -> (O.program * O.typer_state) result
|
val type_program : I.program -> (O.program * O.typer_state) result
|
||||||
val type_declaration : environment -> O.typer_state -> I.declaration -> (environment * O.typer_state * O.declaration option) result
|
val type_declaration : environment -> O.typer_state -> I.declaration -> (environment * O.typer_state * O.declaration) result
|
||||||
(* val type_match : (environment -> 'i -> 'o result) -> environment -> O.type_value -> 'i I.matching -> I.expression -> Location.t -> 'o O.matching result *)
|
(* val type_match : (environment -> 'i -> 'o result) -> environment -> O.type_value -> 'i I.matching -> I.expression -> Location.t -> 'o O.matching result *)
|
||||||
val evaluate_type : environment -> I.type_expression -> O.type_expression result
|
val evaluate_type : environment -> I.type_expression -> O.type_expression result
|
||||||
val type_expression : environment -> O.typer_state -> ?tv_opt:O.type_expression -> I.expression -> (O.expression * O.typer_state) result
|
val type_expression : environment -> O.typer_state -> ?tv_opt:O.type_expression -> I.expression -> (O.expression * O.typer_state) result
|
||||||
|
@ -156,10 +156,11 @@ and map_cases : mapper -> matching_expr -> matching_expr result = fun f m ->
|
|||||||
and map_program : mapper -> program -> program result = fun m p ->
|
and map_program : mapper -> program -> program result = fun m p ->
|
||||||
let aux = fun (x : declaration) ->
|
let aux = fun (x : declaration) ->
|
||||||
match x with
|
match x with
|
||||||
| Declaration_constant {binder; expr ; inline ; post_env} -> (
|
| Declaration_constant {binder; expr ; inline} -> (
|
||||||
let%bind expr = map_expression m expr in
|
let%bind expr = map_expression m expr in
|
||||||
ok (Declaration_constant {binder; expr ; inline ; post_env})
|
ok (Declaration_constant {binder; expr ; inline})
|
||||||
)
|
)
|
||||||
|
| Declaration_type t -> ok (Declaration_type t)
|
||||||
in
|
in
|
||||||
bind_map_list (bind_map_location aux) p
|
bind_map_list (bind_map_location aux) p
|
||||||
|
|
||||||
@ -246,11 +247,15 @@ and fold_map_cases : 'a . 'a fold_mapper -> 'a -> matching_expr -> ('a * matchin
|
|||||||
and fold_map_program : 'a . 'a fold_mapper -> 'a -> program -> ('a * program) result = fun m init p ->
|
and fold_map_program : 'a . 'a fold_mapper -> 'a -> program -> ('a * program) result = fun m init p ->
|
||||||
let aux = fun (acc,acc_prg) (x : declaration Location.wrap) ->
|
let aux = fun (acc,acc_prg) (x : declaration Location.wrap) ->
|
||||||
match Location.unwrap x with
|
match Location.unwrap x with
|
||||||
| Declaration_constant {binder ; expr ; inline ; post_env} -> (
|
| Declaration_constant {binder ; expr ; inline} -> (
|
||||||
let%bind (acc', expr) = fold_map_expression m acc expr in
|
let%bind (acc', expr) = fold_map_expression m acc expr in
|
||||||
let wrap_content = Declaration_constant {binder ; expr ; inline ; post_env} in
|
let wrap_content = Declaration_constant {binder ; expr ; inline} in
|
||||||
ok (acc', List.append acc_prg [{x with wrap_content}])
|
ok (acc', List.append acc_prg [{x with wrap_content}])
|
||||||
)
|
)
|
||||||
|
| Declaration_type t -> (
|
||||||
|
let wrap_content = Declaration_type t in
|
||||||
|
ok (acc, List.append acc_prg [{x with wrap_content}])
|
||||||
|
)
|
||||||
in
|
in
|
||||||
bind_fold_list aux (init,[]) p
|
bind_fold_list aux (init,[]) p
|
||||||
|
|
||||||
@ -298,30 +303,31 @@ type contract_type = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let fetch_contract_type : string -> program -> contract_type result = fun main_fname program ->
|
let fetch_contract_type : string -> program -> contract_type result = fun main_fname program ->
|
||||||
let main_decl = List.rev @@ List.filter
|
let aux declt = match Location.unwrap declt with
|
||||||
(fun declt ->
|
| Declaration_constant ({ binder ; expr=_ ; inline=_ } as p) ->
|
||||||
let (Declaration_constant { binder ; expr=_ ; inline=_ ; post_env=_ }) = Location.unwrap declt in
|
if String.equal (Var.to_name binder) main_fname
|
||||||
String.equal (Var.to_name binder) main_fname
|
then Some p
|
||||||
)
|
else None
|
||||||
program
|
| Declaration_type _ -> None
|
||||||
in
|
in
|
||||||
match main_decl with
|
let main_decl_opt = List.find_map aux @@ List.rev program in
|
||||||
| (hd::_) -> (
|
let%bind main_decl =
|
||||||
let (Declaration_constant { binder=_ ; expr ; inline=_ ; post_env=_ }) = Location.unwrap hd in
|
trace_option (simple_error ("Entrypoint '"^main_fname^"' does not exist")) @@
|
||||||
match expr.type_expression.type_content with
|
main_decl_opt
|
||||||
| T_arrow {type1 ; type2} -> (
|
in
|
||||||
match type1.type_content , type2.type_content with
|
let { binder=_ ; expr ; inline=_ } = main_decl in
|
||||||
| T_record tin , T_record tout when (is_tuple_lmap tin) && (is_tuple_lmap tout) ->
|
match expr.type_expression.type_content with
|
||||||
let%bind (parameter,storage) = Ast_typed.Helpers.get_pair tin in
|
| T_arrow {type1 ; type2} -> (
|
||||||
let%bind (listop,storage') = Ast_typed.Helpers.get_pair tout in
|
match type1.type_content , type2.type_content with
|
||||||
let%bind () = trace_strong (Errors.expected_list_operation main_fname listop expr) @@
|
| T_record tin , T_record tout when (is_tuple_lmap tin) && (is_tuple_lmap tout) ->
|
||||||
Ast_typed.assert_t_list_operation listop in
|
let%bind (parameter,storage) = Ast_typed.Helpers.get_pair tin in
|
||||||
let%bind () = trace_strong (Errors.expected_same main_fname storage storage' expr) @@
|
let%bind (listop,storage') = Ast_typed.Helpers.get_pair tout in
|
||||||
Ast_typed.assert_type_expression_eq (storage,storage') in
|
let%bind () = trace_strong (Errors.expected_list_operation main_fname listop expr) @@
|
||||||
(* TODO: on storage/parameter : assert_storable, assert_passable ? *)
|
Ast_typed.assert_t_list_operation listop in
|
||||||
ok { parameter ; storage }
|
let%bind () = trace_strong (Errors.expected_same main_fname storage storage' expr) @@
|
||||||
| _ -> fail @@ Errors.bad_contract_io main_fname expr
|
Ast_typed.assert_type_expression_eq (storage,storage') in
|
||||||
)
|
(* TODO: on storage/parameter : assert_storable, assert_passable ? *)
|
||||||
| _ -> fail @@ Errors.bad_contract_io main_fname expr
|
ok { parameter ; storage }
|
||||||
|
| _ -> fail @@ Errors.bad_contract_io main_fname expr
|
||||||
)
|
)
|
||||||
| [] -> simple_fail ("Entrypoint '"^main_fname^"' does not exist")
|
| _ -> fail @@ Errors.bad_contract_io main_fname expr
|
||||||
|
@ -13,25 +13,25 @@ let accessor (record:expression) (path:label) (t:type_expression) =
|
|||||||
{ expression_content = E_record_accessor {record; path} ;
|
{ expression_content = E_record_accessor {record; path} ;
|
||||||
location = Location.generated ;
|
location = Location.generated ;
|
||||||
type_expression = t ;
|
type_expression = t ;
|
||||||
environment = record.environment }
|
}
|
||||||
|
|
||||||
let constructor (constructor:constructor') (element:expression) (t:type_expression) =
|
let constructor (constructor:constructor') (element:expression) (t:type_expression) =
|
||||||
{ expression_content = E_constructor { constructor ; element } ;
|
{ expression_content = E_constructor { constructor ; element } ;
|
||||||
location = Location.generated ;
|
location = Location.generated ;
|
||||||
type_expression = t ;
|
type_expression = t ;
|
||||||
environment = element.environment }
|
}
|
||||||
|
|
||||||
let match_var (t:type_expression) =
|
let match_var (t:type_expression) =
|
||||||
{ expression_content = E_variable (Var.of_name "x") ;
|
{ expression_content = E_variable (Var.of_name "x") ;
|
||||||
location = Location.generated ;
|
location = Location.generated ;
|
||||||
type_expression = t ;
|
type_expression = t ;
|
||||||
environment = Environment.add_ez_binder (Var.of_name "x") t Environment.empty}
|
}
|
||||||
|
|
||||||
let matching (e:expression) matchee cases =
|
let matching (e:expression) matchee cases =
|
||||||
{ expression_content = E_matching {matchee ; cases};
|
{ expression_content = E_matching {matchee ; cases};
|
||||||
location = Location.generated ;
|
location = Location.generated ;
|
||||||
type_expression = e.type_expression ;
|
type_expression = e.type_expression ;
|
||||||
environment = e.environment }
|
}
|
||||||
|
|
||||||
let rec descend_types s lmap i =
|
let rec descend_types s lmap i =
|
||||||
if i > 0 then
|
if i > 0 then
|
||||||
@ -105,7 +105,7 @@ let rec to_right_comb_record
|
|||||||
let exp = { expression_content = E_record_accessor {record = prev ; path = label } ;
|
let exp = { expression_content = E_record_accessor {record = prev ; path = label } ;
|
||||||
location = Location.generated ;
|
location = Location.generated ;
|
||||||
type_expression = field_type ;
|
type_expression = field_type ;
|
||||||
environment = prev.environment } in
|
} in
|
||||||
let conv_map' = LMap.add (Label "0") exp conv_map in
|
let conv_map' = LMap.add (Label "0") exp conv_map in
|
||||||
LMap.add (Label "1") ({exp with expression_content = E_record (to_right_comb_record prev tl conv_map')}) conv_map'
|
LMap.add (Label "1") ({exp with expression_content = E_record (to_right_comb_record prev tl conv_map')}) conv_map'
|
||||||
|
|
||||||
@ -275,4 +275,4 @@ let peephole_expression : expression -> expression result = fun e ->
|
|||||||
return match_expr.expression_content
|
return match_expr.expression_content
|
||||||
| _ -> return e.expression_content
|
| _ -> return e.expression_content
|
||||||
)
|
)
|
||||||
| _ as e -> return e
|
| _ as e -> return e
|
||||||
|
@ -13,8 +13,7 @@ let contract_passes = [
|
|||||||
let all_program program =
|
let all_program program =
|
||||||
let all_p = List.map Helpers.map_program all_passes in
|
let all_p = List.map Helpers.map_program all_passes in
|
||||||
let%bind program' = bind_chain all_p program in
|
let%bind program' = bind_chain all_p program in
|
||||||
let program'' = Recompute_environment.program Environment.default program' in
|
ok program'
|
||||||
ok program''
|
|
||||||
|
|
||||||
let all_expression =
|
let all_expression =
|
||||||
let all_p = List.map Helpers.map_expression all_passes in
|
let all_p = List.map Helpers.map_expression all_passes in
|
||||||
|
@ -326,8 +326,10 @@ and matching : (formatter -> expression -> unit) -> _ -> matching_expr -> unit =
|
|||||||
|
|
||||||
let declaration ppf (d : declaration) =
|
let declaration ppf (d : declaration) =
|
||||||
match d with
|
match d with
|
||||||
| Declaration_constant {binder; expr; inline; post_env=_} ->
|
| Declaration_constant {binder; expr; inline} ->
|
||||||
fprintf ppf "const %a = %a%a" expression_variable binder expression expr option_inline inline
|
fprintf ppf "const %a = %a%a" expression_variable binder expression expr option_inline inline
|
||||||
|
| Declaration_type {type_binder; type_expr} ->
|
||||||
|
fprintf ppf "type %a = %a" type_variable type_binder type_expression type_expr
|
||||||
|
|
||||||
let program ppf (p : program) =
|
let program ppf (p : program) =
|
||||||
fprintf ppf "@[<v>%a@]"
|
fprintf ppf "@[<v>%a@]"
|
||||||
|
@ -272,31 +272,30 @@ and declaration_loc = declaration location_wrap
|
|||||||
|
|
||||||
and program = declaration_loc list
|
and program = declaration_loc list
|
||||||
|
|
||||||
|
(* A Declaration_constant is described by
|
||||||
|
* a name + a type-annotated expression
|
||||||
|
* a boolean indicating whether it should be inlined
|
||||||
|
* the environment before the declaration (the original environment)
|
||||||
|
* the environment after the declaration (i.e. with that new declaration added to the original environment). *)
|
||||||
and declaration_constant = {
|
and declaration_constant = {
|
||||||
binder : expression_variable ;
|
binder : expression_variable ;
|
||||||
expr : expression ;
|
expr : expression ;
|
||||||
inline : bool ;
|
inline : bool ;
|
||||||
post_env : environment ;
|
}
|
||||||
|
|
||||||
|
and declaration_type = {
|
||||||
|
type_binder : type_variable ;
|
||||||
|
type_expr : type_expression ;
|
||||||
}
|
}
|
||||||
|
|
||||||
and declaration =
|
and declaration =
|
||||||
(* A Declaration_constant is described by
|
|
||||||
* a name + a type-annotated expression
|
|
||||||
* a boolean indicating whether it should be inlined
|
|
||||||
* the environment before the declaration (the original environment)
|
|
||||||
* the environment after the declaration (i.e. with that new declaration added to the original environment). *)
|
|
||||||
| Declaration_constant of declaration_constant
|
| Declaration_constant of declaration_constant
|
||||||
(*
|
| Declaration_type of declaration_type
|
||||||
| Declaration_type of (type_variable * type_expression)
|
|
||||||
| Declaration_constant of (named_expression * (environment * environment))
|
|
||||||
*)
|
|
||||||
(* | Macro_declaration of macro_declaration *)
|
|
||||||
|
|
||||||
and expression = {
|
and expression = {
|
||||||
expression_content: expression_content ;
|
expression_content: expression_content ;
|
||||||
location: location ;
|
location: location ;
|
||||||
type_expression: type_expression ;
|
type_expression: type_expression ;
|
||||||
environment: environment ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
and map_kv = {
|
and map_kv = {
|
||||||
|
@ -4,7 +4,6 @@ module PP = PP
|
|||||||
module PP_generic = PP_generic
|
module PP_generic = PP_generic
|
||||||
module Combinators = struct
|
module Combinators = struct
|
||||||
include Combinators
|
include Combinators
|
||||||
include Combinators_environment
|
|
||||||
end
|
end
|
||||||
module Misc = struct
|
module Misc = struct
|
||||||
include Misc
|
include Misc
|
||||||
@ -15,3 +14,5 @@ module Helpers = Helpers
|
|||||||
include Types
|
include Types
|
||||||
include Misc
|
include Misc
|
||||||
include Combinators
|
include Combinators
|
||||||
|
|
||||||
|
let program_environment env program = fst (Compute_environment.program env program)
|
||||||
|
@ -24,10 +24,9 @@ module Errors = struct
|
|||||||
end
|
end
|
||||||
|
|
||||||
let make_t ?(loc = Location.generated) type_content core = {type_content; location=loc; type_meta = core}
|
let make_t ?(loc = Location.generated) type_content core = {type_content; location=loc; type_meta = core}
|
||||||
let make_e ?(location = Location.generated) expression_content type_expression environment = {
|
let make_e ?(location = Location.generated) expression_content type_expression = {
|
||||||
expression_content ;
|
expression_content ;
|
||||||
type_expression ;
|
type_expression ;
|
||||||
environment ;
|
|
||||||
location ;
|
location ;
|
||||||
}
|
}
|
||||||
let make_n_t type_name type_value = { type_name ; type_value }
|
let make_n_t type_name type_value = { type_name ; type_value }
|
||||||
@ -83,7 +82,6 @@ let t_shallow_closure param result ?loc ?s () : type_expression = make_t ?loc (T
|
|||||||
|
|
||||||
let get_type_expression (x:expression) = x.type_expression
|
let get_type_expression (x:expression) = x.type_expression
|
||||||
let get_type' (x:type_expression) = x.type_content
|
let get_type' (x:type_expression) = x.type_content
|
||||||
let get_environment (x:expression) = x.environment
|
|
||||||
let get_expression (x:expression) = x.expression_content
|
let get_expression (x:expression) = x.expression_content
|
||||||
|
|
||||||
let get_lambda e : _ result = match e.expression_content with
|
let get_lambda e : _ result = match e.expression_content with
|
||||||
@ -330,13 +328,13 @@ let e_let_in let_binder inline rhs let_result = E_let_in { let_binder ; rhs ; le
|
|||||||
|
|
||||||
let e_constructor constructor element: expression_content = E_constructor {constructor;element}
|
let e_constructor constructor element: expression_content = E_constructor {constructor;element}
|
||||||
|
|
||||||
let e_bool b env : expression_content = e_constructor (Constructor (string_of_bool b)) (make_e (e_unit ())(t_unit()) env)
|
let e_bool b : expression_content = e_constructor (Constructor (string_of_bool b)) (make_e (e_unit ())(t_unit()))
|
||||||
|
|
||||||
let e_a_unit = make_e (e_unit ()) (t_unit ())
|
let e_a_unit = make_e (e_unit ()) (t_unit ())
|
||||||
let e_a_int n = make_e (e_int n) (t_int ())
|
let e_a_int n = make_e (e_int n) (t_int ())
|
||||||
let e_a_nat n = make_e (e_nat n) (t_nat ())
|
let e_a_nat n = make_e (e_nat n) (t_nat ())
|
||||||
let e_a_mutez n = make_e (e_mutez n) (t_mutez ())
|
let e_a_mutez n = make_e (e_mutez n) (t_mutez ())
|
||||||
let e_a_bool b = fun env -> make_e (e_bool b env) (t_bool ()) env
|
let e_a_bool b = make_e (e_bool b) (t_bool ())
|
||||||
let e_a_string s = make_e (e_string s) (t_string ())
|
let e_a_string s = make_e (e_string s) (t_string ())
|
||||||
let e_a_address s = make_e (e_address s) (t_address ())
|
let e_a_address s = make_e (e_address s) (t_address ())
|
||||||
let e_a_pair a b = make_e (e_pair a b)
|
let e_a_pair a b = make_e (e_pair a b)
|
||||||
@ -381,7 +379,8 @@ let get_a_record_accessor = fun t ->
|
|||||||
let get_declaration_by_name : program -> string -> declaration result = fun p name ->
|
let get_declaration_by_name : program -> string -> declaration result = fun p name ->
|
||||||
let aux : declaration -> bool = fun declaration ->
|
let aux : declaration -> bool = fun declaration ->
|
||||||
match declaration with
|
match declaration with
|
||||||
| Declaration_constant { binder ; expr=_ ; inline=_ ; post_env=_ } -> binder = Var.of_name name
|
| Declaration_constant { binder ; expr=_ ; inline=_ } -> binder = Var.of_name name
|
||||||
|
| Declaration_type _ -> false
|
||||||
in
|
in
|
||||||
trace_option (Errors.declaration_not_found name ()) @@
|
trace_option (Errors.declaration_not_found name ()) @@
|
||||||
List.find_opt aux @@ List.map Location.unwrap p
|
List.find_opt aux @@ List.map Location.unwrap p
|
||||||
|
@ -3,7 +3,7 @@ open Types
|
|||||||
|
|
||||||
val make_n_t : type_variable -> type_expression -> named_type_content
|
val make_n_t : type_variable -> type_expression -> named_type_content
|
||||||
val make_t : ?loc:Location.t -> type_content -> S.type_expression option -> type_expression
|
val make_t : ?loc:Location.t -> type_content -> S.type_expression option -> type_expression
|
||||||
val make_e : ?location:Location.t -> expression_content -> type_expression -> environment -> expression
|
val make_e : ?location:Location.t -> expression_content -> type_expression -> expression
|
||||||
|
|
||||||
val t_bool : ?loc:Location.t -> ?s:S.type_expression -> unit -> type_expression
|
val t_bool : ?loc:Location.t -> ?s:S.type_expression -> unit -> type_expression
|
||||||
val t_string : ?loc:Location.t -> ?s:S.type_expression -> unit -> type_expression
|
val t_string : ?loc:Location.t -> ?s:S.type_expression -> unit -> type_expression
|
||||||
@ -38,7 +38,6 @@ val t_function : type_expression -> type_expression -> ?loc:Location.t -> ?s:S.t
|
|||||||
val t_shallow_closure : type_expression -> type_expression -> ?loc:Location.t -> ?s:S.type_expression -> unit -> type_expression
|
val t_shallow_closure : type_expression -> type_expression -> ?loc:Location.t -> ?s:S.type_expression -> unit -> type_expression
|
||||||
val get_type_expression : expression -> type_expression
|
val get_type_expression : expression -> type_expression
|
||||||
val get_type' : type_expression -> type_content
|
val get_type' : type_expression -> type_content
|
||||||
val get_environment : expression -> environment
|
|
||||||
val get_expression : expression -> expression_content
|
val get_expression : expression -> expression_content
|
||||||
val get_lambda : expression -> lambda result
|
val get_lambda : expression -> lambda result
|
||||||
val get_lambda_with_type : expression -> (lambda * ( type_expression * type_expression) ) result
|
val get_lambda_with_type : expression -> (lambda * ( type_expression * type_expression) ) result
|
||||||
@ -119,7 +118,7 @@ val e_unit : unit -> expression_content
|
|||||||
val e_int : Z.t -> expression_content
|
val e_int : Z.t -> expression_content
|
||||||
val e_nat : Z.t -> expression_content
|
val e_nat : Z.t -> expression_content
|
||||||
val e_mutez : Z.t -> expression_content
|
val e_mutez : Z.t -> expression_content
|
||||||
val e_bool : bool -> environment -> expression_content
|
val e_bool : bool -> expression_content
|
||||||
val e_string : ligo_string -> expression_content
|
val e_string : ligo_string -> expression_content
|
||||||
val e_bytes : bytes -> expression_content
|
val e_bytes : bytes -> expression_content
|
||||||
val e_timestamp : Z.t -> expression_content
|
val e_timestamp : Z.t -> expression_content
|
||||||
@ -135,22 +134,22 @@ val e_application : expression -> expression -> expression_content
|
|||||||
val e_variable : expression_variable -> expression_content
|
val e_variable : expression_variable -> expression_content
|
||||||
val e_let_in : expression_variable -> inline -> expression -> expression -> expression_content
|
val e_let_in : expression_variable -> inline -> expression -> expression -> expression_content
|
||||||
|
|
||||||
val e_a_unit : environment -> expression
|
val e_a_unit : expression
|
||||||
val e_a_int : Z.t -> environment -> expression
|
val e_a_int : Z.t -> expression
|
||||||
val e_a_nat : Z.t -> environment -> expression
|
val e_a_nat : Z.t -> expression
|
||||||
val e_a_mutez : Z.t -> environment -> expression
|
val e_a_mutez : Z.t -> expression
|
||||||
val e_a_bool : bool -> environment -> expression
|
val e_a_bool : bool -> expression
|
||||||
val e_a_string : ligo_string -> environment -> expression
|
val e_a_string : ligo_string -> expression
|
||||||
val e_a_address : string -> environment -> expression
|
val e_a_address : string -> expression
|
||||||
val e_a_pair : expression -> expression -> environment -> expression
|
val e_a_pair : expression -> expression -> expression
|
||||||
val e_a_some : expression -> environment -> expression
|
val e_a_some : expression -> expression
|
||||||
val e_a_lambda : lambda -> type_expression -> type_expression -> environment -> expression
|
val e_a_lambda : lambda -> type_expression -> type_expression -> expression
|
||||||
val e_a_none : type_expression -> environment -> expression
|
val e_a_none : type_expression -> expression
|
||||||
val e_a_record : expression label_map -> environment -> expression
|
val e_a_record : expression label_map -> expression
|
||||||
val e_a_application : expression -> expression -> environment -> expression
|
val e_a_application : expression -> expression -> expression
|
||||||
val e_a_variable : expression_variable -> type_expression -> environment -> expression
|
val e_a_variable : expression_variable -> type_expression -> expression
|
||||||
val ez_e_a_record : ( label * expression ) list -> environment -> expression
|
val ez_e_a_record : ( label * expression ) list -> expression
|
||||||
val e_a_let_in : expression_variable -> bool -> expression -> expression -> environment -> expression
|
val e_a_let_in : expression_variable -> bool -> expression -> expression -> expression
|
||||||
|
|
||||||
val get_a_int : expression -> Z.t result
|
val get_a_int : expression -> Z.t result
|
||||||
val get_a_unit : expression -> unit result
|
val get_a_unit : expression -> unit result
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
open Types
|
|
||||||
open Combinators
|
|
||||||
|
|
||||||
let make_a_e_empty expression type_annotation = make_e expression type_annotation Environment.empty
|
|
||||||
|
|
||||||
let e_a_empty_unit = e_a_unit Environment.empty
|
|
||||||
let e_a_empty_int n = e_a_int n Environment.empty
|
|
||||||
let e_a_empty_nat n = e_a_nat n Environment.empty
|
|
||||||
let e_a_empty_mutez n = e_a_mutez n Environment.empty
|
|
||||||
let e_a_empty_bool b = e_a_bool b Environment.empty
|
|
||||||
let e_a_empty_string s = e_a_string s Environment.empty
|
|
||||||
let e_a_empty_address s = e_a_address s Environment.empty
|
|
||||||
let e_a_empty_pair a b = e_a_pair a b Environment.empty
|
|
||||||
let e_a_empty_some s = e_a_some s Environment.empty
|
|
||||||
let e_a_empty_none t = e_a_none t Environment.empty
|
|
||||||
let e_a_empty_record r = e_a_record r Environment.empty
|
|
||||||
let ez_e_a_empty_record r = ez_e_a_record r Environment.empty
|
|
||||||
let e_a_empty_lambda l i o = e_a_lambda l i o Environment.empty
|
|
||||||
|
|
||||||
open Environment
|
|
||||||
|
|
||||||
let env_sum_type ?(env = empty)
|
|
||||||
?(type_name = Var.of_name "a_sum_type")
|
|
||||||
(lst : (constructor' * ctor_content) list) =
|
|
||||||
add_type type_name (make_t_ez_sum lst) env
|
|
@ -1,19 +0,0 @@
|
|||||||
open Types
|
|
||||||
|
|
||||||
val make_a_e_empty : expression_content -> type_expression -> expression
|
|
||||||
|
|
||||||
val e_a_empty_unit : expression
|
|
||||||
val e_a_empty_int : Z.t -> expression
|
|
||||||
val e_a_empty_nat : Z.t -> expression
|
|
||||||
val e_a_empty_mutez : Z.t -> expression
|
|
||||||
val e_a_empty_bool : bool -> expression
|
|
||||||
val e_a_empty_string : ligo_string -> expression
|
|
||||||
val e_a_empty_address : string -> expression
|
|
||||||
val e_a_empty_pair : expression -> expression -> expression
|
|
||||||
val e_a_empty_some : expression -> expression
|
|
||||||
val e_a_empty_none : type_expression -> expression
|
|
||||||
val e_a_empty_record : expression label_map -> expression
|
|
||||||
val ez_e_a_empty_record : ( label * expression ) list -> expression
|
|
||||||
val e_a_empty_lambda : lambda -> type_expression -> type_expression -> expression
|
|
||||||
|
|
||||||
val env_sum_type : ?env:environment -> ?type_name:type_variable -> (constructor' * ctor_content) list -> environment
|
|
@ -1,23 +1,9 @@
|
|||||||
open Ast_typed
|
open Types
|
||||||
|
|
||||||
(*
|
|
||||||
During the modifications of the passes on `Ast_typed`, the binding
|
|
||||||
environments are not kept in sync. To palliate this, this module
|
|
||||||
recomputes them from scratch.
|
|
||||||
*)
|
|
||||||
|
|
||||||
(*
|
|
||||||
This module is very coupled to `typer.ml`. Given environments are
|
|
||||||
not used until the next pass, it makes sense to split this into
|
|
||||||
its own separate pass. This pass would go from `Ast_typed` without
|
|
||||||
environments to `Ast_typed` with embedded environments.
|
|
||||||
*)
|
|
||||||
|
|
||||||
let rec expression : environment -> expression -> expression = fun env expr ->
|
let rec expression : environment -> expression -> expression = fun env expr ->
|
||||||
(* Standard helper functions to help with the fold *)
|
(* Standard helper functions to help with the fold *)
|
||||||
let return ?(env' = env) content = {
|
let return content = {
|
||||||
expr with
|
expr with
|
||||||
environment = env' ;
|
|
||||||
expression_content = content ;
|
expression_content = content ;
|
||||||
} in
|
} in
|
||||||
let return_id = return expr.expression_content in
|
let return_id = return expr.expression_content in
|
||||||
@ -34,9 +20,9 @@ let rec expression : environment -> expression -> expression = fun env expr ->
|
|||||||
return @@ E_lambda { c with result }
|
return @@ E_lambda { c with result }
|
||||||
)
|
)
|
||||||
| E_let_in c -> (
|
| E_let_in c -> (
|
||||||
let env' = Environment.add_ez_declaration c.let_binder c.rhs env in
|
|
||||||
let let_result = self ~env' c.let_result in
|
|
||||||
let rhs = self c.rhs in
|
let rhs = self c.rhs in
|
||||||
|
let env' = Environment.add_ez_declaration c.let_binder rhs env in
|
||||||
|
let let_result = self ~env' c.let_result in
|
||||||
return @@ E_let_in { c with rhs ; let_result }
|
return @@ E_let_in { c with rhs ; let_result }
|
||||||
)
|
)
|
||||||
(* rec fun_name binder -> result *)
|
(* rec fun_name binder -> result *)
|
||||||
@ -90,7 +76,7 @@ and cases : environment -> matching_expr -> matching_expr = fun env cs ->
|
|||||||
let match_cons =
|
let match_cons =
|
||||||
let mc = c.match_cons in
|
let mc = c.match_cons in
|
||||||
let env_hd = Environment.add_ez_binder mc.hd mc.tv env in
|
let env_hd = Environment.add_ez_binder mc.hd mc.tv env in
|
||||||
let env_tl = Environment.add_ez_binder mc.tl (t_list mc.tv ()) env_hd in
|
let env_tl = Environment.add_ez_binder mc.tl (Combinators.t_list mc.tv ()) env_hd in
|
||||||
let body = self ~env':env_tl mc.body in
|
let body = self ~env':env_tl mc.body in
|
||||||
{ mc with body }
|
{ mc with body }
|
||||||
in
|
in
|
||||||
@ -139,24 +125,27 @@ and cases : environment -> matching_expr -> matching_expr = fun env cs ->
|
|||||||
return @@ Match_variant { c with cases }
|
return @@ Match_variant { c with cases }
|
||||||
)
|
)
|
||||||
|
|
||||||
let program : environment -> program -> program = fun init_env prog ->
|
let program : environment -> program -> environment * program = fun init_env prog ->
|
||||||
(*
|
(*
|
||||||
BAD
|
BAD
|
||||||
We take the old type environment and add it to the current value environment
|
We take the old type environment and add it to the current value environment
|
||||||
because type declarations are removed in the typer. They should be added back.
|
because type declarations are removed in the typer. They should be added back.
|
||||||
*)
|
*)
|
||||||
let merge old_env re_env = {
|
|
||||||
expression_environment = re_env.expression_environment ;
|
|
||||||
type_environment = old_env.type_environment ;
|
|
||||||
} in
|
|
||||||
let aux (pre_env , rev_decls) decl_wrapped =
|
let aux (pre_env , rev_decls) decl_wrapped =
|
||||||
let (Declaration_constant c) = Location.unwrap decl_wrapped in
|
match Location.unwrap decl_wrapped with
|
||||||
let expr = expression pre_env c.expr in
|
| Declaration_constant c -> (
|
||||||
let post_env = Environment.add_ez_declaration c.binder c.expr pre_env in
|
let expr = expression pre_env c.expr in
|
||||||
let post_env' = merge c.post_env post_env in
|
let post_env = Environment.add_ez_declaration c.binder expr pre_env in
|
||||||
let wrap_content = Declaration_constant { c with expr ; post_env = post_env' } in
|
let wrap_content = Declaration_constant { c with expr } in
|
||||||
let decl_wrapped' = { decl_wrapped with wrap_content } in
|
let decl_wrapped' = { decl_wrapped with wrap_content } in
|
||||||
(post_env , decl_wrapped' :: rev_decls)
|
(post_env , decl_wrapped' :: rev_decls)
|
||||||
|
)
|
||||||
|
| Declaration_type t -> (
|
||||||
|
let post_env = Environment.add_type t.type_binder t.type_expr pre_env in
|
||||||
|
let wrap_content = Declaration_type t in
|
||||||
|
let decl_wrapped' = { decl_wrapped with wrap_content } in
|
||||||
|
(post_env , decl_wrapped' :: rev_decls)
|
||||||
|
)
|
||||||
in
|
in
|
||||||
let (_last_env , rev_decls) = List.fold_left aux (init_env , []) prog in
|
let (last_env , rev_decls) = List.fold_left aux (init_env , []) prog in
|
||||||
List.rev rev_decls
|
(last_env , List.rev rev_decls)
|
@ -38,6 +38,9 @@ let add_ez_binder : expression_variable -> type_expression -> t -> t = fun k v e
|
|||||||
let add_ez_declaration : expression_variable -> expression -> t -> t = fun k ae e ->
|
let add_ez_declaration : expression_variable -> expression -> t -> t = fun k ae e ->
|
||||||
add_expr k (make_element_declaration e ae) e
|
add_expr k (make_element_declaration e ae) e
|
||||||
|
|
||||||
|
let add_ez_sum_type ?(env = empty) ?(type_name = Var.of_name "a_sum_type") (lst : (constructor' * ctor_content) list) =
|
||||||
|
add_type type_name (make_t_ez_sum lst) env
|
||||||
|
|
||||||
let convert_constructor' (S.Constructor c) = Constructor c
|
let convert_constructor' (S.Constructor c) = Constructor c
|
||||||
|
|
||||||
let get_constructor : Ast_core.constructor' -> t -> (type_expression * type_expression) option = fun k x -> (* Left is the constructor, right is the sum type *)
|
let get_constructor : Ast_core.constructor' -> t -> (type_expression * type_expression) option = fun k x -> (* Left is the constructor, right is the sum type *)
|
||||||
@ -76,4 +79,4 @@ module PP = struct
|
|||||||
expr_environment (get_expr_environment e)
|
expr_environment (get_expr_environment e)
|
||||||
type_environment (get_type_environment e)
|
type_environment (get_type_environment e)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -11,6 +11,7 @@ val get_opt : expression_variable -> t -> element option
|
|||||||
val get_type_opt : type_variable -> t -> type_expression option
|
val get_type_opt : type_variable -> t -> type_expression option
|
||||||
val get_constructor : Ast_core.constructor' -> t -> (type_expression * type_expression) option
|
val get_constructor : Ast_core.constructor' -> t -> (type_expression * type_expression) option
|
||||||
|
|
||||||
|
val add_ez_sum_type : ?env:environment -> ?type_name:type_variable -> (constructor' * ctor_content) list -> environment
|
||||||
module PP : sig
|
module PP : sig
|
||||||
open Format
|
open Format
|
||||||
|
|
||||||
|
@ -511,19 +511,17 @@ let merge_annotation (a:type_expression option) (b:type_expression option) err :
|
|||||||
|
|
||||||
let get_entry (lst : program) (name : string) : expression result =
|
let get_entry (lst : program) (name : string) : expression result =
|
||||||
trace_option (Errors.missing_entry_point name) @@
|
trace_option (Errors.missing_entry_point name) @@
|
||||||
let aux x =
|
let aux x =
|
||||||
let (Declaration_constant { binder ; expr ; inline=_ ; _ }) = Location.unwrap x in
|
match Location.unwrap x with
|
||||||
if Var.equal binder (Var.of_name name)
|
| Declaration_constant { binder ; expr ; inline=_ } -> (
|
||||||
then Some expr
|
if Var.equal binder (Var.of_name name)
|
||||||
else None
|
then Some expr
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
| Declaration_type _ -> None
|
||||||
in
|
in
|
||||||
List.find_map aux lst
|
List.find_map aux lst
|
||||||
|
|
||||||
let program_environment (program : program) : environment =
|
|
||||||
let last_declaration = Location.unwrap List.(hd @@ rev program) in
|
|
||||||
match last_declaration with
|
|
||||||
| Declaration_constant { binder=_ ; expr=_ ; inline=_ ; post_env } -> post_env
|
|
||||||
|
|
||||||
let equal_variables a b : bool =
|
let equal_variables a b : bool =
|
||||||
match a.expression_content, b.expression_content with
|
match a.expression_content, b.expression_content with
|
||||||
| E_variable a, E_variable b -> Var.equal a b
|
| E_variable a, E_variable b -> Var.equal a b
|
||||||
|
@ -70,7 +70,6 @@ val assert_literal_eq : ( literal * literal ) -> unit result
|
|||||||
*)
|
*)
|
||||||
|
|
||||||
val get_entry : program -> string -> expression result
|
val get_entry : program -> string -> expression result
|
||||||
val program_environment : program -> environment
|
|
||||||
|
|
||||||
val p_constant : constant_tag -> p_ctor_args -> type_value
|
val p_constant : constant_tag -> p_ctor_args -> type_value
|
||||||
val c_equation : type_value -> type_value -> string -> type_constraint
|
val c_equation : type_value -> type_value -> string -> type_constraint
|
||||||
|
@ -8,8 +8,9 @@ let program_to_main : program -> string -> lambda result = fun p s ->
|
|||||||
let%bind (main , input_type , _) =
|
let%bind (main , input_type , _) =
|
||||||
let pred = fun d ->
|
let pred = fun d ->
|
||||||
match d with
|
match d with
|
||||||
| Declaration_constant { binder; expr; inline=_ ; post_env=_ } when binder = Var.of_name s -> Some expr
|
| Declaration_constant { binder; expr; inline=_ } when binder = Var.of_name s -> Some expr
|
||||||
| Declaration_constant _ -> None
|
| Declaration_constant _ -> None
|
||||||
|
| Declaration_type _ -> None
|
||||||
in
|
in
|
||||||
let%bind main =
|
let%bind main =
|
||||||
trace_option (simple_error "no main with given name") @@
|
trace_option (simple_error "no main with given name") @@
|
||||||
@ -20,16 +21,11 @@ let program_to_main : program -> string -> lambda result = fun p s ->
|
|||||||
| _ -> simple_fail "program main isn't a function" in
|
| _ -> simple_fail "program main isn't a function" in
|
||||||
ok (main , input_ty , output_ty)
|
ok (main , input_ty , output_ty)
|
||||||
in
|
in
|
||||||
let env =
|
|
||||||
let aux = fun _ d ->
|
|
||||||
match d with
|
|
||||||
| Declaration_constant {binder=_ ; expr= _ ; inline=_ ; post_env } -> post_env in
|
|
||||||
List.fold_left aux Environment.empty (List.map Location.unwrap p) in
|
|
||||||
let binder = Var.of_name "@contract_input" in
|
let binder = Var.of_name "@contract_input" in
|
||||||
let result =
|
let result =
|
||||||
let input_expr = e_a_variable binder input_type env in
|
let input_expr = e_a_variable binder input_type in
|
||||||
let main_expr = e_a_variable (Var.of_name s) (get_type_expression main) env in
|
let main_expr = e_a_variable (Var.of_name s) (get_type_expression main) in
|
||||||
e_a_application main_expr input_expr env in
|
e_a_application main_expr input_expr in
|
||||||
ok {
|
ok {
|
||||||
binder ;
|
binder ;
|
||||||
result ;
|
result ;
|
||||||
@ -46,8 +42,8 @@ module Captured_variables = struct
|
|||||||
let of_list : expression_variable list -> bindings = fun x -> x
|
let of_list : expression_variable list -> bindings = fun x -> x
|
||||||
|
|
||||||
let rec expression : bindings -> expression -> bindings result = fun b e ->
|
let rec expression : bindings -> expression -> bindings result = fun b e ->
|
||||||
expression_content b e.environment e.expression_content
|
expression_content b e.expression_content
|
||||||
and expression_content : bindings -> environment -> expression_content -> bindings result = fun b env ec ->
|
and expression_content : bindings -> expression_content -> bindings result = fun b ec ->
|
||||||
let self = expression b in
|
let self = expression b in
|
||||||
match ec with
|
match ec with
|
||||||
| E_lambda l -> ok @@ Free_variables.lambda empty l
|
| E_lambda l -> ok @@ Free_variables.lambda empty l
|
||||||
@ -56,12 +52,7 @@ module Captured_variables = struct
|
|||||||
let%bind lst' = bind_map_list self arguments in
|
let%bind lst' = bind_map_list self arguments in
|
||||||
ok @@ unions lst'
|
ok @@ unions lst'
|
||||||
| E_variable name -> (
|
| E_variable name -> (
|
||||||
let%bind env_element =
|
if mem name b then ok empty else ok (singleton name)
|
||||||
trace_option (simple_error "missing var in env") @@
|
|
||||||
Environment.get_opt name env in
|
|
||||||
match env_element.definition with
|
|
||||||
| ED_binder -> ok empty
|
|
||||||
| ED_declaration {expr=_ ; free_variables=_} -> simple_fail "todo"
|
|
||||||
)
|
)
|
||||||
| E_application {lamb;args} ->
|
| E_application {lamb;args} ->
|
||||||
let%bind lst' = bind_map_list self [ lamb ; args ] in
|
let%bind lst' = bind_map_list self [ lamb ; args ] in
|
||||||
@ -84,7 +75,7 @@ module Captured_variables = struct
|
|||||||
expression b' li.let_result
|
expression b' li.let_result
|
||||||
| E_recursive r ->
|
| E_recursive r ->
|
||||||
let b' = union (singleton r.fun_name) b in
|
let b' = union (singleton r.fun_name) b in
|
||||||
expression_content b' env @@ E_lambda r.lambda
|
expression_content b' @@ E_lambda r.lambda
|
||||||
|
|
||||||
and matching_variant_case : (bindings -> expression -> bindings result) -> bindings -> matching_content_case -> bindings result = fun f b { constructor=_ ; pattern ; body } ->
|
and matching_variant_case : (bindings -> expression -> bindings result) -> bindings -> matching_content_case -> bindings result = fun f b { constructor=_ ; pattern ; body } ->
|
||||||
f (union (singleton pattern) b) body
|
f (union (singleton pattern) b) body
|
||||||
|
@ -183,6 +183,15 @@ let e_let_in ?loc v tv inline expr body : expression = Expression.(make_tpl ?loc
|
|||||||
E_let_in ((v , tv) , inline, expr , body) ,
|
E_let_in ((v , tv) , inline, expr , body) ,
|
||||||
get_type body
|
get_type body
|
||||||
))
|
))
|
||||||
|
let e_application ?loc f t arg: expression = Expression.(make_tpl ?loc(
|
||||||
|
E_application (f,arg) ,
|
||||||
|
t
|
||||||
|
))
|
||||||
|
let e_var ?loc vname t: expression = Expression.(make_tpl ?loc(
|
||||||
|
E_variable vname ,
|
||||||
|
t
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
let ez_e_sequence ?loc a b : expression = Expression.(make_tpl (E_sequence (make_tpl ?loc (a , t_unit ()) , b) , get_type b))
|
let ez_e_sequence ?loc a b : expression = Expression.(make_tpl (E_sequence (make_tpl ?loc (a , t_unit ()) , b) , get_type b))
|
||||||
|
|
||||||
|
@ -78,3 +78,5 @@ val d_unit : value
|
|||||||
|
|
||||||
val environment_wrap : environment -> environment -> environment_wrap
|
val environment_wrap : environment -> environment -> environment_wrap
|
||||||
val id_environment_wrap : environment -> environment_wrap
|
val id_environment_wrap : environment -> environment_wrap
|
||||||
|
val e_var : ?loc:Location.t -> var_name -> type_expression -> expression
|
||||||
|
val e_application : ?loc:Location.t -> expression -> type_expression -> expression -> expression
|
||||||
|
@ -195,20 +195,19 @@ module Substitution = struct
|
|||||||
let%bind cases = s_matching_expr ~substs cases in
|
let%bind cases = s_matching_expr ~substs cases in
|
||||||
ok @@ T.E_matching {matchee;cases}
|
ok @@ T.E_matching {matchee;cases}
|
||||||
|
|
||||||
and s_expression : T.expression w = fun ~(substs:substs) { expression_content; type_expression; environment; location } ->
|
and s_expression : T.expression w = fun ~(substs:substs) { expression_content; type_expression; location } ->
|
||||||
let%bind expression_content = s_expression_content ~substs expression_content in
|
let%bind expression_content = s_expression_content ~substs expression_content in
|
||||||
let%bind type_expr = s_type_expression ~substs type_expression in
|
let%bind type_expr = s_type_expression ~substs type_expression in
|
||||||
let%bind environment = s_environment ~substs environment in
|
|
||||||
let location = location in
|
let location = location in
|
||||||
ok T.{ expression_content;type_expression=type_expr; environment; location }
|
ok T.{ expression_content;type_expression=type_expr; location }
|
||||||
|
|
||||||
and s_declaration : T.declaration w = fun ~substs ->
|
and s_declaration : T.declaration w = fun ~substs ->
|
||||||
function
|
function
|
||||||
Ast_typed.Declaration_constant {binder ; expr ; inline ; post_env} ->
|
| Ast_typed.Declaration_constant {binder ; expr ; inline} ->
|
||||||
let%bind binder = s_variable ~substs binder in
|
let%bind binder = s_variable ~substs binder in
|
||||||
let%bind expr = s_expression ~substs expr in
|
let%bind expr = s_expression ~substs expr in
|
||||||
let%bind post_env = s_environment ~substs post_env in
|
ok @@ Ast_typed.Declaration_constant {binder; expr; inline}
|
||||||
ok @@ Ast_typed.Declaration_constant {binder; expr; inline; post_env}
|
| Declaration_type t -> ok (Ast_typed.Declaration_type t)
|
||||||
|
|
||||||
and s_declaration_wrap :T.declaration Location.wrap w = fun ~substs d ->
|
and s_declaration_wrap :T.declaration Location.wrap w = fun ~substs d ->
|
||||||
Trace.bind_map_location (s_declaration ~substs) d
|
Trace.bind_map_location (s_declaration ~substs) d
|
||||||
|
72
src/test/contracts/double_fold_converter.religo
Normal file
72
src/test/contracts/double_fold_converter.religo
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
type tokenId = nat;
|
||||||
|
type tokenOwner = address;
|
||||||
|
type tokenAmount = nat;
|
||||||
|
type transferContents = {
|
||||||
|
to_: tokenOwner,
|
||||||
|
token_id: tokenId,
|
||||||
|
amount: tokenAmount
|
||||||
|
};
|
||||||
|
type transfer = {
|
||||||
|
from_: tokenOwner,
|
||||||
|
txs: list(transferContents)
|
||||||
|
};
|
||||||
|
type transferContentsMichelson = michelson_pair_right_comb(transferContents);
|
||||||
|
type transferAuxiliary = {
|
||||||
|
from_: tokenOwner,
|
||||||
|
txs: list(transferContentsMichelson)
|
||||||
|
};
|
||||||
|
type transferMichelson = michelson_pair_right_comb(transferAuxiliary);
|
||||||
|
type transferParameter = list(transferMichelson);
|
||||||
|
type parameter =
|
||||||
|
| Transfer(transferParameter)
|
||||||
|
type storage = big_map(tokenId, tokenOwner);
|
||||||
|
type entrypointParameter = (parameter, storage);
|
||||||
|
type entrypointReturn = (list(operation), storage);
|
||||||
|
let errorTokenUndefined = "TOKEN_UNDEFINED";
|
||||||
|
let errorNotOwner = "NOT_OWNER";
|
||||||
|
let errorInsufficientBalance = "INSUFFICIENT_BALANCE";
|
||||||
|
type transferContentsIteratorAccumulator = (storage, tokenOwner);
|
||||||
|
let transferContentsIterator = ((accumulator, transferContentsMichelson): (transferContentsIteratorAccumulator, transferContentsMichelson)): transferContentsIteratorAccumulator => {
|
||||||
|
let (storage, from_) = accumulator;
|
||||||
|
let transferContents: transferContents = Layout.convert_from_right_comb(transferContentsMichelson);
|
||||||
|
let tokenOwner: option(tokenOwner) = Map.find_opt(transferContents.token_id, storage);
|
||||||
|
let tokenOwner = switch (tokenOwner) {
|
||||||
|
| None => (failwith(errorTokenUndefined): tokenOwner)
|
||||||
|
| Some(tokenOwner) => if (tokenOwner == from_) {
|
||||||
|
tokenOwner
|
||||||
|
} else {
|
||||||
|
(failwith(errorInsufficientBalance): tokenOwner);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let storage = Map.update(
|
||||||
|
transferContents.token_id,
|
||||||
|
Some(transferContents.to_),
|
||||||
|
storage
|
||||||
|
);
|
||||||
|
(storage, from_)
|
||||||
|
};
|
||||||
|
let allowOnlyOwnTransfer = (from: tokenOwner): unit => {
|
||||||
|
if (from != Tezos.sender) {
|
||||||
|
failwith(errorNotOwner)
|
||||||
|
} else { (); }
|
||||||
|
}
|
||||||
|
let transferIterator = ((storage, transferMichelson): (storage, transferMichelson)): storage => {
|
||||||
|
let transferAuxiliary2: transferAuxiliary = Layout.convert_from_right_comb(transferMichelson);
|
||||||
|
let from_: tokenOwner = transferAuxiliary2.from_;
|
||||||
|
allowOnlyOwnTransfer(from_);
|
||||||
|
let (storage, _) = List.fold(
|
||||||
|
transferContentsIterator,
|
||||||
|
transferAuxiliary2.txs,
|
||||||
|
(storage, from_)
|
||||||
|
);
|
||||||
|
storage
|
||||||
|
};
|
||||||
|
let transfer = ((transferParameter, storage): (transferParameter, storage)): entrypointReturn => {
|
||||||
|
let storage = List.fold(transferIterator, transferParameter, storage);
|
||||||
|
(([]: list(operation)), storage);
|
||||||
|
};
|
||||||
|
let main = ((parameter, storage): entrypointParameter): entrypointReturn => {
|
||||||
|
switch (parameter) {
|
||||||
|
| Transfer(transferParameter) => transfer((transferParameter, storage))
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,7 @@ open Ast_imperative
|
|||||||
|
|
||||||
let pack_payload (program:Ast_typed.program) (payload:expression) : bytes result =
|
let pack_payload (program:Ast_typed.program) (payload:expression) : bytes result =
|
||||||
let%bind code =
|
let%bind code =
|
||||||
let env = Ast_typed.program_environment program in
|
let env = Ast_typed.program_environment Environment.default program in
|
||||||
|
|
||||||
let%bind sugar = Compile.Of_imperative.compile_expression payload in
|
let%bind sugar = Compile.Of_imperative.compile_expression payload in
|
||||||
let%bind core = Compile.Of_sugar.compile_expression sugar in
|
let%bind core = Compile.Of_sugar.compile_expression sugar in
|
||||||
@ -89,7 +89,7 @@ let typed_program_with_imperative_input_to_michelson
|
|||||||
(program: Ast_typed.program) (entry_point: string)
|
(program: Ast_typed.program) (entry_point: string)
|
||||||
(input: Ast_imperative.expression) : Compiler.compiled_expression result =
|
(input: Ast_imperative.expression) : Compiler.compiled_expression result =
|
||||||
Printexc.record_backtrace true;
|
Printexc.record_backtrace true;
|
||||||
let env = Ast_typed.program_environment program in
|
let env = Ast_typed.program_environment Environment.default program in
|
||||||
let state = Typer.Solver.initial_state in
|
let state = Typer.Solver.initial_state in
|
||||||
let%bind sugar = Compile.Of_imperative.compile_expression input in
|
let%bind sugar = Compile.Of_imperative.compile_expression input in
|
||||||
let%bind core = Compile.Of_sugar.compile_expression sugar in
|
let%bind core = Compile.Of_sugar.compile_expression sugar in
|
||||||
|
@ -34,7 +34,7 @@ module TestExpressions = struct
|
|||||||
|
|
||||||
module I = Simplified.Combinators
|
module I = Simplified.Combinators
|
||||||
module O = Typed.Combinators
|
module O = Typed.Combinators
|
||||||
module E = O
|
module E = Typed.Environment
|
||||||
|
|
||||||
let unit () : unit result = test_expression I.(e_unit ()) O.(t_unit ())
|
let unit () : unit result = test_expression I.(e_unit ()) O.(t_unit ())
|
||||||
let int () : unit result = test_expression I.(e_int (Z.of_int 32)) O.(t_int ())
|
let int () : unit result = test_expression I.(e_int (Z.of_int 32)) O.(t_int ())
|
||||||
@ -59,7 +59,7 @@ module TestExpressions = struct
|
|||||||
(Typed.Constructor "foo", {ctor_type = Typed.t_int () ; michelson_annotation = None ; ctor_decl_pos = 0});
|
(Typed.Constructor "foo", {ctor_type = Typed.t_int () ; michelson_annotation = None ; ctor_decl_pos = 0});
|
||||||
(Typed.Constructor "bar", {ctor_type = Typed.t_string () ; michelson_annotation = None ; ctor_decl_pos = 1}) ]
|
(Typed.Constructor "bar", {ctor_type = Typed.t_string () ; michelson_annotation = None ; ctor_decl_pos = 1}) ]
|
||||||
in test_expression
|
in test_expression
|
||||||
~env:(E.env_sum_type variant_foo_bar)
|
~env:(E.add_ez_sum_type variant_foo_bar)
|
||||||
I.(e_constructor "foo" (e_int (Z.of_int 32)))
|
I.(e_constructor "foo" (e_int (Z.of_int 32)))
|
||||||
O.(make_t_ez_sum variant_foo_bar)
|
O.(make_t_ez_sum variant_foo_bar)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user