I upgraded the parsers to accept Map.map
etc. I rewrote the doc except "reference" to promote and deprecate built-ins.
This commit is contained in:
parent
656807b22e
commit
31a39bffbc
@ -194,8 +194,8 @@ how those built-ins can be utilized.
|
|||||||
|
|
||||||
### Accepting or Declining Tokens in a Smart Contract
|
### Accepting or Declining Tokens in a Smart Contract
|
||||||
|
|
||||||
This example shows how `amount` and `failwith` can be used to decline
|
This example shows how `Tezos.amount` and `failwith` can be used to
|
||||||
any transaction that sends more tez than `0mutez`, that is, no
|
decline any transaction that sends more tez than `0tez`, that is, no
|
||||||
incoming tokens are accepted.
|
incoming tokens are accepted.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
@ -206,11 +206,13 @@ type storage is unit
|
|||||||
type return is list (operation) * storage
|
type return is list (operation) * storage
|
||||||
|
|
||||||
function deny (const action : parameter; const store : storage) : return is
|
function deny (const action : parameter; const store : storage) : return is
|
||||||
if amount > 0mutez then
|
if Tezos.amount > 0tez then
|
||||||
(failwith ("This contract does not accept tokens.") : return)
|
(failwith ("This contract does not accept tokens.") : return)
|
||||||
else ((nil : list (operation)), store)
|
else ((nil : list (operation)), store)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `amount` is *deprecated*.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=c
|
```cameligo group=c
|
||||||
type parameter = unit
|
type parameter = unit
|
||||||
@ -218,11 +220,13 @@ type storage = unit
|
|||||||
type return = operation list * storage
|
type return = operation list * storage
|
||||||
|
|
||||||
let deny (action, store : parameter * storage) : return =
|
let deny (action, store : parameter * storage) : return =
|
||||||
if amount > 0mutez then
|
if Tezos.amount > 0tez then
|
||||||
(failwith "This contract does not accept tokens.": return)
|
(failwith "This contract does not accept tokens." : return)
|
||||||
else (([] : operation list), store)
|
else (([] : operation list), store)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `amount` is *deprecated*.
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=c
|
```reasonligo group=c
|
||||||
type parameter = unit;
|
type parameter = unit;
|
||||||
@ -230,17 +234,20 @@ type storage = unit;
|
|||||||
type return = (list (operation), storage);
|
type return = (list (operation), storage);
|
||||||
|
|
||||||
let deny = ((action, store): (parameter, storage)) : return => {
|
let deny = ((action, store): (parameter, storage)) : return => {
|
||||||
if (amount > 0mutez) {
|
if (Tezos.amount > 0tez) {
|
||||||
(failwith("This contract does not accept tokens."): return); }
|
(failwith("This contract does not accept tokens."): return); }
|
||||||
else { (([] : list (operation)), store); };
|
else { (([] : list (operation)), store); };
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `amount` is *deprecated*.
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
### Access Control
|
### Access Control
|
||||||
|
|
||||||
This example shows how `sender` or `source` can be used to deny access to an entrypoint.
|
This example shows how `Tezos.source` can be used to deny access to an
|
||||||
|
entrypoint.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
@ -248,28 +255,35 @@ This example shows how `sender` or `source` can be used to deny access to an ent
|
|||||||
const owner : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address);
|
const owner : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address);
|
||||||
|
|
||||||
function main (const action : parameter; const store : storage) : return is
|
function main (const action : parameter; const store : storage) : return is
|
||||||
if source =/= owner then (failwith ("Access denied.") : return)
|
if Tezos.source =/= owner then (failwith ("Access denied.") : return)
|
||||||
else ((nil : list(operation)), store)
|
else ((nil : list (operation)), store)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `source` is *deprecated*.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=c
|
```cameligo group=c
|
||||||
let owner : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address)
|
let owner : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address)
|
||||||
|
|
||||||
let main (action, store: parameter * storage) : return =
|
let main (action, store: parameter * storage) : return =
|
||||||
if source <> owner then (failwith "Access denied." : return)
|
if Tezos.source <> owner then (failwith "Access denied." : return)
|
||||||
else (([] : operation list), store)
|
else (([] : operation list), store)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `source` is *deprecated*.
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=c
|
```reasonligo group=c
|
||||||
let owner : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address);
|
let owner : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address);
|
||||||
|
|
||||||
let main = ((action, store): (parameter, storage)) : storage => {
|
let main = ((action, store) : (parameter, storage)) : storage => {
|
||||||
if (source != owner) { (failwith ("Access denied.") : return); }
|
if (Tezos.source != owner) { (failwith ("Access denied.") : return); }
|
||||||
else { (([] : list (operation)), store); };
|
else { (([] : list (operation)), store); };
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `source` is *deprecated*.
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
### Inter-Contract Invocations
|
### Inter-Contract Invocations
|
||||||
@ -327,11 +341,15 @@ const dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address)
|
|||||||
|
|
||||||
function proxy (const action : parameter; const store : storage): return is
|
function proxy (const action : parameter; const store : storage): return is
|
||||||
block {
|
block {
|
||||||
const counter : contract (parameter) = get_contract (dest);
|
const counter : contract (parameter) =
|
||||||
|
case (Tezos.get_contract_opt (dest) : option (contract (parameter))) of
|
||||||
|
Some (contract) -> contract
|
||||||
|
| None -> (failwith ("Contract not found.") : contract (parameter))
|
||||||
|
end;
|
||||||
(* Reuse the parameter in the subsequent
|
(* Reuse the parameter in the subsequent
|
||||||
transaction or use another one, `mock_param`. *)
|
transaction or use another one, `mock_param`. *)
|
||||||
const mock_param : parameter = Increment (5n);
|
const mock_param : parameter = Increment (5n);
|
||||||
const op : operation = transaction (action, 0mutez, counter);
|
const op : operation = Tezos.transaction (action, 0tez, counter);
|
||||||
const ops : list (operation) = list [op]
|
const ops : list (operation) = list [op]
|
||||||
} with (ops, store)
|
} with (ops, store)
|
||||||
```
|
```
|
||||||
@ -363,14 +381,20 @@ type return = operation list * storage
|
|||||||
let dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address)
|
let dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address)
|
||||||
|
|
||||||
let proxy (action, store : parameter * storage) : return =
|
let proxy (action, store : parameter * storage) : return =
|
||||||
let counter : parameter contract = Operation.get_contract dest in
|
let counter : parameter contract =
|
||||||
|
match (Tezos.get_contract_opt (dest) : parameter contract option) with
|
||||||
|
Some contract -> contract
|
||||||
|
| None -> (failwith "Contract not found." : parameter contract) in
|
||||||
(* Reuse the parameter in the subsequent
|
(* Reuse the parameter in the subsequent
|
||||||
transaction or use another one, `mock_param`. *)
|
transaction or use another one, `mock_param`. *)
|
||||||
let mock_param : parameter = Increment (5n) in
|
let mock_param : parameter = Increment (5n) in
|
||||||
let op : operation = Operation.transaction action 0mutez counter
|
let op : operation = Tezos.transaction action 0tez counter
|
||||||
in [op], store
|
in [op], store
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `Operation.get_contract` and `Operation.transaction` are
|
||||||
|
> *deprecated*.
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo skip
|
```reasonligo skip
|
||||||
// counter.religo
|
// counter.religo
|
||||||
@ -398,13 +422,20 @@ type return = (list (operation), storage);
|
|||||||
let dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address);
|
let dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address);
|
||||||
|
|
||||||
let proxy = ((action, store): (parameter, storage)) : return => {
|
let proxy = ((action, store): (parameter, storage)) : return => {
|
||||||
let counter : contract (parameter) = Operation.get_contract (dest);
|
let counter : contract (parameter) =
|
||||||
|
switch (Tezos.get_contract_opt (dest) : option (contract (parameter))) {
|
||||||
|
| Some (contract) => contract;
|
||||||
|
| None => (failwith ("Contract not found.") : contract (parameter));
|
||||||
|
};
|
||||||
(* Reuse the parameter in the subsequent
|
(* Reuse the parameter in the subsequent
|
||||||
transaction or use another one, `mock_param`. *)
|
transaction or use another one, `mock_param`. *)
|
||||||
let mock_param : parameter = Increment (5n);
|
let mock_param : parameter = Increment (5n);
|
||||||
let op : operation = Operation.transaction (action, 0mutez, counter);
|
let op : operation = Tezos.transaction (action, 0tez, counter);
|
||||||
([op], store)
|
([op], store)
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `Operation.get_contract` and `Operation.transaction` are
|
||||||
|
> *deprecated*.
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
@ -42,59 +42,78 @@ storage value being returned) which in our case is still `Unit`.
|
|||||||
|
|
||||||
Our counter contract will store a single `int` as it's storage, and
|
Our counter contract will store a single `int` as it's storage, and
|
||||||
will accept an `action` variant in order to re-route our single `main`
|
will accept an `action` variant in order to re-route our single `main`
|
||||||
function to two entrypoints for `addition` and `subtraction`.
|
function to two entrypoints for `add` (addition) and `sub`
|
||||||
|
(subtraction).
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
```
|
```
|
||||||
type action is
|
type parameter is
|
||||||
Increment of int
|
Increment of int
|
||||||
| Decrement of int
|
| Decrement of int
|
||||||
|
|
||||||
function main (const p : action ; const s : int) : (list(operation) * int) is
|
type storage is int
|
||||||
|
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
|
function add (const n : int; const store : storage) : storage is store + n
|
||||||
|
function sub (const n : int; const store : storage) : storage is store - n
|
||||||
|
|
||||||
|
function main (const action : parameter; const store : storage) : return is
|
||||||
((nil : list(operation)),
|
((nil : list(operation)),
|
||||||
(case p of
|
case action of
|
||||||
| Increment (n) -> s + n
|
Increment (n) -> add (n, store)
|
||||||
| Decrement (n) -> s - n
|
| Decrement (n) -> sub (n, store)
|
||||||
end))
|
end)
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo
|
```cameligo
|
||||||
type action =
|
type parameter =
|
||||||
| Increment of int
|
Increment of int
|
||||||
| Decrement of int
|
| Decrement of int
|
||||||
|
|
||||||
let main (p, s: action * int) : operation list * int =
|
type storage = int
|
||||||
let result =
|
|
||||||
match p with
|
type return = (operation) list * storage
|
||||||
| Increment n -> s + n
|
|
||||||
| Decrement n -> s - n
|
let add (n, store : int * storage) : storage = store + n
|
||||||
in
|
let sub (n, store : int * storage) : storage = store - n
|
||||||
(([]: operation list), result)
|
|
||||||
|
let main (action, store : parameter * storage) : operation list * storage =
|
||||||
|
(([]: operation list),
|
||||||
|
(match action with
|
||||||
|
Increment n -> add (n, store)
|
||||||
|
| Decrement n -> sub (n, store)))
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo
|
```reasonligo
|
||||||
type action =
|
type parameter =
|
||||||
| Increment(int)
|
Increment (int)
|
||||||
| Decrement(int);
|
| Decrement (int)
|
||||||
|
;
|
||||||
|
|
||||||
let main = (p_s: (action, int)) : (list(operation), int) => {
|
type storage = int;
|
||||||
let p, s = p_s;
|
|
||||||
let result =
|
type return = (list (operation), storage);
|
||||||
switch (p) {
|
|
||||||
| Increment(n) => s + n
|
let add = ((n, store) : (int, storage)) : storage => store + n;
|
||||||
| Decrement(n) => s - n
|
let sub = ((n, store) : (int, storage)) : storage => store - n;
|
||||||
};
|
|
||||||
(([]: list(operation)), result);
|
let main = ((action, store) : (parameter, storage)) : return =>
|
||||||
};
|
(([]: list (operation)),
|
||||||
|
(switch (action) {
|
||||||
|
| Increment (n) => add ((n, store))
|
||||||
|
| Decrement (n) => sub ((n, store))
|
||||||
|
}));
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
To dry-run the counter contract, we will use the `main` entrypoint, provide a variant parameter of `Increment(5)` and an initial storage value of `5`.
|
To dry-run the counter contract, we will provide the `main` function
|
||||||
|
with a variant parameter of value `Increment (5)` and an initial
|
||||||
|
storage value of `5`.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
@ -131,39 +150,30 @@ Command above will output the following Michelson code:
|
|||||||
{ parameter (or (int %decrement) (int %increment)) ;
|
{ parameter (or (int %decrement) (int %increment)) ;
|
||||||
storage int ;
|
storage int ;
|
||||||
code { DUP ;
|
code { DUP ;
|
||||||
CAR ;
|
|
||||||
DIP { DUP } ;
|
|
||||||
SWAP ;
|
|
||||||
CDR ;
|
CDR ;
|
||||||
DIP { DUP } ;
|
DIP { DUP } ;
|
||||||
SWAP ;
|
SWAP ;
|
||||||
|
CAR ;
|
||||||
IF_LEFT
|
IF_LEFT
|
||||||
{ DUP ;
|
{ DUP ;
|
||||||
DIP 2 { DUP } ;
|
DIP { DIP { DUP } ; SWAP } ;
|
||||||
DIG 2 ;
|
PAIR ;
|
||||||
DIP { DUP } ;
|
DUP ;
|
||||||
|
CDR ;
|
||||||
|
DIP { DUP ; CAR } ;
|
||||||
SUB ;
|
SUB ;
|
||||||
SWAP ;
|
DIP { DROP 2 } }
|
||||||
DROP ;
|
|
||||||
SWAP ;
|
|
||||||
DROP }
|
|
||||||
{ DUP ;
|
{ DUP ;
|
||||||
DIP 2 { DUP } ;
|
DIP { DIP { DUP } ; SWAP } ;
|
||||||
DIG 2 ;
|
PAIR ;
|
||||||
DIP { DUP } ;
|
DUP ;
|
||||||
|
CDR ;
|
||||||
|
DIP { DUP ; CAR } ;
|
||||||
ADD ;
|
ADD ;
|
||||||
SWAP ;
|
DIP { DROP 2 } } ;
|
||||||
DROP ;
|
|
||||||
SWAP ;
|
|
||||||
DROP } ;
|
|
||||||
NIL operation ;
|
NIL operation ;
|
||||||
PAIR ;
|
PAIR ;
|
||||||
SWAP ;
|
DIP { DROP 2 } } }
|
||||||
DROP ;
|
|
||||||
SWAP ;
|
|
||||||
DROP ;
|
|
||||||
SWAP ;
|
|
||||||
DROP } }
|
|
||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
@ -180,12 +190,15 @@ ligo compile-storage src/counter.ligo main 5
|
|||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
In our case the LIGO storage value maps 1:1 to its Michelson
|
||||||
In our case the LIGO storage value maps 1:1 to its Michelson representation, however this will not be the case once the parameter is of a more complex data type, like a record.
|
representation, however this will not be the case once the parameter
|
||||||
|
is of a more complex data type, like a record.
|
||||||
|
|
||||||
## Invoking a LIGO contract
|
## Invoking a LIGO contract
|
||||||
|
|
||||||
Same rules apply for parameters, as apply for translating LIGO storage values to Michelson. We will need to use `compile-parameter` to compile our `action` variant into Michelson, here's how:
|
Same rules apply for parameters, as apply for translating LIGO storage
|
||||||
|
values to Michelson. We will need to use `compile-parameter` to
|
||||||
|
compile our `action` variant into Michelson, here's how:
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
@ -195,6 +208,5 @@ ligo compile-parameter src/counter.ligo main 'Increment(5)'
|
|||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
|
||||||
Now we can use `(Right 5)` which is a Michelson value, to invoke our
|
Now we can use `(Right 5)` which is a Michelson value, to invoke our
|
||||||
contract - e.g. via `tezos-client`
|
contract - e.g., via `tezos-client`
|
||||||
|
17
gitlab-pages/docs/advanced/src/counter.ligo
Normal file
17
gitlab-pages/docs/advanced/src/counter.ligo
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
type parameter is
|
||||||
|
Increment of int
|
||||||
|
| Decrement of int
|
||||||
|
|
||||||
|
type storage is int
|
||||||
|
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
|
function add (const n : int; const store : storage) : storage is store + n
|
||||||
|
function sub (const n : int; const store : storage) : storage is store - n
|
||||||
|
|
||||||
|
function main (const action : parameter; const store : storage) : return is
|
||||||
|
((nil : list(operation)),
|
||||||
|
case action of
|
||||||
|
Increment (n) -> add (n, store)
|
||||||
|
| Decrement (n) -> sub (n, store)
|
||||||
|
end)
|
9
gitlab-pages/docs/advanced/src/functions.ligo
Normal file
9
gitlab-pages/docs/advanced/src/functions.ligo
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
function multiply (const a : int; const b : int) : int is
|
||||||
|
block {
|
||||||
|
const result : int = a * b
|
||||||
|
} with result
|
||||||
|
|
||||||
|
function add (const a : int; const b : int) : int is a + b
|
||||||
|
|
||||||
|
function main (const p : unit; const s : unit) : list (operation) * unit is
|
||||||
|
((nil : list (operation)), s)
|
17
gitlab-pages/docs/advanced/src/multiple-entrypoints.ligo
Normal file
17
gitlab-pages/docs/advanced/src/multiple-entrypoints.ligo
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
type parameter is
|
||||||
|
Increment of int
|
||||||
|
| Decrement of int
|
||||||
|
|
||||||
|
type storage is int
|
||||||
|
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
|
function add (const n : int; const store : storage) : storage is store + n
|
||||||
|
function sub (const n : int; const store : storage) : storage is store - n
|
||||||
|
|
||||||
|
function main (const action : parameter; const store : storage) : return is
|
||||||
|
((nil : list(operation)),
|
||||||
|
case action of
|
||||||
|
Increment (n) -> add (n, store)
|
||||||
|
| Decrement (n) -> sub (n, store)
|
||||||
|
end)
|
5
gitlab-pages/docs/advanced/src/variables.ligo
Normal file
5
gitlab-pages/docs/advanced/src/variables.ligo
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const four : int = 4
|
||||||
|
const name : string = "John Doe"
|
||||||
|
|
||||||
|
function main (const p : unit; const s : unit) : list (operation) * unit is
|
||||||
|
((nil : list (operation)), s)
|
@ -18,23 +18,29 @@ current timestamp value.
|
|||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=a
|
```pascaligo group=a
|
||||||
const today : timestamp = now
|
const today : timestamp = Tezos.now
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `now` is *deprecated*.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=a
|
```cameligo group=a
|
||||||
let today : timestamp = Current.time
|
let today : timestamp = Tezos.now
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `Current.time` is *deprecated*.
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=a
|
```reasonligo group=a
|
||||||
let today : timestamp = Current.time;
|
let today : timestamp = Tezos.now;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `Current.time` is *deprecated*.
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
> When running code, the LIGO CLI option
|
> When running code, the LIGO CLI option `--predecessor-timestamp`
|
||||||
> `--predecessor-timestamp` allows you to control what `now` returns.
|
> allows you to control what `Tezos.now` returns.
|
||||||
|
|
||||||
### Timestamp Arithmetics
|
### Timestamp Arithmetics
|
||||||
|
|
||||||
@ -46,31 +52,37 @@ constraints on your smart contracts. Consider the following scenarios.
|
|||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=b
|
```pascaligo group=b
|
||||||
const today : timestamp = now
|
const today : timestamp = Tezos.now
|
||||||
const one_day : int = 86400
|
const one_day : int = 86400
|
||||||
const in_24_hrs : timestamp = today + one_day
|
const in_24_hrs : timestamp = today + one_day
|
||||||
const some_date : timestamp = ("2000-01-01T10:10:10Z" : timestamp)
|
const some_date : timestamp = ("2000-01-01T10:10:10Z" : timestamp)
|
||||||
const one_day_later : timestamp = some_date + one_day
|
const one_day_later : timestamp = some_date + one_day
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `now` is *deprecated*.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=b
|
```cameligo group=b
|
||||||
let today : timestamp = Current.time
|
let today : timestamp = Tezos.now
|
||||||
let one_day : int = 86400
|
let one_day : int = 86400
|
||||||
let in_24_hrs : timestamp = today + one_day
|
let in_24_hrs : timestamp = today + one_day
|
||||||
let some_date : timestamp = ("2000-01-01t10:10:10Z" : timestamp)
|
let some_date : timestamp = ("2000-01-01t10:10:10Z" : timestamp)
|
||||||
let one_day_later : timestamp = some_date + one_day
|
let one_day_later : timestamp = some_date + one_day
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `Current.time` is *deprecated*.
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=b
|
```reasonligo group=b
|
||||||
let today : timestamp = Current.time;
|
let today : timestamp = Tezos.now;
|
||||||
let one_day : int = 86400;
|
let one_day : int = 86400;
|
||||||
let in_24_hrs : timestamp = today + one_day;
|
let in_24_hrs : timestamp = today + one_day;
|
||||||
let some_date : timestamp = ("2000-01-01t10:10:10Z" : timestamp);
|
let some_date : timestamp = ("2000-01-01t10:10:10Z" : timestamp);
|
||||||
let one_day_later : timestamp = some_date + one_day;
|
let one_day_later : timestamp = some_date + one_day;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `Current.time` is *deprecated*.
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
#### 24 hours Ago
|
#### 24 hours Ago
|
||||||
@ -78,25 +90,32 @@ let one_day_later : timestamp = some_date + one_day;
|
|||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=c
|
```pascaligo group=c
|
||||||
const today : timestamp = now
|
const today : timestamp = Tezos.now
|
||||||
const one_day : int = 86400
|
const one_day : int = 86400
|
||||||
const in_24_hrs : timestamp = today - one_day
|
const in_24_hrs : timestamp = today - one_day
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `now` is *deprecated*.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=c
|
```cameligo group=c
|
||||||
let today : timestamp = Current.time
|
let today : timestamp = Tezos.now
|
||||||
let one_day : int = 86400
|
let one_day : int = 86400
|
||||||
let in_24_hrs : timestamp = today - one_day
|
let in_24_hrs : timestamp = today - one_day
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `Current.time` is *deprecated*.
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=c
|
```reasonligo group=c
|
||||||
let today : timestamp = Current.time;
|
let today : timestamp = Tezos.now;
|
||||||
let one_day : int = 86400;
|
let one_day : int = 86400;
|
||||||
let in_24_hrs : timestamp = today - one_day;
|
let in_24_hrs : timestamp = today - one_day;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `Current.time` is *deprecated*.
|
||||||
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
### Comparing Timestamps
|
### Comparing Timestamps
|
||||||
@ -107,19 +126,26 @@ applying to numbers.
|
|||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=c
|
```pascaligo group=c
|
||||||
const not_tommorow : bool = (now = in_24_hrs)
|
const not_tommorow : bool = (Tezos.now = in_24_hrs)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `now` is *deprecated*.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=c
|
```cameligo group=c
|
||||||
let not_tomorrow : bool = (Current.time = in_24_hrs)
|
let not_tomorrow : bool = (Tezos.now = in_24_hrs)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `Current.time` is *deprecated*.
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=c
|
```reasonligo group=c
|
||||||
let not_tomorrow : bool = (Current.time == in_24_hrs);
|
let not_tomorrow : bool = (Tezos.now == in_24_hrs);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `Current.time` is *deprecated*.
|
||||||
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## Addresses
|
## Addresses
|
||||||
|
@ -4,7 +4,7 @@ title: Cheat Sheet
|
|||||||
---
|
---
|
||||||
<div class="cheatsheet">
|
<div class="cheatsheet">
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Note that this table is not compiled before production and currently needs to be managed manually.
|
Note that this table is not compiled before production and currently needs to be managed manually.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ Note that this table is not compiled before production and currently needs to be
|
|||||||
|Includes|```#include "library.ligo"```|
|
|Includes|```#include "library.ligo"```|
|
||||||
|Functions (short form)|<pre><code>function add (const a : int ; const b : int) : int is<br/> block { skip } with a + b</code></pre>|
|
|Functions (short form)|<pre><code>function add (const a : int ; const b : int) : int is<br/> block { skip } with a + b</code></pre>|
|
||||||
|Functions (long form)|<pre><code>function add (const a : int ; const b : int) : int is<br/> block { <br/> const result: int = a + b;<br/> } with result</code></pre>|
|
|Functions (long form)|<pre><code>function add (const a : int ; const b : int) : int is<br/> block { <br/> const result: int = a + b;<br/> } with result</code></pre>|
|
||||||
| If Statement | <pre><code>if age < 16 <br/>then fail("Too young to drive."); <br/>else const new_id: int = prev_id + 1;</code></pre>|
|
| If Statement | <pre><code>if age < 16 <br/>then fail("Too young to drive."); <br/>else const new_id: int = prev_id + 1;</code></pre>|
|
||||||
|Options|<pre><code>type middleName is option(string);<br/>const middleName : middleName = Some("Foo");<br/>const middleName : middleName = None;</code></pre>|
|
|Options|<pre><code>type middleName is option(string);<br/>const middleName : middleName = Some("Foo");<br/>const middleName : middleName = None;</code></pre>|
|
||||||
|Assignment| ```const age: int = 5;```|
|
|Assignment| ```const age: int = 5;```|
|
||||||
|Assignment on an existing variable <br/></br>*⚠️ This feature is not supported at the top-level scope, you can use it e.g. within functions. Works for Records and Maps as well.*| ```age := 18;```, ```p.age := 21``` |
|
|Assignment on an existing variable <br/></br>*⚠️ This feature is not supported at the top-level scope, you can use it e.g. within functions. Works for Records and Maps as well.*| ```age := 18;```, ```p.age := 21``` |
|
||||||
@ -71,8 +71,8 @@ Note that this table is not compiled before production and currently needs to be
|
|||||||
|Variant *(pattern)* matching|<pre><code>let a: action = Increment 5<br/>match a with<br/>| Increment n -> n + 1<br/>| Decrement n -> n - 1<br/></code></pre>|
|
|Variant *(pattern)* matching|<pre><code>let a: action = Increment 5<br/>match a with<br/>| Increment n -> n + 1<br/>| Decrement n -> n - 1<br/></code></pre>|
|
||||||
|Records|<pre><code>type person = {<br/> age: int ;<br/> name: string ;<br/>}<br/><br/>let john : person = {<br/> age = 18;<br/> name = "John Doe";<br/>}<br/><br/>let name: string = john.name</code></pre>|
|
|Records|<pre><code>type person = {<br/> age: int ;<br/> name: string ;<br/>}<br/><br/>let john : person = {<br/> age = 18;<br/> name = "John Doe";<br/>}<br/><br/>let name: string = john.name</code></pre>|
|
||||||
|Maps|<pre><code>type prices = (nat, tez) map<br/><br/>let prices : prices = Map.literal [<br/> (10n, 60mutez);<br/> (50n, 30mutez);<br/> (100n, 10mutez)<br/>]<br/><br/>let price: tez option = Map.find_opt 50n prices<br/><br/>let prices: prices = Map.update 200n (Some 5mutez) prices</code></pre>|
|
|Maps|<pre><code>type prices = (nat, tez) map<br/><br/>let prices : prices = Map.literal [<br/> (10n, 60mutez);<br/> (50n, 30mutez);<br/> (100n, 10mutez)<br/>]<br/><br/>let price: tez option = Map.find_opt 50n prices<br/><br/>let prices: prices = Map.update 200n (Some 5mutez) prices</code></pre>|
|
||||||
|Contracts & Accounts|<pre><code>let destination_address : address = "tz1..."<br/>let contract : unit contract = <br/> Operation.get_contract destination_address</code></pre>|
|
|Contracts & Accounts|<pre><code>let destination_address : address = "tz1..."<br/>let contract : unit contract = <br/> Tezos.get_contract destination_address</code></pre>|
|
||||||
|Transactions|<pre><code>let payment : operation = <br/> Operation.transaction unit amount receiver</code></pre>|
|
|Transactions|<pre><code>let payment : operation = <br/> Tezos.transaction unit amount receiver</code></pre>|
|
||||||
|Exception/Failure|`failwith("Your descriptive error message for the user goes here.")`|
|
|Exception/Failure|`failwith("Your descriptive error message for the user goes here.")`|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
@ -103,8 +103,8 @@ Note that this table is not compiled before production and currently needs to be
|
|||||||
|Variant *(pattern)* matching|<pre><code>let a: action = Increment(5);<br/>switch(a) {<br/>| Increment(n) => n + 1<br/>| Decrement(n) => n - 1;<br/> } <br/></code></pre>|
|
|Variant *(pattern)* matching|<pre><code>let a: action = Increment(5);<br/>switch(a) {<br/>| Increment(n) => n + 1<br/>| Decrement(n) => n - 1;<br/> } <br/></code></pre>|
|
||||||
|Records|<pre><code>type person = {<br/> age: int,<br/> name: string<br/>}<br/><br/>let john : person = {<br/> age: 18,<br/> name: "John Doe"<br/>};<br/><br/>let name: string = john.name;</code></pre>|
|
|Records|<pre><code>type person = {<br/> age: int,<br/> name: string<br/>}<br/><br/>let john : person = {<br/> age: 18,<br/> name: "John Doe"<br/>};<br/><br/>let name: string = john.name;</code></pre>|
|
||||||
|Maps|<pre><code>type prices = map(nat, tez);<br/><br/>let prices : prices = Map.literal([<br/> (10n, 60mutez),<br/> (50n, 30mutez),<br/> (100n, 10mutez)<br/>]);<br/><br/>let price: option(tez) = Map.find_opt(50n, prices);<br/><br/>let prices: prices = Map.update(200n, Some (5mutez), prices);</code></pre>|
|
|Maps|<pre><code>type prices = map(nat, tez);<br/><br/>let prices : prices = Map.literal([<br/> (10n, 60mutez),<br/> (50n, 30mutez),<br/> (100n, 10mutez)<br/>]);<br/><br/>let price: option(tez) = Map.find_opt(50n, prices);<br/><br/>let prices: prices = Map.update(200n, Some (5mutez), prices);</code></pre>|
|
||||||
|Contracts & Accounts|<pre><code>let destination_address : address = "tz1...";<br/>let contract : contract(unit) = <br/> Operation.get_contract(destination_address);</code></pre>|
|
|Contracts & Accounts|<pre><code>let destination_address : address = "tz1...";<br/>let contract : contract(unit) = <br/> Tezos.get_contract(destination_address);</code></pre>|
|
||||||
|Transactions|<pre><code>let payment : operation = <br/> Operation.transaction (unit, amount, receiver);</code></pre>|
|
|Transactions|<pre><code>let payment : operation = <br/> Tezos.transaction (unit, amount, receiver);</code></pre>|
|
||||||
|Exception/Failure|`failwith("Your descriptive error message for the user goes here.");`|
|
|Exception/Failure|`failwith("Your descriptive error message for the user goes here.");`|
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ value:
|
|||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=a
|
```pascaligo group=a
|
||||||
const a : bool = True // Notice the capital letter
|
const a : bool = True // Also: true
|
||||||
const b : bool = False // Same.
|
const b : bool = False // Also: false
|
||||||
```
|
```
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=a
|
```cameligo group=a
|
||||||
@ -137,7 +137,7 @@ state.
|
|||||||
type magnitude is Small | Large // See variant types.
|
type magnitude is Small | Large // See variant types.
|
||||||
|
|
||||||
function compare (const n : nat) : magnitude is
|
function compare (const n : nat) : magnitude is
|
||||||
if n < 10n then Small (Unit) else Large (Unit) // Unit is needed for now.
|
if n < 10n then Small else Large
|
||||||
```
|
```
|
||||||
|
|
||||||
You can run the `compare` function defined above using the LIGO compiler
|
You can run the `compare` function defined above using the LIGO compiler
|
||||||
@ -145,7 +145,7 @@ like this:
|
|||||||
```shell
|
```shell
|
||||||
ligo run-function
|
ligo run-function
|
||||||
gitlab-pages/docs/language-basics/boolean-if-else/cond.ligo compare 21n'
|
gitlab-pages/docs/language-basics/boolean-if-else/cond.ligo compare 21n'
|
||||||
# Outputs: Large (Unit)
|
# Outputs: Large(Unit)
|
||||||
```
|
```
|
||||||
|
|
||||||
When the branches of the conditional are not a single expression, as
|
When the branches of the conditional are not a single expression, as
|
||||||
@ -161,7 +161,7 @@ else skip;
|
|||||||
```
|
```
|
||||||
|
|
||||||
As an exception to the rule, the blocks in a conditional branch do not
|
As an exception to the rule, the blocks in a conditional branch do not
|
||||||
need to be introduced by the keywor `block`, so, we could have written
|
need to be introduced by the keyword `block`, so we could have written
|
||||||
instead:
|
instead:
|
||||||
```pascaligo skip
|
```pascaligo skip
|
||||||
if x < y then {
|
if x < y then {
|
||||||
@ -187,9 +187,15 @@ gitlab-pages/docs/language-basics/boolean-if-else/cond.mligo compare 21n'
|
|||||||
# Outputs: Large
|
# Outputs: Large
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Notice that, as in OCaml, in CameLIGO, if a conditional has a branch
|
||||||
|
> `else ()`, that branch can be omitted. The resulting so-called
|
||||||
|
> *dangling else* problem is parsed by associating any `else` to the
|
||||||
|
> closest previous `then`.
|
||||||
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=e
|
```reasonligo group=e
|
||||||
type magnitude = | Small | Large; // See variant types.
|
type magnitude = Small | Large; // See variant types.
|
||||||
|
|
||||||
let compare = (n : nat) : magnitude =>
|
let compare = (n : nat) : magnitude =>
|
||||||
if (n < 10n) { Small; } else { Large; };
|
if (n < 10n) { Small; } else { Large; };
|
||||||
|
@ -4,7 +4,15 @@ title: Functions
|
|||||||
---
|
---
|
||||||
|
|
||||||
LIGO functions are the basic building block of contracts. For example,
|
LIGO functions are the basic building block of contracts. For example,
|
||||||
entrypoints are functions.
|
entrypoints are functions and each smart contract needs a main
|
||||||
|
function that dispatches control to the entrypoints (it is not already
|
||||||
|
the default entrypoint).
|
||||||
|
|
||||||
|
The semantics of function calls in LIGO is that of a *copy of the
|
||||||
|
arguments but also of the environment*. In the case of PascaLIGO, this
|
||||||
|
means that any mutation (assignment) on variables outside the scope of
|
||||||
|
the function will be lost when the function returns, just as the
|
||||||
|
mutations inside the functions will be.
|
||||||
|
|
||||||
## Declaring Functions
|
## Declaring Functions
|
||||||
|
|
||||||
@ -230,10 +238,14 @@ function to all its elements.
|
|||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=c
|
```pascaligo group=c
|
||||||
function incr_map (const l : list (int)) : list (int) is
|
function incr_map (const l : list (int)) : list (int) is
|
||||||
list_map (function (const i : int) : int is i + 1, l)
|
List.map (function (const i : int) : int is i + 1, l)
|
||||||
```
|
```
|
||||||
You can call the function `incr_map` defined above using the LIGO compiler
|
|
||||||
like so:
|
> Note that `list_map` is *deprecated*.
|
||||||
|
|
||||||
|
You can call the function `incr_map` defined above using the LIGO
|
||||||
|
compiler like so:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
ligo run-function
|
ligo run-function
|
||||||
gitlab-pages/docs/language-basics/src/functions/incr_map.ligo incr_map
|
gitlab-pages/docs/language-basics/src/functions/incr_map.ligo incr_map
|
||||||
|
@ -79,17 +79,21 @@ let gcd (x,y : nat * nat) : nat =
|
|||||||
```
|
```
|
||||||
|
|
||||||
To ease the writing and reading of the iterated functions (here,
|
To ease the writing and reading of the iterated functions (here,
|
||||||
`iter`), two predefined functions are provided: `continue` and `stop`:
|
`iter`), two predefined functions are provided: `Loop.continue` and
|
||||||
|
`Loop.stop`:
|
||||||
|
|
||||||
```cameligo group=a
|
```cameligo group=a
|
||||||
let iter (x,y : nat * nat) : bool * (nat * nat) =
|
let iter (x,y : nat * nat) : bool * (nat * nat) =
|
||||||
if y = 0n then stop (x,y) else continue (y, x mod y)
|
if y = 0n then Loop.stop (x,y) else Loop.continue (y, x mod y)
|
||||||
|
|
||||||
let gcd (x,y : nat * nat) : nat =
|
let gcd (x,y : nat * nat) : nat =
|
||||||
let x,y = if x < y then y,x else x,y in
|
let x,y = if x < y then y,x else x,y in
|
||||||
let x,y = Loop.fold_while iter (x,y)
|
let x,y = Loop.fold_while iter (x,y)
|
||||||
in x
|
in x
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `stop` and `continue` are *deprecated*.
|
||||||
|
|
||||||
You can call the function `gcd` defined above using the LIGO compiler
|
You can call the function `gcd` defined above using the LIGO compiler
|
||||||
like so:
|
like so:
|
||||||
```shell
|
```shell
|
||||||
@ -131,11 +135,12 @@ let gcd = ((x,y) : (nat, nat)) : nat => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
To ease the writing and reading of the iterated functions (here,
|
To ease the writing and reading of the iterated functions (here,
|
||||||
`iter`), two predefined functions are provided: `continue` and `stop`:
|
`iter`), two predefined functions are provided: `Loop.continue` and
|
||||||
|
`Loop.stop`:
|
||||||
|
|
||||||
```reasonligo group=b
|
```reasonligo group=b
|
||||||
let iter = ((x,y) : (nat, nat)) : (bool, (nat, nat)) =>
|
let iter = ((x,y) : (nat, nat)) : (bool, (nat, nat)) =>
|
||||||
if (y == 0n) { stop ((x,y)); } else { continue ((y, x mod y)); };
|
if (y == 0n) { Loop.stop ((x,y)); } else { Loop.continue ((y, x mod y)); };
|
||||||
|
|
||||||
let gcd = ((x,y) : (nat, nat)) : nat => {
|
let gcd = ((x,y) : (nat, nat)) : nat => {
|
||||||
let (x,y) = if (x < y) { (y,x); } else { (x,y); };
|
let (x,y) = if (x < y) { (y,x); } else { (x,y); };
|
||||||
@ -143,6 +148,9 @@ let gcd = ((x,y) : (nat, nat)) : nat => {
|
|||||||
x
|
x
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `stop` and `continue` are *deprecated*.
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## Bounded Loops
|
## Bounded Loops
|
||||||
|
@ -19,7 +19,7 @@ Let us first consider and example of record type declaration.
|
|||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=a
|
```pascaligo group=records1
|
||||||
type user is
|
type user is
|
||||||
record [
|
record [
|
||||||
id : nat;
|
id : nat;
|
||||||
@ -29,7 +29,7 @@ type user is
|
|||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=a
|
```cameligo group=records1
|
||||||
type user = {
|
type user = {
|
||||||
id : nat;
|
id : nat;
|
||||||
is_admin : bool;
|
is_admin : bool;
|
||||||
@ -38,7 +38,7 @@ type user = {
|
|||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=a
|
```reasonligo group=records1
|
||||||
type user = {
|
type user = {
|
||||||
id : nat,
|
id : nat,
|
||||||
is_admin : bool,
|
is_admin : bool,
|
||||||
@ -51,7 +51,7 @@ And here is how a record value is defined:
|
|||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=a
|
```pascaligo group=records1
|
||||||
const alice : user =
|
const alice : user =
|
||||||
record [
|
record [
|
||||||
id = 1n;
|
id = 1n;
|
||||||
@ -61,7 +61,7 @@ const alice : user =
|
|||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=a
|
```cameligo group=records1
|
||||||
let alice : user = {
|
let alice : user = {
|
||||||
id = 1n;
|
id = 1n;
|
||||||
is_admin = true;
|
is_admin = true;
|
||||||
@ -70,7 +70,7 @@ let alice : user = {
|
|||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=a
|
```reasonligo group=records1
|
||||||
let alice : user = {
|
let alice : user = {
|
||||||
id : 1n,
|
id : 1n,
|
||||||
is_admin : true,
|
is_admin : true,
|
||||||
@ -86,17 +86,17 @@ operator, like so:
|
|||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=a
|
```pascaligo group=records1
|
||||||
const alice_admin : bool = alice.is_admin
|
const alice_admin : bool = alice.is_admin
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=a
|
```cameligo group=records1
|
||||||
let alice_admin : bool = alice.is_admin
|
let alice_admin : bool = alice.is_admin
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=a
|
```reasonligo group=records1
|
||||||
let alice_admin : bool = alice.is_admin;
|
let alice_admin : bool = alice.is_admin;
|
||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
@ -123,7 +123,7 @@ In PascaLIGO, the shape of that expression is `<record variable> with
|
|||||||
<record value>`. The record variable is the record to update and the
|
<record value>`. The record variable is the record to update and the
|
||||||
record value is the update itself.
|
record value is the update itself.
|
||||||
|
|
||||||
```pascaligo group=b
|
```pascaligo group=records2
|
||||||
type point is record [x : int; y : int; z : int]
|
type point is record [x : int; y : int; z : int]
|
||||||
type vector is record [dx : int; dy : int]
|
type vector is record [dx : int; dy : int]
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ the blockless function.
|
|||||||
The syntax for the functional updates of record in CameLIGO follows
|
The syntax for the functional updates of record in CameLIGO follows
|
||||||
that of OCaml:
|
that of OCaml:
|
||||||
|
|
||||||
```cameligo group=b
|
```cameligo group=records2
|
||||||
type point = {x : int; y : int; z : int}
|
type point = {x : int; y : int; z : int}
|
||||||
type vector = {dx : int; dy : int}
|
type vector = {dx : int; dy : int}
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ xy_translate "({x=2;y=3;z=1}, {dx=3;dy=4})"
|
|||||||
The syntax for the functional updates of record in ReasonLIGO follows
|
The syntax for the functional updates of record in ReasonLIGO follows
|
||||||
that of ReasonML:
|
that of ReasonML:
|
||||||
|
|
||||||
```reasonligo group=b
|
```reasonligo group=records2
|
||||||
type point = {x : int, y : int, z : int};
|
type point = {x : int, y : int, z : int};
|
||||||
type vector = {dx : int, dy : int};
|
type vector = {dx : int, dy : int};
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ name "patch").
|
|||||||
Let us consider defining a function that translates three-dimensional
|
Let us consider defining a function that translates three-dimensional
|
||||||
points on a plane.
|
points on a plane.
|
||||||
|
|
||||||
```pascaligo group=c
|
```pascaligo group=records3
|
||||||
type point is record [x : int; y : int; z : int]
|
type point is record [x : int; y : int; z : int]
|
||||||
type vector is record [dx : int; dy : int]
|
type vector is record [dx : int; dy : int]
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ Of course, we can actually translate the point with only one `patch`,
|
|||||||
as the previous example was meant to show that, after the first patch,
|
as the previous example was meant to show that, after the first patch,
|
||||||
the value of `p` indeed changed. So, a shorter version would be
|
the value of `p` indeed changed. So, a shorter version would be
|
||||||
|
|
||||||
```pascaligo group=d
|
```pascaligo group=records4
|
||||||
type point is record [x : int; y : int; z : int]
|
type point is record [x : int; y : int; z : int]
|
||||||
type vector is record [dx : int; dy : int]
|
type vector is record [dx : int; dy : int]
|
||||||
|
|
||||||
@ -267,7 +267,7 @@ Record patches can actually be simulated with functional updates. All
|
|||||||
we have to do is *declare a new record value with the same name as the
|
we have to do is *declare a new record value with the same name as the
|
||||||
one we want to update* and use a functional update, like so:
|
one we want to update* and use a functional update, like so:
|
||||||
|
|
||||||
```pascaligo group=e
|
```pascaligo group=records5
|
||||||
type point is record [x : int; y : int; z : int]
|
type point is record [x : int; y : int; z : int]
|
||||||
type vector is record [dx : int; dy : int]
|
type vector is record [dx : int; dy : int]
|
||||||
|
|
||||||
@ -298,71 +298,98 @@ values of the same type. The former are called *key* and the latter
|
|||||||
is that the type of the keys must be *comparable*, in the Michelson
|
is that the type of the keys must be *comparable*, in the Michelson
|
||||||
sense.
|
sense.
|
||||||
|
|
||||||
|
### Declaring a Map
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=f
|
```pascaligo group=maps
|
||||||
type move is int * int
|
type move is int * int
|
||||||
type register is map (address, move)
|
type register is map (address, move)
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=f
|
```cameligo group=maps
|
||||||
type move = int * int
|
type move = int * int
|
||||||
type register = (address, move) map
|
type register = (address, move) map
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=f
|
```reasonligo group=maps
|
||||||
type move = (int, int);
|
type move = (int, int);
|
||||||
type register = map (address, move);
|
type register = map (address, move);
|
||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
And here is how a map value is defined:
|
### Creating an Empty Map
|
||||||
|
|
||||||
|
Here is how to create an empty map.
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
<!--PascaLIGO-->
|
||||||
|
```pascaligo group=maps
|
||||||
|
const empty : register = map []
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--CameLIGO-->
|
||||||
|
```cameligo group=maps
|
||||||
|
let empty : register = Map.empty
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
```reasonligo group=maps
|
||||||
|
let empty : register = Map.empty
|
||||||
|
```
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
### Creating a Non-empty Map
|
||||||
|
|
||||||
|
And here is how to create a non-empty map value:
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
```pascaligo group=f
|
```pascaligo group=maps
|
||||||
const moves : register =
|
const moves : register =
|
||||||
map [
|
map [
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) -> (1,2);
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) -> (1,2);
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) -> (0,3)]
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) -> (0,3)]
|
||||||
```
|
```
|
||||||
|
|
||||||
> Notice the `->` between the key and its value and `;` to separate
|
Notice the `->` between the key and its value and `;` to separate
|
||||||
> individual map entries. The annotated value `("<string value>" :
|
individual map entries. The annotated value `("<string value>" :
|
||||||
> address)` means that we cast a string into an address. Also, `map`
|
address)` means that we cast a string into an address. Also, `map` is
|
||||||
> is a keyword.
|
a keyword.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=f
|
```cameligo group=maps
|
||||||
let moves : register =
|
let moves : register =
|
||||||
Map.literal [
|
Map.literal [
|
||||||
(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address), (1,2));
|
(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address), (1,2));
|
||||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))]
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))]
|
||||||
```
|
```
|
||||||
|
|
||||||
> The `Map.literal` predefined function builds a map from a list of
|
The `Map.literal` predefined function builds a map from a list of
|
||||||
> key-value pair tuples, `(<key>, <value>)`. Note also the `;` to
|
key-value pair tuples, `(<key>, <value>)`. Note also the `;` to
|
||||||
> separate individual map entries. `("<string value>": address)`
|
separate individual map entries. `("<string value>": address)` means
|
||||||
> means that we type-cast a string into an address.
|
that we type-cast a string into an address. -->
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=f
|
```reasonligo group=maps
|
||||||
let moves : register =
|
let moves : register =
|
||||||
Map.literal ([
|
Map.literal ([
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
||||||
```
|
```
|
||||||
|
|
||||||
> The `Map.literal` predefined function builds a map from a list of
|
The `Map.literal` predefined function builds a map from a list of
|
||||||
> key-value pair tuples, `(<key>, <value>)`. Note also the `;` to
|
key-value pair tuples, `(<key>, <value>)`. Note also the `;` to
|
||||||
> separate individual map entries. `("<string value>": address)`
|
separate individual map entries. `("<string value>": address)` means
|
||||||
> means that we type-cast a string into an address.
|
that we type-cast a string into an address. -->
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
@ -375,19 +402,19 @@ In PascaLIGO, we can use the postfix `[]` operator to read the `move`
|
|||||||
value associated to a given key (`address` here) in the register. Here
|
value associated to a given key (`address` here) in the register. Here
|
||||||
is an example:
|
is an example:
|
||||||
|
|
||||||
```pascaligo group=f
|
```pascaligo group=maps
|
||||||
const my_balance : option (move) =
|
const my_balance : option (move) =
|
||||||
moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)]
|
moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)]
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=f
|
```cameligo group=maps
|
||||||
let my_balance : move option =
|
let my_balance : move option =
|
||||||
Map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) moves
|
Map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) moves
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=f
|
```reasonligo group=maps
|
||||||
let my_balance : option (move) =
|
let my_balance : option (move) =
|
||||||
Map.find_opt (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), moves);
|
Map.find_opt (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), moves);
|
||||||
```
|
```
|
||||||
@ -400,7 +427,7 @@ the reader to account for a missing key in the map. This requires
|
|||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=f
|
```pascaligo group=maps
|
||||||
function force_access (const key : address; const moves : register) : move is
|
function force_access (const key : address; const moves : register) : move is
|
||||||
case moves[key] of
|
case moves[key] of
|
||||||
Some (move) -> move
|
Some (move) -> move
|
||||||
@ -409,7 +436,7 @@ function force_access (const key : address; const moves : register) : move is
|
|||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=f
|
```cameligo group=maps
|
||||||
let force_access (key, moves : address * register) : move =
|
let force_access (key, moves : address * register) : move =
|
||||||
match Map.find_opt key moves with
|
match Map.find_opt key moves with
|
||||||
Some move -> move
|
Some move -> move
|
||||||
@ -417,7 +444,7 @@ let force_access (key, moves : address * register) : move =
|
|||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=f
|
```reasonligo group=maps
|
||||||
let force_access = ((key, moves) : (address, register)) : move => {
|
let force_access = ((key, moves) : (address, register)) : move => {
|
||||||
switch (Map.find_opt (key, moves)) {
|
switch (Map.find_opt (key, moves)) {
|
||||||
| Some (move) => move
|
| Some (move) => move
|
||||||
@ -443,7 +470,7 @@ The values of a PascaLIGO map can be updated using the usual
|
|||||||
assignment syntax `<map variable>[<key>] := <new value>`. Let us
|
assignment syntax `<map variable>[<key>] := <new value>`. Let us
|
||||||
consider an example.
|
consider an example.
|
||||||
|
|
||||||
```pascaligo group=f
|
```pascaligo group=maps
|
||||||
function assign (var m : register) : register is
|
function assign (var m : register) : register is
|
||||||
block {
|
block {
|
||||||
m [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9)
|
m [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9)
|
||||||
@ -453,7 +480,7 @@ function assign (var m : register) : register is
|
|||||||
If multiple bindings need to be updated, PascaLIGO offers a *patch
|
If multiple bindings need to be updated, PascaLIGO offers a *patch
|
||||||
instruction* for maps, similar to that for records.
|
instruction* for maps, similar to that for records.
|
||||||
|
|
||||||
```pascaligo group=f
|
```pascaligo group=maps
|
||||||
function assignments (var m : register) : register is
|
function assignments (var m : register) : register is
|
||||||
block {
|
block {
|
||||||
patch m with map [
|
patch m with map [
|
||||||
@ -463,35 +490,51 @@ function assignments (var m : register) : register is
|
|||||||
} with m
|
} with m
|
||||||
```
|
```
|
||||||
|
|
||||||
|
See further for the removal of bindings.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
We can update a binding in a map in CameLIGO by means of the
|
We can update a binding in a map in CameLIGO by means of the
|
||||||
`Map.update` built-in function:
|
`Map.update` built-in function:
|
||||||
|
|
||||||
```cameligo group=f
|
```cameligo group=maps
|
||||||
let assign (m : register) : register =
|
let assign (m : register) : register =
|
||||||
Map.update
|
Map.update
|
||||||
("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 had
|
||||||
> use `None` instead, that would have meant that the binding is
|
use `None` instead, that would have meant that the binding is removed.
|
||||||
> removed.
|
|
||||||
|
As a particular case, we can only add a key and its associated value.
|
||||||
|
|
||||||
|
```cameligo group=maps
|
||||||
|
let add (m : register) : register =
|
||||||
|
Map.add
|
||||||
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (4,9) m
|
||||||
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
We can update a binding in a map in ReasonLIGO by means of the
|
We can update a binding in a map in ReasonLIGO by means of the
|
||||||
`Map.update` built-in function:
|
`Map.update` built-in function:
|
||||||
|
|
||||||
```reasonligo group=f
|
```reasonligo group=maps
|
||||||
let assign = (m : register) : register =>
|
let assign = (m : register) : register =>
|
||||||
Map.update
|
Map.update
|
||||||
(("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 had
|
||||||
> use `None` instead, that would have meant that the binding is
|
use `None` instead, that would have meant that the binding is removed.
|
||||||
> removed.
|
|
||||||
|
As a particular case, we can only add a key and its associated value.
|
||||||
|
|
||||||
|
```reasonligo group=maps
|
||||||
|
let add = (m : register) : register =>
|
||||||
|
Map.add
|
||||||
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (4,9), m);
|
||||||
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
@ -503,7 +546,7 @@ To remove a binding from a map, we need its key.
|
|||||||
|
|
||||||
In PascaLIGO, there is a special instruction to remove a binding from
|
In PascaLIGO, there is a special instruction to remove a binding from
|
||||||
a map.
|
a map.
|
||||||
```pascaligo group=f
|
```pascaligo group=maps
|
||||||
function delete (const key : address; var moves : register) : register is
|
function delete (const key : address; var moves : register) : register is
|
||||||
block {
|
block {
|
||||||
remove key from map moves
|
remove key from map moves
|
||||||
@ -514,7 +557,7 @@ function delete (const key : address; var moves : register) : register is
|
|||||||
|
|
||||||
In CameLIGO, we use the predefined function `Map.remove` as follows:
|
In CameLIGO, we use the predefined function `Map.remove` as follows:
|
||||||
|
|
||||||
```cameligo group=f
|
```cameligo group=maps
|
||||||
let delete (key, moves : address * register) : register =
|
let delete (key, moves : address * register) : register =
|
||||||
Map.remove key moves
|
Map.remove key moves
|
||||||
```
|
```
|
||||||
@ -523,7 +566,7 @@ let delete (key, moves : address * register) : register =
|
|||||||
|
|
||||||
In ReasonLIGO, we use the predefined function `Map.remove` as follows:
|
In ReasonLIGO, we use the predefined function `Map.remove` as follows:
|
||||||
|
|
||||||
```reasonligo group=f
|
```reasonligo group=maps
|
||||||
let delete = ((key, moves) : (address, register)) : register =>
|
let delete = ((key, moves) : (address, register)) : register =>
|
||||||
Map.remove (key, moves);
|
Map.remove (key, moves);
|
||||||
```
|
```
|
||||||
@ -549,34 +592,28 @@ 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
|
||||||
|
over maps is called `Map.iter`. In the following example, the register
|
||||||
|
of moves is iterated to check that the start of each move is above
|
||||||
|
`3`.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
In PascaLIGO, the predefined functional iterator implementing the
|
```pascaligo group=maps
|
||||||
iterated operation over maps is called `map_iter`. In the following
|
|
||||||
example, the register of moves is iterated to check that the start of
|
|
||||||
each move is above `3`.
|
|
||||||
|
|
||||||
```pascaligo group=f
|
|
||||||
function iter_op (const m : register) : unit is
|
function iter_op (const m : register) : unit is
|
||||||
block {
|
block {
|
||||||
function iterated (const i : address; const j : move) : unit is
|
function iterated (const i : address; const j : move) : unit is
|
||||||
if j.1 > 3 then Unit else (failwith ("Below range.") : unit)
|
if j.1 > 3 then Unit else (failwith ("Below range.") : unit)
|
||||||
} with map_iter (iterated, m)
|
} with Map.iter (iterated, m)
|
||||||
```
|
```
|
||||||
|
|
||||||
> The iterated function must be pure, that is, it cannot mutate
|
> Note that `map_iter` is *deprecated*.
|
||||||
> variables.
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
In CameLIGO, the predefinded functional iterator implementing the
|
```cameligo group=maps
|
||||||
iterated operation over maps is called `Map.iter`. In the following
|
|
||||||
example, the register of moves is iterated to check that the start of
|
|
||||||
each move is above `3`.
|
|
||||||
|
|
||||||
```cameligo group=f
|
|
||||||
let iter_op (m : register) : unit =
|
let iter_op (m : register) : unit =
|
||||||
let predicate = fun (i,j : address * move) -> assert (j.0 > 3)
|
let predicate = fun (i,j : address * move) -> assert (j.0 > 3)
|
||||||
in Map.iter predicate m
|
in Map.iter predicate m
|
||||||
@ -584,12 +621,7 @@ let iter_op (m : register) : unit =
|
|||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
In ReasonLIGO, the predefined functional iterator implementing the
|
```reasonligo group=maps
|
||||||
iterated operation over maps is called `Map.iter`. In the following
|
|
||||||
example, the register of moves is iterated to check that the start of
|
|
||||||
each move is above `3`.
|
|
||||||
|
|
||||||
```reasonligo group=f
|
|
||||||
let iter_op = (m : register) : unit => {
|
let iter_op = (m : register) : unit => {
|
||||||
let predicate = ((i,j) : (address, move)) => assert (j[0] > 3);
|
let predicate = ((i,j) : (address, move)) => assert (j[0] > 3);
|
||||||
Map.iter (predicate, m);
|
Map.iter (predicate, m);
|
||||||
@ -601,32 +633,28 @@ let iter_op = (m : register) : unit => {
|
|||||||
|
|
||||||
We may want to change all the bindings of a map by applying to them a
|
We may want to change all the bindings of a map by applying to them a
|
||||||
function. This is called a *map operation*, not to be confused with
|
function. This is called a *map operation*, not to be confused with
|
||||||
the map data structure.
|
the map data structure. The predefined functional iterator
|
||||||
|
implementing the map operation over maps is called `Map.map`. In the
|
||||||
|
following example, we add `1` to the ordinate of the moves in the
|
||||||
|
register.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
In PascaLIGO, the predefined functional iterator implementing the map
|
```pascaligo group=maps
|
||||||
operation over maps is called `map_map` and is used as follows:
|
|
||||||
|
|
||||||
```pascaligo group=f
|
|
||||||
function map_op (const m : register) : register is
|
function map_op (const m : register) : register is
|
||||||
block {
|
block {
|
||||||
function increment (const i : address; const j : move) : move is
|
function increment (const i : address; const j : move) : move is
|
||||||
(j.0, j.1 + 1);
|
(j.0, j.1 + 1)
|
||||||
} with map_map (increment, m)
|
} with Map.map (increment, m)
|
||||||
```
|
```
|
||||||
|
|
||||||
> The mapped function must be pure, that is, it cannot mutate
|
> Note that `map_map` is *deprecated*.
|
||||||
> variables.
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
In CameLIGO, the predefined functional iterator implementing the map
|
```cameligo group=maps
|
||||||
operation over maps is called `Map.map` and is used as follows:
|
|
||||||
|
|
||||||
```cameligo group=f
|
|
||||||
let map_op (m : register) : register =
|
let map_op (m : register) : register =
|
||||||
let increment = fun (i,j : address * move) -> j.0, j.1 + 1
|
let increment = fun (i,j : address * move) -> j.0, j.1 + 1
|
||||||
in Map.map increment m
|
in Map.map increment m
|
||||||
@ -634,10 +662,7 @@ let map_op (m : register) : register =
|
|||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
In ReasonLIGO, the predefined functional iteratir implementing the map
|
```reasonligo group=maps
|
||||||
operation over maps is called `Map.map` and is used as follows:
|
|
||||||
|
|
||||||
```reasonligo group=f
|
|
||||||
let map_op = (m : register) : register => {
|
let map_op = (m : register) : register => {
|
||||||
let increment = ((i,j): (address, move)) => (j[0], j[1] + 1);
|
let increment = ((i,j): (address, move)) => (j[0], j[1] + 1);
|
||||||
Map.map (increment, m);
|
Map.map (increment, m);
|
||||||
@ -653,31 +678,26 @@ function takes two arguments: an *accumulator* and the structure
|
|||||||
enables having a partial result that becomes complete when the
|
enables having a partial result that becomes complete when the
|
||||||
traversal of the data structure is over.
|
traversal of the data structure is over.
|
||||||
|
|
||||||
|
The predefined functional iterator implementing the folded operation
|
||||||
|
over maps is called `Map.fold` and is used as follows.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
In PascaLIGO, the predefined functional iterator implementing the
|
```pascaligo group=maps
|
||||||
folded operation over maps is called `map_fold` and is used as
|
function fold_op (const m : register) : int is
|
||||||
follows:
|
block {
|
||||||
|
function folded (const i : int; const j : address * move) : int is
|
||||||
```pascaligo group=f
|
i + j.1.1
|
||||||
function fold_op (const m : register) : int is block {
|
} with Map.fold (folded, m, 5)
|
||||||
function folded (const j : int; const cur : address * move) : int is
|
|
||||||
j + cur.1.1
|
|
||||||
} with map_fold (folded, m, 5)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> The folded function must be pure, that is, it cannot mutate
|
> Note that `map_fold` is *deprecated*.
|
||||||
> variables.
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
In CameLIGO, the predefined functional iterator implementing the
|
```cameligo group=maps
|
||||||
folded operation over maps is called `Map.fold` and is used as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
```cameligo group=f
|
|
||||||
let fold_op (m : register) : register =
|
let fold_op (m : register) : register =
|
||||||
let folded = fun (i,j : int * (address * move)) -> i + j.1.1
|
let folded = fun (i,j : int * (address * move)) -> i + j.1.1
|
||||||
in Map.fold folded m 5
|
in Map.fold folded m 5
|
||||||
@ -685,11 +705,7 @@ let fold_op (m : register) : register =
|
|||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
In ReasonLIGO, the predefined functional iterator implementing the
|
```reasonligo group=maps
|
||||||
folded operation over maps is called `Map.fold` and is used as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
```reasonligo group=f
|
|
||||||
let fold_op = (m : register) : register => {
|
let fold_op = (m : register) : register => {
|
||||||
let folded = ((i,j): (int, (address, move))) => i + j[1][1];
|
let folded = ((i,j): (int, (address, move))) => i + j[1][1];
|
||||||
Map.fold (folded, m, 5);
|
Map.fold (folded, m, 5);
|
||||||
@ -709,75 +725,102 @@ were it not for *big maps*. Big maps are a data structure offered by
|
|||||||
Michelson which handles the scaling concerns for us. In LIGO, the
|
Michelson which handles the scaling concerns for us. In LIGO, the
|
||||||
interface for big maps is analogous to the one used for ordinary maps.
|
interface for big maps is analogous to the one used for ordinary maps.
|
||||||
|
|
||||||
|
### Declaring a Map
|
||||||
|
|
||||||
Here is how we define a big map:
|
Here is how we define a big map:
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=g
|
```pascaligo group=big_maps
|
||||||
type move is int * int
|
type move is int * int
|
||||||
|
|
||||||
type register is big_map (address, move)
|
type register is big_map (address, move)
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=g
|
```cameligo group=big_maps
|
||||||
type move = int * int
|
type move = int * int
|
||||||
|
|
||||||
type register = (address, move) big_map
|
type register = (address, move) big_map
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=g
|
```reasonligo group=big_maps
|
||||||
type move = (int, int);
|
type move = (int, int);
|
||||||
|
|
||||||
type register = big_map (address, move);
|
type register = big_map (address, move);
|
||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
And here is how a map value is created:
|
### Creating an Empty Big Map
|
||||||
|
|
||||||
|
Here is how to create an empty big map.
|
||||||
|
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
<!--PascaLIGO-->
|
||||||
|
```pascaligo group=big_maps
|
||||||
|
const empty : register = big_map []
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--CameLIGO-->
|
||||||
|
```cameligo group=big_maps
|
||||||
|
let empty : register = Big_map.empty
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
```reasonligo group=big_maps
|
||||||
|
let empty : register = Big_map.empty
|
||||||
|
```
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
### Creating a Non-empty Map
|
||||||
|
|
||||||
|
And here is how to create a non-empty map value:
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
```pascaligo group=g
|
```pascaligo group=big_maps
|
||||||
const moves : register =
|
const moves : register =
|
||||||
big_map [
|
big_map [
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) -> (1,2);
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) -> (1,2);
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) -> (0,3)]
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) -> (0,3)]
|
||||||
```
|
```
|
||||||
|
|
||||||
> Notice the right arrow `->` between the key and its value and the
|
Notice the right arrow `->` between the key and its value and the -->
|
||||||
> semicolon separating individual map entries. The value annotation
|
semicolon separating individual map entries. The value annotation -->
|
||||||
> `("<string value>" : address)` means that we cast a string into an
|
`("<string value>" : address)` means that we cast a string into an -->
|
||||||
> address.
|
address. -->
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
```cameligo group=g
|
```cameligo group=big_maps
|
||||||
let moves : register =
|
let moves : register =
|
||||||
Big_map.literal [
|
Big_map.literal [
|
||||||
(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address), (1,2));
|
(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address), (1,2));
|
||||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))]
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))]
|
||||||
```
|
```
|
||||||
|
|
||||||
> The predefind function `Big_map.literal` constructs a big map from a
|
The predefind 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.
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
```reasonligo group=g
|
```reasonligo group=big_maps
|
||||||
let moves : register =
|
let moves : register =
|
||||||
Big_map.literal ([
|
Big_map.literal ([
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
||||||
```
|
```
|
||||||
|
|
||||||
> The predefind function `Big_map.literal` constructs a big map from a
|
The predefind 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.
|
||||||
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
@ -793,21 +836,21 @@ the value we read is an optional value (in our case, of type `option
|
|||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
```pascaligo group=g
|
```pascaligo group=big_maps
|
||||||
const my_balance : option (move) =
|
const my_balance : option (move) =
|
||||||
moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)]
|
moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)]
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
```cameligo group=g
|
```cameligo group=big_maps
|
||||||
let my_balance : move option =
|
let my_balance : move option =
|
||||||
Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) moves
|
Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) moves
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
```reasonligo group=g
|
```reasonligo group=big_maps
|
||||||
let my_balance : option (move) =
|
let my_balance : option (move) =
|
||||||
Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, moves);
|
Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, moves);
|
||||||
```
|
```
|
||||||
@ -822,7 +865,7 @@ let my_balance : option (move) =
|
|||||||
The values of a PascaLIGO big map can be updated using the
|
The values of a PascaLIGO big map can be updated using the
|
||||||
assignment syntax for ordinary maps
|
assignment syntax for ordinary maps
|
||||||
|
|
||||||
```pascaligo group=g
|
```pascaligo group=big_maps
|
||||||
function add (var m : register) : register is
|
function add (var m : register) : register is
|
||||||
block {
|
block {
|
||||||
m [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9)
|
m [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9)
|
||||||
@ -836,7 +879,7 @@ const updated_map : register = add (moves)
|
|||||||
We can update a big map in CameLIGO using the `Big_map.update`
|
We can update a big map in CameLIGO using the `Big_map.update`
|
||||||
built-in:
|
built-in:
|
||||||
|
|
||||||
```cameligo group=g
|
```cameligo group=big_maps
|
||||||
let updated_map : register =
|
let updated_map : register =
|
||||||
Big_map.update
|
Big_map.update
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (Some (4,9)) moves
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (Some (4,9)) moves
|
||||||
@ -847,10 +890,10 @@ let updated_map : register =
|
|||||||
We can update a big map in ReasonLIGO using the `Big_map.update`
|
We can update a big map in ReasonLIGO using the `Big_map.update`
|
||||||
built-in:
|
built-in:
|
||||||
|
|
||||||
```reasonligo group=g
|
```reasonligo group=big_maps
|
||||||
let updated_map : register =
|
let updated_map : register =
|
||||||
Big_map.update
|
Big_map.update
|
||||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), Some((4,9)), moves);
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), Some ((4,9)), moves);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
@ -867,7 +910,7 @@ syntax.
|
|||||||
PascaLIGO features a special syntactic construct to remove bindings
|
PascaLIGO features a special syntactic construct to remove bindings
|
||||||
from maps, of the form `remove <key> from map <map>`. For example,
|
from maps, of the form `remove <key> from map <map>`. For example,
|
||||||
|
|
||||||
```pascaligo group=g
|
```pascaligo group=big_maps
|
||||||
function rem (var m : register) : register is
|
function rem (var m : register) : register is
|
||||||
block {
|
block {
|
||||||
remove ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) from map moves
|
remove ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) from map moves
|
||||||
@ -881,7 +924,7 @@ const updated_map : register = rem (moves)
|
|||||||
In CameLIGO, the predefined function which removes a binding in a map
|
In CameLIGO, the predefined function which removes a binding in a map
|
||||||
is called `Map.remove` and is used as follows:
|
is called `Map.remove` and is used as follows:
|
||||||
|
|
||||||
```cameligo group=g
|
```cameligo group=big_maps
|
||||||
let updated_map : register =
|
let updated_map : register =
|
||||||
Map.remove ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) moves
|
Map.remove ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) moves
|
||||||
```
|
```
|
||||||
@ -891,7 +934,7 @@ let updated_map : register =
|
|||||||
In ReasonLIGO, the predefined function which removes a binding in a map
|
In ReasonLIGO, the predefined function which removes a binding in a map
|
||||||
is called `Map.remove` and is used as follows:
|
is called `Map.remove` and is used as follows:
|
||||||
|
|
||||||
```reasonligo group=g
|
```reasonligo group=big_maps
|
||||||
let updated_map : register =
|
let updated_map : register =
|
||||||
Map.remove (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), moves)
|
Map.remove (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), moves)
|
||||||
```
|
```
|
||||||
|
@ -3,13 +3,14 @@ id: operators
|
|||||||
title: Operators
|
title: Operators
|
||||||
---
|
---
|
||||||
|
|
||||||
## Available operators
|
## Available Operators
|
||||||
|
|
||||||
> This list is non-exhaustive. More operators will be added in upcoming LIGO releases.
|
> This list is non-exhaustive. More operators will be added in
|
||||||
|
> upcoming LIGO releases.
|
||||||
|
|
||||||
|Michelson |Pascaligo |Description |
|
|Michelson |Pascaligo |Description |
|
||||||
|--- |--- |--- |
|
|--- |--- |--- |
|
||||||
| `SENDER` | `sender` | Address that initiated the current transaction
|
| `SENDER` | `Tezos.sender` | Address that initiated the current transaction
|
||||||
| `SOURCE` | `source` | Address that initiated the transaction, which triggered the current transaction. (useful e.g. when there's a transaction sent by another contract)
|
| `SOURCE` | `Tezos.source` | Address that initiated the transaction, which triggered the current transaction. (useful e.g. when there's a transaction sent by another contract)
|
||||||
| `AMOUNT` | `amount` | Amount of tez sent by the transaction that invoked the contract
|
| `AMOUNT` | `Tezos.amount` | Amount of tez sent by the transaction that invoked the contract
|
||||||
| `NOW` | `now` | Timestamp of the block whose validation triggered execution of the contract, i.e. current time when the contract is run.
|
| `NOW` | `Tezos.now` | Timestamp of the block whose validation triggered execution of the contract, i.e. current time when the contract is run.
|
||||||
|
@ -176,11 +176,6 @@ There are three kinds of functional iterations over LIGO lists: the
|
|||||||
*iterated operation*, the *map operation* (not to be confused with the
|
*iterated operation*, the *map operation* (not to be confused with the
|
||||||
*map data structure*) and the *fold operation*.
|
*map data structure*) and the *fold operation*.
|
||||||
|
|
||||||
> 💡 Lists can be iterated, folded or mapped to different values. You
|
|
||||||
> can find additional examples
|
|
||||||
> [here](https://gitlab.com/ligolang/ligo/tree/dev/src/test/contracts)
|
|
||||||
> and other built-in operators
|
|
||||||
> [here](https://gitlab.com/ligolang/ligo/blob/dev/src/passes/operators/operators.ml#L59)
|
|
||||||
|
|
||||||
#### Iterated Operation over Lists
|
#### Iterated Operation over Lists
|
||||||
|
|
||||||
@ -188,37 +183,28 @@ The first, the *iterated operation*, is an iteration over the list
|
|||||||
with a unit return value. It is useful to enforce certain invariants
|
with a unit return value. It is useful to enforce certain invariants
|
||||||
on the element of a list, or fail. For example you might want to check
|
on the element of a list, or fail. For example you might want to check
|
||||||
that each value inside of a list is within a certain range, and fail
|
that each value inside of a list is within a certain range, and fail
|
||||||
otherwise.
|
otherwise. The predefined functional iterator implementing the
|
||||||
|
iterated operation over lists is called `List.iter`.
|
||||||
|
|
||||||
|
In the following example, a list is iterated to check that all its
|
||||||
|
elements (integers) are strictly greater than `3`.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
In PascaLIGO, the predefined functional iterator implementing the
|
|
||||||
iterated operation over lists is called `list_iter`.
|
|
||||||
|
|
||||||
In the following example, a list is iterated to check that all its
|
|
||||||
elements (integers) are greater than `3`:
|
|
||||||
|
|
||||||
```pascaligo group=lists
|
```pascaligo group=lists
|
||||||
function iter_op (const l : list (int)) : unit is
|
function iter_op (const l : list (int)) : unit is
|
||||||
block {
|
block {
|
||||||
function iterated (const i : int) : unit is
|
function iterated (const i : int) : unit is
|
||||||
if i > 2 then Unit else (failwith ("Below range.") : unit)
|
if i > 3 then Unit else (failwith ("Below range.") : unit)
|
||||||
} with list_iter (iterated, l)
|
} with List.iter (iterated, l)
|
||||||
```
|
```
|
||||||
|
|
||||||
> The iterated function must be pure, that is, it cannot mutate
|
> Note that `list_iter` is *deprecated*.
|
||||||
> variables.
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
In CameLIGO, the predefined functional iterator implementing the
|
|
||||||
iterated operation over lists is called `List.iter`.
|
|
||||||
|
|
||||||
In the following example, a list is iterated to check that all its
|
|
||||||
elements (integers) are greater than `3`:
|
|
||||||
|
|
||||||
```cameligo group=lists
|
```cameligo group=lists
|
||||||
let iter_op (l : int list) : unit =
|
let iter_op (l : int list) : unit =
|
||||||
let predicate = fun (i : int) -> assert (i > 3)
|
let predicate = fun (i : int) -> assert (i > 3)
|
||||||
@ -227,12 +213,6 @@ let iter_op (l : int list) : unit =
|
|||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
In ReasonLIGO, the predefined functional iterator implementing the
|
|
||||||
iterated operation over lists is called `List.iter`.
|
|
||||||
|
|
||||||
In the following example, a list is iterated to check that all its
|
|
||||||
elements (integers) are greater than `3`:
|
|
||||||
|
|
||||||
```reasonligo group=lists
|
```reasonligo group=lists
|
||||||
let iter_op = (l : list (int)) : unit => {
|
let iter_op = (l : list (int)) : unit => {
|
||||||
let predicate = (i : int) => assert (i > 3);
|
let predicate = (i : int) => assert (i > 3);
|
||||||
@ -247,32 +227,25 @@ let iter_op = (l : list (int)) : unit => {
|
|||||||
|
|
||||||
We may want to change all the elements of a given list by applying to
|
We may want to change all the elements of a given list by applying to
|
||||||
them a function. This is called a *map operation*, not to be confused
|
them a function. This is called a *map operation*, not to be confused
|
||||||
with the map data structure.
|
with the map data structure. The predefined functional iterator
|
||||||
|
implementing the mapped operation over lists is called `List.map` and
|
||||||
|
is used as follows.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
In PascaLIGO, the predefined functional iterator implementing the
|
|
||||||
mapped operation over lists is called `list_map` and is used as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
```pascaligo group=lists
|
```pascaligo group=lists
|
||||||
function increment (const i : int): int is i + 1
|
function increment (const i : int): int is i + 1
|
||||||
|
|
||||||
// Creates a new list with all elements incremented by 1
|
// Creates a new list with all elements incremented by 1
|
||||||
const plus_one : list (int) = list_map (increment, larger_list)
|
const plus_one : list (int) = List.map (increment, larger_list)
|
||||||
```
|
```
|
||||||
|
|
||||||
> The mapped function must be pure, that is, it cannot mutate
|
> Note that `list_map` is *deprecated*.
|
||||||
> variables.
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
In CameLIGO, the predefined functional iterator implementing the
|
|
||||||
mapped operation over lists is called `List.map` and is used as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
```cameligo group=lists
|
```cameligo group=lists
|
||||||
let increment (i : int) : int = i + 1
|
let increment (i : int) : int = i + 1
|
||||||
|
|
||||||
@ -282,10 +255,6 @@ let plus_one : int list = List.map increment larger_list
|
|||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
In ReasonLIGO, the predefined functional iterator implementing the
|
|
||||||
mapped operation over lists is called `List.map` and is used as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
```reasonligo group=lists
|
```reasonligo group=lists
|
||||||
let increment = (i : int) : int => i + 1;
|
let increment = (i : int) : int => i + 1;
|
||||||
|
|
||||||
@ -301,29 +270,23 @@ A *folded operation* is the most general of iterations. The folded
|
|||||||
function takes two arguments: an *accumulator* and the structure
|
function takes two arguments: an *accumulator* and the structure
|
||||||
*element* at hand, with which it then produces a new accumulator. This
|
*element* at hand, with which it then produces a new accumulator. This
|
||||||
enables having a partial result that becomes complete when the
|
enables having a partial result that becomes complete when the
|
||||||
traversal of the data structure is over.
|
traversal of the data structure is over. The predefined functional
|
||||||
|
iterator implementing the folded operation over lists is called
|
||||||
|
`List.fold` and is used as follows.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
In PascaLIGO, the predefined functional iterator implementing the
|
|
||||||
folded operation over lists is called `list_fold` and is used as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
```pascaligo group=lists
|
```pascaligo group=lists
|
||||||
function sum (const acc : int; const i : int): int is acc + i
|
function sum (const acc : int; const i : int): int is acc + i
|
||||||
const sum_of_elements : int = list_fold (sum, my_list, 0)
|
const sum_of_elements : int = List.fold (sum, my_list, 0)
|
||||||
```
|
```
|
||||||
|
|
||||||
> The folded function must be pure, that is, it cannot mutate
|
> Note that `list_fold` is *deprecated*.
|
||||||
> variables.
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
In CameLIGO, the predefined functional iterator implementing the folded
|
|
||||||
operation over lists is called `List.fold` and is used as follows:
|
|
||||||
|
|
||||||
```cameligo group=lists
|
```cameligo group=lists
|
||||||
let sum (acc, i: int * int) : int = acc + i
|
let sum (acc, i: int * int) : int = acc + i
|
||||||
let sum_of_elements : int = List.fold sum my_list 0
|
let sum_of_elements : int = List.fold sum my_list 0
|
||||||
@ -331,10 +294,6 @@ let sum_of_elements : int = List.fold sum my_list 0
|
|||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
In ReasonLIGO, the predefined functional iterator implementing the
|
|
||||||
folded operation over lists is called `List.fold` and is used as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
```reasonligo group=lists
|
```reasonligo group=lists
|
||||||
let sum = ((result, i): (int, int)): int => result + i;
|
let sum = ((result, i): (int, int)): int => result + i;
|
||||||
let sum_of_elements : int = List.fold (sum, my_list, 0);
|
let sum_of_elements : int = List.fold (sum, my_list, 0);
|
||||||
@ -472,36 +431,31 @@ in a set as follows:
|
|||||||
```reasonligo group=sets
|
```reasonligo group=sets
|
||||||
let contains_3 : bool = Set.mem (3, my_set);
|
let contains_3 : bool = Set.mem (3, my_set);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
|
||||||
### Cardinal of Sets
|
### Cardinal of Sets
|
||||||
|
|
||||||
|
The predefined function `Set.size` returns the number of
|
||||||
|
elements in a given set as follows.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
In PascaLIGO, the predefined function `size` returns the number of
|
|
||||||
elements in a given set as follows:
|
|
||||||
|
|
||||||
```pascaligo group=sets
|
```pascaligo group=sets
|
||||||
const set_size : nat = size (my_set)
|
const cardinal : nat = Set.size (my_set)
|
||||||
```
|
```
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
In CameLIGO, the predefined function `Set.size` returns the number of
|
|
||||||
elements in a given set as follows:
|
|
||||||
|
|
||||||
```cameligo group=sets
|
```cameligo group=sets
|
||||||
let set_size : nat = Set.size my_set
|
let cardinal : nat = Set.size my_set
|
||||||
```
|
```
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
In ReasonLIGO, the predefined function `Set.size` returns the number
|
|
||||||
of elements in a given set as follows:
|
|
||||||
|
|
||||||
```reasonligo group=sets
|
```reasonligo group=sets
|
||||||
let set_size : nat = Set.size (my_set);
|
let cardinal : nat = Set.size (my_set);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
@ -509,20 +463,23 @@ let set_size : nat = Set.size (my_set);
|
|||||||
|
|
||||||
### Updating Sets
|
### Updating Sets
|
||||||
|
|
||||||
|
There are two ways to update a set, that is to add or remove from
|
||||||
|
it.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
In PascaLIGO, there are two ways to update a set, that is to add or
|
In PascaLIGO, either we create a new set from the given one, or we
|
||||||
remove from it. Either we create a new set from the given one, or we
|
|
||||||
modify it in-place. First, let us consider the former way:
|
modify it in-place. First, let us consider the former way:
|
||||||
|
|
||||||
```pascaligo group=sets
|
```pascaligo group=sets
|
||||||
const larger_set : set (int) = set_add (4, my_set)
|
const larger_set : set (int) = Set.add (4, my_set)
|
||||||
|
const smaller_set : set (int) = Set.remove (3, my_set)
|
||||||
const smaller_set : set (int) = set_remove (3, my_set)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `set_add` and `set_remove` are *deprecated*.
|
||||||
|
|
||||||
If we are in a block, we can use an instruction to modify the set
|
If we are in a block, we can use an instruction to modify the set
|
||||||
bound to a given variable. This is called a *patch*. It is only
|
bound to a given variable. This is called a *patch*. It is only
|
||||||
possible to add elements by means of a patch, not remove any: it is
|
possible to add elements by means of a patch, not remove any: it is
|
||||||
@ -544,23 +501,23 @@ const new_set : set (int) = update (my_set)
|
|||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
In CameLIGO, we update a given set by creating another one, with or
|
In CameLIGO, we can use the predefined functions `Set.add` and
|
||||||
|
`Set.remove`. We update a given set by creating another one, with or
|
||||||
without some elements.
|
without some elements.
|
||||||
|
|
||||||
```cameligo group=sets
|
```cameligo group=sets
|
||||||
let larger_set : int set = Set.add 4 my_set
|
let larger_set : int set = Set.add 4 my_set
|
||||||
|
|
||||||
let smaller_set : int set = Set.remove 3 my_set
|
let smaller_set : int set = Set.remove 3 my_set
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
In ReasonLIGO, we update a given set by creating another one, with or
|
In ReasonLIGO, we can use the predefined functions `Set.add` and
|
||||||
|
`Set.remove`. We update a given set by creating another one, with or
|
||||||
without some elements.
|
without some elements.
|
||||||
|
|
||||||
```reasonligo group=sets
|
```reasonligo group=sets
|
||||||
let larger_set : set (int) = Set.add (4, my_set);
|
let larger_set : set (int) = Set.add (4, my_set);
|
||||||
|
|
||||||
let smaller_set : set (int) = Set.remove (3, my_set);
|
let smaller_set : set (int) = Set.remove (3, my_set);
|
||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
@ -584,35 +541,27 @@ 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
|
||||||
|
over sets is called `Set.iter`. In the following example, a set is
|
||||||
|
iterated to check that all its elements (integers) are greater than
|
||||||
|
`3`.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
In PascaLIGO, the predefined functional iterator implementing the
|
|
||||||
iterated operation over sets is called `set_iter`.
|
|
||||||
|
|
||||||
In the following example, a set is iterated to check that all its
|
|
||||||
elements (integers) are greater than `3`:
|
|
||||||
|
|
||||||
```pascaligo group=sets
|
```pascaligo group=sets
|
||||||
function iter_op (const s : set (int)) : unit is
|
function iter_op (const s : set (int)) : unit is
|
||||||
block {
|
block {
|
||||||
function iterated (const i : int) : unit is
|
function iterated (const i : int) : unit is
|
||||||
if i > 2 then Unit else (failwith ("Below range.") : unit)
|
if i > 2 then Unit else (failwith ("Below range.") : unit)
|
||||||
} with set_iter (iterated, s)
|
} with Set.iter (iterated, s)
|
||||||
```
|
```
|
||||||
|
|
||||||
> The iterated function must be pure, that is, it cannot mutate
|
> Note that `set_iter` is *deprecated*.
|
||||||
> variables.
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
In CameLIGO, the predefined functional iterator implementing the
|
|
||||||
iterated operation over sets is called `Set.iter`.
|
|
||||||
|
|
||||||
In the following example, a set is iterated to check that all its
|
|
||||||
elements (integers) are greater than `3`:
|
|
||||||
|
|
||||||
```cameligo group=sets
|
```cameligo group=sets
|
||||||
let iter_op (s : int set) : unit =
|
let iter_op (s : int set) : unit =
|
||||||
let predicate = fun (i : int) -> assert (i > 3)
|
let predicate = fun (i : int) -> assert (i > 3)
|
||||||
@ -621,12 +570,6 @@ let iter_op (s : int set) : unit =
|
|||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
In ReasonLIGO, the predefined functional iterator implementing the
|
|
||||||
iterated operation over sets is called `Set.iter`.
|
|
||||||
|
|
||||||
In the following example, a set is iterated to check that all its
|
|
||||||
elements (integers) are greater than `3`:
|
|
||||||
|
|
||||||
```reasonligo group=sets
|
```reasonligo group=sets
|
||||||
let iter_op = (s : set (int)) : unit => {
|
let iter_op = (s : set (int)) : unit => {
|
||||||
let predicate = (i : int) => assert (i > 3);
|
let predicate = (i : int) => assert (i > 3);
|
||||||
@ -637,51 +580,51 @@ let iter_op = (s : set (int)) : unit => {
|
|||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
|
||||||
#### Mapped Operation (NOT IMPLEMENTED YET)
|
<!-- #### Mapped Operation (NOT IMPLEMENTED YET) -->
|
||||||
|
|
||||||
We may want to change all the elements of a given set by applying to
|
<!-- We may want to change all the elements of a given set by applying to -->
|
||||||
them a function. This is called a *mapped operation*, not to be
|
<!-- them a function. This is called a *mapped operation*, not to be -->
|
||||||
confused with the map data structure.
|
<!-- confused with the map data structure. -->
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!-- <\!--DOCUSAURUS_CODE_TABS-\-> -->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!-- <\!--PascaLIGO-\-> -->
|
||||||
|
|
||||||
In PascaLIGO, the predefined functional iterator implementing the
|
<!-- In PascaLIGO, the predefined functional iterator implementing the -->
|
||||||
mapped operation over sets is called `set_map` and is used as follows:
|
<!-- mapped operation over sets is called `Set.map` and is used as follows: -->
|
||||||
|
|
||||||
```pascaligo skip
|
<!-- ```pascaligo skip -->
|
||||||
function increment (const i : int): int is i + 1
|
<!-- function increment (const i : int): int is i + 1 -->
|
||||||
|
|
||||||
// Creates a new set with all elements incremented by 1
|
<!-- // Creates a new set with all elements incremented by 1 -->
|
||||||
const plus_one : set (int) = set_map (increment, larger_set)
|
<!-- const plus_one : set (int) = Set.map (increment, larger_set) -->
|
||||||
```
|
<!-- ``` -->
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!-- <\!--CameLIGO-\-> -->
|
||||||
|
|
||||||
In CameLIGO, the predefined functional iterator implementing the
|
<!-- In CameLIGO, the predefined functional iterator implementing the -->
|
||||||
mapped operation over sets is called `Set.map` and is used as follows:
|
<!-- mapped operation over sets is called `Set.map` and is used as follows: -->
|
||||||
|
|
||||||
```cameligo skip
|
<!-- ```cameligo skip -->
|
||||||
let increment (i : int) : int = i + 1
|
<!-- let increment (i : int) : int = i + 1 -->
|
||||||
|
|
||||||
// Creates a new set with all elements incremented by 1
|
<!-- // Creates a new set with all elements incremented by 1 -->
|
||||||
let plus_one : int set = Set.map increment larger_set
|
<!-- let plus_one : int set = Set.map increment larger_set -->
|
||||||
```
|
<!-- ``` -->
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!-- <\!--ReasonLIGO-\-> -->
|
||||||
|
|
||||||
In ReasonLIGO, the predefined functional iterator implementing the
|
<!-- In ReasonLIGO, the predefined functional iterator implementing the -->
|
||||||
mapped operation over sets is called `Set.map` and is used as follows:
|
<!-- mapped operation over sets is called `Set.map` and is used as follows: -->
|
||||||
|
|
||||||
```reasonligo skip
|
<!-- ```reasonligo skip -->
|
||||||
let increment = (i : int) : int => i + 1;
|
<!-- let increment = (i : int) : int => i + 1; -->
|
||||||
|
|
||||||
// Creates a new set with all elements incremented by 1
|
<!-- // Creates a new set with all elements incremented by 1 -->
|
||||||
let plus_one : set (int) = Set.map (increment, larger_set);
|
<!-- let plus_one : set (int) = Set.map (increment, larger_set); -->
|
||||||
```
|
<!-- ``` -->
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!-- <\!--END_DOCUSAURUS_CODE_TABS-\-> -->
|
||||||
|
|
||||||
#### Folded Operation
|
#### Folded Operation
|
||||||
|
|
||||||
@ -689,24 +632,20 @@ A *folded operation* is the most general of iterations. The folded
|
|||||||
function takes two arguments: an *accumulator* and the structure
|
function takes two arguments: an *accumulator* and the structure
|
||||||
*element* at hand, with which it then produces a new accumulator. This
|
*element* at hand, with which it then produces a new accumulator. This
|
||||||
enables having a partial result that becomes complete when the
|
enables having a partial result that becomes complete when the
|
||||||
traversal of the data structure is over.
|
traversal of the data structure is over. The predefined fold over sets
|
||||||
|
is called `Set.fold`.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
In PascaLIGO, the predefined functional iterator implementing the
|
|
||||||
folded operation over sets is called `set_fold` and is used as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
```pascaligo group=sets
|
```pascaligo group=sets
|
||||||
function sum (const acc : int; const i : int): int is acc + i
|
function sum (const acc : int; const i : int): int is acc + i
|
||||||
|
|
||||||
const sum_of_elements : int = set_fold (sum, my_set, 0)
|
const sum_of_elements : int = Set.fold (sum, my_set, 0)
|
||||||
```
|
```
|
||||||
|
|
||||||
> The folded function must be pure, that is, it cannot mutate
|
> Note that `set_fold` is *deprecated*.
|
||||||
> variables.
|
|
||||||
|
|
||||||
It is possible to use a *loop* over a set as well.
|
It is possible to use a *loop* over a set as well.
|
||||||
|
|
||||||
@ -721,8 +660,6 @@ function loop (const s : set (int)) : int is block {
|
|||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
In CameLIGO, the predefined fold over sets is called `Set.fold`.
|
|
||||||
|
|
||||||
```cameligo group=sets
|
```cameligo group=sets
|
||||||
let sum (acc, i : int * int) : int = acc + i
|
let sum (acc, i : int * int) : int = acc + i
|
||||||
|
|
||||||
@ -731,8 +668,6 @@ let sum_of_elements : int = Set.fold sum my_set 0
|
|||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
In ReasonLIGO, the predefined fold over sets is called `Set.fold`.
|
|
||||||
|
|
||||||
```reasonligo group=sets
|
```reasonligo group=sets
|
||||||
let sum = ((acc, i) : (int, int)) : int => acc + i;
|
let sum = ((acc, i) : (int, int)) : int => acc + i;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
type magnitude is Small | Large // See variant types
|
type magnitude is Small | Large // See variant types
|
||||||
|
|
||||||
function compare (const n : nat) : magnitude is
|
function compare (const n : nat) : magnitude is
|
||||||
if n < 10n then Small (Unit) else Large (Unit)
|
if n < 10n then Small else Large
|
||||||
|
@ -2,4 +2,4 @@ function increment (const b : int) : int is
|
|||||||
(function (const a : int) : int is a + 1) (b)
|
(function (const a : int) : int is a + 1) (b)
|
||||||
|
|
||||||
function incr_map (const l : list (int)) : list (int) is
|
function incr_map (const l : list (int)) : list (int) is
|
||||||
list_map (function (const i : int) : int is i + 1, l)
|
List.map (function (const i : int) : int is i + 1, l)
|
||||||
|
@ -4,9 +4,8 @@ const larger_list : int_list = 5 # my_list
|
|||||||
|
|
||||||
function increment (const i : int): int is i + 1
|
function increment (const i : int): int is i + 1
|
||||||
|
|
||||||
// Creates a new list with all elements incremented by 1
|
const plus_one : list (int) = List.map (increment, larger_list);
|
||||||
const plus_one : list (int) = list_map (increment, larger_list);
|
|
||||||
|
|
||||||
function sum (const acc : int; const i : int): int is acc + i
|
function sum (const acc : int; const i : int): int is acc + i
|
||||||
|
|
||||||
const sum_of_elements : int = list_fold (sum, my_list, 0)
|
const sum_of_elements : int = List.fold (sum, my_list, 0)
|
||||||
|
@ -6,9 +6,9 @@ const contains_3 : bool = my_set contains 3
|
|||||||
|
|
||||||
const set_size : nat = size (my_set)
|
const set_size : nat = size (my_set)
|
||||||
|
|
||||||
const larger_set : int_set = set_add (4, my_set)
|
const larger_set : int_set = Set.add (4, my_set)
|
||||||
|
|
||||||
const smaller_set : int_set = set_remove (3, my_set)
|
const smaller_set : int_set = Set.remove (3, my_set)
|
||||||
|
|
||||||
function update (var s : set (int)) : set (int) is block {
|
function update (var s : set (int)) : set (int) is block {
|
||||||
patch s with set [4; 7]
|
patch s with set [4; 7]
|
||||||
@ -18,7 +18,7 @@ const new_set : set (int) = update (my_set)
|
|||||||
|
|
||||||
function sum (const acc : int; const i : int): int is acc + i
|
function sum (const acc : int; const i : int): int is acc + i
|
||||||
|
|
||||||
const sum_of_elements : int = set_fold (sum, my_set, 0)
|
const sum_of_elements : int = Set.fold (sum, my_set, 0)
|
||||||
|
|
||||||
function loop (const s : set (int)) : int is block {
|
function loop (const s : set (int)) : int is block {
|
||||||
var sum : int := 0;
|
var sum : int := 0;
|
||||||
|
@ -2,6 +2,6 @@ type coin is Head | Tail
|
|||||||
|
|
||||||
function flip (const c : coin) : coin is
|
function flip (const c : coin) : coin is
|
||||||
case c of
|
case c of
|
||||||
Head -> Tail (Unit) // Unit needed because of a bug
|
Head -> Tail
|
||||||
| Tail -> Head (Unit) // Unit needed because of a bug
|
| Tail -> Head
|
||||||
end
|
end
|
||||||
|
@ -59,21 +59,27 @@ Strings can be sliced using a built-in function:
|
|||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=b
|
```pascaligo group=b
|
||||||
const name : string = "Alice"
|
const name : string = "Alice"
|
||||||
const slice : string = string_slice (0n, 1n, name)
|
const slice : string = String.slice (0n, 1n, name)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `string_slide` is *deprecated*.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=b
|
```cameligo group=b
|
||||||
let name : string = "Alice"
|
let name : string = "Alice"
|
||||||
let slice : string = String.slice 0n 1n name
|
let slice : string = String.slice 0n 1n name
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=b
|
```reasonligo group=b
|
||||||
let name : string = "Alice";
|
let name : string = "Alice";
|
||||||
let slice : string = String.slice (0n, 1n, name);
|
let slice : string = String.slice (0n, 1n, name);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
> ⚠️ Notice that the offset and length of the slice are natural numbers.
|
> ⚠️ Notice that the offset and length of the slice are natural
|
||||||
|
> numbers.
|
||||||
|
|
||||||
## Length of Strings
|
## Length of Strings
|
||||||
|
|
||||||
@ -83,8 +89,11 @@ The length of a string can be found using a built-in function:
|
|||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=c
|
```pascaligo group=c
|
||||||
const name : string = "Alice"
|
const name : string = "Alice"
|
||||||
const length : nat = size (name) // length = 5
|
const length : nat = String.length (name) // length = 5
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `size` is *deprecated*.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=c
|
```cameligo group=c
|
||||||
let name : string = "Alice"
|
let name : string = "Alice"
|
||||||
|
@ -26,9 +26,11 @@ functionality can be accessed from within LIGO.
|
|||||||
```pascaligo group=a
|
```pascaligo group=a
|
||||||
function id_string (const p : string) : option (string) is block {
|
function id_string (const p : string) : option (string) is block {
|
||||||
const packed : bytes = bytes_pack (p)
|
const packed : bytes = bytes_pack (p)
|
||||||
} with (bytes_unpack (packed) : option (string))
|
} with (Bytes.unpack (packed) : option (string))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `bytes_unpack` is *deprecated*.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=a
|
```cameligo group=a
|
||||||
let id_string (p : string) : string option =
|
let id_string (p : string) : string option =
|
||||||
@ -103,9 +105,11 @@ function check_signature
|
|||||||
(const pk : key;
|
(const pk : key;
|
||||||
const signed : signature;
|
const signed : signature;
|
||||||
const msg : bytes) : bool
|
const msg : bytes) : bool
|
||||||
is crypto_check (pk, signed, msg)
|
is Crypto.check (pk, signed, msg)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note that `crypto_check` is *deprecated*.
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=c
|
```cameligo group=c
|
||||||
let check_signature (pk, signed, msg : key * signature * bytes) : bool =
|
let check_signature (pk, signed, msg : key * signature * bytes) : bool =
|
||||||
@ -124,27 +128,29 @@ let check_signature =
|
|||||||
## Contract's Own Address
|
## Contract's Own Address
|
||||||
|
|
||||||
Often you want to get the address of the contract being executed. You
|
Often you want to get the address of the contract being executed. You
|
||||||
can do it with `self_address`.
|
can do it with `Tezos.self_address`.
|
||||||
|
|
||||||
> ⚠️ Due to limitations in Michelson, `self_address` in a contract is
|
> Note that `self_address` is *deprecated*.
|
||||||
> only allowed at the top-level. Using it in an embedded function will
|
|
||||||
> cause an error.
|
> ⚠️ Due to limitations in Michelson, `Tezos.self_address` in a
|
||||||
|
> contract is only allowed at the top-level. Using it in an embedded
|
||||||
|
> function will cause an error.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=d
|
```pascaligo group=d
|
||||||
const current_addr : address = self_address
|
const current_addr : address = Tezos.self_address
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo group=d
|
```cameligo group=d
|
||||||
let current_addr : address = Current.self_address
|
let current_addr : address = Tezos.self_address
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=d
|
```reasonligo group=d
|
||||||
let current_addr : address = Current.self_address;
|
let current_addr : address = Tezos.self_address;
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
@ -229,7 +229,7 @@ type return = operation list * storage
|
|||||||
|
|
||||||
let back (param, store : unit * storage) : return =
|
let back (param, store : unit * storage) : return =
|
||||||
let no_op : operation list = [] in
|
let no_op : operation list = [] in
|
||||||
if Current.time > store.deadline then
|
if Tezos.now > store.deadline then
|
||||||
(failwith "Deadline passed." : return) // Annotation
|
(failwith "Deadline passed." : return) // Annotation
|
||||||
else
|
else
|
||||||
match Map.find_opt sender store.backers with
|
match Map.find_opt sender store.backers with
|
||||||
@ -255,7 +255,7 @@ type return = (list (operation), storage);
|
|||||||
|
|
||||||
let back = ((param, store) : (unit, storage)) : return => {
|
let back = ((param, store) : (unit, storage)) : return => {
|
||||||
let no_op : list (operation) = [];
|
let no_op : list (operation) = [];
|
||||||
if (Current.time > store.deadline) {
|
if (Tezos.now > store.deadline) {
|
||||||
(failwith ("Deadline passed.") : return); // Annotation
|
(failwith ("Deadline passed.") : return); // Annotation
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -56,8 +56,8 @@ else):
|
|||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo group=b
|
```pascaligo group=b
|
||||||
type coin is Head | Tail
|
type coin is Head | Tail
|
||||||
const head : coin = Head (Unit) // Unit needed for now.
|
const head : coin = Head
|
||||||
const tail : coin = Tail (Unit) // Unit needed for now.
|
const tail : coin = Tail
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
@ -69,14 +69,16 @@ let tail : coin = Tail
|
|||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo group=b
|
```reasonligo group=b
|
||||||
type coin = | Head | Tail;
|
type coin = Head | Tail;
|
||||||
let head : coin = Head;
|
let head : coin = Head;
|
||||||
let tail : coin = Tail;
|
let tail : coin = Tail;
|
||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
The names `Head` and `Tail` in the definition of the type `coin` are
|
The names `Head` and `Tail` in the definition of the type `coin` are
|
||||||
called *data constructors*, or *variants*.
|
called *data constructors*, or *variants*. In this particular, they
|
||||||
|
carry no information beyond their names, so they are called *constant
|
||||||
|
constructors*.
|
||||||
|
|
||||||
In general, it is interesting for variants to carry some information,
|
In general, it is interesting for variants to carry some information,
|
||||||
and thus go beyond enumerated types. In the following, we show how to
|
and thus go beyond enumerated types. In the following, we show how to
|
||||||
@ -94,7 +96,7 @@ type user is
|
|||||||
| Guest
|
| Guest
|
||||||
|
|
||||||
const u : user = Admin (1000n)
|
const u : user = Admin (1000n)
|
||||||
const g : user = Guest (Unit) // Unit needed because of a bug
|
const g : user = Guest
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
@ -125,6 +127,9 @@ let g : user = Guest;
|
|||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
In LIGO, a constant constructor is equivalent to the same constructor
|
||||||
|
taking an argument of type `unit`, so, for example, `Guest` is the
|
||||||
|
same value as `Guest (unit)`.
|
||||||
|
|
||||||
## Optional values
|
## Optional values
|
||||||
|
|
||||||
@ -172,8 +177,8 @@ type coin is Head | Tail
|
|||||||
|
|
||||||
function flip (const c : coin) : coin is
|
function flip (const c : coin) : coin is
|
||||||
case c of
|
case c of
|
||||||
Head -> Tail (Unit) // Unit needed because of a bug
|
Head -> Tail
|
||||||
| Tail -> Head (Unit) // Unit needed because of a bug
|
| Tail -> Head
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -181,7 +186,7 @@ You can call the function `flip` by using the LIGO compiler like so:
|
|||||||
```shell
|
```shell
|
||||||
ligo run-function
|
ligo run-function
|
||||||
gitlab-pages/docs/language-basics/src/unit-option-pattern-matching/flip.ligo
|
gitlab-pages/docs/language-basics/src/unit-option-pattern-matching/flip.ligo
|
||||||
flip "(Head (Unit))"
|
flip "Head"
|
||||||
# Outputs: Tail(Unit)
|
# Outputs: Tail(Unit)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -60,7 +60,10 @@ a *global scope*, but they can be declared and used within functions,
|
|||||||
or as function parameters.
|
or as function parameters.
|
||||||
|
|
||||||
> ⚠️ Please be wary that mutation only works within the function scope
|
> ⚠️ Please be wary that mutation only works within the function scope
|
||||||
> itself, values outside of the function scope will not be affected.
|
> itself, values outside of the function scope will not be
|
||||||
|
> affected. In other words, when a function is called, its arguments
|
||||||
|
> are copied, *as well as the environment*. Any side-effect to that
|
||||||
|
> environment is therefore lost when the function returns.
|
||||||
|
|
||||||
|
|
||||||
```pascaligo group=b
|
```pascaligo group=b
|
||||||
|
@ -1,128 +1,128 @@
|
|||||||
---
|
---
|
||||||
id: big-map-reference
|
id: big-map-reference
|
||||||
title: Big Map — Scalable hashmap primitive
|
title: Big Map — Scalable Maps
|
||||||
---
|
---
|
||||||
|
|
||||||
## Defining A Big Map Type
|
## Defining A Big Map Type
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
```pascaligo
|
```pascaligo group=big_map
|
||||||
type move is (int * int)
|
type move is int * int
|
||||||
type moveset is big_map (address, move)
|
type register is big_map (address, move)
|
||||||
type foo is big_map (int, int)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo
|
```cameligo group=big_map
|
||||||
type move = int * int
|
type move = int * int
|
||||||
type moveset = (address, move) big_map
|
type register = (address, move) big_map
|
||||||
type foo = (int, int) big_map
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo
|
```reasonligo group=big_map
|
||||||
type move = (int, int);
|
type move = (int, int);
|
||||||
type moveset = big_map(address, move);
|
type register = big_map (address, move);
|
||||||
type foo = big_map(int, int);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## Creating A Map
|
## Creating an Empty Big Map
|
||||||
|
|
||||||
|
Create an empty big map.
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
<!--PascaLIGO-->
|
||||||
|
```pascaligo group=big_map
|
||||||
|
const empty : register = big_map []
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--CameLIGO-->
|
||||||
|
```cameligo group=big_map
|
||||||
|
let empty : register = Big_map.empty
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
```reasonligo group=big_map
|
||||||
|
let empty : register = Big_map.empty
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
## Populating A Big Map
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
|
|
||||||
```pascaligo
|
```pascaligo group=big_map
|
||||||
const moves: moveset =
|
const moves: register =
|
||||||
big_map
|
big_map [
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address) -> (1,2);
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) -> (1,2);
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) -> (0,3);
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) -> (0,3)]
|
||||||
end
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
```cameligo
|
```cameligo group=big_map
|
||||||
let moves: moveset =
|
let moves: register =
|
||||||
Big_map.literal [
|
Big_map.literal [
|
||||||
(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address), (1,2));
|
(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address), (1,2));
|
||||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), (0,3));
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))]
|
||||||
]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
```reasonligo
|
```reasonligo group=big_map
|
||||||
let moves: moveset =
|
let moves: register =
|
||||||
Big_map.literal ([
|
Big_map.literal ([
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address, (1,2)),
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, (0,3)),
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
||||||
]);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## Big_map.find_opt(k: a', m: (a',b') big_map) : b' option
|
## Retrieving a Value in a Big Map
|
||||||
|
|
||||||
Retrieve the value associated with a particular key. This version returns an option
|
Retrieve the value associated with a particular key. This version
|
||||||
which can either shift logic in response to a missing value or throw an error.
|
returns an option which can either shift logic in response to a
|
||||||
|
missing value or throw an error.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
```pascaligo
|
```pascaligo group=big_map
|
||||||
const my_balance : option(move) =
|
const my_balance : option (move) =
|
||||||
moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)]
|
moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)]
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
```cameligo
|
The function is `Big_map.find_opt` whose type is `'key ->
|
||||||
|
('key,'value) big_map) -> 'value option`. Recall that the function
|
||||||
|
`Big_map.find_opt` must always be fully applied to its arguments. Here
|
||||||
|
is an example:
|
||||||
|
|
||||||
|
```cameligo group=big_map
|
||||||
let my_balance : move option =
|
let my_balance : move option =
|
||||||
Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) moves
|
Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) moves
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
```reasonligo
|
The function is `Big_map.find_opt` whose type is `('key, ('key,
|
||||||
let my_balance : option(move) =
|
'value) big_map) : 'value option`. Here is an example:
|
||||||
Big_map.find_opt("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, moves);
|
|
||||||
|
```reasonligo group=big_map
|
||||||
|
let my_balance : option (move) =
|
||||||
|
Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, moves);
|
||||||
```
|
```
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## Big_map.find(k: a', m: (a', b') big_map) : b'
|
## Updating a Binding in a Big Map
|
||||||
|
|
||||||
Forcefully retrieve the value associated with a particular key. If that value
|
Given a map, we may want to add a new binding, remove one, or modify
|
||||||
doesn't exist, this function throws an error.
|
one by changing the value associated to an already existing key. We
|
||||||
|
may even want to retain the key but not the associated value. All
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
those operations are called *updates*.
|
||||||
<!--Pascaligo-->
|
|
||||||
```pascaligo
|
|
||||||
const my_balance : move =
|
|
||||||
get_force (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), moves);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
|
|
||||||
```cameligo
|
|
||||||
let my_balance : move =
|
|
||||||
Big_map.find ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) moves
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
|
|
||||||
```reasonligo
|
|
||||||
let my_balance : move =
|
|
||||||
Big_map.find ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, moves);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
## Big_map.update(k: a', v: b', m: (a', b') big_map) : (a', b') big_map
|
|
||||||
|
|
||||||
Change the value associated with a particular key, if that value doesn't already
|
|
||||||
exist add it.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
@ -131,138 +131,123 @@ exist add it.
|
|||||||
The values of a PascaLIGO big map can be updated using the ordinary
|
The values of a PascaLIGO big map can be updated using the ordinary
|
||||||
assignment syntax:
|
assignment syntax:
|
||||||
|
|
||||||
```pascaligo
|
```pascaligo group=big_map
|
||||||
|
function add (var m : register) : register is
|
||||||
function set_ (var m : moveset) : moveset is
|
|
||||||
block {
|
block {
|
||||||
m [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9);
|
m [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9)
|
||||||
} with m
|
} with m
|
||||||
|
|
||||||
|
const updated_map : register = add (moves)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
See further for the removal of bindings.
|
||||||
|
|
||||||
<!--Cameligo-->
|
<!--Cameligo-->
|
||||||
|
|
||||||
```cameligo
|
In CameLIGO, you need the predefined function `Big_map.update` whose
|
||||||
let updated_map : moveset =
|
type is `'key -> 'value option -> ('key, 'value) big_map -> ('key,
|
||||||
Big_map.update ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) (Some (4,9)) moves
|
'value) big_map`. If the value (second argument) is `None`, then the
|
||||||
|
binding is to be removed. Recall that the function `Big_map.update`
|
||||||
|
must always be fully applied to its arguments. Here is an example:
|
||||||
|
|
||||||
|
```cameligo group=big_map
|
||||||
|
let updated_map : register =
|
||||||
|
Big_map.update
|
||||||
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (Some (4,9)) moves
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--Reasonligo-->
|
<!--Reasonligo-->
|
||||||
|
|
||||||
```reasonligo
|
In ReasonLIGO, you need the predefined function `Big_map.update` whose
|
||||||
let updated_map : moveset =
|
type is `('key, 'value option, ('key, 'value) big_map) : ('key,
|
||||||
Big_map.update(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), Some((4,9)), moves);
|
'value) big_map`. If the value (second componenat) is `None`, then the
|
||||||
|
binding is to be removed. Here is an example:
|
||||||
|
|
||||||
|
```reasonligo group=big_map
|
||||||
|
let updated_map : register =
|
||||||
|
Big_map.update
|
||||||
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), Some ((4,9)), moves);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## Big_map.add(k: a', v: b', m: (a', b') big_map) : (a', b') big_map
|
## Adding a Binding to a Big Map
|
||||||
|
|
||||||
Add a key and its associated value to the big map.
|
Add a key and its associated value to the big map.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
```pascaligo group=big_map
|
||||||
```pascaligo
|
function add (var m : register) : register is
|
||||||
function set_ (var n : int ; var m : foo) : foo is block {
|
block {
|
||||||
m[23] := n ;
|
m [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9)
|
||||||
} with m
|
} with m
|
||||||
|
|
||||||
|
const updated_map : register = add (moves)
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo
|
|
||||||
let add (n,m : int * foo) : foo = Big_map.add 23 n m
|
In CameLIGO, we use the predefined function `Big_map.add`, whose type
|
||||||
|
is `'key -> 'value -> ('key, 'value) big_map -> ('key, 'value)
|
||||||
|
big_map`. Recall that the function `Big_map.add` must always be fully
|
||||||
|
applied to its arguments. Here is an example:
|
||||||
|
|
||||||
|
```cameligo group=big_map
|
||||||
|
let add (m : register) : register =
|
||||||
|
Map.add
|
||||||
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (4,9) m
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo
|
|
||||||
let add = ((n,m): (int, foo)): foo => Big_map.add(23, n, m);
|
In ReasonLIGO, we use the predefined function `Big_map.add`, whose
|
||||||
|
type is `('key, 'value, ('key, 'value) big_map : ('key, 'value)
|
||||||
|
big_map`. Here is an example:
|
||||||
|
|
||||||
|
```reasonligo group=big_map
|
||||||
|
let add = (m : register) : register =>
|
||||||
|
Map.add
|
||||||
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (4,9), m);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## Big_map.remove(k: a', m: (a', b') big_map) : (a', b') big_map
|
## Removing a Binding from a Big Map
|
||||||
|
|
||||||
Remove a key and its associated value from the big map.
|
Remove a key and its associated value from the big map.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo
|
```pascaligo group=big_map
|
||||||
function rm (var m : foo) : foo is block {
|
function delete (const key : address; var moves : register) : register is
|
||||||
remove 42 from map m;
|
block {
|
||||||
} with m
|
remove key from map moves
|
||||||
```
|
} with moves
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
```cameligo
|
|
||||||
let rm (m : foo) : foo = Big_map.remove 42 m
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
```reasonligo
|
|
||||||
let rm = (m: foo): foo => Big_map.remove(42, m);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
## Big_map.literal(key_value_pair_list: (a', b') list) : (a', b') big_map
|
|
||||||
|
|
||||||
Constructs a big map from a list of key-value pair tuples.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
<!--Pascaligo-->
|
|
||||||
|
|
||||||
```pascaligo
|
|
||||||
const moves: moveset =
|
|
||||||
big_map
|
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address) -> (1,2);
|
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) -> (0,3);
|
|
||||||
end
|
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
```cameligo
|
In CameLIGO, we use the predefined function `Big_map.remove` whose
|
||||||
let moves: moveset =
|
type is `'key -> ('key, 'value) big_map -> ('key, 'value)
|
||||||
Big_map.literal [
|
big_map`. Note that, despite being curried, the calls to that function
|
||||||
(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address), (1,2));
|
must be complete. Here is an example:
|
||||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), (0,3));
|
|
||||||
]
|
```cameligo group=big_map
|
||||||
|
let delete (key, moves : address * register) : register =
|
||||||
|
Map.remove key moves
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
```reasonligo
|
In ReasonLIGO, we use the predefined function `Big_map.remove` whose
|
||||||
let moves: moveset =
|
type is `('key, ('key, 'value) big_map) : ('key, 'value)
|
||||||
Big_map.literal ([
|
big_map`. Here is an example:
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address, (1,2)),
|
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, (0,3)),
|
```reasonligo group=big_map
|
||||||
]);
|
let delete = ((key, moves) : (address, register)) : register =>
|
||||||
|
Map.remove (key, moves);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
|
||||||
## Big_map.empty() : (a', b') big_map
|
|
||||||
|
|
||||||
Create an empty big map.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
|
||||||
```pascaligo
|
|
||||||
const empty_big_map : big_map(int,int) = big_map end
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
```cameligo
|
|
||||||
let empty_map : foo = Big_map.empty
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
```reasonligo
|
|
||||||
let empty_map: foo = Big_map.empty;
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
|
@ -1,9 +1,182 @@
|
|||||||
---
|
---
|
||||||
id: list-reference
|
id: list-reference
|
||||||
title: List — Ordered collection of a type
|
title: List — Linear Collections
|
||||||
---
|
---
|
||||||
|
|
||||||
## List.size(lst: a' list) : nat
|
Lists are linear collections of elements of the same type. Linear
|
||||||
|
means that, in order to reach an element in a list, we must visit all
|
||||||
|
the elements before (sequential access). Elements can be repeated, as
|
||||||
|
only their order in the collection matters. The first element is
|
||||||
|
called the *head*, and the sub-list after the head is called the
|
||||||
|
*tail*. For those familiar with algorithmic data structure, you can
|
||||||
|
think of a list a *stack*, where the top is written on the left.
|
||||||
|
|
||||||
|
## Defining Lists
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
<!--PascaLIGO-->
|
||||||
|
```pascaligo group=lists
|
||||||
|
const empty_list : list (int) = nil // Or list []
|
||||||
|
const my_list : list (int) = list [1; 2; 2] // The head is 1
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--CameLIGO-->
|
||||||
|
```cameligo group=lists
|
||||||
|
let empty_list : int list = []
|
||||||
|
let my_list : int list = [1; 2; 2] // The head is 1
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
```reasonligo group=lists
|
||||||
|
let empty_list : list (int) = [];
|
||||||
|
let my_list : list (int) = [1, 2, 2]; // The head is 1
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
### Adding to Lists
|
||||||
|
|
||||||
|
Lists can be augmented by adding an element before the head (or, in
|
||||||
|
terms of stack, by *pushing an element on top*).
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
|
```pascaligo group=lists
|
||||||
|
const larger_list : list (int) = 5 # my_list // [5;1;2;2]
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--CameLIGO-->
|
||||||
|
|
||||||
|
```cameligo group=lists
|
||||||
|
let larger_list : int list = 5 :: my_list // [5;1;2;2]
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
|
```reasonligo group=lists
|
||||||
|
let larger_list : list (int) = [5, ...my_list]; // [5,1,2,2]
|
||||||
|
```
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
|
||||||
|
### Functional Iteration over Lists
|
||||||
|
|
||||||
|
A *functional iterator* is a function that traverses a data structure
|
||||||
|
and calls in turn a given function over the elements of that structure
|
||||||
|
to compute some value. Another approach is possible in PascaLIGO:
|
||||||
|
*loops* (see the relevant section).
|
||||||
|
|
||||||
|
There are three kinds of functional iterations over LIGO lists: the
|
||||||
|
*iterated operation*, the *map operation* (not to be confused with the
|
||||||
|
*map data structure*) and the *fold operation*.
|
||||||
|
|
||||||
|
#### Iterated Operation over Lists
|
||||||
|
|
||||||
|
The first, the *iterated operation*, is an iteration over the list
|
||||||
|
with a unit return value. It is useful to enforce certain invariants
|
||||||
|
on the element of a list, or fail.
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
|
```pascaligo group=lists
|
||||||
|
function iter_op (const l : list (int)) : unit is
|
||||||
|
block {
|
||||||
|
function iterated (const i : int) : unit is
|
||||||
|
if i > 2 then Unit else (failwith ("Below range.") : unit)
|
||||||
|
} with list_iter (iterated, l)
|
||||||
|
```
|
||||||
|
<!--CameLIGO-->
|
||||||
|
|
||||||
|
```cameligo group=lists
|
||||||
|
let iter_op (l : int list) : unit =
|
||||||
|
let predicate = fun (i : int) -> assert (i > 3)
|
||||||
|
in List.iter predicate l
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
|
```reasonligo group=lists
|
||||||
|
let iter_op = (l : list (int)) : unit => {
|
||||||
|
let predicate = (i : int) => assert (i > 3);
|
||||||
|
List.iter (predicate, l);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
#### Mapped Operation over Lists
|
||||||
|
|
||||||
|
We may want to change all the elements of a given list by applying to
|
||||||
|
them a function. This is called a *map operation*, not to be confused
|
||||||
|
with the map data structure.
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
|
```pascaligo group=lists
|
||||||
|
function increment (const i : int): int is i + 1
|
||||||
|
|
||||||
|
// Creates a new list with all elements incremented by 1
|
||||||
|
const plus_one : list (int) = list_map (increment, larger_list)
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--CameLIGO-->
|
||||||
|
|
||||||
|
```cameligo group=lists
|
||||||
|
let increment (i : int) : int = i + 1
|
||||||
|
|
||||||
|
// Creates a new list with all elements incremented by 1
|
||||||
|
let plus_one : int list = List.map increment larger_list
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
|
```reasonligo group=lists
|
||||||
|
let increment = (i : int) : int => i + 1;
|
||||||
|
|
||||||
|
// Creates a new list with all elements incremented by 1
|
||||||
|
let plus_one : list (int) = List.map (increment, larger_list);
|
||||||
|
```
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
#### Folded Operation over Lists
|
||||||
|
|
||||||
|
A *folded operation* is the most general of iterations. The folded
|
||||||
|
function takes two arguments: an *accumulator* and the structure
|
||||||
|
*element* at hand, with which it then produces a new accumulator. This
|
||||||
|
enables having a partial result that becomes complete when the
|
||||||
|
traversal of the data structure is over.
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
<!--PascaLIGO-->
|
||||||
|
|
||||||
|
```pascaligo group=lists
|
||||||
|
function sum (const acc : int; const i : int): int is acc + i
|
||||||
|
const sum_of_elements : int = list_fold (sum, my_list, 0)
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--CameLIGO-->
|
||||||
|
|
||||||
|
```cameligo group=lists
|
||||||
|
let sum (acc, i: int * int) : int = acc + i
|
||||||
|
let sum_of_elements : int = List.fold sum my_list 0
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
|
```reasonligo group=lists
|
||||||
|
let sum = ((result, i): (int, int)): int => result + i;
|
||||||
|
let sum_of_elements : int = List.fold (sum, my_list, 0);
|
||||||
|
```
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
## List Length
|
||||||
|
|
||||||
Get the number of elements in a list.
|
Get the number of elements in a list.
|
||||||
|
|
||||||
@ -11,29 +184,25 @@ Get the number of elements in a list.
|
|||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo
|
```pascaligo
|
||||||
function size_ (const m : list(int)) : nat is size(m)
|
function size_of (const l : list (int)) : nat is List.length (l)
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo
|
```cameligo
|
||||||
let size_ (s: int list) : nat = List.size s
|
let size_of (l : int list) : nat = List.length l
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo
|
```reasonligo
|
||||||
let size_ = (s: list(int)): nat => List.size(s);
|
let size_of = (l : list (int)) : nat => List.length (l);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## List.length(lst: a' list) : nat
|
|
||||||
|
|
||||||
Alias of `List.size`.
|
|
||||||
|
|
||||||
## List.map(map_function: a' -> b', lst: a' list) : 'b list
|
## List.map(map_function: a' -> b', lst: a' list) : 'b list
|
||||||
|
|
||||||
Apply an operation defined by `map_function` to each element of a list and return
|
Apply an operation defined by `map_function` to each element of a list
|
||||||
a list of the modified elements.
|
and return a list of the modified elements.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
|
@ -1,392 +1,274 @@
|
|||||||
---
|
---
|
||||||
id: map-reference
|
id: map-reference
|
||||||
title: Map — Hashmaps that it makes sense to iterate over
|
title: Map
|
||||||
---
|
---
|
||||||
|
|
||||||
## Defining A Map Type
|
## Defining A Map Type
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
```pascaligo
|
```pascaligo group=map
|
||||||
type move is int * int
|
type move is int * int
|
||||||
type moveset is map(address, move)
|
type register is map (address, move)
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo
|
```cameligo group=map
|
||||||
type move = int * int
|
type move = int * int
|
||||||
type moveset = (address, move) map
|
type register = (address, move) map
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo
|
```reasonligo group=map
|
||||||
type move = (int, int);
|
type move = (int, int);
|
||||||
type moveset = map(address, move);
|
type register = map (address, move);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## Creating A Map
|
## Creating an Empty Map
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
<!--Pascaligo-->
|
|
||||||
|
|
||||||
```pascaligo
|
|
||||||
const moves: moveset = map
|
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address) -> (1, 2);
|
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) -> (0, 3);
|
|
||||||
end
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
|
|
||||||
```cameligo
|
|
||||||
let moves: moveset = Map.literal
|
|
||||||
[ (("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address), (1, 2)) ;
|
|
||||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), (0, 3)) ;
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
|
|
||||||
```reasonligo
|
|
||||||
let moves : moveset =
|
|
||||||
Map.literal([
|
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address, (1, 2)),
|
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, (0, 3)),
|
|
||||||
]);
|
|
||||||
```
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
## Map.find_opt(k: a', m: (a',b') map) : b' option
|
|
||||||
|
|
||||||
Retrieve the value associated with a particular key. This version returns an option
|
|
||||||
which can either shift logic in response to a missing value or throw an error.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
<!--Pascaligo-->
|
|
||||||
```pascaligo
|
|
||||||
const my_balance : option(move) = moves[("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)];
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
|
|
||||||
```cameligo
|
|
||||||
let my_balance : move option = Map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) moves
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
|
|
||||||
```reasonligo
|
|
||||||
let my_balance : option(move) =
|
|
||||||
Map.find_opt("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, moves);
|
|
||||||
```
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
## Map.find(k: a', m: (a', b') map) : b'
|
|
||||||
|
|
||||||
Forcefully retrieve the value associated with a particular key. If that value
|
|
||||||
doesn't exist, this function throws an error.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
<!--Pascaligo-->
|
|
||||||
```pascaligo
|
|
||||||
const my_balance : move = get_force(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), moves);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
|
|
||||||
```cameligo
|
|
||||||
let my_balance : move = Map.find ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) moves
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
|
|
||||||
```reasonligo
|
|
||||||
let my_balance : move =
|
|
||||||
Map.find("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, moves);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
## Map.update(k: a', v: b', m: (a', b') map) : (a', b') map
|
|
||||||
|
|
||||||
Change the value associated with a particular key, if that value doesn't already
|
|
||||||
exist add it.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
<!--Pascaligo-->
|
|
||||||
|
|
||||||
The values of a PascaLIGO map can be updated using the ordinary assignment syntax:
|
|
||||||
|
|
||||||
```pascaligo
|
|
||||||
|
|
||||||
function set_ (var m: moveset) : moveset is
|
|
||||||
block {
|
|
||||||
m[("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9);
|
|
||||||
} with m
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--Cameligo-->
|
|
||||||
|
|
||||||
We can update a map in CameLIGO using the `Map.update` built-in:
|
|
||||||
|
|
||||||
```cameligo
|
|
||||||
|
|
||||||
let updated_map: moveset = Map.update ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) (Some (4,9)) moves
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--Reasonligo-->
|
|
||||||
|
|
||||||
We can update a map in ReasonLIGO using the `Map.update` built-in:
|
|
||||||
|
|
||||||
```reasonligo
|
|
||||||
|
|
||||||
let updated_map: moveset = Map.update(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), Some((4,9)), moves);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
## Map.add(k: a', v: b', m: (a', b') map) : (a', b') map
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
|
||||||
```pascaligo
|
|
||||||
function set_ (var n : int ; var m : map(int, int)) : map(int, int) is block {
|
|
||||||
m[23] := n ;
|
|
||||||
} with m
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
```cameligo
|
|
||||||
let add (n,m: int * (int, int) map) : foobar = Map.add 23 n m
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
```reasonligo
|
|
||||||
let add = (n: int, m: map(int, int)) : foobar => Map.add(23, n, m);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
## Map.remove(k: a', m: (a', b') map) : (a', b') map
|
|
||||||
|
|
||||||
Remove a key and its associated value from the map.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
|
||||||
```pascaligo
|
|
||||||
function rm (var m : map(int, int)) : map(int, int) is block {
|
|
||||||
remove 42 from map m
|
|
||||||
} with m
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
```cameligo
|
|
||||||
let rm (m: (int, int) map) : (int, int) map = Map.remove 42 m
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
```reasonligo
|
|
||||||
let rm = (m: map(int, int)): map(int, int) => Map.remove(42, m);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
## Map.iter(iterator_function: (a', b') -> unit, m: (a', b') map) : unit
|
|
||||||
|
|
||||||
Run a function returning unit over the contents of a map's key-value pairs.
|
|
||||||
For example an assertion.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
<!--Pascaligo-->
|
|
||||||
```pascaligo
|
|
||||||
function iter_op (const m : moveset) : unit is
|
|
||||||
block {
|
|
||||||
function aggregate (const i : address ; const j : move) : unit is block
|
|
||||||
{ if j.1 > 1 then skip else failwith("fail") } with unit
|
|
||||||
} with map_iter(aggregate, m);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
```cameligo
|
|
||||||
let iter_op (m : moveset) : unit =
|
|
||||||
let assert_eq = fun (i,j: address * move) -> assert (j.0 > 1)
|
|
||||||
in Map.iter assert_eq m
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
```reasonligo
|
|
||||||
let iter_op = (m: moveset): unit => {
|
|
||||||
let assert_eq = ((i,j): (address, move)) => assert (j[0] > 1);
|
|
||||||
Map.iter(assert_eq, m);
|
|
||||||
};
|
|
||||||
```
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
|
|
||||||
## Map.map(mapping_function: (a', b') -> b', m: (a', b') map) : (a', b') map
|
|
||||||
|
|
||||||
Update the values associated with every key in the map according to some update
|
|
||||||
rule `mapping_function`.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
<!--Pascaligo-->
|
|
||||||
```pascaligo
|
|
||||||
function map_op (const m : moveset) : moveset is
|
|
||||||
block {
|
|
||||||
function increment (const i : address ; const j : move) : move is (j.0, j.1 + 1);
|
|
||||||
} with map_map (increment, m);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
```cameligo
|
|
||||||
let map_op (m : moveset) : moveset =
|
|
||||||
let increment = fun (i,j: address * move) -> (j.0, j.1 + 1)
|
|
||||||
in Map.map increment m
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
```reasonligo
|
|
||||||
let map_op = (m: moveset): moveset => {
|
|
||||||
let increment = ((i,j): (address, move)) => (j[0], j[1] + 1);
|
|
||||||
Map.map(increment, m);
|
|
||||||
};
|
|
||||||
```
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
## Map.fold(folding_function: (b', (a', b')) -> b', m: (a', b') map, initial: b') : b'
|
|
||||||
|
|
||||||
Combine every value in the map together according to a fold rule `folding_function`.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
<!--Pascaligo-->
|
|
||||||
```pascaligo
|
|
||||||
function fold_op (const m : moveset) : int is
|
|
||||||
block {
|
|
||||||
function aggregate (const j : int; const cur : address * (int * int)) : int is j + cur.1.1
|
|
||||||
} with map_fold(aggregate, m, 5)
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--CameLIGO-->
|
|
||||||
```cameligo
|
|
||||||
let fold_op (m : moveset) : moveset =
|
|
||||||
let aggregate = fun (i,j: int * (address * (int * int))) -> i + j.1.1
|
|
||||||
in Map.fold aggregate m 5
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
```reasonligo
|
|
||||||
let fold_op = (m: moveset): moveset => {
|
|
||||||
let aggregate = ((i,j): (int, (address, (int,int)))) => i + j[1][1];
|
|
||||||
Map.fold(aggregate, m, 5);
|
|
||||||
};
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
|
|
||||||
## Map.mem(k: a', m: (a', b') map) : bool
|
|
||||||
|
|
||||||
Test whether a particular key `k` exists in a given map `m`.
|
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
|
||||||
```pascaligo
|
|
||||||
function mem (const k: int; const m: map(int, int)) : bool is map_mem(k, m)
|
|
||||||
```
|
|
||||||
<!--CameLIGO-->
|
|
||||||
```cameligo
|
|
||||||
let mem (k,m: int * (int, int) map) : bool = Map.mem k m
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
|
||||||
```reasonligo
|
|
||||||
let mem = ((k,m): (int, map(int,int))): bool => Map.mem(k, m);
|
|
||||||
```
|
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
|
||||||
|
|
||||||
## Map.empty() : (a', b') map
|
|
||||||
|
|
||||||
Create an empty map.
|
Create an empty map.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo
|
```pascaligo group=map
|
||||||
const empty_map : map(int, int) = map end
|
const empty : register = map []
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo
|
```cameligo group=map
|
||||||
let empty_map : (int, int) map = Map.empty
|
let empty : register = Map.empty
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo
|
```reasonligo group=map
|
||||||
let empty_map: map(int, int) = Map.empty;
|
let empty : register = Map.empty
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## Map.literal(key_value_pair_list: (a', b') list) : (a', b') map
|
## Populating A Map
|
||||||
|
|
||||||
Constructs a map from a list of key-value pair tuples.
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
<!--Pascaligo-->
|
||||||
|
|
||||||
|
```pascaligo group=map
|
||||||
|
const moves: register =
|
||||||
|
map [
|
||||||
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) -> (1,2);
|
||||||
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) -> (0,3)]
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--CameLIGO-->
|
||||||
|
|
||||||
|
```cameligo group=map
|
||||||
|
let moves: register =
|
||||||
|
Map.literal [
|
||||||
|
(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address), (1,2));
|
||||||
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))]
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
|
```reasonligo group=map
|
||||||
|
let moves: register =
|
||||||
|
Map.literal ([
|
||||||
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
|
||||||
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
## Retrieving a Value in a Map
|
||||||
|
|
||||||
|
Retrieve the value associated with a particular key. This version
|
||||||
|
returns an option which can either shift logic in response to a
|
||||||
|
missing value or throw an error.
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
<!--Pascaligo-->
|
||||||
|
```pascaligo group=map
|
||||||
|
const my_balance : option (move) =
|
||||||
|
moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)]
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--CameLIGO-->
|
||||||
|
|
||||||
|
The function is `Map.find_opt` whose type is `'key ->
|
||||||
|
('key,'value) map) -> 'value option`. Recall that the function
|
||||||
|
`Map.find_opt` must always be fully applied to its arguments. Here
|
||||||
|
is an example:
|
||||||
|
|
||||||
|
```cameligo group=map
|
||||||
|
let my_balance : move option =
|
||||||
|
Map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) moves
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
|
The function is `Map.find_opt` whose type is `('key, ('key,
|
||||||
|
'value) map) : 'value option`. Here is an example:
|
||||||
|
|
||||||
|
```reasonligo group=map
|
||||||
|
let my_balance : option (move) =
|
||||||
|
Map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, moves);
|
||||||
|
```
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
## Updating a Binding in a Map
|
||||||
|
|
||||||
|
Given a map, we may want to add a new binding, remove one, or modify
|
||||||
|
one by changing the value associated to an already existing key. We
|
||||||
|
may even want to retain the key but not the associated value. All
|
||||||
|
those operations are called *updates*.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--Pascaligo-->
|
<!--Pascaligo-->
|
||||||
|
|
||||||
```pascaligo
|
The values of a PascaLIGO map can be updated using the ordinary
|
||||||
const moves: moveset = map
|
assignment syntax:
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address) -> (1, 2);
|
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) -> (0, 3);
|
```pascaligo group=map
|
||||||
end
|
function add (var m : register) : register is
|
||||||
|
block {
|
||||||
|
m [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9)
|
||||||
|
} with m
|
||||||
|
|
||||||
|
const updated_map : register = add (moves)
|
||||||
|
```
|
||||||
|
|
||||||
|
See further for the removal of bindings.
|
||||||
|
|
||||||
|
<!--Cameligo-->
|
||||||
|
|
||||||
|
In CameLIGO, you need the predefined function `Map.update` whose
|
||||||
|
type is `'key -> 'value option -> ('key, 'value) map -> ('key,
|
||||||
|
'value) map`. If the value (second argument) is `None`, then the
|
||||||
|
binding is to be removed. Recall that the function `Map.update`
|
||||||
|
must always be fully applied to its arguments. Here is an example:
|
||||||
|
|
||||||
|
```cameligo group=map
|
||||||
|
let updated_map : register =
|
||||||
|
Map.update
|
||||||
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (Some (4,9)) moves
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--Reasonligo-->
|
||||||
|
|
||||||
|
In ReasonLIGO, you need the predefined function `Map.update` whose
|
||||||
|
type is `('key, 'value option, ('key, 'value) map) : ('key,
|
||||||
|
'value) map`. If the value (second componenat) is `None`, then the
|
||||||
|
binding is to be removed. Here is an example:
|
||||||
|
|
||||||
|
```reasonligo group=map
|
||||||
|
let updated_map : register =
|
||||||
|
Map.update
|
||||||
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), Some ((4,9)), moves);
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
## Adding a Binding to a Map
|
||||||
|
|
||||||
|
Add a key and its associated value to the map.
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
```pascaligo group=map
|
||||||
|
function add (var m : register) : register is
|
||||||
|
block {
|
||||||
|
m [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)] := (4,9)
|
||||||
|
} with m
|
||||||
|
|
||||||
|
const updated_map : register = add (moves)
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
|
|
||||||
```cameligo
|
In CameLIGO, we use the predefined function `Map.add`, whose type
|
||||||
let moves: moveset = Map.literal
|
is `'key -> 'value -> ('key, 'value) map -> ('key, 'value)
|
||||||
[ (("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address), (1, 2)) ;
|
map`. Recall that the function `Map.add` must always be fully
|
||||||
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), (0, 3)) ;
|
applied to its arguments. Here is an example:
|
||||||
]
|
|
||||||
|
```cameligo group=map
|
||||||
|
let add (m : register) : register =
|
||||||
|
Map.add
|
||||||
|
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (4,9) m
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
|
|
||||||
```reasonligo
|
In ReasonLIGO, we use the predefined function `Map.add`, whose
|
||||||
let moves : moveset =
|
type is `('key, 'value, ('key, 'value) map : ('key, 'value)
|
||||||
Map.literal([
|
map`. Here is an example:
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address, (1, 2)),
|
|
||||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, (0, 3)),
|
```reasonligo group=map
|
||||||
]);
|
let add = (m : register) : register =>
|
||||||
|
Map.add
|
||||||
|
(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (4,9), m);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
## Map.size(m: (a', b') map) : nat
|
## Removing a Binding from a Map
|
||||||
|
|
||||||
Get the size of a given map `m`.
|
Remove a key and its associated value from the map.
|
||||||
|
|
||||||
<!--DOCUSAURUS_CODE_TABS-->
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
<!--PascaLIGO-->
|
<!--PascaLIGO-->
|
||||||
```pascaligo
|
```pascaligo group=map
|
||||||
function size_ (const m : map(int, int)) : nat is
|
function delete (const key : address; var moves : register) : register is
|
||||||
block {skip} with (size(m))
|
block {
|
||||||
|
remove key from map moves
|
||||||
|
} with moves
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--CameLIGO-->
|
<!--CameLIGO-->
|
||||||
```cameligo
|
|
||||||
let size_ (m: (int, int) map) : nat = Map.size m
|
In CameLIGO, we use the predefined function `Map.remove` whose
|
||||||
|
type is `'key -> ('key, 'value) map -> ('key, 'value)
|
||||||
|
map`. Note that, despite being curried, the calls to that function
|
||||||
|
must be complete. Here is an example:
|
||||||
|
|
||||||
|
```cameligo group=map
|
||||||
|
let delete (key, moves : address * register) : register =
|
||||||
|
Map.remove key moves
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--ReasonLIGO-->
|
<!--ReasonLIGO-->
|
||||||
```reasonligo
|
|
||||||
let size_ = (m: map(int, int)): nat => Map.size(m);
|
In ReasonLIGO, we use the predefined function `Map.remove` whose
|
||||||
|
type is `('key, ('key, 'value) map) : ('key, 'value)
|
||||||
|
map`. Here is an example:
|
||||||
|
|
||||||
|
```reasonligo group=map
|
||||||
|
let delete = ((key, moves) : (address, register)) : register =>
|
||||||
|
Map.remove (key, moves);
|
||||||
|
```
|
||||||
|
|
||||||
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
## Getting the Size of a Map
|
||||||
|
|
||||||
|
The size of a map is its number of bindings.
|
||||||
|
|
||||||
|
<!--DOCUSAURUS_CODE_TABS-->
|
||||||
|
|
||||||
|
<!--PascaLIGO-->
|
||||||
|
```pascaligo group=map
|
||||||
|
function size_of (const m : register) : nat is size (m)
|
||||||
|
```
|
||||||
|
<!--CameLIGO-->
|
||||||
|
```cameligo group=map
|
||||||
|
let size_of (m : register) : nat = Map.size m
|
||||||
|
```
|
||||||
|
<!--ReasonLIGO-->
|
||||||
|
```reasonligo group=map
|
||||||
|
let size_of = (m : register): nat => Map.size (m);
|
||||||
```
|
```
|
||||||
|
|
||||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
type action is
|
|
||||||
| Increment of int
|
|
||||||
| Decrement of int
|
|
||||||
|
|
||||||
function main (const p : action ; const s : int) : (list(operation) * int) is
|
|
||||||
block {skip} with ((nil : list(operation)),
|
|
||||||
case p of
|
|
||||||
| Increment n -> s + n
|
|
||||||
| Decrement n -> s - n
|
|
||||||
end)
|
|
@ -1,10 +0,0 @@
|
|||||||
function multiply (const a : int ; const b : int) : int is
|
|
||||||
begin
|
|
||||||
const result : int = a * b ;
|
|
||||||
end with result
|
|
||||||
|
|
||||||
function add (const a : int ; const b : int) : int is
|
|
||||||
block { skip } with a + b
|
|
||||||
|
|
||||||
function main (const p : unit ; const s : unit) : (list(operation) * unit) is
|
|
||||||
block {skip} with ((nil : list(operation)), s)
|
|
@ -1,16 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
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)
|
|
@ -1,5 +0,0 @@
|
|||||||
const four : int = 4;
|
|
||||||
const name : string = "John Doe";
|
|
||||||
|
|
||||||
function main (const p : unit ; const s : unit) : (list(operation) * unit) is
|
|
||||||
block {skip} with ((nil : list(operation)), s)
|
|
@ -20,3 +20,4 @@ $HOME/git/ligo/vendors/ligo-utils/simple-utils/region.ml
|
|||||||
../shared/LexerUnit.ml
|
../shared/LexerUnit.ml
|
||||||
../shared/ParserUnit.ml
|
../shared/ParserUnit.ml
|
||||||
Stubs/Simple_utils.ml
|
Stubs/Simple_utils.ml
|
||||||
|
$HOME/git/ligo/_build/default/src/passes/1-parser/cameligo/ParErr.ml
|
@ -266,7 +266,6 @@ let keywords = [
|
|||||||
let reserved =
|
let reserved =
|
||||||
let open SSet in
|
let open SSet in
|
||||||
empty
|
empty
|
||||||
|> add "and"
|
|
||||||
|> add "as"
|
|> add "as"
|
||||||
|> add "asr"
|
|> add "asr"
|
||||||
|> add "class"
|
|> add "class"
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
(* Driver for the CameLIGO lexer *)
|
(* Driver for the CameLIGO lexer *)
|
||||||
|
|
||||||
|
module Region = Simple_utils.Region
|
||||||
|
|
||||||
module IO =
|
module IO =
|
||||||
struct
|
struct
|
||||||
let ext = ".mligo"
|
let ext = ".mligo"
|
||||||
|
@ -593,10 +593,14 @@ core_expr:
|
|||||||
| par(expr ":" type_expr {$1,$2,$3}) { EAnnot $1 }
|
| par(expr ":" type_expr {$1,$2,$3}) { EAnnot $1 }
|
||||||
|
|
||||||
module_field:
|
module_field:
|
||||||
module_name "." field_name {
|
module_name "." module_fun {
|
||||||
let region = cover $1.region $3.region in
|
let region = cover $1.region $3.region in
|
||||||
{region; value = $1.value ^ "." ^ $3.value} }
|
{region; value = $1.value ^ "." ^ $3.value} }
|
||||||
|
|
||||||
|
module_fun:
|
||||||
|
field_name { $1 }
|
||||||
|
| "or" { {value="or"; region=$1} }
|
||||||
|
|
||||||
projection:
|
projection:
|
||||||
struct_name "." nsepseq(selection,".") {
|
struct_name "." nsepseq(selection,".") {
|
||||||
let start = $1.region in
|
let start = $1.region in
|
||||||
|
@ -24,3 +24,4 @@ $HOME/git/ligo/vendors/ligo-utils/simple-utils/region.ml
|
|||||||
../shared/Memo.mli
|
../shared/Memo.mli
|
||||||
../shared/Memo.ml
|
../shared/Memo.ml
|
||||||
Stubs/Simple_utils.ml
|
Stubs/Simple_utils.ml
|
||||||
|
$HOME/git/ligo/_build/default/src/passes/1-parser/pascaligo/ParErr.ml
|
@ -98,11 +98,12 @@ sepseq(X,Sep):
|
|||||||
|
|
||||||
(* Inlines *)
|
(* Inlines *)
|
||||||
|
|
||||||
%inline var : "<ident>" { $1 }
|
%inline var : "<ident>" { $1 }
|
||||||
%inline type_name : "<ident>" { $1 }
|
%inline type_name : "<ident>" { $1 }
|
||||||
%inline fun_name : "<ident>" { $1 }
|
%inline fun_name : "<ident>" { $1 }
|
||||||
%inline field_name : "<ident>" { $1 }
|
%inline field_name : "<ident>" { $1 }
|
||||||
%inline struct_name : "<ident>" { $1 }
|
%inline struct_name : "<ident>" { $1 }
|
||||||
|
%inline module_name : "<constr>" { $1 }
|
||||||
|
|
||||||
(* Main *)
|
(* Main *)
|
||||||
|
|
||||||
@ -829,7 +830,7 @@ core_expr:
|
|||||||
"<int>" { EArith (Int $1) }
|
"<int>" { EArith (Int $1) }
|
||||||
| "<nat>" { EArith (Nat $1) }
|
| "<nat>" { EArith (Nat $1) }
|
||||||
| "<mutez>" { EArith (Mutez $1) }
|
| "<mutez>" { EArith (Mutez $1) }
|
||||||
| var { EVar $1 }
|
| "<ident>" | module_field { EVar $1 }
|
||||||
| "<string>" { EString (String $1) }
|
| "<string>" { EString (String $1) }
|
||||||
| "<bytes>" { EBytes $1 }
|
| "<bytes>" { EBytes $1 }
|
||||||
| "False" { ELogic (BoolExpr (False $1)) }
|
| "False" { ELogic (BoolExpr (False $1)) }
|
||||||
@ -902,13 +903,32 @@ path:
|
|||||||
var { Name $1 }
|
var { Name $1 }
|
||||||
| projection { Path $1 }
|
| projection { Path $1 }
|
||||||
|
|
||||||
|
module_field:
|
||||||
|
module_name "." module_fun {
|
||||||
|
let region = cover $1.region $3.region in
|
||||||
|
{region; value = $1.value ^ "." ^ $3.value} }
|
||||||
|
|
||||||
|
module_fun:
|
||||||
|
field_name { $1 }
|
||||||
|
| "map" { {value="map"; region=$1} }
|
||||||
|
| "or" { {value="or"; region=$1} }
|
||||||
|
| "and" { {value="and"; region=$1} }
|
||||||
|
| "remove" { {value="remove"; region=$1} }
|
||||||
|
|
||||||
projection:
|
projection:
|
||||||
struct_name "." nsepseq(selection,".") {
|
struct_name "." nsepseq(selection,".") {
|
||||||
let stop = nsepseq_to_region selection_to_region $3 in
|
let stop = nsepseq_to_region selection_to_region $3 in
|
||||||
let region = cover $1.region stop
|
let region = cover $1.region stop
|
||||||
and value = {struct_name = $1;
|
and value = {struct_name=$1; selector=$2; field_path=$3}
|
||||||
selector = $2;
|
in {region; value}
|
||||||
field_path = $3}
|
}
|
||||||
|
| module_name "." field_name "." nsepseq(selection,".") {
|
||||||
|
let value = $1.value ^ "." ^ $3.value in
|
||||||
|
let struct_name = {$1 with value} in
|
||||||
|
let start = $1.region in
|
||||||
|
let stop = nsepseq_to_region selection_to_region $5 in
|
||||||
|
let region = cover start stop in
|
||||||
|
let value = {struct_name; selector=$4; field_path=$5}
|
||||||
in {region; value} }
|
in {region; value} }
|
||||||
|
|
||||||
selection:
|
selection:
|
||||||
@ -939,31 +959,26 @@ record_expr:
|
|||||||
update_record:
|
update_record:
|
||||||
path "with" ne_injection("record",field_path_assignment){
|
path "with" ne_injection("record",field_path_assignment){
|
||||||
let region = cover (path_to_region $1) $3.region in
|
let region = cover (path_to_region $1) $3.region in
|
||||||
let value = {
|
let value = {record=$1; kwd_with=$2; updates=$3}
|
||||||
record = $1;
|
|
||||||
kwd_with = $2;
|
|
||||||
updates = $3}
|
|
||||||
in {region; value} }
|
in {region; value} }
|
||||||
|
|
||||||
|
|
||||||
field_assignment:
|
field_assignment:
|
||||||
field_name "=" expr {
|
field_name "=" expr {
|
||||||
let region = cover $1.region (expr_to_region $3)
|
let region = cover $1.region (expr_to_region $3)
|
||||||
and value = {field_name = $1;
|
and value = {field_name=$1; equal=$2; field_expr=$3}
|
||||||
equal = $2;
|
|
||||||
field_expr = $3}
|
|
||||||
in {region; value} }
|
in {region; value} }
|
||||||
|
|
||||||
field_path_assignment:
|
field_path_assignment:
|
||||||
nsepseq(field_name,".") "=" expr {
|
nsepseq(field_name,".") "=" expr {
|
||||||
let region = cover (nsepseq_to_region (fun x -> x.region) $1) (expr_to_region $3)
|
let start = nsepseq_to_region (fun x -> x.region) $1
|
||||||
and value = {field_path = $1;
|
and stop = expr_to_region $3 in
|
||||||
equal = $2;
|
let region = cover start stop
|
||||||
field_expr = $3}
|
and value = {field_path=$1; equal=$2; field_expr=$3}
|
||||||
in {region; value} }
|
in {region; value} }
|
||||||
|
|
||||||
fun_call:
|
fun_call:
|
||||||
fun_name arguments {
|
fun_name arguments
|
||||||
|
| module_field arguments {
|
||||||
let region = cover $1.region $2.region
|
let region = cover $1.region $2.region
|
||||||
in {region; value = (EVar $1),$2} }
|
in {region; value = (EVar $1),$2} }
|
||||||
|
|
||||||
|
@ -25,4 +25,5 @@ Stubs/Parser_cameligo.ml
|
|||||||
../cameligo/ParserLog.mli
|
../cameligo/ParserLog.mli
|
||||||
../cameligo/ParserLog.ml
|
../cameligo/ParserLog.ml
|
||||||
../cameligo/Scoping.mli
|
../cameligo/Scoping.mli
|
||||||
../cameligo/Scoping.ml
|
../cameligo/Scoping.ml
|
||||||
|
$HOME/git/ligo/_build/default/src/passes/1-parser/reasonligo/ParErr.ml
|
@ -238,12 +238,9 @@ let keywords = [
|
|||||||
(fun reg -> True reg);
|
(fun reg -> True reg);
|
||||||
(fun reg -> Type reg)]
|
(fun reg -> Type reg)]
|
||||||
|
|
||||||
(* See: http://caml.inria.fr/pub/docs/manual-ocaml/lex.html#sec86 and
|
|
||||||
https://github.com/facebook/reason/blob/master/src/reason-parser/reason_parser.mly *)
|
|
||||||
let reserved =
|
let reserved =
|
||||||
let open SSet in
|
let open SSet in
|
||||||
empty
|
empty
|
||||||
|> add "and"
|
|
||||||
|> add "as"
|
|> add "as"
|
||||||
|> add "asr"
|
|> add "asr"
|
||||||
|> add "begin"
|
|> add "begin"
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
(* Driver for the ReasonLIGO lexer *)
|
(* Driver for the ReasonLIGO lexer *)
|
||||||
|
|
||||||
|
module Region = Simple_utils.Region
|
||||||
|
|
||||||
module IO =
|
module IO =
|
||||||
struct
|
struct
|
||||||
let ext = ".religo"
|
let ext = ".religo"
|
||||||
|
@ -24,22 +24,22 @@ type 'a sequence_or_record =
|
|||||||
|
|
||||||
let (<@) f g x = f (g x)
|
let (<@) f g x = f (g x)
|
||||||
|
|
||||||
(**
|
(**
|
||||||
Covert nsepseq to a chain of TFun's.
|
Covert nsepseq to a chain of TFun's.
|
||||||
|
|
||||||
Necessary to handle cases like:
|
Necessary to handle cases like:
|
||||||
`type foo = (int, int) => int;`
|
`type foo = (int, int) => int;`
|
||||||
*)
|
*)
|
||||||
let rec nsepseq_to_curry hd rest =
|
let rec nsepseq_to_curry hd rest =
|
||||||
match hd, rest with
|
match hd, rest with
|
||||||
| hd, (sep, item) :: rest ->
|
| hd, (sep, item) :: rest ->
|
||||||
let start = type_expr_to_region hd in
|
let start = type_expr_to_region hd in
|
||||||
let stop = nsepseq_to_region type_expr_to_region (hd, rest) in
|
let stop = nsepseq_to_region type_expr_to_region (hd, rest) in
|
||||||
let region = cover start stop in
|
let region = cover start stop in
|
||||||
TFun {
|
TFun {
|
||||||
value = hd, sep, (nsepseq_to_curry item rest);
|
value = hd, sep, (nsepseq_to_curry item rest);
|
||||||
region
|
region
|
||||||
}
|
}
|
||||||
| hd, [] -> hd
|
| hd, [] -> hd
|
||||||
|
|
||||||
(* END HEADER *)
|
(* END HEADER *)
|
||||||
@ -178,34 +178,34 @@ type_expr:
|
|||||||
cartesian | sum_type | record_type { $1 }
|
cartesian | sum_type | record_type { $1 }
|
||||||
|
|
||||||
type_expr_func:
|
type_expr_func:
|
||||||
"=>" cartesian {
|
"=>" cartesian {
|
||||||
$1, $2
|
$1, $2
|
||||||
}
|
}
|
||||||
|
|
||||||
cartesian:
|
cartesian:
|
||||||
core_type { $1 }
|
core_type { $1 }
|
||||||
| type_name type_expr_func {
|
| type_name type_expr_func {
|
||||||
let (arrow, c) = $2 in
|
let (arrow, c) = $2 in
|
||||||
let value = TVar $1, arrow, c in
|
let value = TVar $1, arrow, c in
|
||||||
let region = cover $1.region (type_expr_to_region c) in
|
let region = cover $1.region (type_expr_to_region c) in
|
||||||
TFun { region; value }
|
TFun { region; value }
|
||||||
}
|
}
|
||||||
| "(" cartesian ")" type_expr_func {
|
| "(" cartesian ")" type_expr_func {
|
||||||
let (arrow, c) = $4 in
|
let (arrow, c) = $4 in
|
||||||
let value = $2, arrow, c in
|
let value = $2, arrow, c in
|
||||||
let region = cover $1 (type_expr_to_region c) in
|
let region = cover $1 (type_expr_to_region c) in
|
||||||
TFun { region; value }
|
TFun { region; value }
|
||||||
}
|
}
|
||||||
| "(" cartesian "," nsepseq(cartesian,",") ")" type_expr_func? {
|
| "(" cartesian "," nsepseq(cartesian,",") ")" type_expr_func? {
|
||||||
match $6 with
|
match $6 with
|
||||||
| Some (arrow, c) ->
|
| Some (arrow, c) ->
|
||||||
let (hd, rest) = Utils.nsepseq_cons $2 $3 $4 in
|
let (hd, rest) = Utils.nsepseq_cons $2 $3 $4 in
|
||||||
let rest = rest @ [(arrow, c)] in
|
let rest = rest @ [(arrow, c)] in
|
||||||
nsepseq_to_curry hd rest
|
nsepseq_to_curry hd rest
|
||||||
| None ->
|
| None ->
|
||||||
let value = Utils.nsepseq_cons $2 $3 $4 in
|
let value = Utils.nsepseq_cons $2 $3 $4 in
|
||||||
let region = cover $1 $5 in
|
let region = cover $1 $5 in
|
||||||
TProd {region; value}
|
TProd {region; value}
|
||||||
}
|
}
|
||||||
|
|
||||||
core_type:
|
core_type:
|
||||||
@ -515,30 +515,30 @@ fun_expr:
|
|||||||
_
|
_
|
||||||
}; _ }; region} ->
|
}; _ }; region} ->
|
||||||
|
|
||||||
let expr_to_type = function
|
let expr_to_type = function
|
||||||
| EVar v -> TVar v
|
| EVar v -> TVar v
|
||||||
| e -> let open! SyntaxError
|
| e -> let open! SyntaxError
|
||||||
in raise (Error (WrongFunctionArguments e))
|
in raise (Error (WrongFunctionArguments e))
|
||||||
in
|
in
|
||||||
let type_expr = (
|
let type_expr = (
|
||||||
match type_expr with
|
match type_expr with
|
||||||
| TProd {value; _} ->
|
| TProd {value; _} ->
|
||||||
let (hd, rest) = value in
|
let (hd, rest) = value in
|
||||||
let rest = rest @ [(arrow, expr_to_type body)] in
|
let rest = rest @ [(arrow, expr_to_type body)] in
|
||||||
nsepseq_to_curry hd rest
|
nsepseq_to_curry hd rest
|
||||||
| e ->
|
| e ->
|
||||||
TFun {
|
TFun {
|
||||||
value = e, arrow, expr_to_type body;
|
value = e, arrow, expr_to_type body;
|
||||||
region = fun_region
|
region = fun_region
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
in
|
in
|
||||||
PTyped {
|
PTyped {
|
||||||
value = {
|
value = {
|
||||||
pattern;
|
pattern;
|
||||||
colon;
|
colon;
|
||||||
type_expr
|
type_expr
|
||||||
};
|
};
|
||||||
region;
|
region;
|
||||||
}, []
|
}, []
|
||||||
| EPar {value = {inside = fun_arg; _ }; _} ->
|
| EPar {value = {inside = fun_arg; _ }; _} ->
|
||||||
@ -552,7 +552,7 @@ fun_expr:
|
|||||||
arg_to_pattern (fst fun_args), bindings
|
arg_to_pattern (fst fun_args), bindings
|
||||||
| EUnit _ as e ->
|
| EUnit _ as e ->
|
||||||
arg_to_pattern e, []
|
arg_to_pattern e, []
|
||||||
| EVar _ as e ->
|
| EVar _ as e ->
|
||||||
arg_to_pattern e, []
|
arg_to_pattern e, []
|
||||||
| e -> let open! SyntaxError
|
| e -> let open! SyntaxError
|
||||||
in raise (Error (WrongFunctionArguments e))
|
in raise (Error (WrongFunctionArguments e))
|
||||||
@ -834,10 +834,13 @@ core_expr:
|
|||||||
| par(expr) { EPar $1 }
|
| par(expr) { EPar $1 }
|
||||||
|
|
||||||
module_field:
|
module_field:
|
||||||
module_name "." field_name {
|
module_name "." module_fun {
|
||||||
let region = cover $1.region $3.region
|
let region = cover $1.region $3.region in
|
||||||
and value = $1.value ^ "." ^ $3.value
|
{region; value = $1.value ^ "." ^ $3.value} }
|
||||||
in {region; value} }
|
|
||||||
|
module_fun:
|
||||||
|
field_name { $1 }
|
||||||
|
| "or" { {value="or"; region=$1} }
|
||||||
|
|
||||||
selection:
|
selection:
|
||||||
"[" "<int>" "]" selection {
|
"[" "<int>" "]" selection {
|
||||||
|
@ -35,8 +35,8 @@ module Simplify = struct
|
|||||||
let unit_expr = make_t @@ T_constant TC_unit
|
let unit_expr = make_t @@ T_constant TC_unit
|
||||||
|
|
||||||
let type_constants s =
|
let type_constants s =
|
||||||
match s with
|
match s with
|
||||||
| "chain_id" -> ok TC_chain_id
|
"chain_id" -> ok TC_chain_id
|
||||||
| "unit" -> ok TC_unit
|
| "unit" -> ok TC_unit
|
||||||
| "string" -> ok TC_string
|
| "string" -> ok TC_string
|
||||||
| "bytes" -> ok TC_bytes
|
| "bytes" -> ok TC_bytes
|
||||||
@ -50,95 +50,196 @@ module Simplify = struct
|
|||||||
| "key_hash" -> ok TC_key_hash
|
| "key_hash" -> ok TC_key_hash
|
||||||
| "signature" -> ok TC_signature
|
| "signature" -> ok TC_signature
|
||||||
| "timestamp" -> ok TC_timestamp
|
| "timestamp" -> ok TC_timestamp
|
||||||
| _ -> simple_fail @@ "Not a type_constant " ^ s
|
| _ -> simple_fail @@ "Not a built-in type (" ^ s ^ ")."
|
||||||
|
|
||||||
let type_operators s =
|
let type_operators s =
|
||||||
match s with
|
match s with
|
||||||
| "list" -> ok @@ TC_list unit_expr
|
"list" -> ok @@ TC_list unit_expr
|
||||||
| "option" -> ok @@ TC_option unit_expr
|
| "option" -> ok @@ TC_option unit_expr
|
||||||
| "set" -> ok @@ TC_set unit_expr
|
| "set" -> ok @@ TC_set unit_expr
|
||||||
| "map" -> ok @@ TC_map (unit_expr,unit_expr)
|
| "map" -> ok @@ TC_map (unit_expr,unit_expr)
|
||||||
| "big_map" -> ok @@ TC_big_map (unit_expr,unit_expr)
|
| "big_map" -> ok @@ TC_big_map (unit_expr,unit_expr)
|
||||||
| "contract" -> ok @@ TC_contract unit_expr
|
| "contract" -> ok @@ TC_contract unit_expr
|
||||||
| _ -> simple_fail @@ "Not a typ_operator " ^ s
|
| _ -> simple_fail @@ "Not a built-in type (" ^ s ^ ")."
|
||||||
|
|
||||||
|
|
||||||
module Pascaligo = struct
|
module Pascaligo = struct
|
||||||
|
|
||||||
let constants = function
|
let constants = function
|
||||||
| "assert" -> ok C_ASSERTION
|
(* Tezos module (ex-Michelson) *)
|
||||||
| "get_chain_id" -> ok C_CHAIN_ID
|
|
||||||
| "transaction" -> ok C_CALL
|
| "Tezos.chain_id" -> ok C_CHAIN_ID
|
||||||
| "get_contract" -> ok C_CONTRACT
|
| "chain_id" -> ok C_CHAIN_ID (* Deprecated *)
|
||||||
| "get_contract_opt"-> ok C_CONTRACT_OPT
|
| "get_chain_id" -> ok C_CHAIN_ID (* Deprecated *)
|
||||||
| "get_entrypoint" -> ok C_CONTRACT_ENTRYPOINT
|
| "Tezos.balance" -> ok C_BALANCE
|
||||||
| "get_entrypoint_opt" -> ok C_CONTRACT_ENTRYPOINT_OPT
|
| "balance" -> ok C_BALANCE (* Deprecated *)
|
||||||
| "size" -> ok C_SIZE
|
| "Tezos.now" -> ok C_NOW
|
||||||
| "int" -> ok C_INT
|
| "now" -> ok C_NOW (* Deprecated *)
|
||||||
| "abs" -> ok C_ABS
|
| "Tezos.amount" -> ok C_AMOUNT
|
||||||
| "is_nat" -> ok C_IS_NAT
|
| "amount" -> ok C_AMOUNT (* Deprecated *)
|
||||||
| "amount" -> ok C_AMOUNT
|
| "Tezos.sender" -> ok C_SENDER
|
||||||
| "balance" -> ok C_BALANCE
|
| "sender" -> ok C_SENDER (* Deprecated *)
|
||||||
| "now" -> ok C_NOW
|
| "Tezos.address" -> ok C_ADDRESS
|
||||||
| "unit" -> ok C_UNIT
|
| "address" -> ok C_ADDRESS (* Deprecated *)
|
||||||
| "source" -> ok C_SOURCE
|
| "Tezos.self_address" -> ok C_SELF_ADDRESS
|
||||||
| "sender" -> ok C_SENDER
|
| "self_address" -> ok C_SELF_ADDRESS (* Deprecated *)
|
||||||
| "failwith" -> ok C_FAILWITH
|
| "Tezos.implicit_account" -> ok C_IMPLICIT_ACCOUNT
|
||||||
| "bitwise_or" -> ok C_OR
|
| "implicit_account" -> ok C_IMPLICIT_ACCOUNT (* Deprecated *)
|
||||||
| "bitwise_and" -> ok C_AND
|
| "Tezos.source" -> ok C_SOURCE
|
||||||
| "bitwise_xor" -> ok C_XOR
|
| "source" -> ok C_SOURCE (* Deprecated *)
|
||||||
| "bitwise_lsl" -> ok C_LSL
|
| "Tezos.failwith" -> ok C_FAILWITH
|
||||||
| "bitwise_lsr" -> ok C_LSR
|
| "failwith" -> ok C_FAILWITH
|
||||||
| "string_concat" -> ok C_CONCAT
|
|
||||||
| "string_slice" -> ok C_SLICE
|
| "Tezos.transaction" -> ok C_CALL
|
||||||
| "crypto_check" -> ok C_CHECK_SIGNATURE
|
| "transaction" -> ok C_CALL (* Deprecated *)
|
||||||
| "crypto_hash_key" -> ok C_HASH_KEY
|
| "Tezos.set_delegate" -> ok C_SET_DELEGATE
|
||||||
| "bytes_concat" -> ok C_CONCAT
|
| "set_delegate" -> ok C_SET_DELEGATE (* Deprecated *)
|
||||||
| "bytes_slice" -> ok C_SLICE
|
| "get_contract" -> ok C_CONTRACT (* Deprecated *)
|
||||||
| "bytes_pack" -> ok C_BYTES_PACK
|
| "Tezos.get_contract_opt" -> ok C_CONTRACT_OPT
|
||||||
| "bytes_unpack" -> ok C_BYTES_UNPACK
|
| "get_contract_opt" -> ok C_CONTRACT_OPT (* Deprecated *)
|
||||||
| "set_empty" -> ok C_SET_EMPTY
|
| "get_entrypoint" -> ok C_CONTRACT_ENTRYPOINT (* Deprecated *)
|
||||||
| "set_mem" -> ok C_SET_MEM
|
| "Tezos.get_entrypoint_opt" -> ok C_CONTRACT_ENTRYPOINT_OPT
|
||||||
| "set_add" -> ok C_SET_ADD
|
| "get_entrypoint_opt" -> ok C_CONTRACT_ENTRYPOINT_OPT (* Deprecated *)
|
||||||
| "set_remove" -> ok C_SET_REMOVE
|
|
||||||
| "set_iter" -> ok C_SET_ITER
|
| "Michelson.is_nat" -> ok C_IS_NAT (* Deprecated *)
|
||||||
| "set_fold" -> ok C_SET_FOLD
|
| "is_nat" -> ok C_IS_NAT
|
||||||
| "list_iter" -> ok C_LIST_ITER
|
| "int" -> ok C_INT
|
||||||
| "list_fold" -> ok C_LIST_FOLD
|
| "abs" -> ok C_ABS
|
||||||
| "list_map" -> ok C_LIST_MAP
|
| "unit" -> ok C_UNIT
|
||||||
| "get_force" -> ok C_MAP_FIND
|
|
||||||
| "map_iter" -> ok C_MAP_ITER
|
| "NEG" -> ok C_NEG
|
||||||
| "map_map" -> ok C_MAP_MAP
|
| "ADD" -> ok C_ADD
|
||||||
| "map_fold" -> ok C_MAP_FOLD
|
| "SUB" -> ok C_SUB
|
||||||
| "map_remove" -> ok C_MAP_REMOVE
|
| "TIMES" -> ok C_MUL
|
||||||
| "map_update" -> ok C_MAP_UPDATE
|
| "DIV" -> ok C_DIV
|
||||||
| "map_get" -> ok C_MAP_FIND_OPT
|
| "MOD" -> ok C_MOD
|
||||||
| "map_mem" -> ok C_MAP_MEM
|
| "EQ" -> ok C_EQ
|
||||||
| "sha_256" -> ok C_SHA256
|
| "NOT" -> ok C_NOT
|
||||||
| "sha_512" -> ok C_SHA512
|
| "AND" -> ok C_AND
|
||||||
| "blake2b" -> ok C_BLAKE2b
|
| "OR" -> ok C_OR
|
||||||
| "cons" -> ok C_CONS
|
| "GT" -> ok C_GT
|
||||||
| "EQ" -> ok C_EQ
|
| "GE" -> ok C_GE
|
||||||
| "NEQ" -> ok C_NEQ
|
| "LT" -> ok C_LT
|
||||||
| "NEG" -> ok C_NEG
|
| "LE" -> ok C_LE
|
||||||
| "ADD" -> ok C_ADD
|
| "CONS" -> ok C_CONS
|
||||||
| "SUB" -> ok C_SUB
|
| "cons" -> ok C_CONS (* Deprecated *)
|
||||||
| "TIMES" -> ok C_MUL
|
| "NEQ" -> ok C_NEQ
|
||||||
| "DIV" -> ok C_DIV
|
|
||||||
| "MOD" -> ok C_MOD
|
(* Crypto module *)
|
||||||
| "NOT" -> ok C_NOT
|
|
||||||
| "AND" -> ok C_AND
|
| "Crypto.check" -> ok C_CHECK_SIGNATURE
|
||||||
| "OR" -> ok C_OR
|
| "crypto_check" -> ok C_CHECK_SIGNATURE (* Deprecated *)
|
||||||
| "GT" -> ok C_GT
|
| "Crypto.hash_key" -> ok C_HASH_KEY
|
||||||
| "GE" -> ok C_GE
|
| "crypto_hash_key" -> ok C_HASH_KEY (* Deprecated *)
|
||||||
| "LT" -> ok C_LT
|
| "Crypto.blake2b" -> ok C_BLAKE2b
|
||||||
| "LE" -> ok C_LE
|
| "blake2b" -> ok C_BLAKE2b (* Deprecated *)
|
||||||
| "CONS" -> ok C_CONS
|
| "Crypto.sha256" -> ok C_SHA256
|
||||||
| "address" -> ok C_ADDRESS
|
| "sha_256" -> ok C_SHA256 (* Deprecated *)
|
||||||
| "self_address" -> ok C_SELF_ADDRESS
|
| "Crypto.sha512" -> ok C_SHA512
|
||||||
| "implicit_account"-> ok C_IMPLICIT_ACCOUNT
|
| "sha_512" -> ok C_SHA512 (* Deprecated *)
|
||||||
| "set_delegate" -> ok C_SET_DELEGATE
|
|
||||||
| _ -> simple_fail "Not a PascaLIGO constant"
|
(* Bytes module *)
|
||||||
|
|
||||||
|
| "Bytes.pack" -> ok C_BYTES_PACK
|
||||||
|
| "bytes_pack" -> ok C_BYTES_PACK (* Deprecated *)
|
||||||
|
| "Bytes.unpack" -> ok C_BYTES_UNPACK
|
||||||
|
| "bytes_unpack" -> ok C_BYTES_UNPACK (* Deprecated *)
|
||||||
|
| "Bytes.length" -> ok C_SIZE
|
||||||
|
| "Bytes.size" -> ok C_SIZE
|
||||||
|
| "bytes_concat" -> ok C_CONCAT (* Deprecated *)
|
||||||
|
| "Bytes.concat" -> ok C_CONCAT
|
||||||
|
| "Bytes.slice" -> ok C_SLICE
|
||||||
|
| "bytes_slice" -> ok C_SLICE (* Deprecated *)
|
||||||
|
| "Bytes.sub" -> ok C_SLICE
|
||||||
|
|
||||||
|
(* List module *)
|
||||||
|
|
||||||
|
| "List.length" -> ok C_SIZE
|
||||||
|
| "List.size" -> ok C_SIZE
|
||||||
|
| "list_size" -> ok C_SIZE (* Deprecated *)
|
||||||
|
| "List.iter" -> ok C_LIST_ITER
|
||||||
|
| "list_iter" -> ok C_LIST_ITER (* Deprecated *)
|
||||||
|
| "List.map" -> ok C_LIST_MAP
|
||||||
|
| "list_map" -> ok C_LIST_MAP (* Deprecated *)
|
||||||
|
| "List.fold" -> ok C_LIST_FOLD
|
||||||
|
| "list_fold" -> ok C_LIST_FOLD (* Deprecated *)
|
||||||
|
|
||||||
|
(* Set module *)
|
||||||
|
|
||||||
|
| "Set.size" -> ok C_SIZE
|
||||||
|
| "set_size" -> ok C_SIZE (* Deprecated *)
|
||||||
|
| "set_empty" -> ok C_SET_EMPTY (* Deprecated *)
|
||||||
|
| "Set.mem" -> ok C_SET_MEM
|
||||||
|
| "set_mem" -> ok C_SET_MEM (* Deprecated *)
|
||||||
|
| "Set.add" -> ok C_SET_ADD
|
||||||
|
| "set_add" -> ok C_SET_ADD (* Deprecated *)
|
||||||
|
| "Set.remove" -> ok C_SET_REMOVE
|
||||||
|
| "set_remove" -> ok C_SET_REMOVE (* Deprecated *)
|
||||||
|
| "Set.iter" -> ok C_SET_ITER
|
||||||
|
| "set_iter" -> ok C_SET_ITER (* Deprecated *)
|
||||||
|
| "Set.fold" -> ok C_SET_FOLD
|
||||||
|
| "set_fold" -> ok C_SET_FOLD (* Deprecated *)
|
||||||
|
|
||||||
|
(* Map module *)
|
||||||
|
|
||||||
|
| "get_force" -> ok C_MAP_FIND (* Deprecated *)
|
||||||
|
| "map_get" -> ok C_MAP_FIND_OPT (* Deprecated *)
|
||||||
|
| "Map.find_opt" -> ok C_MAP_FIND_OPT
|
||||||
|
| "Map.update" -> ok C_MAP_UPDATE
|
||||||
|
| "map_update" -> ok C_MAP_UPDATE (* Deprecated *)
|
||||||
|
| "map_remove" -> ok C_MAP_REMOVE (* Deprecated *)
|
||||||
|
| "Map.iter" -> ok C_MAP_ITER
|
||||||
|
| "map_iter" -> ok C_MAP_ITER (* Deprecated *)
|
||||||
|
| "Map.map" -> ok C_MAP_MAP
|
||||||
|
| "map_map" -> ok C_MAP_MAP (* Deprecated *)
|
||||||
|
| "Map.fold" -> ok C_MAP_FOLD
|
||||||
|
| "map_fold" -> ok C_MAP_FOLD (* Deprecated *)
|
||||||
|
| "Map.mem" -> ok C_MAP_MEM
|
||||||
|
| "map_mem" -> ok C_MAP_MEM (* Deprecated *)
|
||||||
|
| "Map.size" -> ok C_SIZE
|
||||||
|
| "map_size" -> ok C_SIZE (* Deprecated *)
|
||||||
|
|
||||||
|
(* Big_map module *)
|
||||||
|
|
||||||
|
| "Big_map.find_opt" -> ok C_MAP_FIND_OPT
|
||||||
|
| "Big_map.update" -> ok C_MAP_UPDATE
|
||||||
|
| "Big_map.literal" -> ok C_BIG_MAP_LITERAL
|
||||||
|
| "Big_map.empty" -> ok C_BIG_MAP_EMPTY
|
||||||
|
| "Big_map.size" -> ok C_SIZE
|
||||||
|
| "Big_map.mem" -> ok C_MAP_MEM
|
||||||
|
| "Big_map.iter" -> ok C_MAP_ITER
|
||||||
|
| "Big_map.map" -> ok C_MAP_MAP
|
||||||
|
| "Big_map.fold" -> ok C_MAP_FOLD
|
||||||
|
| "Big_map.remove" -> ok C_MAP_REMOVE
|
||||||
|
|
||||||
|
(* Bitwise module *)
|
||||||
|
|
||||||
|
| "Bitwise.or" -> ok C_OR
|
||||||
|
| "bitwise_or" -> ok C_OR (* Deprecated *)
|
||||||
|
| "Bitwise.and" -> ok C_AND
|
||||||
|
| "bitwise_and" -> ok C_AND (* Deprecated *)
|
||||||
|
| "Bitwise.xor" -> ok C_XOR
|
||||||
|
| "bitwise_xor" -> ok C_XOR (* Deprecated *)
|
||||||
|
| "Bitwise.shift_left" -> ok C_LSL
|
||||||
|
| "bitwise_lsl" -> ok C_LSL (* Deprecated *)
|
||||||
|
| "Bitwise.shift_right" -> ok C_LSR
|
||||||
|
| "bitwise_lsr" -> ok C_LSR (* Deprecated *)
|
||||||
|
|
||||||
|
(* String module *)
|
||||||
|
|
||||||
|
| "String.length" -> ok C_SIZE
|
||||||
|
| "String.size" -> ok C_SIZE
|
||||||
|
| "String.slice" -> ok C_SLICE
|
||||||
|
| "string_slice" -> ok C_SLICE (* Deprecated *)
|
||||||
|
| "String.sub" -> ok C_SLICE
|
||||||
|
| "String.concat" -> ok C_CONCAT
|
||||||
|
| "string_concat" -> ok C_CONCAT (* Deprecated *)
|
||||||
|
|
||||||
|
(* Others *)
|
||||||
|
|
||||||
|
| "assert" -> ok C_ASSERTION
|
||||||
|
| "size" -> ok C_SIZE (* Deprecated *)
|
||||||
|
|
||||||
|
| _ -> simple_fail "Not a PascaLIGO built-in."
|
||||||
|
|
||||||
let type_constants = type_constants
|
let type_constants = type_constants
|
||||||
let type_operators = type_operators
|
let type_operators = type_operators
|
||||||
@ -147,119 +248,163 @@ module Simplify = struct
|
|||||||
|
|
||||||
module Cameligo = struct
|
module Cameligo = struct
|
||||||
let constants = function
|
let constants = function
|
||||||
| "assert" -> ok C_ASSERTION
|
(* Tezos (ex-Michelson, ex-Current, ex-Operation) *)
|
||||||
| "chain_id" -> ok C_CHAIN_ID
|
|
||||||
| "Current.balance" -> ok C_BALANCE
|
|
||||||
| "balance" -> ok C_BALANCE
|
|
||||||
| "Current.time" -> ok C_NOW
|
|
||||||
| "time" -> ok C_NOW
|
|
||||||
| "Current.amount" -> ok C_AMOUNT
|
|
||||||
| "amount" -> ok C_AMOUNT
|
|
||||||
| "Current.sender" -> ok C_SENDER
|
|
||||||
| "Current.address" -> ok C_ADDRESS
|
|
||||||
| "Current.self_address" -> ok C_SELF_ADDRESS
|
|
||||||
| "Current.implicit_account" -> ok C_IMPLICIT_ACCOUNT
|
|
||||||
| "sender" -> ok C_SENDER
|
|
||||||
| "Current.source" -> ok C_SOURCE
|
|
||||||
| "source" -> ok C_SOURCE
|
|
||||||
| "Current.failwith" -> ok C_FAILWITH
|
|
||||||
| "failwith" -> ok C_FAILWITH
|
|
||||||
|
|
||||||
| "Crypto.blake2b" -> ok C_BLAKE2b
|
| "Tezos.chain_id" -> ok C_CHAIN_ID
|
||||||
| "Crypto.sha256" -> ok C_SHA256
|
| "chain_id" -> ok C_CHAIN_ID (* Deprecated *)
|
||||||
| "Crypto.sha512" -> ok C_SHA512
|
| "Tezos.balance" -> ok C_BALANCE
|
||||||
| "Crypto.hash_key" -> ok C_HASH_KEY
|
| "Current.balance" -> ok C_BALANCE (* Deprecated *)
|
||||||
| "Crypto.check" -> ok C_CHECK_SIGNATURE
|
| "balance" -> ok C_BALANCE (* Deprecated *)
|
||||||
|
| "Tezos.now" -> ok C_NOW
|
||||||
|
| "Current.time" -> ok C_NOW (* Deprecated *)
|
||||||
|
| "time" -> ok C_NOW (* Deprecated *)
|
||||||
|
| "Tezos.amount" -> ok C_AMOUNT
|
||||||
|
| "Current.amount" -> ok C_AMOUNT (* Deprecated *)
|
||||||
|
| "amount" -> ok C_AMOUNT (* Deprecated *)
|
||||||
|
| "Tezos.sender" -> ok C_SENDER
|
||||||
|
| "Current.sender" -> ok C_SENDER (* Deprecated *)
|
||||||
|
| "sender" -> ok C_SENDER (* Deprecated *)
|
||||||
|
| "Tezos.address" -> ok C_ADDRESS
|
||||||
|
| "Current.address" -> ok C_ADDRESS (* Deprecated *)
|
||||||
|
| "Tezos.self_address" -> ok C_SELF_ADDRESS
|
||||||
|
| "Current.self_address" -> ok C_SELF_ADDRESS (* Deprecated *)
|
||||||
|
| "Tezos.implicit_account" -> ok C_IMPLICIT_ACCOUNT
|
||||||
|
| "Current.implicit_account" -> ok C_IMPLICIT_ACCOUNT (* Deprecated *)
|
||||||
|
| "Tezos.source" -> ok C_SOURCE
|
||||||
|
| "Current.source" -> ok C_SOURCE (* Deprecated *)
|
||||||
|
| "source" -> ok C_SOURCE (* Deprecated *)
|
||||||
|
| "Tezos.failwith" -> ok C_FAILWITH
|
||||||
|
| "Current.failwith" -> ok C_FAILWITH (* Deprecated *)
|
||||||
|
| "failwith" -> ok C_FAILWITH
|
||||||
|
|
||||||
| "Bytes.pack" -> ok C_BYTES_PACK
|
| "Tezos.transaction" -> ok C_CALL
|
||||||
| "Bytes.unpack" -> ok C_BYTES_UNPACK
|
| "Operation.transaction" -> ok C_CALL (* Deprecated *)
|
||||||
| "Bytes.length" -> ok C_SIZE
|
| "Tezos.set_delegate" -> ok C_SET_DELEGATE (* Deprecated *)
|
||||||
| "Bytes.size" -> ok C_SIZE
|
| "Operation.set_delegate" -> ok C_SET_DELEGATE (* Deprecated *)
|
||||||
| "Bytes.concat" -> ok C_CONCAT
|
| "Operation.get_contract" -> ok C_CONTRACT (* Deprecated *)
|
||||||
| "Bytes.slice" -> ok C_SLICE
|
| "Tezos.get_contract_opt" -> ok C_CONTRACT_OPT
|
||||||
| "Bytes.sub" -> ok C_SLICE
|
| "Operation.get_contract_opt" -> ok C_CONTRACT_OPT (* Deprecated *)
|
||||||
|
| "Operation.get_entrypoint" -> ok C_CONTRACT_ENTRYPOINT (* Deprecated *)
|
||||||
|
| "Tezos.get_entrypoint_opt" -> ok C_CONTRACT_ENTRYPOINT_OPT
|
||||||
|
| "Operation.get_entrypoint_opt" -> ok C_CONTRACT_ENTRYPOINT_OPT (* Deprecated *)
|
||||||
|
|
||||||
| "Set.mem" -> ok C_SET_MEM
|
| "Michelson.is_nat" -> ok C_IS_NAT (* Deprecated *)
|
||||||
| "Set.iter" -> ok C_SET_ITER
|
| "is_nat" -> ok C_IS_NAT
|
||||||
| "Set.empty" -> ok C_SET_EMPTY
|
| "int" -> ok C_INT
|
||||||
| "Set.literal" -> ok C_SET_LITERAL
|
| "abs" -> ok C_ABS
|
||||||
| "Set.add" -> ok C_SET_ADD
|
| "unit" -> ok C_UNIT
|
||||||
| "Set.remove" -> ok C_SET_REMOVE
|
|
||||||
| "Set.fold" -> ok C_SET_FOLD
|
|
||||||
| "Set.size" -> ok C_SIZE
|
|
||||||
|
|
||||||
| "Map.find_opt" -> ok C_MAP_FIND_OPT
|
| "NEG" -> ok C_NEG
|
||||||
| "Map.find" -> ok C_MAP_FIND
|
| "ADD" -> ok C_ADD
|
||||||
| "Map.update" -> ok C_MAP_UPDATE
|
| "SUB" -> ok C_SUB
|
||||||
| "Map.add" -> ok C_MAP_ADD
|
| "TIMES" -> ok C_MUL
|
||||||
| "Map.remove" -> ok C_MAP_REMOVE
|
| "DIV" -> ok C_DIV
|
||||||
| "Map.iter" -> ok C_MAP_ITER
|
| "MOD" -> ok C_MOD
|
||||||
| "Map.map" -> ok C_MAP_MAP
|
| "EQ" -> ok C_EQ
|
||||||
| "Map.fold" -> ok C_MAP_FOLD
|
| "NOT" -> ok C_NOT
|
||||||
| "Map.mem" -> ok C_MAP_MEM
|
| "AND" -> ok C_AND
|
||||||
| "Map.empty" -> ok C_MAP_EMPTY
|
| "OR" -> ok C_OR
|
||||||
| "Map.literal" -> ok C_MAP_LITERAL
|
| "GT" -> ok C_GT
|
||||||
| "Map.size" -> ok C_SIZE
|
| "GE" -> ok C_GE
|
||||||
|
| "LT" -> ok C_LT
|
||||||
|
| "LE" -> ok C_LE
|
||||||
|
| "CONS" -> ok C_CONS
|
||||||
|
| "NEQ" -> ok C_NEQ
|
||||||
|
|
||||||
| "Big_map.find_opt" -> ok C_MAP_FIND_OPT
|
(* Crypto module *)
|
||||||
| "Big_map.find" -> ok C_MAP_FIND
|
|
||||||
| "Big_map.update" -> ok C_MAP_UPDATE
|
|
||||||
| "Big_map.add" -> ok C_MAP_ADD
|
|
||||||
| "Big_map.remove" -> ok C_MAP_REMOVE
|
|
||||||
| "Big_map.literal" -> ok C_BIG_MAP_LITERAL
|
|
||||||
| "Big_map.empty" -> ok C_BIG_MAP_EMPTY
|
|
||||||
|
|
||||||
| "Bitwise.lor" -> ok C_OR
|
| "Crypto.check" -> ok C_CHECK_SIGNATURE
|
||||||
| "Bitwise.land" -> ok C_AND
|
| "Crypto.hash_key" -> ok C_HASH_KEY
|
||||||
| "Bitwise.lxor" -> ok C_XOR
|
| "Crypto.blake2b" -> ok C_BLAKE2b
|
||||||
| "Bitwise.shift_left" -> ok C_LSL
|
| "Crypto.sha256" -> ok C_SHA256
|
||||||
| "Bitwise.shift_right" -> ok C_LSR
|
| "Crypto.sha512" -> ok C_SHA512
|
||||||
|
|
||||||
| "String.length" -> ok C_SIZE
|
(* Bytes module *)
|
||||||
| "String.size" -> ok C_SIZE
|
|
||||||
| "String.slice" -> ok C_SLICE
|
|
||||||
| "String.sub" -> ok C_SLICE
|
|
||||||
| "String.concat" -> ok C_CONCAT
|
|
||||||
|
|
||||||
| "List.length" -> ok C_SIZE
|
| "Bytes.pack" -> ok C_BYTES_PACK
|
||||||
| "List.size" -> ok C_SIZE
|
| "Bytes.unpack" -> ok C_BYTES_UNPACK
|
||||||
| "List.iter" -> ok C_LIST_ITER
|
| "Bytes.length" -> ok C_SIZE
|
||||||
| "List.map" -> ok C_LIST_MAP
|
| "Bytes.size" -> ok C_SIZE
|
||||||
| "List.fold" -> ok C_LIST_FOLD
|
| "Bytes.concat" -> ok C_CONCAT
|
||||||
|
| "Bytes.slice" -> ok C_SLICE
|
||||||
|
| "Bytes.sub" -> ok C_SLICE
|
||||||
|
|
||||||
| "Loop.fold_while" -> ok C_FOLD_WHILE
|
(* List module *)
|
||||||
| "continue" -> ok C_CONTINUE
|
|
||||||
| "stop" -> ok C_STOP
|
|
||||||
|
|
||||||
| "Operation.transaction" -> ok C_CALL
|
| "List.length" -> ok C_SIZE
|
||||||
| "Operation.set_delegate" -> ok C_SET_DELEGATE
|
| "List.size" -> ok C_SIZE
|
||||||
| "Operation.get_contract" -> ok C_CONTRACT
|
| "List.iter" -> ok C_LIST_ITER
|
||||||
| "Operation.get_contract_opt" -> ok C_CONTRACT_OPT
|
| "List.map" -> ok C_LIST_MAP
|
||||||
| "Operation.get_entrypoint" -> ok C_CONTRACT_ENTRYPOINT
|
| "List.fold" -> ok C_LIST_FOLD
|
||||||
| "Operation.get_entrypoint_opt" -> ok C_CONTRACT_ENTRYPOINT_OPT
|
|
||||||
| "int" -> ok C_INT
|
|
||||||
| "abs" -> ok C_ABS
|
|
||||||
| "unit" -> ok C_UNIT
|
|
||||||
|
|
||||||
| "NEG" -> ok C_NEG
|
(* Set module *)
|
||||||
| "ADD" -> ok C_ADD
|
|
||||||
| "SUB" -> ok C_SUB
|
|
||||||
| "TIMES" -> ok C_MUL
|
|
||||||
| "DIV" -> ok C_DIV
|
|
||||||
| "MOD" -> ok C_MOD
|
|
||||||
| "EQ" -> ok C_EQ
|
|
||||||
| "NOT" -> ok C_NOT
|
|
||||||
| "AND" -> ok C_AND
|
|
||||||
| "OR" -> ok C_OR
|
|
||||||
| "GT" -> ok C_GT
|
|
||||||
| "GE" -> ok C_GE
|
|
||||||
| "LT" -> ok C_LT
|
|
||||||
| "LE" -> ok C_LE
|
|
||||||
| "CONS" -> ok C_CONS
|
|
||||||
| "NEQ" -> ok C_NEQ
|
|
||||||
|
|
||||||
| "Michelson.is_nat" -> ok C_IS_NAT
|
| "Set.mem" -> ok C_SET_MEM
|
||||||
| _ -> simple_fail "Not a constant"
|
| "Set.iter" -> ok C_SET_ITER
|
||||||
|
| "Set.empty" -> ok C_SET_EMPTY
|
||||||
|
| "Set.literal" -> ok C_SET_LITERAL
|
||||||
|
| "Set.add" -> ok C_SET_ADD
|
||||||
|
| "Set.remove" -> ok C_SET_REMOVE
|
||||||
|
| "Set.fold" -> ok C_SET_FOLD
|
||||||
|
| "Set.size" -> ok C_SIZE
|
||||||
|
|
||||||
|
(* Map module *)
|
||||||
|
|
||||||
|
| "Map.find_opt" -> ok C_MAP_FIND_OPT
|
||||||
|
| "Map.find" -> ok C_MAP_FIND (* Deprecated *)
|
||||||
|
| "Map.update" -> ok C_MAP_UPDATE
|
||||||
|
| "Map.add" -> ok C_MAP_ADD
|
||||||
|
| "Map.remove" -> ok C_MAP_REMOVE
|
||||||
|
| "Map.iter" -> ok C_MAP_ITER
|
||||||
|
| "Map.map" -> ok C_MAP_MAP
|
||||||
|
| "Map.fold" -> ok C_MAP_FOLD
|
||||||
|
| "Map.mem" -> ok C_MAP_MEM
|
||||||
|
| "Map.empty" -> ok C_MAP_EMPTY
|
||||||
|
| "Map.literal" -> ok C_MAP_LITERAL
|
||||||
|
| "Map.size" -> ok C_SIZE
|
||||||
|
|
||||||
|
(* Big_map module *)
|
||||||
|
|
||||||
|
| "Big_map.find_opt" -> ok C_MAP_FIND_OPT
|
||||||
|
| "Big_map.find" -> ok C_MAP_FIND
|
||||||
|
| "Big_map.update" -> ok C_MAP_UPDATE
|
||||||
|
| "Big_map.add" -> ok C_MAP_ADD
|
||||||
|
| "Big_map.remove" -> ok C_MAP_REMOVE
|
||||||
|
| "Big_map.literal" -> ok C_BIG_MAP_LITERAL
|
||||||
|
| "Big_map.empty" -> ok C_BIG_MAP_EMPTY
|
||||||
|
|
||||||
|
(* Bitwise module *)
|
||||||
|
|
||||||
|
| "Bitwise.or" -> ok C_OR
|
||||||
|
| "Bitwise.lor" -> ok C_OR (* Deprecated *)
|
||||||
|
| "Bitwise.and" -> ok C_AND
|
||||||
|
| "Bitwise.land" -> ok C_AND (* Deprecated *)
|
||||||
|
| "Bitwise.xor" -> ok C_XOR
|
||||||
|
| "Bitwise.lxor" -> ok C_XOR (* Deprecated *)
|
||||||
|
| "Bitwise.shift_left" -> ok C_LSL
|
||||||
|
| "Bitwise.shift_right" -> ok C_LSR
|
||||||
|
|
||||||
|
(* String module *)
|
||||||
|
|
||||||
|
| "String.length" -> ok C_SIZE
|
||||||
|
| "String.size" -> ok C_SIZE
|
||||||
|
| "String.slice" -> ok C_SLICE
|
||||||
|
| "String.sub" -> ok C_SLICE
|
||||||
|
| "String.concat" -> ok C_CONCAT
|
||||||
|
|
||||||
|
(* Loop module *)
|
||||||
|
|
||||||
|
| "Loop.fold_while" -> ok C_FOLD_WHILE
|
||||||
|
| "Loop.continue" -> ok C_CONTINUE
|
||||||
|
| "continue" -> ok C_CONTINUE (* Deprecated *)
|
||||||
|
| "Loop.stop" -> ok C_STOP
|
||||||
|
| "stop" -> ok C_STOP (* Deprecated *)
|
||||||
|
|
||||||
|
(* Others *)
|
||||||
|
|
||||||
|
| "assert" -> ok C_ASSERTION
|
||||||
|
|
||||||
|
| _ -> simple_fail "Not a CameLIGO built-in."
|
||||||
|
|
||||||
let type_constants = type_constants
|
let type_constants = type_constants
|
||||||
let type_operators = type_operators
|
let type_operators = type_operators
|
||||||
@ -821,19 +966,19 @@ module Typer = struct
|
|||||||
let%bind key = get_t_set set in
|
let%bind key = get_t_set set in
|
||||||
if eq_1 elt key
|
if eq_1 elt key
|
||||||
then ok @@ t_bool ()
|
then ok @@ t_bool ()
|
||||||
else fail @@ Operator_errors.type_error "Set_mem: elt and set don't match" elt key ()
|
else fail @@ Operator_errors.type_error "Set.mem: elt and set don't match" elt key ()
|
||||||
|
|
||||||
let set_add = typer_2 "SET_ADD" @@ fun elt set ->
|
let set_add = typer_2 "SET_ADD" @@ fun elt set ->
|
||||||
let%bind key = get_t_set set in
|
let%bind key = get_t_set set in
|
||||||
if eq_1 elt key
|
if eq_1 elt key
|
||||||
then ok set
|
then ok set
|
||||||
else fail @@ Operator_errors.type_error "Set_add: elt and set don't match" elt key ()
|
else fail @@ Operator_errors.type_error "Set.add: elt and set don't match" elt key ()
|
||||||
|
|
||||||
let set_remove = typer_2 "SET_REMOVE" @@ fun elt set ->
|
let set_remove = typer_2 "SET_REMOVE" @@ fun elt set ->
|
||||||
let%bind key = get_t_set set in
|
let%bind key = get_t_set set in
|
||||||
if eq_1 elt key
|
if eq_1 elt key
|
||||||
then ok set
|
then ok set
|
||||||
else fail @@ Operator_errors.type_error "Set_remove: elt and set don't match" key elt ()
|
else fail @@ Operator_errors.type_error "Set.remove: elt and set don't match" key elt ()
|
||||||
|
|
||||||
let set_iter = typer_2 "SET_ITER" @@ fun body set ->
|
let set_iter = typer_2 "SET_ITER" @@ fun body set ->
|
||||||
let%bind (arg , res) = get_t_function body in
|
let%bind (arg , res) = get_t_function body in
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
// Test PascaLIGO bitwise operators
|
// Test PascaLIGO bitwise operators
|
||||||
|
|
||||||
function or_op (const n : nat) : nat is bitwise_or (n, 4n)
|
function or_op (const n : nat) : nat is Bitwise.or (n, 4n)
|
||||||
|
function and_op (const n : nat) : nat is Bitwise.and (n, 7n)
|
||||||
function and_op (const n : nat) : nat is bitwise_and (n, 7n)
|
function xor_op (const n : nat) : nat is Bitwise.xor (n, 7n)
|
||||||
|
function lsl_op (const n : nat) : nat is Bitwise.shift_left (n, 7n)
|
||||||
function xor_op (const n : nat) : nat is bitwise_xor (n, 7n)
|
function lsr_op (const n : nat) : nat is Bitwise.shift_right (n, 7n)
|
||||||
|
|
||||||
function lsl_op (const n : nat) : nat is bitwise_lsl (n, 7n)
|
|
||||||
|
|
||||||
function lsr_op (const n : nat) : nat is bitwise_lsr (n, 7n)
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
(* Test CameLIGO bitwise operators *)
|
(* Test CameLIGO bitwise operators *)
|
||||||
|
|
||||||
let or_op (n: nat) : nat = Bitwise.lor n 4n
|
let or_op (n: nat) : nat = Bitwise.or n 4n
|
||||||
let and_op (n: nat) : nat = Bitwise.land n 7n
|
let and_op (n: nat) : nat = Bitwise.and n 7n
|
||||||
let xor_op (n: nat) : nat = Bitwise.lxor n 7n
|
let xor_op (n: nat) : nat = Bitwise.xor n 7n
|
||||||
let lsl_op (n: nat) : nat = Bitwise.shift_left n 7n
|
let lsl_op (n: nat) : nat = Bitwise.shift_left n 7n
|
||||||
let lsr_op (n: nat) : nat = Bitwise.shift_right n 7n
|
let lsr_op (n: nat) : nat = Bitwise.shift_right n 7n
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* Test ReasonLigo bitwise operators */
|
/* Test ReasonLigo bitwise operators */
|
||||||
|
|
||||||
let or_op = (n: nat): nat => Bitwise.lor(n, 4n);
|
let or_op = (n : nat) : nat => Bitwise.or (n, 4n);
|
||||||
let and_op = (n: nat): nat => Bitwise.land(n, 7n);
|
let and_op = (n : nat) : nat => Bitwise.and (n, 7n);
|
||||||
let xor_op = (n: nat): nat => Bitwise.lxor(n, 7n);
|
let xor_op = (n : nat) : nat => Bitwise.xor (n, 7n);
|
||||||
let lsl_op = (n: nat) : nat => Bitwise.shift_left(n, 7n);
|
let lsl_op = (n : nat) : nat => Bitwise.shift_left (n, 7n);
|
||||||
let lsr_op = (n: nat) : nat => Bitwise.shift_right(n, 7n);
|
let lsr_op = (n : nat) : nat => Bitwise.shift_right (n, 7n);
|
Loading…
Reference in New Issue
Block a user