First batch of rewritten contracts (PascaLIGO).
This commit is contained in:
parent
71474e1b0d
commit
541728fc6c
@ -32,7 +32,7 @@ module Simplify = struct
|
|||||||
- The left-hand-side is the reserved name in the given front-end.
|
- The left-hand-side is the reserved name in the given front-end.
|
||||||
- The right-hand-side is the name that will be used in the AST.
|
- The right-hand-side is the name that will be used in the AST.
|
||||||
*)
|
*)
|
||||||
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
|
||||||
@ -1157,7 +1157,7 @@ module Compiler = struct
|
|||||||
| C_CONCAT -> ok @@ simple_binary @@ prim I_CONCAT
|
| C_CONCAT -> ok @@ simple_binary @@ prim I_CONCAT
|
||||||
| C_CHAIN_ID -> ok @@ simple_constant @@ prim I_CHAIN_ID
|
| C_CHAIN_ID -> ok @@ simple_constant @@ prim I_CHAIN_ID
|
||||||
| _ -> simple_fail @@ Format.asprintf "operator not implemented for %a" Stage_common.PP.constant c
|
| _ -> simple_fail @@ Format.asprintf "operator not implemented for %a" Stage_common.PP.constant c
|
||||||
|
|
||||||
|
|
||||||
(*
|
(*
|
||||||
Some complex operators will need to be added in compiler/compiler_program.
|
Some complex operators will need to be added in compiler/compiler_program.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// function main (const c: contract(unit)) : address is address(c)
|
// function main (const c : contract (unit)) : address is address (c)
|
||||||
|
|
||||||
function main (const p : key_hash) : address is block {
|
function main (const p : key_hash) : address is block {
|
||||||
const c : contract(unit) = implicit_account(p) ;
|
const c : contract (unit) = implicit_account (p);
|
||||||
} with address(c)
|
} with address (c)
|
@ -1,6 +1,6 @@
|
|||||||
(* Test that a string is cast to an address given a type annotation *)
|
(* Test that a string is cast to an address given a type annotation *)
|
||||||
|
|
||||||
const lst : list(int) = list []
|
const lst : list (int) = list []
|
||||||
|
|
||||||
const my_address : address =
|
const my_address : address =
|
||||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address)
|
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address)
|
||||||
|
@ -1,21 +1,13 @@
|
|||||||
// Test different ways of calling functions in PascaLIGO
|
// Test different ways of calling functions in PascaLIGO
|
||||||
|
|
||||||
type foo is record
|
type foo is record [bar : int -> int]
|
||||||
bar : int -> int ;
|
|
||||||
end
|
|
||||||
|
|
||||||
function f (const i : int) : int is
|
function f (const i : int) : int is i
|
||||||
begin
|
|
||||||
skip
|
|
||||||
end with i
|
|
||||||
|
|
||||||
function g (const i : unit) : int -> int is
|
function g (const i : unit) : int -> int is f
|
||||||
begin skip end with f
|
|
||||||
|
|
||||||
const r : foo = record
|
const r : foo = record [bar = f]
|
||||||
bar = f ;
|
|
||||||
end
|
|
||||||
|
|
||||||
const x : int = f(42)
|
const x : int = f (42)
|
||||||
const y : int = r.bar(42)
|
const y : int = r.bar (42)
|
||||||
const z : int = (g(unit))(42)
|
const z : int = (g (unit))(42)
|
||||||
|
@ -1,22 +1,15 @@
|
|||||||
// Test PascaLIGO arithmetic operators
|
// Test PascaLIGO arithmetic operators
|
||||||
|
|
||||||
function mod_op (const n : int) : nat is
|
function mod_op (const n : int) : nat is n mod 42
|
||||||
begin skip end with n mod 42
|
|
||||||
|
|
||||||
function plus_op (const n : int) : int is
|
function plus_op (const n : int) : int is n + 42
|
||||||
begin skip end with n + 42
|
|
||||||
|
|
||||||
function minus_op (const n : int) : int is
|
function minus_op (const n : int) : int is n - 42
|
||||||
begin skip end with n - 42
|
|
||||||
|
|
||||||
function times_op (const n : int) : int is
|
function times_op (const n : int) : int is n * 42
|
||||||
begin skip end with n * 42
|
|
||||||
|
|
||||||
function div_op (const n : int) : int is
|
function div_op (const n : int) : int is n / 2
|
||||||
begin skip end with n / 2
|
|
||||||
|
|
||||||
function int_op (const n : nat) : int is
|
function int_op (const n : nat) : int is int (n)
|
||||||
block { skip } with int(n)
|
|
||||||
|
|
||||||
function neg_op (const n : int) : int is
|
function neg_op (const n : int) : int is -n
|
||||||
begin skip end with -n
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
function main (const i : int) : int is
|
function main (const i : int) : int is
|
||||||
begin
|
block {
|
||||||
i := i + 1 ;
|
i := i + 1
|
||||||
end with i
|
} with i
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
const x : int = 1; attributes ["inline"]
|
const x : int = 1; attributes ["inline"]
|
||||||
|
|
||||||
function foo (const a : int) : int is
|
function foo (const a : int) : int is
|
||||||
begin
|
block {
|
||||||
const test : int = 2 + a;
|
const test : int = 2 + a;
|
||||||
attributes ["inline"];
|
attributes ["inline"];
|
||||||
end with test;
|
} with test;
|
||||||
attributes ["inline"];
|
attributes ["inline"];
|
||||||
|
|
||||||
const y : int = 1; attributes ["inline"; "other"]
|
const y : int = 1; attributes ["inline"; "other"]
|
||||||
|
|
||||||
function bar (const b : int) : int is
|
function bar (const b : int) : int is
|
||||||
begin
|
block {
|
||||||
function test (const z : int) : int is
|
function test (const z : int) : int is
|
||||||
begin
|
block {
|
||||||
const r : int = 2 + b + z
|
const r : int = 2 + b + z
|
||||||
end with r;
|
} with r;
|
||||||
attributes ["inline"; "foo"; "bar"]
|
attributes ["inline"; "foo"; "bar"]
|
||||||
end with test(b)
|
} with test (b)
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
type storage_ is timestamp
|
type parameter is unit
|
||||||
|
type storage is timestamp
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
function main(const p : unit; const s : storage_) : list(operation) * storage_ is
|
function main (const p : parameter; const s : storage) : return is
|
||||||
block {
|
block {
|
||||||
var toto : timestamp := ("badtimestamp" : timestamp);
|
var stamp : timestamp := ("badtimestamp" : timestamp)
|
||||||
}
|
}
|
||||||
with ((nil: list(operation)), toto)
|
with ((nil: list(operation)), stamp)
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
type t is (nat * nat)
|
type parameter is unit
|
||||||
type s is map(t)
|
|
||||||
|
|
||||||
function main (const u : unit; const s : s) : (list(operation) * s) is ((nil : list(operation)), s)
|
type binding is nat * nat
|
||||||
|
type storage is map (binding)
|
||||||
|
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
|
function main (const param : parameter; const store : storage) : return is
|
||||||
|
((nil : list (operation)), store)
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
(**
|
(*
|
||||||
|
|
||||||
This test makes sure that the balance is accessible in PascaLIGO.
|
This test makes sure that the balance is accessible in PascaLIGO.
|
||||||
It's there to detect a regression of: https://gitlab.com/ligolang/ligo/issues/68
|
|
||||||
|
|
||||||
|
It is meant to detect the regression detailled in the following issue: https://gitlab.com/ligolang/ligo/issues/68
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
type parameter is unit
|
||||||
type storage is tez
|
type storage is tez
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
function main (const p : unit; const s: tez) : list(operation) * storage is
|
function main (const param : parameter; const store: storage) : return is
|
||||||
((nil : list(operation)), balance)
|
((nil : list (operation)), balance)
|
||||||
|
@ -1,36 +1,35 @@
|
|||||||
type storage_ is big_map(int, int) * unit
|
type parameter is unit
|
||||||
type foo is big_map(int, int)
|
type storage is big_map (int, int) * unit
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
function main(const p : unit; const s : storage_) : list(operation) * storage_ is
|
function main (const p : parameter; const s : storage) : return is
|
||||||
block {
|
block {
|
||||||
var toto : option (int) := Some(0);
|
var toto : option (int) := Some (0);
|
||||||
toto := s.0[23];
|
toto := s.0[23];
|
||||||
s.0[2] := 444;
|
s.0[2] := 444
|
||||||
}
|
}
|
||||||
with ((nil: list(operation)), s)
|
with ((nil: list(operation)), s)
|
||||||
|
|
||||||
function set_ (var n : int ; var m : foo) : foo is block {
|
type foo is big_map (int, int)
|
||||||
m[23] := n ;
|
|
||||||
|
function set_ (var n : int; var m : foo) : foo is block {
|
||||||
|
m[23] := n
|
||||||
} with m
|
} with m
|
||||||
|
|
||||||
function rm (var m : foo) : foo is block {
|
function rm (var m : foo) : foo is block {
|
||||||
remove 42 from map m;
|
remove 42 from map m
|
||||||
} with m
|
} with m
|
||||||
|
|
||||||
function gf (const m : foo) : int is begin skip end with get_force(23, m)
|
function gf (const m : foo) : int is get_force (23, m)
|
||||||
|
|
||||||
function get (const m : foo) : option(int) is begin skip end with m[42]
|
function get (const m : foo) : option (int) is m[42]
|
||||||
|
|
||||||
const empty_big_map : big_map(int,int) = big_map end
|
const empty_big_map : big_map (int,int) = big_map []
|
||||||
|
|
||||||
const big_map1 : big_map(int,int) = big_map
|
const big_map1 : big_map (int,int) = big_map [23 -> 0; 42 -> 0]
|
||||||
23 -> 0 ;
|
|
||||||
42 -> 0 ;
|
|
||||||
end
|
|
||||||
|
|
||||||
function mutimaps (const m : foo ; const n : foo) : foo is block
|
function mutimaps (const m : foo; const n : foo) : foo is block {
|
||||||
{
|
var bar : foo := m;
|
||||||
var bar : foo := m ;
|
bar[42] := 0;
|
||||||
bar[42] := 0 ;
|
n[42] := get_force (42, bar)
|
||||||
n[42] := get_force(42, bar) ;
|
|
||||||
} with n
|
} with n
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
// Test PascaLIGO bitwise operators
|
// Test PascaLIGO bitwise operators
|
||||||
|
|
||||||
function or_op (const n : nat) : nat is
|
function or_op (const n : nat) : nat is bitwise_or (n, 4n)
|
||||||
begin skip end with bitwise_or(n , 4n)
|
|
||||||
|
|
||||||
function and_op (const n : nat) : nat is
|
function and_op (const n : nat) : nat is bitwise_and (n, 7n)
|
||||||
begin skip end with bitwise_and(n , 7n)
|
|
||||||
|
|
||||||
function xor_op (const n : nat) : nat is
|
function xor_op (const n : nat) : nat is bitwise_xor (n, 7n)
|
||||||
begin skip end with bitwise_xor(n , 7n)
|
|
||||||
|
@ -1,2 +1 @@
|
|||||||
function blockless (const n: int) : int is
|
function blockless (const n : int) : int is n + 10
|
||||||
n + 10;
|
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
// Test PascaLIGO boolean operators
|
// Test PascaLIGO boolean operators
|
||||||
|
|
||||||
function or_true (const b : bool) : bool is
|
function or_true (const b : bool) : bool is b or True
|
||||||
begin skip end with b or True
|
|
||||||
|
|
||||||
function or_false (const b : bool) : bool is
|
function or_false (const b : bool) : bool is b or False
|
||||||
begin skip end with b or False
|
|
||||||
|
|
||||||
function and_true (const b : bool) : bool is
|
function and_true (const b : bool) : bool is b and True
|
||||||
begin skip end with b and True
|
|
||||||
|
|
||||||
function and_false (const b : bool) : bool is
|
function and_false (const b : bool) : bool is b and False
|
||||||
begin skip end with b and False
|
|
||||||
|
|
||||||
function not_bool (const b: bool) : bool is
|
function not_bool (const b : bool) : bool is not b
|
||||||
begin skip end with not b
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
function concat_op (const s : bytes) : bytes is
|
function concat_op (const s : bytes) : bytes is bytes_concat (s, 0x7070)
|
||||||
begin skip end with bytes_concat(s , 0x7070)
|
|
||||||
|
|
||||||
function slice_op (const s : bytes) : bytes is
|
function slice_op (const s : bytes) : bytes is bytes_slice (1n, 2n, s)
|
||||||
begin skip end with bytes_slice(1n , 2n , s)
|
|
||||||
|
|
||||||
function hasherman (const s : bytes) : bytes is
|
function hasherman (const s : bytes) : bytes is sha_256 (s)
|
||||||
begin skip end with sha_256(s)
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
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))
|
||||||
|
|
||||||
function id_int (const p : int) : option(int) is block {
|
function id_int (const p : int) : option (int) is block {
|
||||||
const packed : bytes = bytes_pack(p) ;
|
const packed : bytes = bytes_pack (p)
|
||||||
} with (bytes_unpack(packed): option(int))
|
} with (bytes_unpack (packed) : option (int))
|
||||||
|
|
||||||
function id_address (const p : address) : option(address) is block {
|
function id_address (const p : address) : option (address) is block {
|
||||||
const packed : bytes = bytes_pack(p) ;
|
const packed : bytes = bytes_pack (p)
|
||||||
} with (bytes_unpack(packed): option(address))
|
} with (bytes_unpack (packed) : option (address))
|
||||||
|
@ -1,5 +1 @@
|
|||||||
|
function chain_id (const tt : chain_id) : chain_id is get_chain_id
|
||||||
function chain_id (const tt : chain_id) : chain_id is
|
|
||||||
block {
|
|
||||||
var toto : chain_id := get_chain_id ;
|
|
||||||
} with ( toto )
|
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
function check_signature (const pk: key; const signed: signature; const msg: bytes) : bool is
|
function check_signature (const pk : key;
|
||||||
crypto_check(pk, signed, msg)
|
const signed : signature;
|
||||||
|
const msg: bytes) : bool
|
||||||
|
is crypto_check (pk, signed, msg)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
function foo (const i : int) : int is
|
function foo (const i : int) : int is
|
||||||
block {
|
block {
|
||||||
function bar (const j : int) : int is
|
function add (const j : int) : int is i+j
|
||||||
i + j ;
|
} with add (i)
|
||||||
} with bar (i)
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
function foobar(const i : int) : int is
|
function foobar (const i : int) : int is
|
||||||
block {
|
block {
|
||||||
const j : int = 3 ;
|
const j : int = 3;
|
||||||
function toto(const k : int) : int is
|
function add (const k : int) : int is i+j+k
|
||||||
i + j + k ;
|
} with add (42)
|
||||||
} with toto(42)
|
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
// This might seem like it's covered by induction with closure-2.ligo
|
// This might seem like it is covered by induction with closure-2.ligo,
|
||||||
// But it exists to prevent a regression on the bug patched by:
|
// but it exists to prevent a regression on the bug patched by:
|
||||||
// https://gitlab.com/ligolang/ligo/commit/faf3bbc06106de98189f1c1673bd57e78351dc7e
|
// https://gitlab.com/ligolang/ligo/commit/faf3bbc06106de98189f1c1673bd57e78351dc7e
|
||||||
|
|
||||||
function foobar(const i : int) : int is
|
function foobar (const i : int) : int is
|
||||||
block {
|
block {
|
||||||
const j : int = 3 ;
|
const j : int = 3;
|
||||||
const k : int = 4 ;
|
const k : int = 4;
|
||||||
function toto(const l : int) : int is
|
function add (const l : int) : int is i+j+k+l
|
||||||
i + j + k + l;
|
} with add (42)
|
||||||
|
|
||||||
} with toto(42)
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
function toto (const i : int) : int is
|
function toto (const i : int) : int is
|
||||||
block {
|
block {
|
||||||
function tata (const j : int) : int is
|
function tata (const j : int) : int is i+j;
|
||||||
i + j ;
|
function titi (const j : int) : int is i+j
|
||||||
function titi (const j : int) : int is
|
} with tata (i) + titi (i)
|
||||||
i + j ;
|
|
||||||
} with tata(i) + titi(i)
|
|
||||||
|
@ -1,98 +1,113 @@
|
|||||||
// Copyright Coase, Inc 2019
|
// Copyright Coase, Inc 2019
|
||||||
|
|
||||||
type card_pattern_id is nat
|
type card_pattern_id is nat
|
||||||
|
|
||||||
type card_pattern is record [
|
type card_pattern is record [
|
||||||
coefficient : tez ;
|
coefficient : tez;
|
||||||
quantity : nat ;
|
quantity : nat
|
||||||
]
|
]
|
||||||
|
|
||||||
type card_patterns is map(card_pattern_id , card_pattern)
|
type card_patterns is map (card_pattern_id, card_pattern)
|
||||||
|
|
||||||
type card_id is nat
|
type card_id is nat
|
||||||
type card is record [
|
|
||||||
card_owner : address ;
|
|
||||||
card_pattern : card_pattern_id ;
|
|
||||||
]
|
|
||||||
type cards is map(card_id , card)
|
|
||||||
|
|
||||||
type storage_type is record [
|
type card is record [
|
||||||
cards : cards ;
|
card_owner : address;
|
||||||
card_patterns : card_patterns ;
|
card_pattern : card_pattern_id
|
||||||
next_id : nat ;
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
type cards is map (card_id, card)
|
||||||
|
|
||||||
|
type storage is record [
|
||||||
|
cards : cards;
|
||||||
|
card_patterns : card_patterns;
|
||||||
|
next_id : nat
|
||||||
|
]
|
||||||
|
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
type action_buy_single is record [
|
type action_buy_single is record [
|
||||||
card_to_buy : card_pattern_id ;
|
card_to_buy : card_pattern_id
|
||||||
]
|
|
||||||
type action_sell_single is record [
|
|
||||||
card_to_sell : card_id ;
|
|
||||||
]
|
|
||||||
type action_transfer_single is record [
|
|
||||||
card_to_transfer : card_id ;
|
|
||||||
destination : address ;
|
|
||||||
]
|
]
|
||||||
|
|
||||||
type action is
|
type action_sell_single is record [
|
||||||
| Buy_single of action_buy_single
|
card_to_sell : card_id
|
||||||
| Sell_single of action_sell_single
|
]
|
||||||
|
|
||||||
|
type action_transfer_single is record [
|
||||||
|
card_to_transfer : card_id;
|
||||||
|
destination : address
|
||||||
|
]
|
||||||
|
|
||||||
|
type parameter is
|
||||||
|
Buy_single of action_buy_single
|
||||||
|
| Sell_single of action_sell_single
|
||||||
| Transfer_single of action_transfer_single
|
| Transfer_single of action_transfer_single
|
||||||
|
|
||||||
function transfer_single(const action : action_transfer_single ; const s : storage_type) : (list(operation) * storage_type) is
|
function transfer_single (const action : action_transfer_single;
|
||||||
begin
|
const s : storage) : return is block {
|
||||||
const cards : cards = s.cards ;
|
const cards : cards = s.cards;
|
||||||
const card : card = get_force(action.card_to_transfer , cards) ;
|
const card : card = get_force (action.card_to_transfer, cards);
|
||||||
if (card.card_owner =/= source) then failwith ("This card doesn't belong to you") else skip ;
|
if card.card_owner =/= source then
|
||||||
card.card_owner := action.destination ;
|
failwith ("This card doesn't belong to you")
|
||||||
cards[action.card_to_transfer] := card ;
|
else skip;
|
||||||
s.cards := cards ;
|
card.card_owner := action.destination;
|
||||||
const operations : list(operation) = nil ;
|
cards[action.card_to_transfer] := card;
|
||||||
end with (operations , s) ;
|
s.cards := cards;
|
||||||
|
const operations : list (operation) = nil
|
||||||
|
} with (operations, s)
|
||||||
|
|
||||||
function sell_single(const action : action_sell_single ; const s : storage_type) : (list(operation) * storage_type) is
|
function sell_single (const action : action_sell_single;
|
||||||
begin
|
const s : storage) : return is
|
||||||
const card : card = get_force(action.card_to_sell , s.cards) ;
|
block {
|
||||||
if (card.card_owner =/= source) then failwith ("This card doesn't belong to you") else skip ;
|
const card : card = get_force (action.card_to_sell, s.cards);
|
||||||
const card_pattern : card_pattern = get_force(card.card_pattern , s.card_patterns) ;
|
if card.card_owner =/= source
|
||||||
card_pattern.quantity := abs(card_pattern.quantity - 1n);
|
then failwith ("This card doesn't belong to you")
|
||||||
const card_patterns : card_patterns = s.card_patterns ;
|
else skip;
|
||||||
card_patterns[card.card_pattern] := card_pattern ;
|
const card_pattern : card_pattern =
|
||||||
s.card_patterns := card_patterns ;
|
get_force (card.card_pattern, s.card_patterns);
|
||||||
const cards : cards = s.cards ;
|
card_pattern.quantity := abs (card_pattern.quantity - 1n);
|
||||||
remove action.card_to_sell from map cards ;
|
const card_patterns : card_patterns = s.card_patterns;
|
||||||
s.cards := cards ;
|
card_patterns[card.card_pattern] := card_pattern;
|
||||||
const price : tez = card_pattern.coefficient * card_pattern.quantity ;
|
s.card_patterns := card_patterns;
|
||||||
const receiver : contract(unit) = get_contract(source) ;
|
const cards : cards = s.cards;
|
||||||
const op : operation = transaction(unit , price , receiver) ;
|
remove action.card_to_sell from map cards;
|
||||||
const operations : list(operation) = list op end ;
|
s.cards := cards;
|
||||||
end with (operations , s)
|
const price : tez = card_pattern.coefficient * card_pattern.quantity;
|
||||||
|
const receiver : contract (unit) = get_contract (source);
|
||||||
|
const op : operation = transaction (unit, price, receiver);
|
||||||
|
const operations : list (operation) = list [op]
|
||||||
|
} with (operations, s)
|
||||||
|
|
||||||
function buy_single(const action : action_buy_single ; const s : storage_type) : (list(operation) * storage_type) is
|
function buy_single (const action : action_buy_single;
|
||||||
begin
|
const s : storage) : return is
|
||||||
|
block {
|
||||||
// Check funds
|
// Check funds
|
||||||
const card_pattern : card_pattern = get_force(action.card_to_buy , s.card_patterns) ;
|
const card_pattern : card_pattern =
|
||||||
const price : tez = card_pattern.coefficient * (card_pattern.quantity + 1n) ;
|
get_force (action.card_to_buy, s.card_patterns);
|
||||||
if (price > amount) then failwith ("Not enough money") else skip ;
|
const price : tez =
|
||||||
|
card_pattern.coefficient * (card_pattern.quantity + 1n);
|
||||||
|
if price > amount then failwith ("Not enough money") else skip;
|
||||||
// Administrative procedure
|
// Administrative procedure
|
||||||
const operations : list(operation) = nil ;
|
const operations : list(operation) = nil;
|
||||||
// Increase quantity
|
// Increase quantity
|
||||||
card_pattern.quantity := card_pattern.quantity + 1n ;
|
card_pattern.quantity := card_pattern.quantity + 1n;
|
||||||
const card_patterns : card_patterns = s.card_patterns ;
|
const card_patterns : card_patterns = s.card_patterns;
|
||||||
card_patterns[action.card_to_buy] := card_pattern ;
|
card_patterns[action.card_to_buy] := card_pattern;
|
||||||
s.card_patterns := card_patterns ;
|
s.card_patterns := card_patterns;
|
||||||
// Add card
|
// Add card
|
||||||
const cards : cards = s.cards ;
|
const cards : cards = s.cards;
|
||||||
cards[s.next_id] := record
|
cards[s.next_id] := record [
|
||||||
card_owner = source ;
|
card_owner = source;
|
||||||
card_pattern = action.card_to_buy ;
|
card_pattern = action.card_to_buy
|
||||||
end ;
|
];
|
||||||
s.cards := cards ;
|
s.cards := cards;
|
||||||
s.next_id := s.next_id + 1n ;
|
s.next_id := s.next_id + 1n
|
||||||
end with (operations , s)
|
} with (operations, s)
|
||||||
|
|
||||||
function main(const action : action ; const s : storage_type) : (list(operation) * storage_type) is
|
function main (const action : parameter; const s : storage) : return is
|
||||||
block {skip} with
|
|
||||||
case action of
|
case action of
|
||||||
| Buy_single (bs) -> buy_single (bs , s)
|
Buy_single (bs) -> buy_single (bs, s)
|
||||||
| Sell_single (as) -> sell_single (as , s)
|
| Sell_single (as) -> sell_single (as, s)
|
||||||
| Transfer_single (at) -> transfer_single (at , s)
|
| Transfer_single (at) -> transfer_single (at, s)
|
||||||
end
|
end
|
||||||
|
@ -1,10 +1 @@
|
|||||||
// Test if conditional with trivial conditions in PascaLIGO
|
function main (const i : int) : int is if 1 = 1 then 42 else 0
|
||||||
|
|
||||||
function main (const i : int) : int is
|
|
||||||
begin
|
|
||||||
if 1 = 1 then
|
|
||||||
i := 42
|
|
||||||
else
|
|
||||||
i := 0
|
|
||||||
end with i
|
|
||||||
|
|
||||||
|
@ -1,16 +1,10 @@
|
|||||||
// Test if conditional in PascaLIGO
|
|
||||||
|
|
||||||
function main (const i : int) : int is
|
function main (const i : int) : int is
|
||||||
begin
|
block {
|
||||||
var result : int := 23 ;
|
var result : int := 23;
|
||||||
if i = 2 then
|
if i = 2 then result := 42 else result := 0
|
||||||
result := 42
|
} with result
|
||||||
else
|
|
||||||
result := 0
|
|
||||||
end with result
|
|
||||||
|
|
||||||
function foo (const b : bool) : int is
|
function foo (const b : bool) : int is
|
||||||
begin
|
block {
|
||||||
var x : int := 41 ;
|
const x : int = 41
|
||||||
x := 1 + (if b then x else main(x)) ;
|
} with 1 + (if b then x else main (x))
|
||||||
end with x
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
type some_type is int
|
type t is int
|
||||||
|
|
||||||
function main (const p : int ; const s : some_type) : (list(operation) * int) is
|
function main (const p : int ; const s : t) : list (operation) * int is
|
||||||
block { skip } // skip is a do nothing instruction, needed for empty blocks
|
block {
|
||||||
|
skip
|
||||||
|
} // skip is a do nothing instruction, needed for empty blocks
|
||||||
with ((nil : list(operation)), p + s)
|
with ((nil : list(operation)), p + s)
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
function hasherman512 (const s: bytes) : bytes is sha_512(s)
|
function hasherman512 (const s: bytes) : bytes is sha_512 (s)
|
||||||
|
|
||||||
function hasherman_blake (const s: bytes) : bytes is blake2b(s)
|
function hasherman_blake (const s: bytes) : bytes is blake2b (s)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Test PasaLIGO variable declarations inside of a block
|
// Test PasaLIGO variable declarations inside of a block
|
||||||
|
|
||||||
function main (const i : int) : int is block {
|
function main (const i : int) : int is block {
|
||||||
const j : int = 42 ;
|
const j : int = 42
|
||||||
} with j
|
} with j
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
// Test PascaLIGO top level declarations
|
// Test PascaLIGO top-level declarations
|
||||||
|
|
||||||
const foo : int = 42
|
const foo : int = 42
|
||||||
|
|
||||||
function main (const i : int) : int is
|
function main (const i : int) : int is i + foo
|
||||||
begin
|
|
||||||
skip
|
|
||||||
end with i + foo
|
|
||||||
|
@ -1,31 +1,29 @@
|
|||||||
//Test deep_access in PascalLigo
|
// Test deep access
|
||||||
type pii is (int*int)
|
|
||||||
type ppi is record x:pii; y:pii end
|
|
||||||
type ppp is (ppi*ppi)
|
|
||||||
|
|
||||||
function main (const toto : unit) : int is block {
|
type pii is int * int
|
||||||
var a : ppp := (
|
|
||||||
record
|
type ppi is record [x : pii; y : pii]
|
||||||
x = (0,1);
|
|
||||||
y = (10,11);
|
type ppp is ppi * ppi
|
||||||
end ,
|
|
||||||
record
|
function main (const toto : unit) : int is
|
||||||
x = (100,101);
|
block {
|
||||||
y = (110,111);
|
var a : ppp :=
|
||||||
end
|
(record [x = (0,1); y = (10,11)],
|
||||||
) ;
|
record [x = (100,101); y = (110,111)]);
|
||||||
a.0.x.0 := 2;
|
a.0.x.0 := 2;
|
||||||
const b:int = a.0.x.0;
|
} with a.0.x.0
|
||||||
} with b
|
|
||||||
|
|
||||||
|
|
||||||
function asymetric_tuple_access(const foo : unit) : int is block {
|
function asymetric_tuple_access (const foo : unit) : int is
|
||||||
var mytuple : int * (int * (int * int)) := (0,(1,(2,3))) ;
|
block {
|
||||||
} with mytuple.0 + mytuple.1.0 + mytuple.1.1.0 + mytuple.1.1.1
|
var tuple : int * (int * (int * int)) := (0,(1,(2,3)))
|
||||||
|
} with tuple.0 + tuple.1.0 + tuple.1.1.0 + tuple.1.1.1
|
||||||
|
|
||||||
type nested_record_t is record
|
type nested_record_t is
|
||||||
nesty : (record mymap : map(int,string) ; end) ;
|
record [nesty : record [mymap : map (int,string)]]
|
||||||
end
|
|
||||||
function nested_record (var nee : nested_record_t) : string is block {
|
function nested_record (var nee : nested_record_t) : string is
|
||||||
nee.nesty.mymap[1] := "one" ;
|
block {
|
||||||
} with ( get_force(1, nee.nesty.mymap) )
|
nee.nesty.mymap[1] := "one"
|
||||||
|
} with get_force (1, nee.nesty.mymap)
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
type action is
|
type parameter is
|
||||||
| Increment of int
|
Increment of int
|
||||||
| Decrement of int
|
| Decrement of int
|
||||||
|
|
||||||
function increment(const i : int ; const n : int) : int is
|
type storage is int
|
||||||
block { skip } with (i + n)
|
|
||||||
|
|
||||||
function decrement(const i : int ; const n : int) : int is
|
type return is list (operation) * storage
|
||||||
block { skip } with (i - n)
|
|
||||||
|
|
||||||
function main (const p : action ; const s : int) : (list(operation) * int) is
|
function increment (const i : int; const n : int) : int is i+n
|
||||||
block {skip} with ((nil : list(operation)),
|
|
||||||
case p of
|
function decrement (const i : int; const n : int) : int is i-n
|
||||||
| Increment (n) -> increment (s, n)
|
|
||||||
| Decrement (n) -> decrement (s, n)
|
const nop : list (operation) = nil
|
||||||
end)
|
|
||||||
|
function main (const action : parameter; const store : storage) : return is
|
||||||
|
case action of
|
||||||
|
Increment (n) -> (nop, increment (store, n))
|
||||||
|
| Decrement (n) -> (nop, decrement (store, n))
|
||||||
|
end
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
function main(const p : unit; const s : int) : list(operation) * int is
|
type parameter is unit
|
||||||
((list end : list(operation)), s + 1)
|
type storage is int
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
function main(const p : unit; const s : int) : list(operation) * int is
|
function main(const p : parameter; const s : storage) : return is
|
||||||
begin
|
((nil : list(operation)), s+1)
|
||||||
const ret : list(operation) * int = main(p, s)
|
|
||||||
end
|
function main (const p : parameter; const s : storage) : return is
|
||||||
with (ret.0, ret.1 + 1)
|
block {
|
||||||
|
const ret : return = main (p, s)
|
||||||
|
} with (ret.0, ret.1 + 1)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
type foo is
|
type t is
|
||||||
| Bar of int
|
Bar of int
|
||||||
| Baz
|
| Baz
|
||||||
|
|
||||||
function main (const f: foo) : int is
|
function main (const x : t) : int is
|
||||||
(case f of
|
case x of
|
||||||
| Bar (n) -> n
|
Bar (n) -> n
|
||||||
| Baz -> -1
|
| Baz -> -1
|
||||||
end)
|
end
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
function cb(const a : address; const s : unit) : list(operation) * unit is
|
type storage is unit
|
||||||
|
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
|
function cb (const a : address; const s : storage) : return is
|
||||||
block {
|
block {
|
||||||
const c : contract(unit) = get_entrypoint("%cb", a)
|
const c : contract (unit) = get_entrypoint ("%cb", a)
|
||||||
}
|
}
|
||||||
with (list transaction(unit, 0mutez, c) end, s)
|
with (list [transaction (unit, 0mutez, c)], s)
|
||||||
|
|
||||||
|
|
||||||
function cbo(const a : address; const s : unit) : list(operation) * unit is
|
function cbo (const a : address; const s : storage) : return is
|
||||||
block {
|
block {
|
||||||
const c : contract(unit) =
|
const c : contract (unit) =
|
||||||
case (get_entrypoint_opt("%cbo", a) : option(contract (unit))) of
|
case (get_entrypoint_opt ("%cbo", a) : option (contract (unit))) of
|
||||||
| Some (c) -> c
|
Some (c) -> c
|
||||||
| None -> (failwith ("entrypoint not found") : contract (unit))
|
| None -> (failwith ("entrypoint not found") : contract (unit))
|
||||||
end
|
end
|
||||||
}
|
} with (list [transaction(unit, 0mutez, c)], s)
|
||||||
with (list transaction(unit, 0mutez, c) end, s)
|
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
type myrec is record
|
type t is record [foo : nat; bar : string]
|
||||||
foo : nat;
|
|
||||||
bar : string;
|
|
||||||
end;
|
|
||||||
|
|
||||||
const a : myrec = record
|
const a : t = record [foo = 0n; bar = "bar"]
|
||||||
foo = 0n;
|
|
||||||
bar = "bar";
|
|
||||||
end;
|
|
||||||
|
|
||||||
const b : int = 2 ;
|
const b : int = 2
|
||||||
|
@ -1,37 +1,43 @@
|
|||||||
type param is
|
type parameter is
|
||||||
| Zero of nat
|
Zero of nat
|
||||||
| Pos of nat
|
| Pos of nat
|
||||||
|
|
||||||
function main (const p : param; const s : unit) : list(operation) * unit is
|
type storage is unit
|
||||||
|
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
|
function main (const p : parameter; const s : storage) : return is
|
||||||
block {
|
block {
|
||||||
case p of
|
case p of
|
||||||
| Zero (n) -> if n > 0n then failwith("fail") else skip
|
Zero (n) -> if n > 0n then failwith ("fail") else skip
|
||||||
| Pos (n) -> if n > 0n then skip else failwith("fail")
|
| Pos (n) -> if n > 0n then skip else failwith ("fail")
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
with ((nil : list(operation)), s)
|
with ((nil : list (operation)), s)
|
||||||
|
|
||||||
function foobar (const i : int) : int is
|
function foobar (const i : int) : int is
|
||||||
block {
|
block {
|
||||||
var p : param := Zero (42n) ;
|
var p : parameter := Zero (42n);
|
||||||
if i > 0 then block {
|
if i > 0 then {
|
||||||
i := i + 1 ;
|
i := i + 1;
|
||||||
if i > 10 then block {
|
if i > 10 then {
|
||||||
i := 20 ;
|
i := 20;
|
||||||
failwith ("who knows") ;
|
failwith ("who knows");
|
||||||
i := 30 ;
|
i := 30 // Should be no-op
|
||||||
} else skip
|
}
|
||||||
} else block {
|
else skip
|
||||||
case p of
|
|
||||||
| Zero (n) -> failwith ("wooo")
|
|
||||||
| Pos (n) -> skip
|
|
||||||
end
|
|
||||||
}
|
}
|
||||||
} with case p of
|
else
|
||||||
| Zero (n) -> i
|
case p of
|
||||||
| Pos (n) -> (failwith ("waaaa") : int)
|
Zero (n) -> failwith ("wooo")
|
||||||
end
|
| Pos (n) -> skip
|
||||||
|
end
|
||||||
|
} with
|
||||||
|
case p of
|
||||||
|
Zero (n) -> i
|
||||||
|
| Pos (n) -> (failwith ("waaaa") : int)
|
||||||
|
end
|
||||||
|
|
||||||
function failer(const p : int) : int is block {
|
function failer (const p : int) : int is block {
|
||||||
if p = 1 then failwith("some_string") else skip ;
|
if p = 1 then failwith ("some_string") else skip
|
||||||
} with p
|
} with p
|
||||||
|
@ -1,11 +1,2 @@
|
|||||||
// This was meant to test the for loop in PascaLIGO
|
|
||||||
// But for whatever reason, the LIGO compiler currently thinks this is a 'complex loop'
|
|
||||||
// even though it isn't.
|
|
||||||
// See this error:
|
|
||||||
// $ ligo dry-run for.ligo main 0 0
|
|
||||||
// bounded iterators: only simple for loops are supported yet
|
|
||||||
// {"loop_loc":"in file \"for.ligo\", line 4, characters 10-42"}
|
|
||||||
|
|
||||||
|
|
||||||
function main (const a: int) : int is
|
function main (const a: int) : int is
|
||||||
block { for i := 0 to 100 block { skip } } with i;
|
block { for i := 0 to 100 block { skip } } with i
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
// Test a PascaLIGO function with more complex logic than function.ligo
|
// Test a PascaLIGO function with more complex logic than function.ligo
|
||||||
|
|
||||||
function main (const i : int) : int is
|
function main (const i : int) : int is
|
||||||
begin
|
block {
|
||||||
var j : int := 0 ;
|
var j : int := 0;
|
||||||
var k : int := 1 ;
|
var k : int := 1;
|
||||||
j := k + i ;
|
j := k + i;
|
||||||
k := i + j ;
|
k := i + j
|
||||||
end with (k + j)
|
} with k + j
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
// Test a PascaLIGO function which uses other functions as subroutines
|
// Test a PascaLIGO function which uses other functions as subroutines
|
||||||
|
|
||||||
function inc ( const i : int ) : int is
|
function inc (const i : int) : int is i+1
|
||||||
block { skip } with i + 1
|
|
||||||
|
|
||||||
function double_inc ( const i : int ) : int is
|
function double_inc (const i : int) : int is inc (i+1)
|
||||||
block { skip } with inc(i + 1)
|
|
||||||
|
|
||||||
function foo ( const i : int ) : int is
|
function foo (const i : int) : int is inc (i) + double_inc (i)
|
||||||
block { skip } with inc(i) + double_inc(i)
|
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
// Test a trivial PascaLIGO function
|
// Test a trivial PascaLIGO function
|
||||||
|
|
||||||
function main (const i : int) : int is
|
function main (const i : int) : int is i
|
||||||
begin
|
|
||||||
skip
|
|
||||||
end with i
|
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
function cb(const s : unit) : list(operation) * unit is
|
type storage is unit
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
|
function cb (const s : storage) : return is
|
||||||
block {
|
block {
|
||||||
const c : contract(unit) = get_contract(source)
|
const c : contract (unit) = get_contract (source)
|
||||||
}
|
}
|
||||||
with (list transaction(unit, 0mutez, c) end, s)
|
with (list [transaction(unit, 0mutez, c)], s)
|
||||||
|
|
||||||
|
|
||||||
function cbo(const s : unit) : list(operation) * unit is
|
function cbo (const s : unit) : return is
|
||||||
block {
|
block {
|
||||||
const c : contract(unit) =
|
const c : contract (unit) =
|
||||||
case (get_contract_opt(source) : option(contract (unit))) of
|
case (get_contract_opt (source) : option (contract (unit))) of
|
||||||
| Some (c) -> c
|
Some (c) -> c
|
||||||
| None -> (failwith ("contract not found") : contract (unit))
|
| None -> (failwith ("contract not found") : contract (unit))
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
with (list transaction(unit, 0mutez, c) end, s)
|
with (list [transaction(unit, 0mutez, c)], s)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
type heap_element is int * string
|
type heap_elt is int * string
|
||||||
|
|
||||||
function heap_element_lt(const x : heap_element ; const y : heap_element) : bool is
|
function heap_elt_lt (const x : heap_elt;
|
||||||
block { skip } with x.0 < y.0
|
const y : heap_elt) : bool is x.0 < y.0
|
||||||
|
|
||||||
#include "heap.ligo"
|
#include "heap.ligo"
|
||||||
|
@ -1,93 +1,95 @@
|
|||||||
// Implementation of the heap data structure in PascaLIGO
|
// Implementation of the heap data structure in PascaLIGO
|
||||||
// See: https://en.wikipedia.org/wiki/Heap_%28data_structure%29
|
// See: https://en.wikipedia.org/wiki/Heap_%28data_structure%29
|
||||||
|
|
||||||
type heap is map(nat, heap_element) ;
|
type heap is map (nat, heap_elt)
|
||||||
|
|
||||||
function is_empty (const h : heap) : bool is
|
function is_empty (const h : heap) : bool is size (h) = 0n
|
||||||
block {skip} with size(h) = 0n
|
|
||||||
|
|
||||||
function get_top (const h : heap) : heap_element is
|
function get_top (const h : heap) : heap_elt is get_force (1n, h)
|
||||||
block {skip} with get_force(1n, h)
|
|
||||||
|
|
||||||
function pop_switch (const h : heap) : heap is
|
function pop_switch (const h : heap) : heap is
|
||||||
block {
|
block {
|
||||||
const result : heap_element = get_top (h) ;
|
const result : heap_elt = get_top (h);
|
||||||
const s : nat = size(h) ;
|
const s : nat = size (h);
|
||||||
const last : heap_element = get_force(s, h) ;
|
const last : heap_elt = get_force (s, h);
|
||||||
remove 1n from map h ;
|
remove 1n from map h;
|
||||||
h[1n] := last ;
|
h[1n] := last
|
||||||
} with h
|
} with h
|
||||||
|
|
||||||
function pop_ (const h : heap) : nat is
|
function pop_ (const h : heap) : nat is
|
||||||
begin
|
block {
|
||||||
const result : heap_element = get_top (h) ;
|
const result : heap_elt = get_top (h);
|
||||||
const s : nat = size(h) ;
|
const s : nat = size (h);
|
||||||
var current : heap_element := get_force(s, h) ;
|
var current : heap_elt := get_force (s, h);
|
||||||
const i : nat = 1n ;
|
const i : nat = 1n;
|
||||||
const left : nat = 2n * i ;
|
const left : nat = 2n * i;
|
||||||
const right : nat = left + 1n ;
|
const right : nat = left + 1n;
|
||||||
remove 1n from map h ;
|
remove 1n from map h;
|
||||||
h[1n] := current ;
|
h[1n] := current;
|
||||||
var largest : nat := i ;
|
var largest : nat := i;
|
||||||
if (left <= s and heap_element_lt(get_force(s , h) , get_force(left , h))) then
|
const tmp : heap_elt = get_force (s, h);
|
||||||
largest := left
|
if left <= s and heap_elt_lt (tmp, get_force (left,h))
|
||||||
else if (right <= s and heap_element_lt(get_force(s , h) , get_force(right , h))) then
|
then largest := left
|
||||||
largest := right
|
else
|
||||||
else skip
|
if right <= s and heap_elt_lt (tmp, get_force (right,h))
|
||||||
end with largest
|
then largest := right
|
||||||
|
else skip
|
||||||
|
} with largest
|
||||||
|
|
||||||
function insert (const h : heap ; const e : heap_element) : heap is
|
function insert (const h : heap ; const e : heap_elt) : heap is
|
||||||
begin
|
block {
|
||||||
var i : nat := size(h) + 1n ;
|
var i : nat := size (h) + 1n;
|
||||||
h[i] := e ;
|
h[i] := e;
|
||||||
var largest : nat := i ;
|
var largest : nat := i;
|
||||||
var parent : nat := 0n ;
|
var parent : nat := 0n;
|
||||||
while (largest =/= i) block {
|
while largest =/= i block {
|
||||||
parent := i / 2n ;
|
parent := i/2n;
|
||||||
largest := i ;
|
largest := i;
|
||||||
if (parent >= 1n) then block {
|
if parent >= 1n then {
|
||||||
if (heap_element_lt(get_force(parent , h) , get_force(i , h))) then block {
|
if heap_elt_lt (get_force (parent,h), get_force(i,h))) then {
|
||||||
largest := parent ;
|
largest := parent;
|
||||||
const tmp : heap_element = get_force(i , h) ;
|
const tmp : heap_elt = get_force (i,h);
|
||||||
h[i] := get_force(parent , h) ;
|
h[i] := get_force(parent, h);
|
||||||
h[parent] := tmp ;
|
h[parent] := tmp
|
||||||
} else skip
|
} else skip
|
||||||
} else skip
|
} else skip
|
||||||
}
|
}
|
||||||
end with h
|
} with h
|
||||||
|
|
||||||
function pop (const h : heap) : (heap * heap_element * nat) is
|
function pop (const h : heap) : heap * heap_elt * nat is
|
||||||
begin
|
block {
|
||||||
const result : heap_element = get_top (h) ;
|
const result : heap_elt = get_top (h);
|
||||||
var s : nat := size(h) ;
|
var s : nat := size (h);
|
||||||
const last : heap_element = get_force(s, h) ;
|
const last : heap_elt = get_force (s,h);
|
||||||
remove s from map h ;
|
remove s from map h;
|
||||||
h[1n] := last ;
|
h[1n] := last;
|
||||||
s := size(h) ;
|
s := size (h);
|
||||||
var i : nat := 0n ;
|
var i : nat := 0n;
|
||||||
var largest : nat := 1n ;
|
var largest : nat := 1n;
|
||||||
var left : nat := 0n ;
|
var left : nat := 0n;
|
||||||
var right : nat := 0n ;
|
var right : nat := 0n;
|
||||||
var c : nat := 0n ;
|
var c : nat := 0n;
|
||||||
while (largest =/= i) block {
|
while largest =/= i block {
|
||||||
c := c + 1n ;
|
c := c + 1n;
|
||||||
i := largest ;
|
i := largest;
|
||||||
left := 2n * i ;
|
left := 2n * i;
|
||||||
right := left + 1n ;
|
right := left + 1n;
|
||||||
if (left <= s) then begin
|
if left <= s then {
|
||||||
if (heap_element_lt(get_force(left , h) , get_force(i , h))) then begin
|
if heap_elt_lt (get_force (left,h), get_force(i,h)) then {
|
||||||
largest := left ;
|
largest := left;
|
||||||
const tmp : heap_element = get_force(i , h) ;
|
const tmp : heap_elt = get_force(i,h);
|
||||||
h[i] := get_force(left , h) ;
|
h[i] := get_force (left, h);
|
||||||
h[left] := tmp ;
|
h[left] := tmp
|
||||||
end else skip ;
|
} else skip
|
||||||
end else if (right <= s) then begin
|
}
|
||||||
if (heap_element_lt(get_force(right , h) , get_force(i , h))) then begin
|
else
|
||||||
largest := right ;
|
if right <= s then {
|
||||||
const tmp : heap_element = get_force(i , h) ;
|
if heap_elt_lt (get_force (right, h), get_force (i,h)) then {
|
||||||
h[i] := get_force(right , h) ;
|
largest := right;
|
||||||
h[left] := tmp ;
|
const tmp : heap_elt = get_force (i,h);
|
||||||
end else skip ;
|
h[i] := get_force (right, h);
|
||||||
end else skip ;
|
h[left] := tmp
|
||||||
}
|
} else skip
|
||||||
end with (h , result , c)
|
} else skip
|
||||||
|
}
|
||||||
|
} with (h, result, c)
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
// Test a PascaLIGO function which takes another PascaLIGO function as an argument
|
(* Test a PascaLIGO function which takes another function as an
|
||||||
|
argument *)
|
||||||
|
|
||||||
function foobar (const i : int) : int is
|
function foobar (const i : int) : int is
|
||||||
begin
|
block {
|
||||||
function foo (const i : int) : int is i;
|
function foo (const i : int) : int is i;
|
||||||
function bar (const f : int -> int) : int is f (i);
|
function bar (const f : int -> int) : int is f (i);
|
||||||
end with bar (foo);
|
} with bar (foo)
|
||||||
|
|
||||||
// higher order function with more than one argument
|
// higher order function with more than one argument
|
||||||
function higher2(const i : int; const f : int -> int): int is
|
|
||||||
begin
|
function higher2 (const i : int; const f : int -> int): int is f (i)
|
||||||
const ii: int = f (i)
|
|
||||||
end with ii
|
|
||||||
|
|
||||||
function foobar2 (const i : int) : int is
|
function foobar2 (const i : int) : int is
|
||||||
begin
|
block {
|
||||||
function foo2 (const i : int) : int is i
|
function foo2 (const i : int) : int is i
|
||||||
end with higher2 (i,foo2)
|
} with higher2 (i, foo2)
|
||||||
|
|
||||||
const a : int = 0;
|
const a : int = 0
|
||||||
|
|
||||||
function foobar3 (const i : int) : int is
|
function foobar3 (const i : int) : int is
|
||||||
begin
|
block {
|
||||||
function foo2 (const i : int) : int is a+i
|
function foo2 (const i : int) : int is a+i
|
||||||
end with higher2 (i,foo2)
|
} with higher2 (i, foo2)
|
||||||
|
|
||||||
function f (const i : int) : int is i
|
function f (const i : int) : int is i
|
||||||
|
|
||||||
@ -29,17 +29,15 @@ function g (const i : int) : int is f (i)
|
|||||||
|
|
||||||
function foobar4 (const i : int) : int is g (g (i))
|
function foobar4 (const i : int) : int is g (g (i))
|
||||||
|
|
||||||
function higher3(const i : int; const f : int -> int; const g : int -> int)
|
function higher3 (const i : int;
|
||||||
: int is
|
const f : int -> int;
|
||||||
begin
|
const g : int -> int) : int is f (g (i))
|
||||||
const ii : int = f(g(i))
|
|
||||||
end with ii
|
|
||||||
|
|
||||||
function foobar5 (const i : int) : int is
|
function foobar5 (const i : int) : int is
|
||||||
begin
|
block {
|
||||||
const a : int = 0;
|
const a : int = 0;
|
||||||
function foo (const i : int) : int is a+i;
|
function foo (const i : int) : int is a+i;
|
||||||
function goo (const i : int) : int is foo (i)
|
function goo (const i : int) : int is foo (i)
|
||||||
end with higher3(i,foo,goo)
|
} with higher3 (i, foo, goo)
|
||||||
|
|
||||||
function foobar6 (const i : int) : int -> int is f
|
function foobar6 (const i : int) : int -> int is f
|
||||||
|
@ -1 +1 @@
|
|||||||
function main (const kh: key_hash) : contract(unit) is implicit_account(kh)
|
function main (const kh: key_hash) : contract (unit) is implicit_account (kh)
|
||||||
|
@ -1,2 +1 @@
|
|||||||
function main (const i: int) : option(nat) is
|
function main (const i : int) : option (nat) is is_nat (i)
|
||||||
block {skip} with is_nat(i)
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
function check_hash_key (const kh1 : key_hash; const k2 : key) : bool*key_hash is block {
|
function check_hash_key (const kh1 : key_hash;
|
||||||
var ret : bool := False ;
|
const k2 : key) : bool * key_hash is
|
||||||
var kh2 : key_hash := crypto_hash_key(k2) ;
|
block {
|
||||||
if kh1 = kh2 then ret := True else skip;
|
var ret : bool := False;
|
||||||
} with (ret, kh2)
|
var kh2 : key_hash := crypto_hash_key (k2);
|
||||||
|
if kh1 = kh2 then ret := True else skip
|
||||||
|
} with (ret, kh2)
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
function f (const x : unit) : unit is
|
function f (const x : unit) : unit is Unit
|
||||||
begin skip end with unit
|
|
||||||
|
|
||||||
function main (const p : unit ; const s : unit) : unit is
|
function main (const p : unit ; const s : unit) : unit is f (Unit)
|
||||||
begin
|
|
||||||
var y : unit := f(unit) ;
|
|
||||||
end with y
|
|
||||||
|
@ -1,49 +1,33 @@
|
|||||||
// Test list type and related built-in functions in PascaLIGO
|
// Test list type and related built-in functions in PascaLIGO
|
||||||
|
|
||||||
type foobar is list(int)
|
type foobar is list (int)
|
||||||
|
|
||||||
const fb : foobar = list
|
const fb : foobar = list [23; 42]
|
||||||
23 ;
|
|
||||||
42 ;
|
|
||||||
end
|
|
||||||
|
|
||||||
const fb2 : foobar = 144 # fb
|
const fb2 : foobar = 144 # fb
|
||||||
|
|
||||||
const fb3 : foobar = cons(688 , fb2)
|
const fb3 : foobar = cons (688, fb2)
|
||||||
|
|
||||||
function size_ (const m : foobar) : nat is
|
function size_ (const m : foobar) : nat is size (m)
|
||||||
block {skip} with (size(m))
|
|
||||||
|
|
||||||
// function hdf (const m : foobar) : int is begin skip end with hd(m)
|
// function hdf (const m : foobar) : int is hd (m)
|
||||||
|
|
||||||
const bl : foobar = list
|
const bl : foobar = list [144; 51; 42; 120; 421]
|
||||||
144 ;
|
|
||||||
51 ;
|
|
||||||
42 ;
|
|
||||||
120 ;
|
|
||||||
421 ;
|
|
||||||
end
|
|
||||||
|
|
||||||
function fold_op (const s: list(int)) : int is
|
function fold_op (const s : list (int)) : int is
|
||||||
begin
|
|
||||||
function aggregate (const prec: int; const cur: int) : int is
|
|
||||||
begin
|
|
||||||
skip
|
|
||||||
end with prec + cur
|
|
||||||
end with list_fold(aggregate, s, 10)
|
|
||||||
|
|
||||||
|
|
||||||
function iter_op (const s : list(int)) : int is
|
|
||||||
begin
|
|
||||||
var r : int := 0 ;
|
|
||||||
function aggregate (const i : int) : unit is
|
|
||||||
begin
|
|
||||||
r := r + i ;
|
|
||||||
end with unit ;
|
|
||||||
list_iter(aggregate, s) ;
|
|
||||||
end with r
|
|
||||||
|
|
||||||
function map_op (const s : list(int)) : list(int) is
|
|
||||||
block {
|
block {
|
||||||
function increment (const i : int) : int is block { skip } with i + 1
|
function aggregate (const prec: int; const cur: int) : int is prec+cur
|
||||||
} with list_map(increment, s)
|
} with list_fold (aggregate, s, 10)
|
||||||
|
|
||||||
|
function iter_op (const s : list (int)) : int is
|
||||||
|
block {
|
||||||
|
var r : int := 0;
|
||||||
|
function aggregate (const i : int) : unit is
|
||||||
|
block { r := r + i } with unit;
|
||||||
|
list_iter (aggregate, s)
|
||||||
|
} with r
|
||||||
|
|
||||||
|
function map_op (const s : list (int)) : list (int) is
|
||||||
|
block {
|
||||||
|
function increment (const i : int) : int is i+1
|
||||||
|
} with list_map (increment, s)
|
||||||
|
@ -1,193 +1,188 @@
|
|||||||
// Test while loops in PascaLIGO
|
// Test while loops in PascaLIGO
|
||||||
|
|
||||||
function counter (var n : nat) : nat is block {
|
function counter (var n : nat) : nat is
|
||||||
var i : nat := 0n ;
|
block {
|
||||||
while i < n block {
|
var i : nat := 0n;
|
||||||
i := i + 1n;
|
while i < n block {
|
||||||
}
|
i := i + 1n
|
||||||
} with i
|
}
|
||||||
|
} with i
|
||||||
|
|
||||||
function while_sum (var n : nat) : nat is block {
|
function while_sum (var n : nat) : nat is
|
||||||
var i : nat := 0n ;
|
block {
|
||||||
var r : nat := 0n ;
|
var i : nat := 0n;
|
||||||
while i < n block {
|
var r : nat := 0n;
|
||||||
i := i + 1n;
|
while i < n block {
|
||||||
r := r + i;
|
i := i + 1n;
|
||||||
}
|
r := r + i
|
||||||
} with r
|
}
|
||||||
|
} with r
|
||||||
|
|
||||||
function for_sum (var n : nat) : int is block {
|
function for_sum (var n : nat) : int is
|
||||||
var acc : int := 0 ;
|
block {
|
||||||
for i := 1 to int(n)
|
var acc : int := 0;
|
||||||
begin
|
for i := 1 to int (n)
|
||||||
acc := acc + i;
|
block {
|
||||||
end
|
acc := acc + i
|
||||||
} with acc
|
}
|
||||||
|
} with acc
|
||||||
|
|
||||||
function for_collection_list (var nee : unit) : (int * string) is block {
|
function for_collection_list (var nee : unit) : (int * string) is
|
||||||
var acc : int := 0;
|
block {
|
||||||
var st : string := "to";
|
var acc : int := 0;
|
||||||
var mylist : list(int) := list 1; 1; 1 end;
|
var st : string := "to";
|
||||||
for x in list mylist
|
var mylist : list (int) := list [1; 1; 1];
|
||||||
begin
|
for x in list mylist
|
||||||
|
block {
|
||||||
|
acc := acc + x;
|
||||||
|
st := st ^ "to"
|
||||||
|
}
|
||||||
|
} with (acc, st)
|
||||||
|
|
||||||
|
function for_collection_set (var nee : unit) : int * string is
|
||||||
|
block {
|
||||||
|
var acc : int := 0;
|
||||||
|
var st : string := "to";
|
||||||
|
var myset : set (int) := set [1; 2; 3];
|
||||||
|
for x in set myset block {
|
||||||
acc := acc + x;
|
acc := acc + x;
|
||||||
st := st ^ "to";
|
st := st ^ "to"
|
||||||
end
|
}
|
||||||
} with (acc, st)
|
} with (acc, st)
|
||||||
|
|
||||||
function for_collection_set (var nee : unit) : (int * string) is block {
|
function for_collection_if_and_local_var (var nee : unit) : int is
|
||||||
var acc : int := 0;
|
block {
|
||||||
var st : string := "to";
|
var acc : int := 0;
|
||||||
var myset : set(int) := set 1; 2; 3 end;
|
const theone : int = 1;
|
||||||
for x in set myset
|
var myset : set (int) := set [1; 2; 3];
|
||||||
begin
|
for x in set myset block {
|
||||||
acc := acc + x ;
|
const thetwo : int = 2;
|
||||||
st := st^"to" ;
|
if x = theone then acc := acc + x
|
||||||
end
|
else if x = thetwo then acc := acc + thetwo
|
||||||
} with (acc, st)
|
else acc := acc + 10
|
||||||
|
}
|
||||||
|
} with acc
|
||||||
|
|
||||||
function for_collection_if_and_local_var (var nee : unit) : int is block {
|
function for_collection_rhs_capture (var nee : unit) : int is
|
||||||
var acc : int := 0 ;
|
block {
|
||||||
const theone : int = 1 ;
|
var acc : int := 0;
|
||||||
var myset : set(int) := set 1 ; 2 ; 3 end ;
|
const mybigint : int = 1000;
|
||||||
for x in set myset
|
var myset : set (int) := set [1; 2; 3];
|
||||||
begin
|
for x in set myset block {
|
||||||
const thetwo : int = 2 ;
|
if x = 1 then acc := acc + mybigint
|
||||||
if x=theone then
|
else acc := acc + 10
|
||||||
acc := acc + x
|
}
|
||||||
else if x=thetwo then
|
} with acc
|
||||||
acc := acc + thetwo;
|
|
||||||
else
|
|
||||||
acc := acc + 10;
|
|
||||||
end
|
|
||||||
} with acc
|
|
||||||
|
|
||||||
function for_collection_rhs_capture (var nee : unit) : int is block {
|
function for_collection_proc_call (var nee : unit) : int is
|
||||||
var acc : int := 0 ;
|
block {
|
||||||
const mybigint : int = 1000 ;
|
var acc : int := 0;
|
||||||
var myset : set(int) := set 1 ; 2 ; 3 end ;
|
var myset : set (int) := set [1; 2; 3];
|
||||||
for x in set myset
|
for x in set myset block {
|
||||||
begin
|
if x = 1 then
|
||||||
if x=1 then acc := acc + mybigint;
|
acc := acc + for_collection_rhs_capture (unit)
|
||||||
else acc := acc + 10;
|
else acc := acc + 10
|
||||||
end
|
}
|
||||||
} with acc
|
} with acc
|
||||||
|
|
||||||
function for_collection_proc_call (var nee : unit) : int is block {
|
function for_collection_comp_with_acc (var nee : unit) : int is
|
||||||
var acc : int := 0 ;
|
block {
|
||||||
var myset : set(int) := set 1 ; 2 ; 3 end ;
|
var myint : int := 0;
|
||||||
for x in set myset
|
var mylist : list (int) := list [1; 10; 15];
|
||||||
begin
|
for x in list mylist block {
|
||||||
if x=1 then
|
|
||||||
acc := acc + for_collection_rhs_capture(unit);
|
|
||||||
else
|
|
||||||
acc := acc + 10;
|
|
||||||
end
|
|
||||||
} with acc
|
|
||||||
|
|
||||||
function for_collection_comp_with_acc (var nee : unit) : int is block {
|
|
||||||
var myint : int := 0 ;
|
|
||||||
var mylist : list(int) := list 1 ; 10 ; 15 end;
|
|
||||||
for x in list mylist
|
|
||||||
begin
|
|
||||||
if x < myint then skip;
|
if x < myint then skip;
|
||||||
else myint := myint + 10
|
else myint := myint + 10
|
||||||
end
|
}
|
||||||
} with myint
|
} with myint
|
||||||
|
|
||||||
function for_collection_with_patches (var nee : unit) : map(string,int) is block {
|
function for_collection_with_patches (var nee : unit) : map (string,int) is
|
||||||
var myint : int := 12 ;
|
block {
|
||||||
var mylist : list(string) := list "I"; "am"; "foo" end;
|
var myint : int := 12;
|
||||||
var mymap : map(string,int) := map end;
|
var mylist : list (string) := list ["I"; "am"; "foo"];
|
||||||
for x in list mylist
|
var mymap : map (string,int) := map [];
|
||||||
begin
|
for x in list mylist block {
|
||||||
patch mymap with map [x -> myint];
|
patch mymap with map [x -> myint]
|
||||||
end
|
}
|
||||||
} with mymap
|
} with mymap
|
||||||
|
|
||||||
function for_collection_empty (var nee : unit) : int is block {
|
function for_collection_empty (var nee : unit) : int is
|
||||||
var acc : int := 0 ;
|
block {
|
||||||
var myset : set(int) := set 1; 2; 3 end;
|
var acc : int := 0;
|
||||||
for x in set myset
|
var myset : set(int) := set [1; 2; 3];
|
||||||
begin
|
for x in set myset block {
|
||||||
skip
|
skip
|
||||||
end
|
}
|
||||||
} with acc
|
} with acc
|
||||||
|
|
||||||
function for_collection_map_kv (var nee : unit) : (int * string) is block {
|
function for_collection_map_kv (var nee : unit) : int * string is
|
||||||
var acc : int := 0;
|
block {
|
||||||
var st : string := "";
|
var acc : int := 0;
|
||||||
var mymap : map(string,int) := map "1" -> 1; "2" -> 2; "3" -> 3 end;
|
var st : string := "";
|
||||||
for k -> v in map mymap
|
var mymap : map (string, int) := map ["1" -> 1; "2" -> 2; "3" -> 3];
|
||||||
begin
|
for k -> v in map mymap block {
|
||||||
acc := acc + v;
|
acc := acc + v;
|
||||||
st := st ^ k;
|
st := st ^ k;
|
||||||
end
|
}
|
||||||
} with (acc, st)
|
} with (acc, st)
|
||||||
|
|
||||||
function for_collection_map_k (var nee : unit) : string is block {
|
function for_collection_map_k (var nee : unit) : string is
|
||||||
var st : string := "" ;
|
block {
|
||||||
var mymap : map(string,int) := map "1" -> 1 ; "2" -> 2 ; "3" -> 3 end ;
|
var st : string := "";
|
||||||
for k in map mymap
|
var mymap : map (string, int) := map ["1" -> 1; "2" -> 2; "3" -> 3];
|
||||||
begin
|
for k in map mymap block {
|
||||||
st := st ^ k;
|
st := st ^ k
|
||||||
end
|
}
|
||||||
} with st
|
} with st
|
||||||
|
|
||||||
function nested_for_collection (var nee : unit) : (int*string) is block {
|
function nested_for_collection (var nee : unit) : int * string is
|
||||||
var myint : int := 0;
|
block {
|
||||||
var mystoo : string := "";
|
var myint : int := 0;
|
||||||
var mylist : list(int) := list 1 ; 2 ; 3 end ;
|
var mystoo : string := "";
|
||||||
var mymap : map(string,string) := map " one" -> "," ; "two" -> " " end ;
|
var mylist : list(int) := list [1; 2; 3];
|
||||||
|
var mymap : map (string, string) := map [" one" -> ","; "two" -> " "];
|
||||||
|
for i in list mylist block {
|
||||||
|
myint := myint + i;
|
||||||
|
var myset : set (string) := set ["1"; "2"; "3"];
|
||||||
|
for st in set myset block {
|
||||||
|
myint := myint + i;
|
||||||
|
mystoo := mystoo ^ st;
|
||||||
|
for k -> v in map mymap block {
|
||||||
|
mystoo := mystoo ^ k ^ v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} with (myint, mystoo)
|
||||||
|
|
||||||
for i in list mylist
|
function nested_for_collection_local_var (var nee : unit) : int*string is
|
||||||
begin
|
block {
|
||||||
myint := myint + i ;
|
var myint : int := 0;
|
||||||
var myset : set(string) := set "1" ; "2" ; "3" end ;
|
var myst : string := "";
|
||||||
for st in set myset
|
var mylist : list (int) := list [1; 2; 3];
|
||||||
begin
|
for i in list mylist block {
|
||||||
myint := myint + i ;
|
var myst_loc : string := "";
|
||||||
mystoo := mystoo ^ st ;
|
myint := myint + i;
|
||||||
for k -> v in map mymap
|
var myset : set (string) := set ["1"; "2"; "3"];
|
||||||
begin
|
for st in set myset block {
|
||||||
mystoo := mystoo ^ k ^ v ;
|
myint := myint + i;
|
||||||
end
|
myst_loc := myst_loc ^ st;
|
||||||
end
|
};
|
||||||
end
|
myst := myst_loc ^ myst
|
||||||
} with (myint,mystoo)
|
}
|
||||||
|
} with (myint, myst)
|
||||||
function nested_for_collection_local_var (var nee : unit) : (int*string) is block {
|
|
||||||
var myint : int := 0;
|
|
||||||
var myst : string := "";
|
|
||||||
var mylist : list(int) := list 1 ; 2 ; 3 end ;
|
|
||||||
|
|
||||||
for i in list mylist
|
|
||||||
begin
|
|
||||||
var myst_loc : string := "" ;
|
|
||||||
myint := myint + i ;
|
|
||||||
var myset : set(string) := set "1" ; "2" ; "3" end ;
|
|
||||||
for st in set myset
|
|
||||||
begin
|
|
||||||
myint := myint + i ;
|
|
||||||
myst_loc := myst_loc ^ st ;
|
|
||||||
end;
|
|
||||||
myst := myst_loc ^ myst ;
|
|
||||||
end
|
|
||||||
} with (myint,myst)
|
|
||||||
|
|
||||||
function dummy (const n : nat) : nat is block {
|
function dummy (const n : nat) : nat is block {
|
||||||
while False block { skip }
|
while False block { skip }
|
||||||
} with n
|
} with n
|
||||||
|
|
||||||
function inner_capture_in_conditional_block (var nee : unit) : bool*int is block {
|
function inner_capture_in_conditional_block (var nee : unit) : bool * int is
|
||||||
var count : int := 1 ;
|
block {
|
||||||
var ret : bool := False ;
|
var count : int := 1;
|
||||||
var mylist : list(int) := list 1 ; 2 ; 3 end ;
|
var ret : bool := False;
|
||||||
for it1 in list mylist block {
|
var mylist : list (int) := list [1; 2; 3];
|
||||||
for it2 in list mylist block {
|
for it1 in list mylist block {
|
||||||
if count = it2 then ret := not (ret)
|
for it2 in list mylist block {
|
||||||
else skip;
|
if count = it2 then ret := not (ret) else skip
|
||||||
};
|
};
|
||||||
count := count + 1;
|
count := count + 1
|
||||||
}
|
}
|
||||||
} with (ret,count)
|
} with (ret, count)
|
||||||
|
@ -1,23 +1,20 @@
|
|||||||
// Test map type and related built-in functions in PascaLIGO
|
// Test map type and related built-in functions in PascaLIGO
|
||||||
|
|
||||||
type foobar is map(int, int)
|
type foobar is map (int, int)
|
||||||
|
|
||||||
const empty_map : foobar = map end
|
const empty_map : foobar = map []
|
||||||
|
|
||||||
const map1 : foobar = map
|
const map1 : foobar = map [
|
||||||
144 -> 23 ;
|
144 -> 23;
|
||||||
51 -> 23 ;
|
51 -> 23;
|
||||||
42 -> 23 ;
|
42 -> 23;
|
||||||
120 -> 23 ;
|
120 -> 23;
|
||||||
421 -> 23 ;
|
421 -> 23]
|
||||||
end
|
|
||||||
const map2 : foobar = map
|
|
||||||
23 -> 0 ;
|
|
||||||
42 -> 0 ;
|
|
||||||
end
|
|
||||||
|
|
||||||
function set_ (var n : int ; var m : foobar) : foobar is block {
|
const map2 : foobar = map [23 -> 0; 42 -> 0]
|
||||||
m[23] := n ;
|
|
||||||
|
function set_ (var n : int; var m : foobar) : foobar is block {
|
||||||
|
m[23] := n
|
||||||
} with m
|
} with m
|
||||||
|
|
||||||
|
|
||||||
@ -25,50 +22,43 @@ function rm (var m : foobar) : foobar is block {
|
|||||||
remove 42 from map m
|
remove 42 from map m
|
||||||
} with m
|
} with m
|
||||||
|
|
||||||
function patch_ (var m: foobar) : foobar is block {
|
function patch_ (var m : foobar) : foobar is block {
|
||||||
patch m with map [0 -> 5; 1 -> 6; 2 -> 7]
|
patch m with map [0 -> 5; 1 -> 6; 2 -> 7]
|
||||||
} with m
|
} with m
|
||||||
|
|
||||||
function patch_deep (var m: foobar * nat) : foobar * nat is
|
function patch_deep (var m : foobar * nat) : foobar * nat is
|
||||||
begin patch m.0 with map [1 -> 9]; end with m
|
block { patch m.0 with map [1 -> 9] } with m
|
||||||
|
|
||||||
function size_ (const m : foobar) : nat is
|
function size_ (const m : foobar) : nat is size (m)
|
||||||
block {skip} with (size(m))
|
|
||||||
|
|
||||||
function gf (const m : foobar) : int is begin skip end with get_force(23, m)
|
function gf (const m : foobar) : int is get_force (23, m)
|
||||||
|
|
||||||
function get (const m : foobar) : option(int) is
|
function get (const m : foobar) : option (int) is m[42]
|
||||||
begin
|
|
||||||
skip
|
|
||||||
end with m[42]
|
|
||||||
|
|
||||||
function get_ (const m : foobar) : option(int) is
|
function get_ (const m : foobar) : option (int) is map_get (42, m)
|
||||||
begin
|
|
||||||
skip
|
|
||||||
end with map_get(42 , m)
|
|
||||||
|
|
||||||
function mem (const k: int; const m: foobar) : bool is map_mem(k, m)
|
function mem (const k: int; const m: foobar) : bool is map_mem (k, m)
|
||||||
|
|
||||||
function iter_op (const m : foobar) : unit is
|
function iter_op (const m : foobar) : unit is
|
||||||
block {
|
block {
|
||||||
function aggregate (const i : int ; const j : int) : unit is block
|
function aggregate (const i : int; const j : int) : unit is block
|
||||||
{ if (i=j) then skip else failwith("fail") } with unit ;
|
{ if i=j then skip else failwith ("fail") } with unit
|
||||||
// map_iter(m , aggregate) ;
|
} with map_iter (aggregate, m)
|
||||||
} with map_iter(aggregate, m) ;
|
|
||||||
|
|
||||||
function map_op (const m : foobar) : foobar is
|
function map_op (const m : foobar) : foobar is
|
||||||
block {
|
block {
|
||||||
function increment (const i : int ; const j : int) : int is block { skip } with j + 1 ;
|
function increment (const i : int; const j : int) : int is j+1
|
||||||
} with map_map(increment, m) ;
|
} with map_map (increment, m)
|
||||||
|
|
||||||
function fold_op (const m : foobar) : int is
|
function fold_op (const m : foobar) : int is
|
||||||
block {
|
block {
|
||||||
function aggregate (const i : int ; const j : (int * int)) : int is block { skip } with i + j.0 + j.1 ;
|
function aggregate (const i : int; const j : int * int) : int is
|
||||||
} with map_fold(aggregate, m , 10)
|
i + j.0 + j.1
|
||||||
|
} with map_fold(aggregate, m, 10)
|
||||||
|
|
||||||
function deep_op (var m : foobar) : foobar is
|
function deep_op (var m : foobar) : foobar is
|
||||||
block {
|
block {
|
||||||
var coco : (int*foobar) := (0, m);
|
var coco : int * foobar := (0, m);
|
||||||
remove 42 from map coco.1 ;
|
remove 42 from map coco.1;
|
||||||
coco.1[32] := 16 ;
|
coco.1[32] := 16
|
||||||
} with coco.1
|
} with coco.1
|
||||||
|
@ -1,37 +1,37 @@
|
|||||||
// Test the pattern matching functionality of PascaLIGO
|
// Test the pattern matching functionality of PascaLIGO
|
||||||
|
|
||||||
function match_bool (const i : int) : int is
|
function match_bool (const i : int) : int is
|
||||||
begin
|
block {
|
||||||
var result : int := 23 ;
|
var result : int := 23;
|
||||||
case i = 2 of
|
case i = 2 of
|
||||||
| True -> result := 42
|
True -> result := 42
|
||||||
| False -> result := 0
|
| False -> result := 0
|
||||||
end
|
end
|
||||||
end with result
|
} with result
|
||||||
|
|
||||||
function match_option (const o : option(int)) : int is
|
function match_option (const o : option (int)) : int is
|
||||||
begin
|
block {
|
||||||
var result : int := 23 ;
|
var result : int := 23;
|
||||||
case o of
|
case o of
|
||||||
| None -> skip
|
None -> skip
|
||||||
| Some (s) -> result := s
|
| Some (s) -> result := s
|
||||||
end
|
end
|
||||||
end with result
|
} with result
|
||||||
|
|
||||||
function match_expr_bool (const i : int) : int is
|
function match_expr_bool (const i : int) : int is
|
||||||
case i = 2 of
|
case i = 2 of
|
||||||
| True -> 42
|
True -> 42
|
||||||
| False -> 0
|
| False -> 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function match_expr_option (const o : option(int)) : int is
|
function match_expr_option (const o : option (int)) : int is
|
||||||
case o of
|
case o of
|
||||||
| None -> 42
|
None -> 42
|
||||||
| Some (s) -> s
|
| Some (s) -> s
|
||||||
end
|
end
|
||||||
|
|
||||||
function match_expr_list (const l : list(int)) : int is
|
function match_expr_list (const l : list (int)) : int is
|
||||||
case l of
|
case l of
|
||||||
| nil -> -1
|
nil -> -1
|
||||||
| hd # tl -> hd
|
| hd # tl -> hd
|
||||||
end
|
end
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
// Test functions with several parameters in PascaLIGO
|
// Test functions with several parameters in PascaLIGO
|
||||||
|
|
||||||
function ab(const a : int; const b : int) : int is
|
function ab (const a : int; const b : int) : int is a+b
|
||||||
begin skip end with (a + b)
|
|
||||||
|
|
||||||
function abcd(const a : int; const b : int; const c : int; const d : int) : int is
|
function abcd (const a : int;
|
||||||
begin skip end with (a + b + c + d + 2)
|
const b : int;
|
||||||
|
const c : int;
|
||||||
|
const d : int) : int is a+b+c+d+2
|
||||||
|
|
||||||
function abcde(const a : int; const b : int; const c : int; const d : int; const e : int) : int is
|
function abcde (const a : int;
|
||||||
begin skip end with (c + e + 3)
|
const b : int;
|
||||||
|
const c : int;
|
||||||
|
const d : int;
|
||||||
|
const e : int) : int is c+e+3
|
||||||
|
@ -1,118 +1,150 @@
|
|||||||
// storage type
|
// storage type
|
||||||
type threshold_t is nat
|
|
||||||
type max_proposal_t is nat
|
|
||||||
type max_message_size_t is nat
|
|
||||||
type state_hash_t is bytes
|
|
||||||
type addr_set_t is set(address)
|
|
||||||
type message_store_t is map(bytes,addr_set_t)
|
|
||||||
type proposal_counters_t is map(address,nat)
|
|
||||||
|
|
||||||
type storage_t is record
|
type threshold is nat
|
||||||
state_hash : state_hash_t ;
|
type max_proposal is nat
|
||||||
threshold : threshold_t ;
|
type max_message_size is nat
|
||||||
max_proposal : max_proposal_t ;
|
type state_hash is bytes
|
||||||
max_message_size : max_message_size_t ;
|
type addr_set is set (address)
|
||||||
authorized_addresses : addr_set_t ;
|
type message_store is map (bytes, addr_set)
|
||||||
message_store : message_store_t ;
|
type proposal_counters is map (address, nat)
|
||||||
proposal_counters : proposal_counters_t ;
|
|
||||||
end
|
type storage is
|
||||||
|
record [
|
||||||
|
state_hash : state_hash;
|
||||||
|
threshold : threshold;
|
||||||
|
max_proposal : max_proposal;
|
||||||
|
max_message_size : max_message_size;
|
||||||
|
authorized_addresses : addr_set;
|
||||||
|
message_store : message_store;
|
||||||
|
proposal_counters : proposal_counters
|
||||||
|
]
|
||||||
|
|
||||||
// I/O types
|
// I/O types
|
||||||
type message_t is (bytes -> list(operation))
|
|
||||||
type send_pt is message_t
|
type message is bytes -> list (operation)
|
||||||
type withdraw_pt is message_t
|
type send_pt is message
|
||||||
|
type withdraw_pt is message
|
||||||
type default_pt is unit
|
type default_pt is unit
|
||||||
|
|
||||||
type contract_return_t is (list(operation) * storage_t)
|
type return is list (operation) * storage
|
||||||
|
|
||||||
type entry_point_t is
|
type parameter is
|
||||||
| Send of send_pt
|
Send of send_pt
|
||||||
| Withdraw of withdraw_pt
|
| Withdraw of withdraw_pt
|
||||||
| Default of default_pt
|
| Default of default_pt
|
||||||
|
|
||||||
|
function send (const param : send_pt; const s : storage) : return is
|
||||||
|
block {
|
||||||
|
// check sender against the authorized addresses
|
||||||
|
|
||||||
function send (const param : send_pt; const s : storage_t) : contract_return_t is block {
|
if not set_mem (sender, s.authorized_addresses)
|
||||||
|
then failwith("Unauthorized address")
|
||||||
|
else skip;
|
||||||
|
|
||||||
// check sender against the authorized addresses
|
// check message size against the stored limit
|
||||||
if not set_mem(sender,s.authorized_addresses) then failwith("Unauthorized address") else skip ;
|
|
||||||
|
|
||||||
// check message size against the stored limit
|
var message : message := param;
|
||||||
var message : message_t := param ;
|
const packed_msg : bytes = bytes_pack (message);
|
||||||
const packed_msg : bytes = bytes_pack(message) ;
|
if size (packed_msg) > s.max_message_size
|
||||||
if size(packed_msg) > s.max_message_size then failwith("Message size exceed maximum limit")
|
then failwith ("Message size exceed maximum limit")
|
||||||
else skip ;
|
else skip;
|
||||||
|
|
||||||
// compute the new set of addresses associated with the message and update counters
|
(* compute the new set of addresses associated with the message and
|
||||||
var new_store : addr_set_t := set_empty ;
|
update counters *)
|
||||||
case map_get(packed_msg, s.message_store) of
|
|
||||||
| Some(voters) -> block { // the message is already stored
|
|
||||||
// increment the counter only if the sender isn't already associated with the message
|
|
||||||
if set_mem(sender,voters) then skip
|
|
||||||
else s.proposal_counters[sender] := get_force(sender,s.proposal_counters) + 1n ;
|
|
||||||
|
|
||||||
new_store := set_add(sender,voters)
|
var new_store : addr_set := set_empty;
|
||||||
}
|
|
||||||
| None -> block { // the message has never been received before
|
|
||||||
s.proposal_counters[sender] := get_force(sender,s.proposal_counters) + 1n ;
|
|
||||||
new_store := set [sender];
|
|
||||||
}
|
|
||||||
end ;
|
|
||||||
|
|
||||||
// check sender counters against the maximum number of proposal
|
case map_get (packed_msg, s.message_store) of
|
||||||
var sender_proposal_counter : nat := get_force(sender,s.proposal_counters) ;
|
Some (voters) ->
|
||||||
if sender_proposal_counter > s.max_proposal then failwith("Maximum number of proposal reached")
|
block {
|
||||||
else skip ;
|
(* The message is already stored.
|
||||||
|
Increment the counter only if the sender is not already
|
||||||
|
associated with the message. *)
|
||||||
|
if set_mem (sender, voters)
|
||||||
|
then skip
|
||||||
|
else s.proposal_counters[sender] :=
|
||||||
|
get_force (sender, s.proposal_counters) + 1n;
|
||||||
|
|
||||||
// check the threshold
|
new_store := set_add(sender,voters)
|
||||||
var ret_ops : list(operation) := (nil : list(operation)) ;
|
}
|
||||||
if size(new_store) >= s.threshold then block {
|
| None ->
|
||||||
remove packed_msg from map s.message_store ;
|
block {
|
||||||
ret_ops := message(s.state_hash) ;
|
// the message has never been received before
|
||||||
// update the state hash
|
s.proposal_counters[sender] :=
|
||||||
s.state_hash := sha_256 ( bytes_concat (s.state_hash , packed_msg) ) ;
|
get_force (sender, s.proposal_counters) + 1n;
|
||||||
// decrement the counters
|
new_store := set [sender]
|
||||||
for addr -> ctr in map s.proposal_counters block {
|
}
|
||||||
if set_mem(addr,new_store) then
|
end;
|
||||||
s.proposal_counters[addr] := abs (ctr - 1n)
|
|
||||||
else skip ;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
s.message_store[packed_msg] := new_store
|
|
||||||
|
|
||||||
} with ( ret_ops , s)
|
|
||||||
|
|
||||||
function withdraw (const param : withdraw_pt; const s : storage_t) : contract_return_t is block {
|
// check sender counters against the maximum number of proposal
|
||||||
|
|
||||||
var message : message_t := param ;
|
var sender_proposal_counter : nat :=
|
||||||
const packed_msg : bytes = bytes_pack(message) ;
|
get_force (sender, s.proposal_counters);
|
||||||
|
|
||||||
case map_get(packed_msg, s.message_store) of
|
if sender_proposal_counter > s.max_proposal
|
||||||
| Some(voters) -> block { // the message is stored
|
then failwith ("Maximum number of proposal reached")
|
||||||
const new_set : addr_set_t = set_remove(sender,voters) ;
|
else skip;
|
||||||
|
|
||||||
// decrement the counter only if the sender was already associated with the message
|
// check the threshold
|
||||||
if size(voters) =/= size(new_set) then
|
|
||||||
s.proposal_counters[sender] := abs (get_force(sender,s.proposal_counters) - 1n)
|
|
||||||
else skip ;
|
|
||||||
|
|
||||||
// if the message is left without any associated addresses, remove the corresponding message_store field
|
var ret_ops : list (operation) := nil;
|
||||||
if size(new_set) = 0n then remove packed_msg from map s.message_store
|
|
||||||
else s.message_store[packed_msg] := new_set
|
|
||||||
}
|
|
||||||
| None -> skip end // the message isn't stored, ignore
|
|
||||||
|
|
||||||
} with ( (nil: list(operation)) , s)
|
if size (new_store) >= s.threshold then {
|
||||||
|
remove packed_msg from map s.message_store;
|
||||||
|
ret_ops := message (s.state_hash);
|
||||||
|
// update the state hash
|
||||||
|
s.state_hash := sha_256 (bytes_concat (s.state_hash, packed_msg));
|
||||||
|
// decrement the counters
|
||||||
|
for addr -> ctr in map s.proposal_counters block {
|
||||||
|
if set_mem(addr,new_store) then
|
||||||
|
s.proposal_counters[addr] := abs (ctr - 1n)
|
||||||
|
else skip
|
||||||
|
}
|
||||||
|
} else s.message_store[packed_msg] := new_store
|
||||||
|
} with (ret_ops, s)
|
||||||
|
|
||||||
function default (const p : default_pt; const s : storage_t) : contract_return_t is
|
function withdraw (const param : withdraw_pt; const s : storage) : return is
|
||||||
((nil: list(operation)) , s)
|
block {
|
||||||
|
var message : message := param;
|
||||||
|
const packed_msg : bytes = bytes_pack (message);
|
||||||
|
|
||||||
function main(const param : entry_point_t; const s : storage_t) : contract_return_t is
|
case map_get(packed_msg, s.message_store) of
|
||||||
|
Some (voters) ->
|
||||||
|
block {
|
||||||
|
// The message is stored
|
||||||
|
const new_set : addr_set = set_remove (sender, voters);
|
||||||
|
|
||||||
|
(* Decrement the counter only if the sender was already
|
||||||
|
associated with the message *)
|
||||||
|
|
||||||
|
if size (voters) =/= size (new_set)
|
||||||
|
then s.proposal_counters[sender] :=
|
||||||
|
abs (get_force (sender, s.proposal_counters) - 1n)
|
||||||
|
else skip ;
|
||||||
|
|
||||||
|
(* If the message is left without any associated addresses,
|
||||||
|
remove the corresponding message_store field *)
|
||||||
|
|
||||||
|
if size (new_set) = 0n
|
||||||
|
then remove packed_msg from map s.message_store
|
||||||
|
else s.message_store[packed_msg] := new_set
|
||||||
|
}
|
||||||
|
| None -> skip
|
||||||
|
end // The message is not stored, ignore.
|
||||||
|
} with ((nil : list (operation)), s)
|
||||||
|
|
||||||
|
function default (const p : default_pt; const s : storage) : return is
|
||||||
|
((nil : list (operation)), s)
|
||||||
|
|
||||||
|
function main (const param : parameter; const s : storage) : return is
|
||||||
case param of
|
case param of
|
||||||
// propagate message p if the number authorized addresses having
|
(* Propagate message p if the number of authorized addresses having
|
||||||
// voted for the same message p equals the threshold
|
voted for the same message p equals the threshold. *)
|
||||||
| Send (p) -> send(p,s)
|
| Send (p) -> send (p, s)
|
||||||
// withraw vote for message p
|
|
||||||
| Withdraw (p) -> withdraw(p,s)
|
(* Withraw vote for message p *)
|
||||||
// use this entry-point to transfer tez to the contract
|
| Withdraw (p) -> withdraw (p, s)
|
||||||
| Default (p) -> default(p,s)
|
|
||||||
end
|
(* Use this action to transfer tez to the contract *)
|
||||||
|
| Default (p) -> default (p, s)
|
||||||
|
end
|
||||||
|
@ -1,62 +1,66 @@
|
|||||||
// storage type
|
// storage type
|
||||||
type counter_t is nat
|
|
||||||
type threshold_t is nat
|
|
||||||
type authorized_keys_t is list(key)
|
|
||||||
type id_t is string
|
|
||||||
|
|
||||||
type storage_t is record
|
type counter is nat
|
||||||
id : id_t ;
|
type threshold is nat
|
||||||
counter : counter_t ;
|
type authorized_keys is list (key)
|
||||||
threshold : threshold_t ;
|
type id is string
|
||||||
auth : authorized_keys_t ;
|
|
||||||
end
|
type storage is
|
||||||
|
record [
|
||||||
|
id : id;
|
||||||
|
counter : counter;
|
||||||
|
threshold : threshold;
|
||||||
|
auth : authorized_keys
|
||||||
|
]
|
||||||
|
|
||||||
// I/O types
|
// I/O types
|
||||||
type message_t is (unit -> list(operation))
|
|
||||||
type signatures_t is list(key_hash * signature)
|
|
||||||
type check_message_pt is record
|
|
||||||
counter : counter_t ;
|
|
||||||
message : message_t ;
|
|
||||||
signatures : signatures_t ;
|
|
||||||
end
|
|
||||||
|
|
||||||
type contract_return_t is (list(operation) * storage_t)
|
type message is unit -> list (operation)
|
||||||
|
|
||||||
type entry_point_t is
|
type signatures is list (key_hash * signature)
|
||||||
| CheckMessage of check_message_pt
|
|
||||||
|
type check_message_pt is
|
||||||
|
record [
|
||||||
|
counter : counter;
|
||||||
|
message : message;
|
||||||
|
signatures : signatures
|
||||||
|
]
|
||||||
|
|
||||||
|
type return is list (operation) * storage
|
||||||
|
|
||||||
|
type parameter is CheckMessage of check_message_pt
|
||||||
|
|
||||||
function check_message (const param : check_message_pt;
|
function check_message (const param : check_message_pt;
|
||||||
const s : storage_t) : contract_return_t is block {
|
const s : storage) : return is block {
|
||||||
var message : message_t := param.message ;
|
var message : message := param.message;
|
||||||
|
|
||||||
if param.counter =/= s.counter then
|
if param.counter =/= s.counter then
|
||||||
failwith ("Counters does not match")
|
failwith ("Counters does not match")
|
||||||
else block {
|
else {
|
||||||
const packed_payload : bytes =
|
const packed_payload : bytes =
|
||||||
bytes_pack((message , param.counter , s.id , get_chain_id));
|
bytes_pack ((message, param.counter, s.id, get_chain_id));
|
||||||
var valid : nat := 0n ;
|
var valid : nat := 0n;
|
||||||
|
|
||||||
var keys : authorized_keys_t := s.auth ;
|
var keys : authorized_keys := s.auth;
|
||||||
for pkh_sig in list param.signatures block {
|
for pkh_sig in list param.signatures block {
|
||||||
case keys of
|
case keys of
|
||||||
| nil -> skip
|
nil -> skip
|
||||||
| key # tl -> block {
|
| key # tl -> block {
|
||||||
keys := tl ;
|
keys := tl;
|
||||||
if pkh_sig.0 = crypto_hash_key(key) then
|
if pkh_sig.0 = crypto_hash_key (key) then
|
||||||
if crypto_check(key,pkh_sig.1,packed_payload) then valid := valid + 1n ;
|
if crypto_check (key, pkh_sig.1, packed_payload)
|
||||||
else failwith ("Invalid signature")
|
then valid := valid + 1n
|
||||||
else skip;
|
else failwith ("Invalid signature")
|
||||||
}
|
else skip
|
||||||
|
}
|
||||||
end
|
end
|
||||||
};
|
};
|
||||||
|
|
||||||
if valid < s.threshold then
|
if valid < s.threshold then
|
||||||
failwith ("Not enough signatures passed the check")
|
failwith ("Not enough signatures passed the check")
|
||||||
else s.counter := s.counter + 1n ;
|
else s.counter := s.counter + 1n
|
||||||
}
|
}
|
||||||
} with (message(unit), s)
|
} with (message (unit), s)
|
||||||
|
|
||||||
function main(const param : entry_point_t; const s : storage_t) : contract_return_t is
|
function main (const param : parameter; const s : storage) : return is
|
||||||
case param of
|
case param of CheckMessage (p) -> check_message (p,s) end
|
||||||
| CheckMessage (p) -> check_message(p,s)
|
|
||||||
end
|
|
||||||
|
Loading…
Reference in New Issue
Block a user