Add ReasonLIGO support
This commit is contained in:
commit
fec4cc9c45
@ -18,4 +18,5 @@ services:
|
||||
- ./website/sidebars.json:/app/website/sidebars.json
|
||||
- ./website/siteConfig.js:/app/website/siteConfig.js
|
||||
- ./website/versions.json:/app/website/versions.json
|
||||
- ./website/node_modules/reason-highlightjs:/app/website/node_modules/reason-highlightjs
|
||||
working_dir: /app/website
|
||||
|
@ -20,6 +20,12 @@ const b: bool = False;
|
||||
let a: bool = true
|
||||
let b: bool = false
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let a: bool = true;
|
||||
let b: bool = false;
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -44,6 +50,13 @@ let b: string = "Alice"
|
||||
// true
|
||||
let c: bool = (a = b)
|
||||
```
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let a: string = "Alice";
|
||||
let b: string = "Alice";
|
||||
// true
|
||||
let c: bool = (a == b);
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -72,6 +85,18 @@ let f: bool = (a <= b)
|
||||
let g: bool = (a >= b)
|
||||
let h: bool = (a =/= b)
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let a: int = 5;
|
||||
let b: int = 4;
|
||||
let c: bool = (a == b);
|
||||
let d: bool = (a > b);
|
||||
let e: bool = (a < b);
|
||||
let f: bool = (a <= b);
|
||||
let g: bool = (a >= b);
|
||||
let h: bool = (a != b);
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -93,6 +118,13 @@ let b: tez = 10mutez
|
||||
// false
|
||||
let c: bool = (a = b)
|
||||
```
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let a: tez = 5mutez;
|
||||
let b: tez = 10mutez;
|
||||
// false
|
||||
let c: bool = (a == b);
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -144,6 +176,26 @@ let min_age: nat = 16n
|
||||
let is_adult (age: nat) : bool =
|
||||
if (age > min_age) then true else false
|
||||
```
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let min_age: nat = 16n;
|
||||
|
||||
/**
|
||||
|
||||
This function is really obnoxious, but it showcases
|
||||
how the if statement and it's syntax can be used.
|
||||
|
||||
Normally, you'd use `with (age > min_age)` instead.
|
||||
|
||||
*/
|
||||
|
||||
let is_adult = (age: nat): bool =>
|
||||
if (age > min_age) {
|
||||
true;
|
||||
} else {
|
||||
false;
|
||||
};
|
||||
```
|
||||
|
||||
> You can run the function above with
|
||||
> ```
|
||||
|
@ -99,4 +99,9 @@ const a: int = increment(1);
|
||||
let increment : (int -> int) = fun (i: int) -> i + 1
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let increment: (int => int) = (i: int) => i + 1;
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
@ -22,6 +22,11 @@ type ledger is map(address, tez);
|
||||
type ledger = (address, tez) map
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
type ledger = map(address, tez);
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
And here's how a map value is populated:
|
||||
@ -51,6 +56,20 @@ let ledger: ledger = Map.literal
|
||||
> Note also the `;` to separate individual map entries.
|
||||
>
|
||||
> `("<string value>": address)` means that we type-cast a string into an address.
|
||||
|
||||
<!--Reasonligo-->
|
||||
|
||||
```reasonligo
|
||||
let ledger: ledger =
|
||||
Map.literal([
|
||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address, 1000(mutez)),
|
||||
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, 2000(mutez)),
|
||||
]);
|
||||
|
||||
> Map.literal constructs the map from a list of key-value pair tuples, `(<key>, <value>)`.
|
||||
>
|
||||
> `("<string value>": address)` means that we type-cast a string into an address.
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
### Accessing map values by key
|
||||
@ -68,6 +87,13 @@ const balance: option(tez) = ledger[("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": add
|
||||
```cameligo
|
||||
let balance: tez option = Map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) ledger
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
|
||||
```reasonligo
|
||||
let balance: option(tez) =
|
||||
Map.find_opt("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, ledger);
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
#### Obtaining a map value forcefully
|
||||
@ -86,6 +112,13 @@ const balance: tez = get_force(("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address)
|
||||
let balance: tez = Map.find ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) ledger
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
|
||||
```reasonligo
|
||||
let balance: tez =
|
||||
Map.find("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address, ledger);
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
### Iteration over the contents of a map
|
||||
@ -112,6 +145,14 @@ let iter_op (m : ledger) : unit =
|
||||
let assert_eq = fun (i: address) (j: tez) -> assert (j > 100)
|
||||
in Map.iter assert_eq m
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let iter_op = (m: ledger): unit => {
|
||||
let assert_eq = (i: address, j: tez) => assert(j > 100);
|
||||
Map.iter(assert_eq, m);
|
||||
};
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
`map` is a way to create a new map by modifying the contents of an existing one.
|
||||
@ -131,6 +172,14 @@ let map_op (m : ledger) : ledger =
|
||||
let increment = fun (_: address) (j: tez) -> j+1
|
||||
in Map.map increment m
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let map_op = (m: ledger): ledger => {
|
||||
let increment = (ignore: address, j: tez) => j + 1;
|
||||
Map.map(increment, m);
|
||||
};
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
`fold` is an aggregation function that return the combination of a maps contents.
|
||||
@ -154,10 +203,19 @@ function fold_op (const m : ledger) : tez is
|
||||
<!--Cameligo-->
|
||||
```cameligo
|
||||
let fold_op (m : ledger) : ledger =
|
||||
let aggregate = fun (_: address) (j: tez * tez) -> j.0 + j.1
|
||||
let aggregate = fun (ignore: address) (j: tez * tez) -> j.0 + j.1
|
||||
in Map.fold aggregate m 10
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let fold_op = (m: ledger): ledger => {
|
||||
let aggregate = (ignore: address, j: (tez, tez)) => j[0] + j[1];
|
||||
Map.fold(aggregate, m, 10);
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
## Records
|
||||
@ -185,6 +243,15 @@ type user = {
|
||||
}
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
type user = {
|
||||
id: nat,
|
||||
is_admin: bool,
|
||||
name: string
|
||||
};
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
And here's how a record value is populated:
|
||||
@ -208,6 +275,14 @@ let user: user = {
|
||||
}
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let user: user = {
|
||||
id: 1n,
|
||||
is_admin: true,
|
||||
name: "Alice"
|
||||
};
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -226,4 +301,9 @@ const is_admin: bool = user.is_admin;
|
||||
let is_admin: bool = user.is_admin
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let is_admin: bool = user.is_admin;
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
@ -60,6 +60,29 @@ let g: int = 1_000_000
|
||||
>let g: int = 1_000_000;
|
||||
>```
|
||||
|
||||
<!--Reasonligo-->
|
||||
|
||||
```reasonligo
|
||||
// int + int produces int
|
||||
let a: int = 5 + 10;
|
||||
// nat + int produces int
|
||||
let b: int = 5n + 10;
|
||||
// tez + tez produces tez
|
||||
let c: tez = 5mutez + 10mutez;
|
||||
// you can't add tez + int or tez + nat, this won't compile
|
||||
// let d: tez = 5mutez + 10n;
|
||||
let e: nat = 5n + 10n;
|
||||
// nat + int produces an int, this won't compile
|
||||
// let f: nat = 5n + 10;
|
||||
let g: int = 1_000_000;
|
||||
```
|
||||
|
||||
> Pro tip: you can use underscores for readability when defining large numbers
|
||||
>
|
||||
>```reasonligo
|
||||
>let g: int = 1_000_000;
|
||||
>```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
## Subtraction
|
||||
@ -89,6 +112,16 @@ let b: int = 5n - 2n
|
||||
let d: tez = 5mutez - 1mt
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let a: int = 5 - 10;
|
||||
// substraction of two nats, yields an int
|
||||
let b: int = 5n - 2n;
|
||||
// won't compile, result is an int, not a nat
|
||||
// let c: nat = 5n - 2n;
|
||||
let d: tez = 5mutez - 1mt;
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -114,6 +147,14 @@ let b: nat = 5n * 5n
|
||||
let c: tez = 5n * 5mutez
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let a: int = 5 * 5;
|
||||
let b: nat = 5n * 5n;
|
||||
// you can also multiply `nat` and `tez`
|
||||
let c: tez = 5n * 5mutez;
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -138,6 +179,13 @@ let b: nat = 10n / 3n
|
||||
let c: nat = 10mutez / 3mutez
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let a: int = 10 / 3;
|
||||
let b: nat = 10n / 3n;
|
||||
let c: nat = 10mutez / 3mutez;
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
## From `int` to `nat` and back
|
||||
|
@ -31,6 +31,13 @@ let my_set: int_set =
|
||||
Set.add 3 (Set.add 2 (Set.add 1 (Set.empty: int set)))
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
type int_set = set(int);
|
||||
let my_set: int_set =
|
||||
Set.add(3, Set.add(2, Set.add(1, Set.empty: set(int))));
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
### Empty sets
|
||||
@ -45,7 +52,10 @@ const my_set_2: int_set = set_empty;
|
||||
```cameligo
|
||||
let my_set: int_set = (Set.empty: int set)
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let my_set: int_set = (Set.empty: set(int));
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
### Checking if set contains an element
|
||||
@ -62,6 +72,10 @@ const contains_three_fn: bool = set_mem(3, my_set);
|
||||
```cameligo
|
||||
let contains_three: bool = Set.mem 3 my_set
|
||||
```
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let contains_three: bool = Set.mem(3, my_set);
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
@ -78,6 +92,11 @@ const set_size: nat = size(my_set);
|
||||
let set_size: nat = Set.size my_set
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let set_size: nat = Set.size(my_set);
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -96,6 +115,13 @@ let larger_set: int_set = Set.add 4 my_set
|
||||
let smaller_set: int_set = Set.remove 3 my_set
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
|
||||
```reasonligo
|
||||
let larger_set: int_set = Set.add(4, my_set);
|
||||
let smaller_set: int_set = Set.remove(3, my_set);
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -114,6 +140,11 @@ let sum (result: int) (i: int) : int = result + i
|
||||
let sum_of_a_set: int = Set.fold sum my_set 0
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let sum = (result: int, i: int): int => result + i;
|
||||
let sum_of_a_set: int = Set.fold(sum, my_set, 0);
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
## Lists
|
||||
@ -141,6 +172,12 @@ type int_list = int list
|
||||
let my_list: int_list = [1; 2; 3]
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
type int_list = list(int);
|
||||
let my_list: int_list = [1, 2, 3];
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -159,6 +196,12 @@ let larger_list: int_list = 4 :: my_list
|
||||
(* CameLIGO doesn't have a List.cons *)
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let larger_list: int_list = [4, ...my_list];
|
||||
/* Reasonligo doesn't have a List.cons */
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
<br/>
|
||||
@ -182,6 +225,15 @@ let increment (i: int) : int = i + 1
|
||||
let incremented_list: int_list = List.map increment larger_list
|
||||
```
|
||||
|
||||
|
||||
<!--Reasonligo-->
|
||||
|
||||
```reasonligo
|
||||
let increment = (i: int): int => i + 1;
|
||||
/* Creates a new list with elements incremented by 1 */
|
||||
let incremented_list: int_list = List.map(increment, larger_list);
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -202,6 +254,14 @@ let sum (result: int) (i: int) : int = result + i
|
||||
let sum_of_a_list: int = List.fold sum my_list 0
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
|
||||
```reasonligo
|
||||
let sum = (result: int, i: int): int => result + i;
|
||||
// Outputs 6
|
||||
let sum_of_a_list: int = List.fold(sum, my_list, 0);
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -239,6 +299,13 @@ type full_name = string * string
|
||||
let full_name: full_name = ("Alice", "Johnson")
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
type full_name = (string, string);
|
||||
/* The parenthesis here are optional */
|
||||
let full_name: full_name = ("Alice", "Johnson");
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -262,4 +329,9 @@ const first_name: string = full_name.1;
|
||||
let first_name: string = full_name.1
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let first_name: string = full_name[1];
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
@ -39,6 +39,12 @@ let name: string = "Alice"
|
||||
let greeting: string = "Hello"
|
||||
let full_greeting: string = greeting ^ " " ^ name
|
||||
```
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let name: string = "Alice";
|
||||
let greeting: string = "Hello";
|
||||
let full_greeting: string = greeting ++ " " ++ name;
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -58,6 +64,11 @@ const slice: string = string_slice(0n, 1n, name);
|
||||
let name: string = "Alice"
|
||||
let slice: string = String.slice 0n 1n name
|
||||
```
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let name: string = "Alice";
|
||||
let slice: string = String.slice(0n, 1n, name);
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
> ⚠️ Notice that the `offset` and slice `length` are `nats`
|
||||
@ -78,4 +89,9 @@ const length: nat = size(name);
|
||||
let name: string = "Alice"
|
||||
let length: nat = String.size name
|
||||
```
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let name: string = "Alice";
|
||||
let length: nat = String.size(name);
|
||||
```
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
@ -27,6 +27,13 @@ type animal_breed = string
|
||||
let dog_breed: animal_breed = "Saluki"
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
|
||||
```reasonligo
|
||||
type animal_breed = string;
|
||||
let dog_breed: animal_breed = "Saluki";
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
## Simple types
|
||||
@ -44,12 +51,23 @@ end
|
||||
<!--Cameligo-->
|
||||
```cameligo
|
||||
// account_balances is a simple type, a map of address <-> tez
|
||||
type account_balances is (address, tez) map
|
||||
type account_balances = (address, tez) map
|
||||
|
||||
let ledger: account_balances = Map.literal
|
||||
[(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address), 10mutez)]
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
// account_balances is a simple type, a map of address <-> tez
|
||||
type account_balances = map(address, tez);
|
||||
|
||||
let ledger: account_balances =
|
||||
Map.literal([
|
||||
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address, 10(mutez)),
|
||||
]);
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
## Composed types
|
||||
@ -104,4 +122,29 @@ let ledger: account_balances = Map.literal
|
||||
)]
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
/* alias two types */
|
||||
type account = address;
|
||||
type number_of_transactions = nat;
|
||||
/* account_data consists of a record with two fields (balance, number_of_transactions) */
|
||||
type account_data = {
|
||||
balance: tez,
|
||||
number_of_transactions,
|
||||
};
|
||||
/* our ledger / account_balances is a map of account <-> account_data */
|
||||
type account_balances = map(account, account_data);
|
||||
|
||||
// pseudo-JSON representation of our map
|
||||
// {"tz1...": {balance: 10mutez, number_of_transactions: 5n}}
|
||||
let ledger: account_balances =
|
||||
Map.literal([
|
||||
(
|
||||
"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address,
|
||||
{balance: 10(mutez), number_of_transactions: 5n},
|
||||
),
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
@ -24,6 +24,11 @@ const n: unit = Unit;
|
||||
let n: unit = ()
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let n: unit = ();
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
## Variants
|
||||
@ -57,6 +62,18 @@ let u: user = Admin 1000n
|
||||
let g: user = Guest ()
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
type id = nat;
|
||||
type user =
|
||||
| Admin(id)
|
||||
| Manager(id)
|
||||
| Guest(unit);
|
||||
|
||||
let u: user = Admin(1000n);
|
||||
let g: user = Guest();
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
Defining a varient can be extremely useful for building semantically appealing contracts. We'll learn how to use variants for 'logic purposes' shortly.
|
||||
@ -84,6 +101,14 @@ let p1: dinner = None
|
||||
let p2: dinner = Some "Hamburgers"
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
type dinner = option(string);
|
||||
|
||||
let p1: dinner = None;
|
||||
let p2: dinner = Some("Hamburgers");
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
|
||||
@ -113,4 +138,14 @@ let is_hungry (d: dinner) : bool =
|
||||
| Some s -> false
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
type dinner = option(string);
|
||||
let is_hungry = (d: dinner): bool =>
|
||||
switch (d) {
|
||||
| None => true
|
||||
| Some(s) => false
|
||||
};
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
@ -32,6 +32,17 @@ ligo evaluate-value -s cameligo gitlab-pages/docs/language-basics/src/variables-
|
||||
# Outputs: 25
|
||||
```
|
||||
|
||||
<!--Reasonligo-->
|
||||
```reasonligo
|
||||
let age: int = 25;
|
||||
```
|
||||
|
||||
You can evaluate the constant definition above using the following CLI command:
|
||||
```shell
|
||||
ligo evaluate-value -s reasonligo gitlab-pages/docs/language-basics/src/variables-and-constants/const.religo age
|
||||
# Outputs: 25
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
||||
## Variables
|
||||
@ -77,7 +88,7 @@ with a new value being bound in place of the old one.
|
||||
|
||||
```cameligo
|
||||
|
||||
let add(const a: int; const b: int) : int =
|
||||
let add (a: int) (b: int) : int =
|
||||
let c : int = a + b in c
|
||||
```
|
||||
|
||||
@ -87,5 +98,27 @@ You can run the `add` function defined above using the LIGO compiler like this:
|
||||
ligo run-function -s cameligo gitlab-pages/docs/language-basics/src/variables-and-constants/add.mligo add '(1,1)'
|
||||
# Outputs: 2
|
||||
```
|
||||
<!--Reasonligo-->
|
||||
|
||||
As expected from a functional language, Reasonligo uses value-binding
|
||||
for variables rather than assignment. Variables are changed by replacement,
|
||||
with a new value being bound in place of the old one.
|
||||
|
||||
> 💡 Don't worry if you don't understand the function syntax yet. We'll get to it in upcoming sections of the docs.
|
||||
|
||||
```reasonligo
|
||||
|
||||
let add = (a: int, b: int): int => {
|
||||
let c: int = a + b;
|
||||
c;
|
||||
};
|
||||
```
|
||||
|
||||
You can run the `add` function defined above using the LIGO compiler like this:
|
||||
|
||||
```shell
|
||||
ligo run-function -s reasonligo gitlab-pages/docs/language-basics/src/variables-and-constants/add.religo add '(1,1)'
|
||||
# Outputs: 2
|
||||
```
|
||||
|
||||
<!--END_DOCUSAURUS_CODE_TABS-->
|
||||
|
@ -44,6 +44,34 @@ let%entry main(p : action) storage =
|
||||
in (([] : operation list), storage)
|
||||
${pre}`;
|
||||
|
||||
|
||||
const REASONLIGO_EXAMPLE = `${pre}reasonligo
|
||||
type storage = int;
|
||||
|
||||
/* variant defining pseudo multi-entrypoint
|
||||
actions */
|
||||
type action =
|
||||
| Increment(int)
|
||||
| Decrement(int);
|
||||
|
||||
let add = (a: int, b: int): int => a + b;
|
||||
|
||||
let subtract = (a: int, b: int): int => a - b;
|
||||
|
||||
/* real entrypoint that re-routes the flow
|
||||
based on the action provided */
|
||||
let main = (p: action, storage) => {
|
||||
let storage =
|
||||
switch (p) {
|
||||
| Increment(n) => add(storage, n)
|
||||
| Decrement(n) => subtract(storage, n)
|
||||
};
|
||||
([]: list(operation), storage);
|
||||
};
|
||||
|
||||
${pre}`;
|
||||
|
||||
|
||||
module.exports = props => {
|
||||
const MarkdownBlock = props.MarkdownBlock;
|
||||
|
||||
@ -60,7 +88,9 @@ module.exports = props => {
|
||||
<div className="nav-link" data-group="examples" data-tab="cameligo">
|
||||
CameLIGO
|
||||
</div>
|
||||
<div className="disabled">ReasonLIGO (coming soon)</div>
|
||||
<div className="nav-link" data-group="examples" data-tab="reasonligo">
|
||||
ReasonLIGO
|
||||
</div>
|
||||
</div>
|
||||
<div className="tab-content">
|
||||
<div id="pascaligo" className="tab-pane active" data-group="examples">
|
||||
@ -69,6 +99,9 @@ module.exports = props => {
|
||||
<div id="cameligo" className="tab-pane" data-group="examples">
|
||||
<MarkdownBlock>{CAMELIGO_EXAMPLE}</MarkdownBlock>
|
||||
</div>
|
||||
<div id="reasonligo" className="tab-pane" data-group="examples">
|
||||
<MarkdownBlock>{REASONLIGO_EXAMPLE}</MarkdownBlock>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -11,6 +11,7 @@
|
||||
"rename-version": "docusaurus-rename-version"
|
||||
},
|
||||
"devDependencies": {
|
||||
"docusaurus": "^1.14.0"
|
||||
"docusaurus": "^1.14.0",
|
||||
"reason-highlightjs": "0.2.1"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
const repoUrl = 'https://gitlab.com/ligolang/ligo';
|
||||
|
||||
let reasonHighlightJs = require('reason-highlightjs');
|
||||
|
||||
const siteConfig = {
|
||||
title: 'LIGO', // Title for your website.
|
||||
tagline: 'LIGO is a friendly smart-contract language for Tezos',
|
||||
@ -78,6 +80,7 @@ const siteConfig = {
|
||||
// Highlight.js theme to use for syntax highlighting in code blocks.
|
||||
theme: 'default',
|
||||
hljs: function (hljs) {
|
||||
hljs.registerLanguage('reasonligo', reasonHighlightJs);
|
||||
hljs.registerLanguage('pascaligo', function (hljs) {
|
||||
return {
|
||||
// case_insensitive: true,
|
||||
|
@ -1,7 +1,7 @@
|
||||
open Trace
|
||||
|
||||
type s_syntax = Syntax_name of string
|
||||
type v_syntax = Pascaligo | Cameligo
|
||||
type v_syntax = Pascaligo | Cameligo | ReasonLIGO
|
||||
|
||||
let syntax_to_variant : s_syntax -> string option -> v_syntax result =
|
||||
fun syntax source_filename ->
|
||||
@ -16,9 +16,11 @@ let syntax_to_variant : s_syntax -> string option -> v_syntax result =
|
||||
match (syntax , source_filename) with
|
||||
| "auto" , Some sf when endswith sf ".ligo" -> ok Pascaligo
|
||||
| "auto" , Some sf when endswith sf ".mligo" -> ok Cameligo
|
||||
| "auto" , Some sf when endswith sf ".religo" -> ok ReasonLIGO
|
||||
| "auto" , _ -> simple_fail "cannot auto-detect syntax, pleas use -s name_of_syntax"
|
||||
| "pascaligo" , _ -> ok Pascaligo
|
||||
| "cameligo" , _ -> ok Cameligo
|
||||
| "reasonligo", _ -> ok ReasonLIGO
|
||||
| _ -> simple_fail "unrecognized parser"
|
||||
|
||||
let parsify_pascaligo = fun source ->
|
||||
@ -57,10 +59,38 @@ let parsify_expression_ligodity = fun source ->
|
||||
Simplify.Ligodity.simpl_expression raw in
|
||||
ok simplified
|
||||
|
||||
let parsify_reasonligo = fun source ->
|
||||
let%bind raw =
|
||||
trace (simple_error "parsing") @@
|
||||
Parser.Reasonligo.parse_file source in
|
||||
let%bind simplified =
|
||||
trace (simple_error "simplifying") @@
|
||||
Simplify.Ligodity.simpl_program raw in
|
||||
ok simplified
|
||||
|
||||
let parsify_string_reasonligo = fun source ->
|
||||
let%bind raw =
|
||||
trace (simple_error "parsing") @@
|
||||
Parser.Reasonligo.parse_string source in
|
||||
let%bind simplified =
|
||||
trace (simple_error "simplifying") @@
|
||||
Simplify.Ligodity.simpl_program raw in
|
||||
ok simplified
|
||||
|
||||
let parsify_expression_reasonligo = fun source ->
|
||||
let%bind raw =
|
||||
trace (simple_error "parsing expression") @@
|
||||
Parser.Reasonligo.parse_expression source in
|
||||
let%bind simplified =
|
||||
trace (simple_error "simplifying expression") @@
|
||||
Simplify.Ligodity.simpl_expression raw in
|
||||
ok simplified
|
||||
|
||||
let parsify = fun (syntax : v_syntax) source_filename ->
|
||||
let%bind parsify = match syntax with
|
||||
| Pascaligo -> ok parsify_pascaligo
|
||||
| Cameligo -> ok parsify_ligodity
|
||||
| ReasonLIGO -> ok parsify_reasonligo
|
||||
in
|
||||
let%bind parsified = parsify source_filename in
|
||||
let%bind applied = Self_ast_simplified.all_program parsified in
|
||||
@ -70,6 +100,7 @@ let parsify_expression = fun syntax source ->
|
||||
let%bind parsify = match syntax with
|
||||
| Pascaligo -> ok parsify_expression_pascaligo
|
||||
| Cameligo -> ok parsify_expression_ligodity
|
||||
| ReasonLIGO -> ok parsify_expression_reasonligo
|
||||
in
|
||||
let%bind parsified = parsify source in
|
||||
let%bind applied = Self_ast_simplified.all_expression parsified in
|
||||
|
@ -8,6 +8,7 @@
|
||||
parser_pascaligo
|
||||
parser_camligo
|
||||
parser_ligodity
|
||||
parser_reasonligo
|
||||
)
|
||||
(preprocess
|
||||
(pps ppx_let)
|
||||
|
@ -1 +0,0 @@
|
||||
ocamlc: -w -42
|
@ -1,5 +1,6 @@
|
||||
module Pascaligo = Pascaligo
|
||||
module Camligo = Parser_camligo
|
||||
module Ligodity = Ligodity
|
||||
module Reasonligo = Reasonligo
|
||||
|
||||
|
||||
|
112
src/passes/1-parser/reasonligo.ml
Normal file
112
src/passes/1-parser/reasonligo.ml
Normal file
@ -0,0 +1,112 @@
|
||||
open Trace
|
||||
|
||||
module Parser = Parser_reasonligo.Parser
|
||||
module AST = Parser_ligodity.AST
|
||||
module ParserLog = Parser_ligodity.ParserLog
|
||||
module LexToken = Parser_reasonligo.LexToken
|
||||
module Lexer = Lexer.Make(LexToken)
|
||||
|
||||
let parse_file (source: string) : AST.t result =
|
||||
let pp_input =
|
||||
let prefix = Filename.(source |> basename |> remove_extension)
|
||||
and suffix = ".pp.religo"
|
||||
in prefix ^ suffix in
|
||||
|
||||
let cpp_cmd = Printf.sprintf "cpp -traditional-cpp %s > %s"
|
||||
source pp_input in
|
||||
let%bind () = sys_command cpp_cmd in
|
||||
|
||||
let%bind channel =
|
||||
generic_try (simple_error "error opening file") @@
|
||||
(fun () -> open_in pp_input) in
|
||||
let lexbuf = Lexing.from_channel channel in
|
||||
let Lexer.{read ; close ; _} =
|
||||
Lexer.open_token_stream None in
|
||||
specific_try (function
|
||||
| Parser.Error -> (
|
||||
let start = Lexing.lexeme_start_p lexbuf in
|
||||
let end_ = Lexing.lexeme_end_p lexbuf in
|
||||
let str = Format.sprintf
|
||||
"Parse error at \"%s\" from (%d, %d) to (%d, %d). In file \"%s|%s\"\n"
|
||||
(Lexing.lexeme lexbuf)
|
||||
start.pos_lnum (start.pos_cnum - start.pos_bol)
|
||||
end_.pos_lnum (end_.pos_cnum - end_.pos_bol)
|
||||
start.pos_fname source
|
||||
in
|
||||
simple_error str
|
||||
)
|
||||
| exn ->
|
||||
let start = Lexing.lexeme_start_p lexbuf in
|
||||
let end_ = Lexing.lexeme_end_p lexbuf in
|
||||
let str = Format.sprintf
|
||||
"Unrecognized error (%s) at \"%s\" from (%d, %d) to (%d, %d). In file \"%s|%s\"\n"
|
||||
(Printexc.to_string exn)
|
||||
(Lexing.lexeme lexbuf)
|
||||
start.pos_lnum (start.pos_cnum - start.pos_bol)
|
||||
end_.pos_lnum (end_.pos_cnum - end_.pos_bol)
|
||||
start.pos_fname source
|
||||
in
|
||||
simple_error str
|
||||
) @@ (fun () ->
|
||||
let raw = Parser.contract read lexbuf in
|
||||
close () ;
|
||||
raw
|
||||
) >>? fun raw ->
|
||||
ok raw
|
||||
|
||||
let parse_string (s:string) : AST.t result =
|
||||
let lexbuf = Lexing.from_string s in
|
||||
let Lexer.{read ; close ; _} =
|
||||
Lexer.open_token_stream None in
|
||||
specific_try (function
|
||||
| Parser.Error -> (
|
||||
let start = Lexing.lexeme_start_p lexbuf in
|
||||
let end_ = Lexing.lexeme_end_p lexbuf in
|
||||
let str = Format.sprintf
|
||||
"Parse error at \"%s\" from (%d, %d) to (%d, %d)\n"
|
||||
(Lexing.lexeme lexbuf)
|
||||
start.pos_lnum (start.pos_cnum - start.pos_bol)
|
||||
end_.pos_lnum (end_.pos_cnum - end_.pos_bol) in
|
||||
simple_error str
|
||||
)
|
||||
| _ -> simple_error "unrecognized parse_ error"
|
||||
) @@ (fun () ->
|
||||
let raw = Parser.contract read lexbuf in
|
||||
close () ;
|
||||
raw
|
||||
) >>? fun raw ->
|
||||
ok raw
|
||||
|
||||
let parse_expression (s:string) : AST.expr result =
|
||||
let lexbuf = Lexing.from_string s in
|
||||
let Lexer.{read ; close; _} =
|
||||
Lexer.open_token_stream None in
|
||||
specific_try (function
|
||||
| Parser.Error -> (
|
||||
let start = Lexing.lexeme_start_p lexbuf in
|
||||
let end_ = Lexing.lexeme_end_p lexbuf in
|
||||
let str = Format.sprintf
|
||||
"Parse error at \"%s\" from (%d, %d) to (%d, %d)\n"
|
||||
(Lexing.lexeme lexbuf)
|
||||
start.pos_lnum (start.pos_cnum - start.pos_bol)
|
||||
end_.pos_lnum (end_.pos_cnum - end_.pos_bol) in
|
||||
simple_error str
|
||||
)
|
||||
| exn ->
|
||||
let start = Lexing.lexeme_start_p lexbuf in
|
||||
let end_ = Lexing.lexeme_end_p lexbuf in
|
||||
let str = Format.sprintf
|
||||
"Unrecognized error (%s) at \"%s\" from (%d, %d) to (%d, %d). In expression \"%s|%s\"\n"
|
||||
(Printexc.to_string exn)
|
||||
(Lexing.lexeme lexbuf)
|
||||
start.pos_lnum (start.pos_cnum - start.pos_bol)
|
||||
end_.pos_lnum (end_.pos_cnum - end_.pos_bol)
|
||||
start.pos_fname s
|
||||
in
|
||||
simple_error str
|
||||
) @@ (fun () ->
|
||||
let raw = Parser.interactive_expr read lexbuf in
|
||||
close () ;
|
||||
raw
|
||||
) >>? fun raw ->
|
||||
ok raw
|
158
src/passes/1-parser/reasonligo/LexToken.mli
Normal file
158
src/passes/1-parser/reasonligo/LexToken.mli
Normal file
@ -0,0 +1,158 @@
|
||||
(* This signature defines the lexical tokens for LIGO
|
||||
|
||||
_Tokens_ are the abstract units which are used by the parser to
|
||||
build the abstract syntax tree (AST), in other words, the stream of
|
||||
tokens is the minimal model of the input program, carrying
|
||||
implicitly all its structure in a linear encoding, and nothing
|
||||
else, in particular, comments and whitespace are absent.
|
||||
|
||||
A _lexeme_ is a specific character string (concrete
|
||||
representation) denoting a token (abstract representation). Tokens
|
||||
can be thought of as sets, and lexemes as elements of those sets --
|
||||
there is often an infinite number of lexemes, but a small number of
|
||||
tokens. (Think of identifiers as lexemes and one token.)
|
||||
|
||||
The tokens are qualified here as being "lexical" because the
|
||||
parser generator Menhir expects to define them, in which context
|
||||
they are called "parsing tokens", and they are made to match each
|
||||
other. (This is an idiosyncratic terminology.)
|
||||
|
||||
The type of the lexical tokens is the variant [t], also
|
||||
aliased to [token].
|
||||
*)
|
||||
|
||||
module Region = Simple_utils.Region
|
||||
module Pos = Simple_utils.Pos
|
||||
|
||||
type lexeme = string
|
||||
|
||||
(* TOKENS *)
|
||||
|
||||
type t =
|
||||
(* Symbols *)
|
||||
|
||||
CAT of Region.t (* "++" *)
|
||||
|
||||
(* Arithmetics *)
|
||||
|
||||
| MINUS of Region.t (* "-" *)
|
||||
| PLUS of Region.t (* "+" *)
|
||||
| SLASH of Region.t (* "/" *)
|
||||
| TIMES of Region.t (* "*" *)
|
||||
|
||||
(* Compounds *)
|
||||
|
||||
| LPAR of Region.t (* "(" *)
|
||||
| RPAR of Region.t (* ")" *)
|
||||
| LBRACKET of Region.t (* "[" *)
|
||||
| RBRACKET of Region.t (* "]" *)
|
||||
| LBRACE of Region.t (* "{" *)
|
||||
| RBRACE of Region.t (* "}" *)
|
||||
|
||||
(* Separators *)
|
||||
|
||||
| COMMA of Region.t (* "," *)
|
||||
| SEMI of Region.t (* ";" *)
|
||||
| VBAR of Region.t (* "|" *)
|
||||
| COLON of Region.t (* ":" *)
|
||||
| DOT of Region.t (* "." *)
|
||||
| DOTDOTDOT of Region.t (* "..." *)
|
||||
|
||||
(* Wildcard *)
|
||||
|
||||
| WILD of Region.t (* "_" *)
|
||||
|
||||
(* Comparisons *)
|
||||
|
||||
| EQ of Region.t (* "=" *)
|
||||
| EQEQ of Region.t (* "=" *)
|
||||
| NE of Region.t (* "!=" *)
|
||||
| LT of Region.t (* "<" *)
|
||||
| GT of Region.t (* ">" *)
|
||||
| LE of Region.t (* "=<" *)
|
||||
| GE of Region.t (* ">=" *)
|
||||
| ARROW of Region.t (* "=>" *)
|
||||
|
||||
| BOOL_OR of Region.t (* "||" *)
|
||||
| BOOL_AND of Region.t(* "&&" *)
|
||||
|
||||
| NOT of Region.t (* ! *)
|
||||
|
||||
(* Identifiers, labels, numbers and strings *)
|
||||
|
||||
| Ident of string Region.reg
|
||||
| Constr of string Region.reg
|
||||
| Int of (string * Z.t) Region.reg
|
||||
| Nat of (string * Z.t) Region.reg
|
||||
| Mtz of (string * Z.t) Region.reg
|
||||
| Str of string Region.reg
|
||||
| Bytes of (string * Hex.t) Region.reg
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
| Else of Region.t
|
||||
| False of Region.t
|
||||
| If of Region.t
|
||||
| Let of Region.t
|
||||
| Switch of Region.t
|
||||
| Mod of Region.t
|
||||
| Or of Region.t
|
||||
| True of Region.t
|
||||
| Type of Region.t
|
||||
|
||||
(* Data constructors *)
|
||||
|
||||
| C_None of Region.t (* "None" *)
|
||||
| C_Some of Region.t (* "Some" *)
|
||||
|
||||
(* Virtual tokens *)
|
||||
|
||||
| EOF of Region.t (* End of file *)
|
||||
|
||||
type token = t
|
||||
|
||||
(* Projections
|
||||
|
||||
The difference between extracting the lexeme and a string from a
|
||||
token is that the latter is the textual representation of the OCaml
|
||||
value denoting the token (its abstract syntax), rather than its
|
||||
lexeme (concrete syntax).
|
||||
*)
|
||||
|
||||
val to_lexeme : token -> lexeme
|
||||
val to_string : token -> ?offsets:bool -> [`Byte | `Point] -> string
|
||||
val to_region : token -> Region.t
|
||||
|
||||
(* comments *)
|
||||
val block_comment_start : lexeme -> bool
|
||||
val block_comment_end : lexeme -> bool
|
||||
val line_comment_start : lexeme -> bool
|
||||
|
||||
(* Injections *)
|
||||
|
||||
type int_err = Non_canonical_zero
|
||||
type ident_err = Reserved_name
|
||||
type nat_err = Invalid_natural
|
||||
| Non_canonical_zero_nat
|
||||
type sym_err = Invalid_symbol
|
||||
|
||||
val mk_string : lexeme -> Region.t -> token
|
||||
val mk_bytes : lexeme -> Region.t -> token
|
||||
val mk_int : lexeme -> Region.t -> (token, int_err) result
|
||||
val mk_nat : lexeme -> Region.t -> (token, nat_err) result
|
||||
val mk_mutez : lexeme -> Region.t -> (token, int_err) result
|
||||
val mk_ident : lexeme -> Region.t -> (token, ident_err) result
|
||||
val mk_constr : lexeme -> Region.t -> token
|
||||
val mk_sym : lexeme -> Region.t -> (token, sym_err) result
|
||||
val eof : Region.t -> token
|
||||
|
||||
(* Predicates *)
|
||||
|
||||
val is_string : token -> bool
|
||||
val is_bytes : token -> bool
|
||||
val is_int : token -> bool
|
||||
val is_ident : token -> bool
|
||||
val is_kwd : token -> bool
|
||||
val is_constr : token -> bool
|
||||
val is_sym : token -> bool
|
||||
val is_eof : token -> bool
|
504
src/passes/1-parser/reasonligo/LexToken.mll
Normal file
504
src/passes/1-parser/reasonligo/LexToken.mll
Normal file
@ -0,0 +1,504 @@
|
||||
{
|
||||
type lexeme = string
|
||||
|
||||
let sprintf = Printf.sprintf
|
||||
|
||||
module Region = Simple_utils.Region
|
||||
module Pos = Simple_utils.Pos
|
||||
module SMap = Utils.String.Map
|
||||
module SSet = Utils.String.Set
|
||||
|
||||
(* TOKENS *)
|
||||
|
||||
type t =
|
||||
(* Symbols *)
|
||||
|
||||
CAT of Region.t (* "++" *)
|
||||
|
||||
(* Arithmetics *)
|
||||
|
||||
| MINUS of Region.t (* "-" *)
|
||||
| PLUS of Region.t (* "+" *)
|
||||
| SLASH of Region.t (* "/" *)
|
||||
| TIMES of Region.t (* "*" *)
|
||||
|
||||
(* Compounds *)
|
||||
|
||||
| LPAR of Region.t (* "(" *)
|
||||
| RPAR of Region.t (* ")" *)
|
||||
| LBRACKET of Region.t (* "[" *)
|
||||
| RBRACKET of Region.t (* "]" *)
|
||||
| LBRACE of Region.t (* "{" *)
|
||||
| RBRACE of Region.t (* "}" *)
|
||||
|
||||
(* Separators *)
|
||||
|
||||
| COMMA of Region.t (* "," *)
|
||||
| SEMI of Region.t (* ";" *)
|
||||
| VBAR of Region.t (* "|" *)
|
||||
| COLON of Region.t (* ":" *)
|
||||
| DOT of Region.t (* "." *)
|
||||
| DOTDOTDOT of Region.t (* "..." *)
|
||||
|
||||
(* Wildcard *)
|
||||
|
||||
| WILD of Region.t (* "_" *)
|
||||
|
||||
(* Comparisons *)
|
||||
|
||||
| EQ of Region.t (* "=" *)
|
||||
| EQEQ of Region.t (* "==" *)
|
||||
| NE of Region.t (* "!=" *)
|
||||
| LT of Region.t (* "<" *)
|
||||
| GT of Region.t (* ">" *)
|
||||
| LE of Region.t (* "<=" *)
|
||||
| GE of Region.t (* ">=" *)
|
||||
| ARROW of Region.t (* "=>" *)
|
||||
|
||||
| BOOL_OR of Region.t (* "||" *)
|
||||
| BOOL_AND of Region.t (* "&&" *)
|
||||
|
||||
| NOT of Region.t (* ! *)
|
||||
|
||||
(* Identifiers, labels, numbers and strings *)
|
||||
|
||||
| Ident of string Region.reg
|
||||
| Constr of string Region.reg
|
||||
| Int of (string * Z.t) Region.reg
|
||||
| Nat of (string * Z.t) Region.reg
|
||||
| Mtz of (string * Z.t) Region.reg
|
||||
| Str of string Region.reg
|
||||
| Bytes of (string * Hex.t) Region.reg
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
(*| And*)
|
||||
| Else of Region.t
|
||||
| False of Region.t
|
||||
| If of Region.t
|
||||
| Let of Region.t
|
||||
| Switch of Region.t
|
||||
| Mod of Region.t
|
||||
| Or of Region.t
|
||||
| True of Region.t
|
||||
| Type of Region.t
|
||||
(* Data constructors *)
|
||||
|
||||
| C_None of Region.t (* "None" *)
|
||||
| C_Some of Region.t (* "Some" *)
|
||||
|
||||
(* Virtual tokens *)
|
||||
|
||||
| EOF of Region.t (* End of file *)
|
||||
|
||||
type token = t
|
||||
|
||||
let proj_token = function
|
||||
| CAT region -> region, "CAT"
|
||||
| MINUS region -> region, "MINUS"
|
||||
| PLUS region -> region, "PLUS"
|
||||
| SLASH region -> region, "SLASH"
|
||||
| TIMES region -> region, "TIMES"
|
||||
| LPAR region -> region, "LPAR"
|
||||
| RPAR region -> region, "RPAR"
|
||||
| LBRACKET region -> region, "LBRACKET"
|
||||
| RBRACKET region -> region, "RBRACKET"
|
||||
| LBRACE region -> region, "LBRACE"
|
||||
| RBRACE region -> region, "RBRACE"
|
||||
| COMMA region -> region, "COMMA"
|
||||
| SEMI region -> region, "SEMI"
|
||||
| VBAR region -> region, "VBAR"
|
||||
| COLON region -> region, "COLON"
|
||||
| DOT region -> region, "DOT"
|
||||
| DOTDOTDOT region -> region, "DOTDOTDOT"
|
||||
| WILD region -> region, "WILD"
|
||||
| EQ region -> region, "EQ"
|
||||
| EQEQ region -> region, "EQEQ"
|
||||
| NE region -> region, "NE"
|
||||
| LT region -> region, "LT"
|
||||
| GT region -> region, "GT"
|
||||
| LE region -> region, "LE"
|
||||
| GE region -> region, "GE"
|
||||
| ARROW region -> region, "ARROW"
|
||||
| BOOL_OR region -> region, "BOOL_OR"
|
||||
| BOOL_AND region -> region, "BOOL_AND"
|
||||
| Ident Region.{region; value} ->
|
||||
region, sprintf "Ident %s" value
|
||||
| Constr Region.{region; value} ->
|
||||
region, sprintf "Constr %s" value
|
||||
| Int Region.{region; value = s,n} ->
|
||||
region, sprintf "Int (\"%s\", %s)" s (Z.to_string n)
|
||||
| Nat Region.{region; value = s,n} ->
|
||||
region, sprintf "Nat (\"%s\", %s)" s (Z.to_string n)
|
||||
| Mtz Region.{region; value = s,n} ->
|
||||
region, sprintf "Mutez (\"%s\", %s)" s (Z.to_string n)
|
||||
| Str Region.{region; value} ->
|
||||
region, sprintf "Str %s" value
|
||||
| Bytes Region.{region; value = s,b} ->
|
||||
region,
|
||||
sprintf "Bytes (\"%s\", \"0x%s\")"
|
||||
s (Hex.to_string b)
|
||||
| Else region -> region, "Else"
|
||||
| False region -> region, "False"
|
||||
| If region -> region, "If"
|
||||
| Let region -> region, "Let"
|
||||
| Switch region -> region, "Switch"
|
||||
| Mod region -> region, "Mod"
|
||||
| NOT region -> region, "!"
|
||||
| Or region -> region, "Or"
|
||||
| True region -> region, "True"
|
||||
| Type region -> region, "Type"
|
||||
| C_None region -> region, "C_None"
|
||||
| C_Some region -> region, "C_Some"
|
||||
| EOF region -> region, "EOF"
|
||||
|
||||
let to_lexeme = function
|
||||
| CAT _ -> "++"
|
||||
| MINUS _ -> "-"
|
||||
| PLUS _ -> "+"
|
||||
| SLASH _ -> "/"
|
||||
| TIMES _ -> "*"
|
||||
| LPAR _ -> "("
|
||||
| RPAR _ -> ")"
|
||||
| LBRACKET _ -> "["
|
||||
| RBRACKET _ -> "]"
|
||||
| LBRACE _ -> "{"
|
||||
| RBRACE _ -> "}"
|
||||
| COMMA _ -> ","
|
||||
| SEMI _ -> ";"
|
||||
| VBAR _ -> "|"
|
||||
| COLON _ -> ":"
|
||||
| DOT _ -> "."
|
||||
| DOTDOTDOT _ -> "..."
|
||||
| WILD _ -> "_"
|
||||
| EQ _ -> "="
|
||||
| EQEQ _ -> "=="
|
||||
| NE _ -> "!="
|
||||
| LT _ -> "<"
|
||||
| GT _ -> ">"
|
||||
| LE _ -> "<="
|
||||
| GE _ -> ">="
|
||||
| ARROW _ -> "=>"
|
||||
| BOOL_OR _ -> "||"
|
||||
| BOOL_AND _ -> "&&"
|
||||
| Ident id -> id.Region.value
|
||||
| Constr id -> id.Region.value
|
||||
| Int i
|
||||
| Nat i
|
||||
| Mtz i -> fst i.Region.value
|
||||
| Str s -> s.Region.value
|
||||
| Bytes b -> fst b.Region.value
|
||||
| Else _ -> "else"
|
||||
| False _ -> "false"
|
||||
| If _ -> "if"
|
||||
| Let _ -> "let"
|
||||
| Mod _ -> "mod"
|
||||
| NOT _ -> "!"
|
||||
| Or _ -> "or"
|
||||
| Switch _ -> "switch"
|
||||
| True _ -> "true"
|
||||
| Type _ -> "type"
|
||||
| C_None _ -> "None"
|
||||
| C_Some _ -> "Some"
|
||||
| EOF _ -> ""
|
||||
|
||||
let to_string token ?(offsets=true) mode =
|
||||
let region, val_str = proj_token token in
|
||||
let reg_str = region#compact ~offsets mode
|
||||
in sprintf "%s: %s" reg_str val_str
|
||||
|
||||
let to_region token = proj_token token |> fst
|
||||
|
||||
(* Injections *)
|
||||
|
||||
type int_err = Non_canonical_zero
|
||||
type ident_err = Reserved_name
|
||||
type nat_err = Invalid_natural
|
||||
| Non_canonical_zero_nat
|
||||
type sym_err = Invalid_symbol
|
||||
|
||||
(* LEXIS *)
|
||||
|
||||
let keywords = [
|
||||
(fun reg -> Else reg);
|
||||
(fun reg -> False reg);
|
||||
(fun reg -> If reg);
|
||||
(fun reg -> Let reg);
|
||||
(fun reg -> Switch reg);
|
||||
(fun reg -> Mod reg);
|
||||
(fun reg -> Or reg);
|
||||
(fun reg -> True 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 open SSet in
|
||||
empty
|
||||
|> add "and"
|
||||
|> add "as"
|
||||
|> add "asr"
|
||||
|> add "begin"
|
||||
|> add "class"
|
||||
|> add "constraint"
|
||||
|> add "do"
|
||||
|> add "done"
|
||||
|> add "downto"
|
||||
|> add "end"
|
||||
|> add "exception"
|
||||
|> add "external"
|
||||
|> add "for"
|
||||
|> add "function"
|
||||
|> add "functor"
|
||||
|> add "inherit"
|
||||
|> add "initializer"
|
||||
(* |> add "land" - see https://ligo.atlassian.net/browse/LIGO-263 *)
|
||||
|> add "lazy"
|
||||
(* |> add "lor" - see https://ligo.atlassian.net/browse/LIGO-263 *)
|
||||
|> add "lsl"
|
||||
|> add "lsr"
|
||||
(* |> add "lxor" - see https://ligo.atlassian.net/browse/LIGO-263 *)
|
||||
|> add "match"
|
||||
|> add "method"
|
||||
|> add "module"
|
||||
|> add "mutable"
|
||||
|> add "new"
|
||||
|> add "nonrec"
|
||||
|> add "object"
|
||||
|> add "of"
|
||||
|> add "open"
|
||||
|> add "private"
|
||||
|> add "rec"
|
||||
|> add "sig"
|
||||
|> add "struct"
|
||||
|> add "then"
|
||||
|> add "to"
|
||||
|> add "try"
|
||||
|> add "val"
|
||||
|> add "virtual"
|
||||
|> add "when"
|
||||
|> add "while"
|
||||
|> add "pri"
|
||||
|> add "pub"
|
||||
|
||||
let constructors = [
|
||||
(fun reg -> C_None reg);
|
||||
(fun reg -> C_Some reg);
|
||||
]
|
||||
|
||||
let add map (key, value) = SMap.add key value map
|
||||
|
||||
let mk_map mk_key list =
|
||||
let apply map value = add map (mk_key value, value)
|
||||
in List.fold_left apply SMap.empty list
|
||||
|
||||
type lexis = {
|
||||
kwd : (Region.t -> token) SMap.t;
|
||||
cstr : (Region.t -> token) SMap.t;
|
||||
res : SSet.t
|
||||
}
|
||||
|
||||
let lexicon : lexis =
|
||||
let build list = mk_map (fun f -> to_lexeme (f Region.ghost)) list
|
||||
in {kwd = build keywords;
|
||||
cstr = build constructors;
|
||||
res = reserved}
|
||||
|
||||
}
|
||||
|
||||
(* START LEXER DEFINITION *)
|
||||
|
||||
(* Named regular expressions *)
|
||||
|
||||
let small = ['a'-'z']
|
||||
let capital = ['A'-'Z']
|
||||
let letter = small | capital
|
||||
let digit = ['0'-'9']
|
||||
let ident = small (letter | '_' | digit)*
|
||||
let constr = capital (letter | '_' | digit)*
|
||||
|
||||
(* Rules *)
|
||||
|
||||
rule scan_ident region lexicon = parse
|
||||
(ident as value) eof {
|
||||
if SSet.mem value lexicon.res
|
||||
then Error Reserved_name
|
||||
else Ok (match SMap.find_opt value lexicon.kwd with
|
||||
Some mk_kwd -> mk_kwd region
|
||||
| None -> Ident Region.{region; value}) }
|
||||
|
||||
and scan_constr region lexicon = parse
|
||||
(constr as value) eof {
|
||||
match SMap.find_opt value lexicon.cstr with
|
||||
Some mk_cstr -> mk_cstr region
|
||||
| None -> Constr Region.{region; value} }
|
||||
|
||||
(* END LEXER DEFINITION *)
|
||||
|
||||
{
|
||||
(* START TRAILER *)
|
||||
|
||||
(* comments *)
|
||||
let block_comment_start lexeme = lexeme = "/*"
|
||||
let block_comment_end lexeme = lexeme = "*/"
|
||||
let line_comment_start lexeme = lexeme = "//"
|
||||
|
||||
(* Smart constructors (injections) *)
|
||||
|
||||
let mk_string lexeme region = Str Region.{region; value=lexeme}
|
||||
|
||||
let mk_bytes lexeme region =
|
||||
let norm = Str.(global_replace (regexp "_") "" lexeme) in
|
||||
let value = lexeme, Hex.of_string norm
|
||||
in Bytes Region.{region; value}
|
||||
|
||||
let mk_int lexeme region =
|
||||
let z = Str.(global_replace (regexp "_") "" lexeme)
|
||||
|> Z.of_string in
|
||||
if Z.equal z Z.zero && lexeme <> "0"
|
||||
then Error Non_canonical_zero
|
||||
else Ok (Int Region.{region; value = lexeme, z})
|
||||
|
||||
let mk_nat lexeme region =
|
||||
let z =
|
||||
Str.(global_replace (regexp "_") "" lexeme) |>
|
||||
Str.(global_replace (regexp "n") "") |>
|
||||
Z.of_string in
|
||||
if Z.equal z Z.zero && lexeme <> "0n"
|
||||
then Error Non_canonical_zero_nat
|
||||
else Ok (Nat Region.{region; value = lexeme, z})
|
||||
|
||||
let mk_mutez lexeme region =
|
||||
let z =
|
||||
Str.(global_replace (regexp "_") "" lexeme) |>
|
||||
Str.(global_replace (regexp "mutez") "") |>
|
||||
Z.of_string in
|
||||
if Z.equal z Z.zero && lexeme <> "0mutez"
|
||||
then Error Non_canonical_zero
|
||||
else Ok (Mtz Region.{region; value = lexeme, z})
|
||||
|
||||
let eof region = EOF region
|
||||
|
||||
let mk_sym lexeme region =
|
||||
match lexeme with
|
||||
"-" -> Ok (MINUS region)
|
||||
| "+" -> Ok (PLUS region)
|
||||
| "/" -> Ok (SLASH region)
|
||||
| "*" -> Ok (TIMES region)
|
||||
| "[" -> Ok (LBRACKET region)
|
||||
| "]" -> Ok (RBRACKET region)
|
||||
| "{" -> Ok (LBRACE region)
|
||||
| "}" -> Ok (RBRACE region)
|
||||
| "," -> Ok (COMMA region)
|
||||
| ";" -> Ok (SEMI region)
|
||||
| "|" -> Ok (VBAR region)
|
||||
| ":" -> Ok (COLON region)
|
||||
| "." -> Ok (DOT region)
|
||||
| "_" -> Ok (WILD region)
|
||||
| "=" -> Ok (EQ region)
|
||||
| "!=" -> Ok (NE region)
|
||||
| "<" -> Ok (LT region)
|
||||
| ">" -> Ok (GT region)
|
||||
| "<=" -> Ok (LE region)
|
||||
| ">=" -> Ok (GE region)
|
||||
| "||" -> Ok (BOOL_OR region)
|
||||
| "&&" -> Ok (BOOL_AND region)
|
||||
| "(" -> Ok (LPAR region)
|
||||
| ")" -> Ok (RPAR region)
|
||||
|
||||
(* Symbols specific to ReasonLIGO *)
|
||||
| "..."-> Ok (DOTDOTDOT region)
|
||||
| "=>" -> Ok (ARROW region)
|
||||
| "==" -> Ok (EQEQ region)
|
||||
| "!" -> Ok (NOT region)
|
||||
| "++" -> Ok (CAT region)
|
||||
| _ -> Error Invalid_symbol
|
||||
|
||||
(* Identifiers *)
|
||||
|
||||
let mk_ident' lexeme region lexicon =
|
||||
Lexing.from_string lexeme |> scan_ident region lexicon
|
||||
|
||||
let mk_ident lexeme region = mk_ident' lexeme region lexicon
|
||||
|
||||
(* Constructors *)
|
||||
|
||||
let mk_constr' lexeme region lexicon =
|
||||
Lexing.from_string lexeme |> scan_constr region lexicon
|
||||
|
||||
let mk_constr lexeme region = mk_constr' lexeme region lexicon
|
||||
|
||||
(* Predicates *)
|
||||
|
||||
let is_string = function
|
||||
Str _ -> true
|
||||
| _ -> false
|
||||
|
||||
let is_bytes = function
|
||||
Bytes _ -> true
|
||||
| _ -> false
|
||||
|
||||
let is_int = function
|
||||
Int _ -> true
|
||||
| _ -> false
|
||||
|
||||
let is_ident = function
|
||||
Ident _ -> true
|
||||
| _ -> false
|
||||
|
||||
let is_kwd = function
|
||||
| Else _
|
||||
| False _
|
||||
| If _
|
||||
| Let _
|
||||
| Switch _
|
||||
| Mod _
|
||||
| Or _
|
||||
| True _
|
||||
| Type _
|
||||
| _ -> false
|
||||
|
||||
let is_constr = function
|
||||
| Constr _
|
||||
| Ident _
|
||||
| False _
|
||||
| True _ -> true
|
||||
| _ -> false
|
||||
|
||||
let is_sym = function
|
||||
| CAT _
|
||||
| MINUS _
|
||||
| PLUS _
|
||||
| SLASH _
|
||||
| TIMES _
|
||||
| LPAR _
|
||||
| RPAR _
|
||||
| LBRACKET _
|
||||
| RBRACKET _
|
||||
| LBRACE _
|
||||
| RBRACE _
|
||||
| COMMA _
|
||||
| SEMI _
|
||||
| VBAR _
|
||||
| COLON _
|
||||
| DOT _
|
||||
| DOTDOTDOT _
|
||||
| WILD _
|
||||
| EQ _
|
||||
| EQEQ _
|
||||
| NE _
|
||||
| LT _
|
||||
| GT _
|
||||
| LE _
|
||||
| GE _
|
||||
| ARROW _
|
||||
| BOOL_OR _
|
||||
| NOT _
|
||||
| BOOL_AND _ -> true
|
||||
| _ -> false
|
||||
|
||||
let is_eof = function EOF _ -> true | _ -> false
|
||||
|
||||
(* END TRAILER *)
|
||||
}
|
62
src/passes/1-parser/reasonligo/LexerMain.ml
Normal file
62
src/passes/1-parser/reasonligo/LexerMain.ml
Normal file
@ -0,0 +1,62 @@
|
||||
(* Driver for the lexer of ReasonLIGO *)
|
||||
|
||||
(* Error printing and exception tracing *)
|
||||
|
||||
let () = Printexc.record_backtrace true
|
||||
|
||||
(* Running the lexer on the source *)
|
||||
|
||||
let options = EvalOpt.read "ReasonLIGO" ".religo"
|
||||
|
||||
open EvalOpt
|
||||
|
||||
let external_ text =
|
||||
Utils.highlight (Printf.sprintf "External error: %s" text); exit 1;;
|
||||
|
||||
(* Path for CPP inclusions (#include) *)
|
||||
|
||||
let lib_path =
|
||||
match options.libs with
|
||||
[] -> ""
|
||||
| libs -> let mk_I dir path = Printf.sprintf " -I %s%s" dir path
|
||||
in List.fold_right mk_I libs ""
|
||||
|
||||
(* Preprocessing the input source and opening the input channels *)
|
||||
|
||||
let prefix =
|
||||
match options.input with
|
||||
None | Some "-" -> "temp"
|
||||
| Some file -> Filename.(file |> basename |> remove_extension)
|
||||
|
||||
let suffix = ".pp.religo"
|
||||
|
||||
let pp_input =
|
||||
if Utils.String.Set.mem "cpp" options.verbose
|
||||
then prefix ^ suffix
|
||||
else let pp_input, pp_out = Filename.open_temp_file prefix suffix
|
||||
in close_out pp_out; pp_input
|
||||
|
||||
let cpp_cmd =
|
||||
|
||||
match options.input with
|
||||
None | Some "-" ->
|
||||
Printf.sprintf "cpp -traditional-cpp%s - > %s"
|
||||
lib_path pp_input
|
||||
| Some file ->
|
||||
Printf.sprintf "cpp -traditional-cpp%s %s > %s"
|
||||
lib_path file pp_input
|
||||
|
||||
let () =
|
||||
if Utils.String.Set.mem "cpp" options.verbose
|
||||
then Printf.eprintf "%s\n%!" cpp_cmd;
|
||||
if Sys.command cpp_cmd <> 0 then
|
||||
external_ (Printf.sprintf "the command \"%s\" failed." cpp_cmd)
|
||||
|
||||
(* Running the lexer on the input file *)
|
||||
|
||||
module Lexer = Lexer.Make (LexToken)
|
||||
|
||||
module Log = LexerLog.Make (Lexer)
|
||||
|
||||
let () = Log.trace ~offsets:options.offsets
|
||||
options.mode (Some pp_input) options.cmd
|
76
src/passes/1-parser/reasonligo/ParToken.mly
Normal file
76
src/passes/1-parser/reasonligo/ParToken.mly
Normal file
@ -0,0 +1,76 @@
|
||||
%{
|
||||
%}
|
||||
|
||||
(* Tokens (mirroring thise defined in module LexToken) *)
|
||||
|
||||
(* Literals *)
|
||||
|
||||
%token <string Region.reg> Ident
|
||||
%token <string Region.reg> Constr
|
||||
%token <string Region.reg> Str
|
||||
%token <(string * Z.t) Region.reg> Int
|
||||
%token <(string * Z.t) Region.reg> Nat
|
||||
%token <(string * Z.t) Region.reg> Mtz
|
||||
|
||||
(* Symbols *)
|
||||
|
||||
%token <Region.t> MINUS
|
||||
%token <Region.t> PLUS
|
||||
%token <Region.t> SLASH
|
||||
%token <Region.t> TIMES
|
||||
|
||||
%token <Region.t> LPAR
|
||||
%token <Region.t> RPAR
|
||||
%token <Region.t> LBRACKET
|
||||
%token <Region.t> RBRACKET
|
||||
%token <Region.t> LBRACE
|
||||
%token <Region.t> RBRACE
|
||||
|
||||
%token <Region.t> CAT
|
||||
%token <Region.t> DOT
|
||||
%token <Region.t> DOTDOTDOT
|
||||
|
||||
%token <Region.t> COMMA
|
||||
%token <Region.t> SEMI
|
||||
%token <Region.t> COLON
|
||||
%token <Region.t> VBAR
|
||||
|
||||
%token <Region.t> WILD
|
||||
|
||||
%token <Region.t> EQ
|
||||
%token <Region.t> EQEQ
|
||||
%token <Region.t> NE
|
||||
%token <Region.t> LT
|
||||
%token <Region.t> GT
|
||||
%token <Region.t> LE
|
||||
%token <Region.t> GE
|
||||
%token <Region.t> ARROW
|
||||
|
||||
%token <Region.t> NOT
|
||||
|
||||
%token <Region.t> BOOL_OR
|
||||
%token <Region.t> BOOL_AND
|
||||
|
||||
|
||||
(* Keywords *)
|
||||
|
||||
%token <Region.t> Else
|
||||
%token <Region.t> False
|
||||
%token <Region.t> If
|
||||
%token <Region.t> Let
|
||||
%token <Region.t> Switch
|
||||
%token <Region.t> Mod
|
||||
%token <Region.t> Or
|
||||
%token <Region.t> True
|
||||
%token <Region.t> Type
|
||||
|
||||
(* Data constructors *)
|
||||
|
||||
%token <Region.t> C_None (* "None" *)
|
||||
%token <Region.t> C_Some (* "Some" *)
|
||||
|
||||
(* Virtual tokens *)
|
||||
|
||||
%token <Region.t> EOF
|
||||
|
||||
%%
|
1077
src/passes/1-parser/reasonligo/Parser.mly
Normal file
1077
src/passes/1-parser/reasonligo/Parser.mly
Normal file
File diff suppressed because it is too large
Load Diff
124
src/passes/1-parser/reasonligo/ParserMain.ml
Normal file
124
src/passes/1-parser/reasonligo/ParserMain.ml
Normal file
@ -0,0 +1,124 @@
|
||||
(* Driver for the parser of ReasonLIGO *)
|
||||
|
||||
(* Error printing and exception tracing *)
|
||||
|
||||
let () = Printexc.record_backtrace true
|
||||
|
||||
(* Reading the command-line options *)
|
||||
|
||||
let options = EvalOpt.read "ReasonLIGO" ".religo"
|
||||
|
||||
open EvalOpt
|
||||
|
||||
(* Auxiliary functions *)
|
||||
|
||||
let sprintf = Printf.sprintf
|
||||
|
||||
(* Extracting the input file *)
|
||||
|
||||
let file =
|
||||
match options.input with
|
||||
None | Some "-" -> false
|
||||
| Some _ -> true
|
||||
|
||||
(* Error printing and exception tracing *)
|
||||
|
||||
let () = Printexc.record_backtrace true
|
||||
|
||||
let external_ text =
|
||||
Utils.highlight (Printf.sprintf "External error: %s" text); exit 1;;
|
||||
|
||||
type Error.t += ParseError
|
||||
|
||||
let error_to_string = function
|
||||
ParseError -> "Syntax error.\n"
|
||||
| _ -> assert false
|
||||
|
||||
let print_error ?(offsets=true) mode Region.{region; value} ~file =
|
||||
let msg = error_to_string value in
|
||||
let reg = region#to_string ~file ~offsets mode in
|
||||
Utils.highlight (sprintf "Parse error %s:\n%s%!" reg msg)
|
||||
|
||||
(* Path for CPP inclusions (#include) *)
|
||||
|
||||
let lib_path =
|
||||
match options.libs with
|
||||
[] -> ""
|
||||
| libs -> let mk_I dir path = Printf.sprintf " -I %s%s" dir path
|
||||
in List.fold_right mk_I libs ""
|
||||
|
||||
(* Preprocessing the input source and opening the input channels *)
|
||||
|
||||
let prefix =
|
||||
match options.input with
|
||||
None | Some "-" -> "temp"
|
||||
| Some file -> Filename.(file |> basename |> remove_extension)
|
||||
|
||||
let suffix = ".pp.religo"
|
||||
|
||||
let pp_input =
|
||||
if Utils.String.Set.mem "cpp" options.verbose
|
||||
then prefix ^ suffix
|
||||
else let pp_input, pp_out = Filename.open_temp_file prefix suffix
|
||||
in close_out pp_out; pp_input
|
||||
|
||||
let cpp_cmd =
|
||||
match options.input with
|
||||
None | Some "-" ->
|
||||
Printf.sprintf "cpp -traditional-cpp%s - > %s"
|
||||
lib_path pp_input
|
||||
| Some file ->
|
||||
Printf.sprintf "cpp -traditional-cpp%s %s > %s"
|
||||
lib_path file pp_input
|
||||
|
||||
let () =
|
||||
if Utils.String.Set.mem "cpp" options.verbose
|
||||
then Printf.eprintf "%s\n%!" cpp_cmd;
|
||||
if Sys.command cpp_cmd <> 0 then
|
||||
external_ (Printf.sprintf "the command \"%s\" failed." cpp_cmd)
|
||||
|
||||
(* Instanciating the lexer *)
|
||||
|
||||
module Lexer = Lexer.Make (LexToken)
|
||||
|
||||
module Log = LexerLog.Make (Lexer)
|
||||
|
||||
let Lexer.{read; buffer; get_pos; get_last; close} =
|
||||
Lexer.open_token_stream (Some pp_input)
|
||||
|
||||
and cout = stdout
|
||||
|
||||
let log = Log.output_token ~offsets:options.offsets
|
||||
options.mode options.cmd cout
|
||||
|
||||
and close_all () = close (); close_out cout
|
||||
|
||||
(* Tokeniser *)
|
||||
|
||||
let tokeniser = read ~log
|
||||
|
||||
(* Main *)
|
||||
|
||||
let () =
|
||||
try
|
||||
let ast = Parser.contract tokeniser buffer in
|
||||
if Utils.String.Set.mem "ast" options.verbose
|
||||
then let buffer = Buffer.create 131 in
|
||||
begin
|
||||
Parser_ligodity.ParserLog.offsets := options.offsets;
|
||||
Parser_ligodity.ParserLog.mode := options.mode;
|
||||
Parser_ligodity.ParserLog.print_tokens buffer ast;
|
||||
Buffer.output_buffer stdout buffer
|
||||
end
|
||||
with
|
||||
Lexer.Error err ->
|
||||
close_all ();
|
||||
Lexer.print_error ~offsets:options.offsets
|
||||
options.mode err ~file
|
||||
| Parser.Error ->
|
||||
let region = get_last () in
|
||||
let error = Region.{region; value=ParseError} in
|
||||
let () = close_all () in
|
||||
print_error ~offsets:options.offsets
|
||||
options.mode error ~file
|
||||
| Sys_error msg -> Utils.highlight msg
|
41
src/passes/1-parser/reasonligo/dune
Normal file
41
src/passes/1-parser/reasonligo/dune
Normal file
@ -0,0 +1,41 @@
|
||||
(ocamllex LexToken)
|
||||
|
||||
(menhir
|
||||
(merge_into Parser)
|
||||
(modules ParToken Parser)
|
||||
(flags -la 1 --explain --dump --strict --external-tokens LexToken))
|
||||
|
||||
(library
|
||||
(name parser_reasonligo)
|
||||
(public_name ligo.parser.reasonligo)
|
||||
(modules reasonligo LexToken Parser)
|
||||
(libraries
|
||||
parser_shared
|
||||
parser_ligodity
|
||||
str
|
||||
simple-utils
|
||||
tezos-utils
|
||||
getopt
|
||||
)
|
||||
(flags (:standard -open Simple_utils -open Parser_shared -open Parser_ligodity ))
|
||||
)
|
||||
|
||||
(executable
|
||||
(name LexerMain)
|
||||
(libraries
|
||||
parser_reasonligo)
|
||||
(modules
|
||||
LexerMain
|
||||
)
|
||||
(flags (:standard -open Parser_shared -open Parser_reasonligo))
|
||||
)
|
||||
|
||||
(executable
|
||||
(name ParserMain)
|
||||
(libraries
|
||||
parser_reasonligo)
|
||||
(modules
|
||||
ParserMain
|
||||
)
|
||||
(flags (:standard -open Simple_utils -open Parser_shared -open Parser_reasonligo))
|
||||
)
|
5
src/passes/1-parser/reasonligo/reasonligo.ml
Normal file
5
src/passes/1-parser/reasonligo/reasonligo.ml
Normal file
@ -0,0 +1,5 @@
|
||||
module Parser = Parser
|
||||
module AST = Parser_ligodity.AST
|
||||
module Lexer = Lexer
|
||||
module LexToken = LexToken
|
||||
module ParserLog = Parser_ligodity.ParserLog
|
@ -526,13 +526,14 @@ let esc = "\\n" | "\\\"" | "\\\\" | "\\b"
|
||||
| "\\r" | "\\t" | "\\x" byte
|
||||
let pascaligo_sym = "=/=" | '#' | ":="
|
||||
let cameligo_sym = "<>" | "::" | "||" | "&&"
|
||||
let reasonligo_sym = '!' | "=>" | "!=" | "==" | "++" | "..." | "||" | "&&"
|
||||
|
||||
let symbol =
|
||||
';' | ',' | '(' | ')'| '[' | ']' | '{' | '}'
|
||||
| '=' | ':' | '|' | "->" | '.' | '_' | '^'
|
||||
| '+' | '-' | '*' | '/'
|
||||
| '<' | "<=" | '>' | ">="
|
||||
| pascaligo_sym | cameligo_sym
|
||||
| pascaligo_sym | cameligo_sym | reasonligo_sym
|
||||
|
||||
let string = [^'"' '\\' '\n']* (* For strings of #include *)
|
||||
|
||||
|
@ -258,9 +258,10 @@ module Simplify = struct
|
||||
| "LT" -> ok C_LT
|
||||
| "LE" -> ok C_LE
|
||||
| "CONS" -> ok C_CONS
|
||||
| "NEQ" -> ok C_NEQ
|
||||
|
||||
| "Michelson.is_nat" -> ok C_IS_NAT
|
||||
| _ -> simple_fail "Not a Ligodity constant"
|
||||
| _ -> simple_fail "Not a constant"
|
||||
|
||||
let type_constants = type_constants
|
||||
let type_operators = type_operators
|
||||
|
1
src/test/contracts/address.religo
Normal file
1
src/test/contracts/address.religo
Normal file
@ -0,0 +1 @@
|
||||
let main = (c: contract(unit)): address => Current.address(c);
|
24
src/test/contracts/arithmetic.religo
Normal file
24
src/test/contracts/arithmetic.religo
Normal file
@ -0,0 +1,24 @@
|
||||
/* Test ReasonLIGO arithmetic operators */
|
||||
|
||||
let mod_op = (n: int): nat => n mod 42;
|
||||
|
||||
let plus_op = (n: int): int => n + 42;
|
||||
|
||||
let minus_op = (n: int): int => n - 42;
|
||||
|
||||
let times_op = (n: int): int => n * 42;
|
||||
|
||||
let div_op = (n: int): int => n / 2;
|
||||
|
||||
/* TODO (?): Support conversion from nat to int and back
|
||||
|
||||
let int_op (n : nat) : int =
|
||||
Int n
|
||||
|
||||
*/
|
||||
|
||||
let neg_op = (n: int): int => - n;
|
||||
|
||||
let foo = (n: int): int => n + 10;
|
||||
|
||||
let neg_op_2 = (b: int): int => - foo(b);
|
4
src/test/contracts/assert.religo
Normal file
4
src/test/contracts/assert.religo
Normal file
@ -0,0 +1,4 @@
|
||||
let main = (p: bool, s: unit) => {
|
||||
let u: unit = assert(p);
|
||||
([]: list(operation), s);
|
||||
};
|
15
src/test/contracts/balance_constant.religo
Normal file
15
src/test/contracts/balance_constant.religo
Normal file
@ -0,0 +1,15 @@
|
||||
/**
|
||||
|
||||
This test makes sure that the balance is accessible in ReasonLIGO.
|
||||
It's there to detect a regression of: https://gitlab.com/ligolang/ligo/issues/61
|
||||
|
||||
Which results in this error when you attempt to compile this contract:
|
||||
|
||||
generated. unrecognized constant: {"constant":"BALANCE","location":"generated"}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
type storage = tez;
|
||||
|
||||
let main = (p: unit, storage) => ([]: list(operation), balance);
|
3
src/test/contracts/basic.religo
Normal file
3
src/test/contracts/basic.religo
Normal file
@ -0,0 +1,3 @@
|
||||
type toto = int;
|
||||
|
||||
let foo : toto = 42 + 127;
|
20
src/test/contracts/big_map.religo
Normal file
20
src/test/contracts/big_map.religo
Normal file
@ -0,0 +1,20 @@
|
||||
type foo = big_map(int, int);
|
||||
|
||||
let set_ = (n: int, m: foo): foo => Big_map.update(23, Some(n), m);
|
||||
|
||||
let rm = (m: foo): foo => Big_map.remove(42, m);
|
||||
|
||||
let gf = (m: foo): int => Big_map.find(23, m);
|
||||
|
||||
let get = (m: foo): option(int) => Big_map.find_opt(42, m);
|
||||
|
||||
let empty_map: foo = Big_map.empty;
|
||||
|
||||
let map1: foo = Big_map.literal([(23, 0), (42, 0)]);
|
||||
|
||||
let map1: foo = Big_map.literal([(23, 0), (42, 0)]);
|
||||
|
||||
let mutimaps = (m: foo, n: foo): foo => {
|
||||
let bar: foo = Big_map.update(42, Some(0), m);
|
||||
Big_map.update(42, get(bar), n);
|
||||
};
|
5
src/test/contracts/bitwise_arithmetic.religo
Normal file
5
src/test/contracts/bitwise_arithmetic.religo
Normal file
@ -0,0 +1,5 @@
|
||||
/* Test ReasonLigo bitwise operators */
|
||||
|
||||
let or_op = (n: nat): nat => Bitwise.lor(n, 4n);
|
||||
let and_op = (n: nat): nat => Bitwise.land(n, 7n);
|
||||
let xor_op = (n: nat): nat => Bitwise.lxor(n, 7n);
|
11
src/test/contracts/boolean_operators.religo
Normal file
11
src/test/contracts/boolean_operators.religo
Normal file
@ -0,0 +1,11 @@
|
||||
// Test ReasonLIGO boolean operators
|
||||
|
||||
let or_true = (b: bool): bool => b || true;
|
||||
|
||||
let or_false = (b: bool): bool => b || false;
|
||||
|
||||
let and_true = (b: bool): bool => b && true;
|
||||
|
||||
let and_false = (b: bool): bool => b && false;
|
||||
|
||||
let not_bool = (b: bool): bool => !b;
|
5
src/test/contracts/bytes_arithmetic.religo
Normal file
5
src/test/contracts/bytes_arithmetic.religo
Normal file
@ -0,0 +1,5 @@
|
||||
let concat_op = (s: bytes): bytes => Bytes.concat(s, "7070": bytes);
|
||||
|
||||
let slice_op = (s: bytes): bytes => Bytes.slice(1n, 2n, s);
|
||||
|
||||
let hasherman = (s: bytes): bytes => Crypto.sha256(s);
|
9
src/test/contracts/closure.religo
Normal file
9
src/test/contracts/closure.religo
Normal file
@ -0,0 +1,9 @@
|
||||
/* Test whether closures retain values in ReasonLIGO */
|
||||
|
||||
let test = (k: int): int => {
|
||||
let j: int = k + 5;
|
||||
let close: (int => int) = (i: int) => i + j;
|
||||
|
||||
let j: int = 20; /* Shadow original variable to see if value close'd */
|
||||
close(20);
|
||||
};
|
6
src/test/contracts/condition-annot.religo
Normal file
6
src/test/contracts/condition-annot.religo
Normal file
@ -0,0 +1,6 @@
|
||||
let main = (i: int) =>
|
||||
if (((i == 2): bool)) {
|
||||
(42: int);
|
||||
} else {
|
||||
(0: int);
|
||||
};
|
12
src/test/contracts/condition-shadowing.religo
Normal file
12
src/test/contracts/condition-shadowing.religo
Normal file
@ -0,0 +1,12 @@
|
||||
/* TODO : make a test using mutation, not shadowing */
|
||||
|
||||
let main = (i: int) => {
|
||||
let result = 0;
|
||||
if (i == 2) {
|
||||
let result = 42;
|
||||
result;
|
||||
} else {
|
||||
let result = 0;
|
||||
result;
|
||||
};
|
||||
};
|
8
src/test/contracts/condition.religo
Normal file
8
src/test/contracts/condition.religo
Normal file
@ -0,0 +1,8 @@
|
||||
/* Test conditional in ReasonLIGO */
|
||||
|
||||
let main = (i: int) =>
|
||||
if (i == 2) {
|
||||
42;
|
||||
} else {
|
||||
0;
|
||||
};
|
4
src/test/contracts/counter.religo
Normal file
4
src/test/contracts/counter.religo
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
type storage = int;
|
||||
|
||||
let main = (p: int, storage): string => ([]: list(operation), p + storage);
|
8
src/test/contracts/failwith.religo
Normal file
8
src/test/contracts/failwith.religo
Normal file
@ -0,0 +1,8 @@
|
||||
type storage = unit;
|
||||
|
||||
let main = (p: unit, storage) =>
|
||||
if (true) {
|
||||
failwith("This contract always fails");
|
||||
} else {
|
||||
();
|
||||
};
|
7
src/test/contracts/function-shared.religo
Normal file
7
src/test/contracts/function-shared.religo
Normal file
@ -0,0 +1,7 @@
|
||||
/* Test use of multiple subroutines in a ReasonLIGO function */
|
||||
|
||||
let foo = (i: int): int => i + 20;
|
||||
|
||||
let bar = (i: int): int => i + 50;
|
||||
|
||||
let foobar = (i: int): int => foo(i) + bar(i);
|
48
src/test/contracts/high-order.religo
Normal file
48
src/test/contracts/high-order.religo
Normal file
@ -0,0 +1,48 @@
|
||||
/* Test a function which takes another function as an argument */
|
||||
let foobar = (i: int): int => {
|
||||
let foo: int => int = (i: int) => i;
|
||||
|
||||
let bar: ((int => int) => int) = (f: (int => int)) => f(i);
|
||||
|
||||
bar(foo);
|
||||
};
|
||||
|
||||
/* higher order function with more than one argument */
|
||||
let higher2 = (i: int, f: (int => int)): int => {
|
||||
let ii: int = f(i);
|
||||
ii;
|
||||
};
|
||||
|
||||
let foobar2 = (i: int): int => {
|
||||
let foo2: int => int = (i: int) => i;
|
||||
|
||||
higher2(i, foo2);
|
||||
};
|
||||
|
||||
let a: int = 0;
|
||||
|
||||
let foobar3 = (i: int): int => {
|
||||
let foo2: int => int = (i: int) => a + i;
|
||||
|
||||
higher2(i, foo2);
|
||||
};
|
||||
|
||||
let f = (i: int): int => i;
|
||||
|
||||
let g = (i: int): int => f(i);
|
||||
|
||||
let foobar4 = (i: int): int => g(g(i));
|
||||
|
||||
let higher3 = (i: int, f: (int => int), g: (int => int)): int => {
|
||||
let ii: int = f(g(i));
|
||||
ii;
|
||||
};
|
||||
|
||||
let foobar5 = (i: int): int => {
|
||||
let a: int = 0;
|
||||
let foo: int => int = (i: int) => a + i;
|
||||
|
||||
let goo: int => int = (i: int) => foo(i);
|
||||
|
||||
higher3(i, foo, goo);
|
||||
};
|
1
src/test/contracts/implicit_account.religo
Normal file
1
src/test/contracts/implicit_account.religo
Normal file
@ -0,0 +1 @@
|
||||
let main = (kh: key_hash): contract(unit) => Current.implicit_account(kh);
|
1
src/test/contracts/isnat.religo
Normal file
1
src/test/contracts/isnat.religo
Normal file
@ -0,0 +1 @@
|
||||
let main = (i: int): option(nat) => Michelson.is_nat(i);
|
8
src/test/contracts/lambda.religo
Normal file
8
src/test/contracts/lambda.religo
Normal file
@ -0,0 +1,8 @@
|
||||
type storage = unit;
|
||||
|
||||
/* not supported yet
|
||||
let%entry main (p:unit) storage =
|
||||
(fun x -> ()) ()
|
||||
*/
|
||||
|
||||
let main = ((p: unit), storage) => (((xxx: unit)) => ())();
|
8
src/test/contracts/lambda2.religo
Normal file
8
src/test/contracts/lambda2.religo
Normal file
@ -0,0 +1,8 @@
|
||||
type storage = unit;
|
||||
|
||||
/* Not supported yet:
|
||||
let main (p:unit) storage = (fun x -> ()) ()
|
||||
*/
|
||||
|
||||
let main = (z: unit, storage) =>
|
||||
((f: (unit => unit)) => f())((z: unit) => unit);
|
14
src/test/contracts/let_multiple.religo
Normal file
14
src/test/contracts/let_multiple.religo
Normal file
@ -0,0 +1,14 @@
|
||||
/* Simple test of binding multiple values */
|
||||
|
||||
let ((x: int), (y: int)) = (1, 2);
|
||||
|
||||
let main = (p: unit): int => x + y;
|
||||
|
||||
let ((x: int), (y: int)) = (3, 3);
|
||||
|
||||
let main_paren = (p: unit): int => x + y;
|
||||
|
||||
let foobar: (int, int) = (23, 42);
|
||||
let ((foo: int), (bar: int)) = foobar;
|
||||
|
||||
let non_tuple_rhs = (p: unit): int => foo + bar;
|
9
src/test/contracts/letin.religo
Normal file
9
src/test/contracts/letin.religo
Normal file
@ -0,0 +1,9 @@
|
||||
type storage = (int, int);
|
||||
|
||||
let main = ((n : int), storage) => {
|
||||
let x: (int, int) = {
|
||||
let x: int = 7;
|
||||
(x + n, storage[0] + storage[1]);
|
||||
};
|
||||
([]: list(operation), x);
|
||||
};
|
29
src/test/contracts/list.religo
Normal file
29
src/test/contracts/list.religo
Normal file
@ -0,0 +1,29 @@
|
||||
type storage = (int, list(int));
|
||||
|
||||
type param = list(int);
|
||||
|
||||
let x: list(int) = [];
|
||||
let y: list(int) = [3, 4, 5];
|
||||
let z: list(int) = [2, ...y];
|
||||
|
||||
let main = (p: param, storage) => {
|
||||
let storage =
|
||||
switch (p) {
|
||||
| [] => storage
|
||||
| [hd, ...tl] => (storage[0] + hd, tl)
|
||||
};
|
||||
([]: list(operation), storage);
|
||||
};
|
||||
|
||||
let fold_op = (s: list(int)): int => {
|
||||
let aggregate = (prec: int, cur: int) => prec + cur;
|
||||
List.fold(aggregate, s, 10);
|
||||
};
|
||||
|
||||
let map_op = (s: list(int)): list(int) =>
|
||||
List.map((cur: int) => cur + 1, s);
|
||||
|
||||
let iter_op = (s: list(int)): unit => {
|
||||
let do_nothing = (z: int) => unit;
|
||||
List.iter(do_nothing, s);
|
||||
};
|
46
src/test/contracts/loop.religo
Normal file
46
src/test/contracts/loop.religo
Normal file
@ -0,0 +1,46 @@
|
||||
/* Test loops in ReasonLIGO */
|
||||
|
||||
let aux_simple = (i: int): (bool, int) =>
|
||||
if (i < 100) {
|
||||
continue(i + 1);
|
||||
} else {
|
||||
stop(i);
|
||||
};
|
||||
|
||||
let counter_simple = (n: int): int => Loop.fold_while(aux_simple, n);
|
||||
|
||||
type sum_aggregator = {
|
||||
counter: int,
|
||||
sum: int,
|
||||
};
|
||||
|
||||
let counter = (n: int): int => {
|
||||
let initial: sum_aggregator = {counter: 0, sum: 0};
|
||||
let out: sum_aggregator =
|
||||
Loop.fold_while(
|
||||
(prev: sum_aggregator) =>
|
||||
if (prev.counter <= n) {
|
||||
continue({counter: prev.counter + 1, sum: prev.counter + prev.sum});
|
||||
} else {
|
||||
stop({counter: prev.counter, sum: prev.sum});
|
||||
},
|
||||
initial
|
||||
);
|
||||
out.sum;
|
||||
};
|
||||
|
||||
let aux_nest = (prev: sum_aggregator): (bool, sum_aggregator) =>
|
||||
if (prev.counter < 100) {
|
||||
continue({
|
||||
counter: prev.counter + 1,
|
||||
sum: prev.sum + Loop.fold_while(aux_simple, prev.counter),
|
||||
});
|
||||
} else {
|
||||
stop({counter: prev.counter, sum: prev.sum});
|
||||
};
|
||||
|
||||
let counter_nest = (n: int): int => {
|
||||
let initial: sum_aggregator = {counter: 0, sum: 0};
|
||||
let out: sum_aggregator = Loop.fold_while(aux_nest, initial);
|
||||
out.sum;
|
||||
};
|
57
src/test/contracts/map.religo
Normal file
57
src/test/contracts/map.religo
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
type foobar = map(int, int);
|
||||
|
||||
let empty_map: foobar = Map.empty;
|
||||
|
||||
let map1: foobar =
|
||||
Map.literal([(144, 23), (51, 23), (42, 23), (120, 23), (421, 23)]);
|
||||
|
||||
let map2: foobar = Map.literal([(23, 0), (42, 0)]);
|
||||
|
||||
let set_ = (n: int, m: foobar): foobar => Map.update(23, Some(n), m);
|
||||
|
||||
let rm = (m: foobar): foobar => Map.remove(42, m);
|
||||
|
||||
/* Dummy test so that we can add the same test for PascaLIGO */
|
||||
let patch_ = (m: foobar): foobar => Map.literal([(0, 5), (1, 6), (2, 7)]);
|
||||
|
||||
/* Second dummy test, see above */
|
||||
let patch_empty = (m: foobar): foobar =>
|
||||
Map.literal([(0, 0), (1, 1), (2, 2)]);
|
||||
|
||||
/* Third dummy test, see above */
|
||||
let patch_deep = (m: (foobar, nat)): (foobar, nat) => (
|
||||
Map.literal([(0, 0), (1, 9), (2, 2)]),
|
||||
10n
|
||||
);
|
||||
|
||||
let size_ = (m: foobar): nat => Map.size(m);
|
||||
|
||||
let gf = (m: foobar): int => Map.find(23, m);
|
||||
|
||||
let get = (m: foobar): option(int) => Map.find_opt(42, m);
|
||||
let get_ = (m: foobar): option(int) => Map.find_opt(42, m);
|
||||
|
||||
let mem = (km: (int, foobar)): bool => Map.mem(km[0], km[1]);
|
||||
|
||||
let iter_op = (m: foobar): unit => {
|
||||
let assert_eq = (i: int, j: int) => assert(i == j);
|
||||
Map.iter(assert_eq, m);
|
||||
};
|
||||
|
||||
let map_op = (m: foobar): foobar => {
|
||||
let increment = (z: int, j: int) => j + 1;
|
||||
Map.map(increment, m);
|
||||
};
|
||||
|
||||
let fold_op = (m: foobar): foobar => {
|
||||
let aggregate = (i: int, j: (int, int)) => i + j[0] + j[1];
|
||||
Map.fold(aggregate, m, 10);
|
||||
};
|
||||
|
||||
let deep_op = (m: foobar): foobar => {
|
||||
let coco = (0, m);
|
||||
let coco = (0, Map.remove(42, coco[1]));
|
||||
let coco = (0, Map.update(32, Some(16), coco[1]));
|
||||
coco[1];
|
||||
};
|
17
src/test/contracts/match.religo
Normal file
17
src/test/contracts/match.religo
Normal file
@ -0,0 +1,17 @@
|
||||
type storage = int;
|
||||
|
||||
type param =
|
||||
| Add(int)
|
||||
| Sub(int);
|
||||
|
||||
let main = ((p: param), storage) => {
|
||||
let storage =
|
||||
storage
|
||||
+ (
|
||||
switch (p) {
|
||||
| Add(n) => n
|
||||
| Sub(n) => 0 - n
|
||||
}
|
||||
);
|
||||
(([]: list(operation)), storage);
|
||||
};
|
22
src/test/contracts/match_bis.religo
Normal file
22
src/test/contracts/match_bis.religo
Normal file
@ -0,0 +1,22 @@
|
||||
type storage = int;
|
||||
|
||||
/* variant defining pseudo multi-entrypoint actions */
|
||||
|
||||
type action =
|
||||
| Increment(int)
|
||||
| Decrement(int);
|
||||
|
||||
let add = ((a: int), (b: int)) => a + b;
|
||||
|
||||
let subtract = ((a: int), (b: int)) => a - b;
|
||||
|
||||
/* real entrypoint that re-routes the flow based on the action provided */
|
||||
|
||||
let main = ((p: action), storage) => {
|
||||
let storage =
|
||||
switch (p) {
|
||||
| Increment(n) => add(storage, n)
|
||||
| Decrement(n) => subtract(storage, n)
|
||||
};
|
||||
(([]: list(operation)), storage);
|
||||
};
|
3
src/test/contracts/multiple-parameters.religo
Normal file
3
src/test/contracts/multiple-parameters.religo
Normal file
@ -0,0 +1,3 @@
|
||||
/* Test function with several parameters */
|
||||
|
||||
let abcde = (a: int, b: int, c: int, d: int, e: int): int => c + e + 3;
|
4
src/test/contracts/option.religo
Normal file
4
src/test/contracts/option.religo
Normal file
@ -0,0 +1,4 @@
|
||||
type foobar = option(int);
|
||||
|
||||
let s: foobar = Some(42);
|
||||
let n: foobar = None;
|
1
src/test/contracts/self_address.religo
Normal file
1
src/test/contracts/self_address.religo
Normal file
@ -0,0 +1 @@
|
||||
let main = (p: unit): address => Current.self_address;
|
20
src/test/contracts/set_arithmetic.religo
Normal file
20
src/test/contracts/set_arithmetic.religo
Normal file
@ -0,0 +1,20 @@
|
||||
/* Test set operations in ReasonLIGO */
|
||||
|
||||
let add_op = (s: set(string)): set(string) => Set.add("foobar", s);
|
||||
|
||||
let remove_op = (s: set(string)): set(string) => Set.remove("foobar", s);
|
||||
|
||||
let remove_deep = (s: (set(string), nat)): (set(string), nat) =>
|
||||
Set.remove("foobar", s[0]);
|
||||
|
||||
/*
|
||||
let patch_op (s: string set) : string set =
|
||||
begin patch s with set ["foobar"]; end with s
|
||||
|
||||
let patch_op_deep (s: string set * nat) : string set * nat =
|
||||
begin patch s[0] with set ["foobar"]; end with s
|
||||
*/
|
||||
|
||||
let mem_op = (s: set(string)): bool => Set.mem("foobar", s);
|
||||
|
||||
let size_op = (s: set(string)): nat => Set.size(s);
|
7
src/test/contracts/string_arithmetic.religo
Normal file
7
src/test/contracts/string_arithmetic.religo
Normal file
@ -0,0 +1,7 @@
|
||||
/* Test that the string concatenation syntax in ReasonLIGO works */
|
||||
|
||||
let size_op = (s: string): nat => String.size(s);
|
||||
|
||||
let slice_op = (s: string): string => String.slice(1n, 2n, s);
|
||||
|
||||
let concat_syntax = (s: string) => s ++ "test_literal";
|
12
src/test/contracts/super-counter.religo
Normal file
12
src/test/contracts/super-counter.religo
Normal file
@ -0,0 +1,12 @@
|
||||
type action =
|
||||
| Increment(int)
|
||||
| Decrement(int);
|
||||
|
||||
let main = (p: action, s: int): (list(operation), int) => {
|
||||
let storage =
|
||||
switch (p) {
|
||||
| Increment(n) => s + n
|
||||
| Decrement(n) => s - n
|
||||
};
|
||||
([]: list(operation), storage);
|
||||
};
|
13
src/test/contracts/tuple.religo
Normal file
13
src/test/contracts/tuple.religo
Normal file
@ -0,0 +1,13 @@
|
||||
type abc = (int, int, int);
|
||||
|
||||
let projection_abc = (tpl: abc): int => tpl[1];
|
||||
|
||||
type foobar = (int, int);
|
||||
|
||||
let fb: foobar = (0, 0);
|
||||
|
||||
let projection = (tpl: foobar): int => tpl[0] + tpl[1];
|
||||
|
||||
type big_tuple = (int, int, int, int, int);
|
||||
|
||||
let br: big_tuple = (23, 23, 23, 23, 23);
|
54
src/test/contracts/tuples_sequences_functions.religo
Normal file
54
src/test/contracts/tuples_sequences_functions.religo
Normal file
@ -0,0 +1,54 @@
|
||||
let a = 1;
|
||||
let b = 1n;
|
||||
let c = 2mutez;
|
||||
let d = 1n + 2n;
|
||||
let e = 1mutez + 3mutez;
|
||||
let f = (a, c);
|
||||
let g = (a + 1, c);
|
||||
let h = ("a" ++ "2", d);
|
||||
let i = (a: int, b: int) => a + b;
|
||||
let j = (a: int, b: int) => a - b;
|
||||
/* not supported by typer yet: let k = () => b; */
|
||||
/* not supported by typer yet: let l = () => i(2,3); */
|
||||
let m = {
|
||||
let z = 3;
|
||||
z;
|
||||
};
|
||||
let n = (a: int): int => a + 1;
|
||||
let o = (a: int): int => a + 1;
|
||||
let n = (a: int, b: int): int => a + 1;
|
||||
let o = (a: int, b: int): int => a + 1;
|
||||
let p = {{
|
||||
3;
|
||||
}};
|
||||
let q = {
|
||||
f: 3,
|
||||
g: 6,
|
||||
h: {
|
||||
i: "bla",
|
||||
j: 1 + 2,
|
||||
k: {
|
||||
l: 1,
|
||||
z: 2
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
Not supported yet by parser:
|
||||
|
||||
let r = {
|
||||
a: 1
|
||||
};
|
||||
*/
|
||||
|
||||
let s = {
|
||||
let a = 2;
|
||||
{
|
||||
z: a,
|
||||
a
|
||||
};
|
||||
};
|
||||
|
||||
let t = (((((((2)))))));
|
||||
let u = if (true) { 1; } else { 2; };
|
10
src/test/contracts/variant.religo
Normal file
10
src/test/contracts/variant.religo
Normal file
@ -0,0 +1,10 @@
|
||||
type foobar =
|
||||
| Foo(int)
|
||||
| Bar(bool)
|
||||
| Kee(nat);
|
||||
|
||||
let foo: foobar = Foo(42);
|
||||
|
||||
let bar: foobar = Bar(true);
|
||||
|
||||
let kee: foobar = Kee(23n);
|
21
src/test/contracts/website2.religo
Normal file
21
src/test/contracts/website2.religo
Normal file
@ -0,0 +1,21 @@
|
||||
type storage = int;
|
||||
|
||||
/* variant defining pseudo multi-entrypoint actions */
|
||||
|
||||
type action =
|
||||
| Increment(int)
|
||||
| Decrement(int);
|
||||
|
||||
let add = (a: int, b: int): int => a + b;
|
||||
let sub = (a: int, b: int): int => a - b;
|
||||
|
||||
/* real entrypoint that re-routes the flow based on the action provided */
|
||||
|
||||
let main = (p: action, storage) => {
|
||||
let storage =
|
||||
switch (p) {
|
||||
| Increment(n) => add(storage, n)
|
||||
| Decrement(n) => sub(storage, n)
|
||||
};
|
||||
([]: list(operation), storage);
|
||||
};
|
@ -3,6 +3,10 @@ open Test_helpers
|
||||
|
||||
open Ast_simplified.Combinators
|
||||
|
||||
let retype_file f =
|
||||
let%bind (typed , state , _env) = Ligo.Compile.Wrapper.source_to_typed (Syntax_name "reasonligo") f in
|
||||
let () = Typer.Solver.discard_state state in
|
||||
ok typed
|
||||
let mtype_file f =
|
||||
let%bind (typed , state , _env) = Ligo.Compile.Wrapper.source_to_typed (Syntax_name "cameligo") f in
|
||||
let () = Typer.Solver.discard_state state in
|
||||
@ -98,6 +102,20 @@ let variant_mligo () : unit result =
|
||||
expect_eq_evaluate program "kee" expected in
|
||||
ok ()
|
||||
|
||||
let variant_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/variant.religo" in
|
||||
let%bind () =
|
||||
let expected = e_constructor "Foo" (e_int 42) in
|
||||
expect_eq_evaluate program "foo" expected in
|
||||
let%bind () =
|
||||
let expected = e_constructor "Bar" (e_bool true) in
|
||||
expect_eq_evaluate program "bar" expected in
|
||||
let%bind () =
|
||||
let expected = e_constructor "Kee" (e_nat 23) in
|
||||
expect_eq_evaluate program "kee" expected in
|
||||
ok ()
|
||||
|
||||
|
||||
let variant_matching () : unit result =
|
||||
let%bind program = type_file "./contracts/variant-matching.ligo" in
|
||||
let%bind () =
|
||||
@ -143,6 +161,16 @@ let closure_mligo () : unit result =
|
||||
in
|
||||
ok ()
|
||||
|
||||
let closure_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/closure.religo" in
|
||||
let%bind _ =
|
||||
let input = e_int 0 in
|
||||
let expected = e_int 25 in
|
||||
expect_eq program "test" input expected
|
||||
in
|
||||
ok ()
|
||||
|
||||
|
||||
let shadow () : unit result =
|
||||
let%bind program = type_file "./contracts/shadow.ligo" in
|
||||
let make_expect = fun _ -> 0 in
|
||||
@ -168,6 +196,15 @@ let higher_order_mligo () : unit result =
|
||||
let%bind _ = expect_eq_n_int program "foobar5" make_expect in
|
||||
ok ()
|
||||
|
||||
let higher_order_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/high-order.religo" in
|
||||
let make_expect = fun n -> n in
|
||||
let%bind _ = expect_eq_n_int program "foobar" make_expect in
|
||||
let%bind _ = expect_eq_n_int program "foobar2" make_expect in
|
||||
let%bind _ = expect_eq_n_int program "foobar3" make_expect in
|
||||
let%bind _ = expect_eq_n_int program "foobar4" make_expect in
|
||||
let%bind _ = expect_eq_n_int program "foobar5" make_expect in
|
||||
ok ()
|
||||
|
||||
let shared_function () : unit result =
|
||||
let%bind program = type_file "./contracts/function-shared.ligo" in
|
||||
@ -204,6 +241,14 @@ let shared_function_mligo () : unit result =
|
||||
in
|
||||
ok ()
|
||||
|
||||
let shared_function_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/function-shared.religo" in
|
||||
let%bind () =
|
||||
let make_expect = fun n -> (2 * n + 70) in
|
||||
expect_eq_n_int program "foobar" make_expect
|
||||
in
|
||||
ok ()
|
||||
|
||||
let bool_expression () : unit result =
|
||||
let%bind program = type_file "./contracts/boolean_operators.ligo" in
|
||||
let%bind _ =
|
||||
@ -230,6 +275,19 @@ let bool_expression_mligo () : unit result =
|
||||
] in
|
||||
ok ()
|
||||
|
||||
let bool_expression_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/boolean_operators.religo" in
|
||||
let%bind _ =
|
||||
let aux (name, f) = expect_eq_b_bool program name f in
|
||||
bind_map_list aux [
|
||||
("or_true", fun b -> b || true) ;
|
||||
("or_false", fun b -> b || false) ;
|
||||
("and_true", fun b -> b && true) ;
|
||||
("and_false", fun b -> b && false) ;
|
||||
("not_bool", fun b -> not b) ;
|
||||
] in
|
||||
ok ()
|
||||
|
||||
let arithmetic () : unit result =
|
||||
let%bind program = type_file "./contracts/arithmetic.ligo" in
|
||||
let%bind _ =
|
||||
@ -260,6 +318,21 @@ let arithmetic_mligo () : unit result =
|
||||
let%bind () = expect_eq_n_pos program "div_op" e_int (fun n -> e_int (n / 2)) in
|
||||
ok ()
|
||||
|
||||
let arithmetic_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/arithmetic.religo" in
|
||||
let%bind _ =
|
||||
let aux (name, f) = expect_eq_n_int program name f in
|
||||
bind_map_list aux [
|
||||
("plus_op", fun n -> (n + 42)) ;
|
||||
("minus_op", fun n -> (n - 42)) ;
|
||||
("times_op", fun n -> (n * 42)) ;
|
||||
("neg_op", fun n -> (-n)) ;
|
||||
("neg_op_2", fun n -> -(n + 10)) ;
|
||||
] in
|
||||
let%bind () = expect_eq_n_pos program "mod_op" e_int (fun n -> e_nat (n mod 42)) in
|
||||
let%bind () = expect_eq_n_pos program "div_op" e_int (fun n -> e_int (n / 2)) in
|
||||
ok ()
|
||||
|
||||
let bitwise_arithmetic () : unit result =
|
||||
let%bind program = type_file "./contracts/bitwise_arithmetic.ligo" in
|
||||
let%bind () = expect_eq program "or_op" (e_nat 7) (e_nat 7) in
|
||||
@ -292,6 +365,22 @@ let bitwise_arithmetic_mligo () : unit result =
|
||||
let%bind () = expect_eq program "xor_op" (e_nat 7) (e_nat 0) in
|
||||
ok ()
|
||||
|
||||
let bitwise_arithmetic_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/bitwise_arithmetic.religo" in
|
||||
let%bind () = expect_eq program "or_op" (e_nat 7) (e_nat 7) in
|
||||
let%bind () = expect_eq program "or_op" (e_nat 3) (e_nat 7) in
|
||||
let%bind () = expect_eq program "or_op" (e_nat 2) (e_nat 6) in
|
||||
let%bind () = expect_eq program "or_op" (e_nat 14) (e_nat 14) in
|
||||
let%bind () = expect_eq program "or_op" (e_nat 10) (e_nat 14) in
|
||||
let%bind () = expect_eq program "and_op" (e_nat 7) (e_nat 7) in
|
||||
let%bind () = expect_eq program "and_op" (e_nat 3) (e_nat 3) in
|
||||
let%bind () = expect_eq program "and_op" (e_nat 2) (e_nat 2) in
|
||||
let%bind () = expect_eq program "and_op" (e_nat 14) (e_nat 6) in
|
||||
let%bind () = expect_eq program "and_op" (e_nat 10) (e_nat 2) in
|
||||
let%bind () = expect_eq program "xor_op" (e_nat 0) (e_nat 7) in
|
||||
let%bind () = expect_eq program "xor_op" (e_nat 7) (e_nat 0) in
|
||||
ok ()
|
||||
|
||||
let string_arithmetic () : unit result =
|
||||
let%bind program = type_file "./contracts/string_arithmetic.ligo" in
|
||||
let%bind () = expect_eq program "concat_op" (e_string "foo") (e_string "foototo") in
|
||||
@ -309,6 +398,15 @@ let string_arithmetic_mligo () : unit result =
|
||||
let%bind () = expect_eq program "concat_syntax" (e_string "string_") (e_string "string_test_literal")
|
||||
in ok ()
|
||||
|
||||
let string_arithmetic_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/string_arithmetic.religo" in
|
||||
let%bind () = expect_eq program "size_op" (e_string "tata") (e_nat 4) in
|
||||
let%bind () = expect_eq program "slice_op" (e_string "tata") (e_string "at") in
|
||||
let%bind () = expect_eq program "slice_op" (e_string "foo") (e_string "oo") in
|
||||
let%bind () = expect_eq program "concat_syntax" (e_string "string_") (e_string "string_test_literal")
|
||||
in ok ()
|
||||
|
||||
|
||||
let bytes_arithmetic () : unit result =
|
||||
let%bind program = type_file "./contracts/bytes_arithmetic.ligo" in
|
||||
let%bind foo = e_bytes "0f00" in
|
||||
@ -349,6 +447,26 @@ let bytes_arithmetic_mligo () : unit result =
|
||||
let%bind () = Assert.assert_fail @@ Ast_simplified.Misc.assert_value_eq (b3 , b1) in
|
||||
ok ()
|
||||
|
||||
let bytes_arithmetic_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/bytes_arithmetic.religo" in
|
||||
let%bind foo = e_bytes "0f00" in
|
||||
let%bind foototo = e_bytes "0f007070" in
|
||||
let%bind toto = e_bytes "7070" in
|
||||
let%bind empty = e_bytes "" in
|
||||
let%bind tata = e_bytes "7a7a7a7a" in
|
||||
let%bind at = e_bytes "7a7a" in
|
||||
let%bind ba = e_bytes "ba" in
|
||||
let%bind () = expect_eq program "concat_op" foo foototo in
|
||||
let%bind () = expect_eq program "concat_op" empty toto in
|
||||
let%bind () = expect_eq program "slice_op" tata at in
|
||||
let%bind () = expect_fail program "slice_op" foo in
|
||||
let%bind () = expect_fail program "slice_op" ba in
|
||||
let%bind b1 = Test_helpers.run_typed_program_with_simplified_input program"hasherman" foo in
|
||||
let%bind () = expect_eq program "hasherman" foo b1 in
|
||||
let%bind b3 = Test_helpers.run_typed_program_with_simplified_input program "hasherman" foototo in
|
||||
let%bind () = Assert.assert_fail @@ Ast_simplified.Misc.assert_value_eq (b3 , b1) in
|
||||
ok ()
|
||||
|
||||
let set_arithmetic () : unit result =
|
||||
let%bind program = type_file "./contracts/set_arithmetic.ligo" in
|
||||
let%bind program_1 = type_file "./contracts/set_arithmetic-1.ligo" in
|
||||
@ -442,6 +560,36 @@ let set_arithmetic_mligo () : unit result =
|
||||
in
|
||||
ok ()
|
||||
|
||||
let set_arithmetic_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/set_arithmetic.religo" in
|
||||
let%bind program_1 = type_file "./contracts/set_arithmetic-1.ligo" in
|
||||
let%bind () =
|
||||
expect_eq program "size_op"
|
||||
(e_set [e_string "foo"; e_string "bar"; e_string "foobar"])
|
||||
(e_nat 3) in
|
||||
let%bind () =
|
||||
expect_eq program "add_op"
|
||||
(e_set [e_string "foo" ; e_string "bar"])
|
||||
(e_set [e_string "foo" ; e_string "bar" ; e_string "foobar"]) in
|
||||
let%bind () =
|
||||
expect_eq program "add_op"
|
||||
(e_set [e_string "foo" ; e_string "bar" ; e_string "foobar"])
|
||||
(e_set [e_string "foo" ; e_string "bar" ; e_string "foobar"]) in
|
||||
let%bind () =
|
||||
expect_eq program "remove_op"
|
||||
(e_set [e_string "foo" ; e_string "bar"])
|
||||
(e_set [e_string "foo" ; e_string "bar"]) in
|
||||
let%bind () =
|
||||
expect_eq program "remove_op"
|
||||
(e_set [e_string "foo" ; e_string "bar" ; e_string "foobar"])
|
||||
(e_set [e_string "foo" ; e_string "bar"]) in
|
||||
let%bind () =
|
||||
expect_eq program_1 "fold_op"
|
||||
(e_set [ e_int 4 ; e_int 10 ])
|
||||
(e_int 29)
|
||||
in
|
||||
ok ()
|
||||
|
||||
let unit_expression () : unit result =
|
||||
let%bind program = type_file "./contracts/unit.ligo" in
|
||||
expect_eq_evaluate program "u" (e_unit ())
|
||||
@ -486,6 +634,18 @@ let multiple_parameters_mligo () : unit result =
|
||||
] in
|
||||
ok ()
|
||||
|
||||
let multiple_parameters_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/multiple-parameters.religo" in
|
||||
let aux ((name : string) , make_input , make_output) =
|
||||
let make_output' = fun n -> e_int @@ make_output n in
|
||||
expect_eq_n program name make_input make_output'
|
||||
in
|
||||
let%bind _ = bind_list @@ List.map aux [
|
||||
(* Didn't include the other tests because they're probably not necessary *)
|
||||
("abcde", tuple_ez_int ["a";"b";"c";"d";"e"], fun n -> 2 * n + 3) ;
|
||||
] in
|
||||
ok ()
|
||||
|
||||
let record () : unit result =
|
||||
let%bind program = type_file "./contracts/record.ligo" in
|
||||
let%bind () =
|
||||
@ -581,6 +741,31 @@ let tuple_mligo () : unit result =
|
||||
in
|
||||
ok ()
|
||||
|
||||
|
||||
let tuple_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/tuple.religo" in
|
||||
let ez n =
|
||||
e_tuple (List.map e_int n) in
|
||||
let%bind () =
|
||||
let expected = ez [0 ; 0] in
|
||||
expect_eq_evaluate program "fb" expected
|
||||
in
|
||||
let%bind () =
|
||||
let make_input = fun n -> ez [n ; n] in
|
||||
let make_expected = fun n -> e_int (2 * n) in
|
||||
expect_eq_n program "projection" make_input make_expected
|
||||
in
|
||||
let%bind () =
|
||||
let make_input = fun n -> ez [n ; 2 * n ; n] in
|
||||
let make_expected = fun n -> e_int (2 * n) in
|
||||
expect_eq_n program "projection_abc" make_input make_expected
|
||||
in
|
||||
let%bind () =
|
||||
let expected = ez [23 ; 23 ; 23 ; 23 ; 23] in
|
||||
expect_eq_evaluate program "br" expected
|
||||
in
|
||||
ok ()
|
||||
|
||||
let option () : unit result =
|
||||
let%bind program = type_file "./contracts/option.ligo" in
|
||||
let%bind () =
|
||||
@ -609,6 +794,19 @@ let moption () : unit result =
|
||||
in
|
||||
ok ()
|
||||
|
||||
let reoption () : unit result =
|
||||
let%bind program = retype_file "./contracts/option.religo" in
|
||||
let%bind () =
|
||||
let expected = e_some (e_int 42) in
|
||||
expect_eq_evaluate program "s" expected
|
||||
in
|
||||
let%bind () =
|
||||
let expected = e_typed_none t_int in
|
||||
expect_eq_evaluate program "n" expected
|
||||
in
|
||||
ok ()
|
||||
|
||||
|
||||
let map_ type_f path : unit result =
|
||||
let%bind program = type_f path in
|
||||
let ez lst =
|
||||
@ -738,8 +936,10 @@ let big_map_ type_f path : unit result =
|
||||
|
||||
let map () : unit result = map_ type_file "./contracts/map.ligo"
|
||||
let mmap () : unit result = map_ mtype_file "./contracts/map.mligo"
|
||||
let remap () : unit result = map_ retype_file "./contracts/map.religo"
|
||||
let big_map () : unit result = big_map_ type_file "./contracts/big_map.ligo"
|
||||
let mbig_map () : unit result = big_map_ mtype_file "./contracts/big_map.mligo"
|
||||
let rebig_map () : unit result = big_map_ retype_file "./contracts/big_map.religo"
|
||||
|
||||
|
||||
let list () : unit result =
|
||||
@ -813,6 +1013,21 @@ let condition_mligo () : unit result =
|
||||
] in
|
||||
ok ()
|
||||
|
||||
let condition_religo () : unit result =
|
||||
let%bind _ =
|
||||
let aux file =
|
||||
let%bind program = retype_file file in
|
||||
let make_input = e_int in
|
||||
let make_expected = fun n -> e_int (if n = 2 then 42 else 0) in
|
||||
expect_eq_n program "main" make_input make_expected in
|
||||
bind_map_list aux [
|
||||
"./contracts/condition.religo";
|
||||
"./contracts/condition-shadowing.religo";
|
||||
"./contracts/condition-annot.religo";
|
||||
] in
|
||||
ok ()
|
||||
|
||||
|
||||
let condition_simple () : unit result =
|
||||
let%bind program = type_file "./contracts/condition-simple.ligo" in
|
||||
let make_input = e_int in
|
||||
@ -910,6 +1125,25 @@ let loop_mligo () : unit result =
|
||||
expect_eq program "counter_nest" input expected
|
||||
in ok ()
|
||||
|
||||
let loop_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/loop.religo" in
|
||||
let%bind () =
|
||||
let input = e_int 0 in
|
||||
let expected = e_int 100 in
|
||||
expect_eq program "counter_simple" input expected
|
||||
in
|
||||
let%bind () =
|
||||
let input = e_int 100 in
|
||||
let expected = e_int 5050 in
|
||||
expect_eq program "counter" input expected
|
||||
in
|
||||
let%bind () =
|
||||
let input = e_int 100 in
|
||||
let expected = e_int 10000 in
|
||||
expect_eq program "counter_nest" input expected
|
||||
in ok ()
|
||||
|
||||
|
||||
let matching () : unit result =
|
||||
let%bind program = type_file "./contracts/match.ligo" in
|
||||
let%bind () =
|
||||
@ -1010,6 +1244,17 @@ let super_counter_contract_mligo () : unit result =
|
||||
e_pair (e_typed_list [] t_operation) (e_int (op 42 n)) in
|
||||
expect_eq_n program "main" make_input make_expected
|
||||
|
||||
let super_counter_contract_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/super-counter.religo" in
|
||||
let make_input = fun n ->
|
||||
let action = if n mod 2 = 0 then "Increment" else "Decrement" in
|
||||
e_pair (e_constructor action (e_int n)) (e_int 42) in
|
||||
let make_expected = fun n ->
|
||||
let op = if n mod 2 = 0 then (+) else (-) in
|
||||
e_pair (e_typed_list [] t_operation) (e_int (op 42 n)) in
|
||||
expect_eq_n program "main" make_input make_expected
|
||||
|
||||
|
||||
let dispatch_counter_contract () : unit result =
|
||||
let%bind program = type_file "./contracts/dispatch-counter.ligo" in
|
||||
let make_input = fun n ->
|
||||
@ -1040,6 +1285,11 @@ let failwith_mligo () : unit result =
|
||||
let make_input = e_pair (e_unit ()) (e_unit ()) in
|
||||
expect_fail program "main" make_input
|
||||
|
||||
let failwith_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/failwith.religo" in
|
||||
let make_input = e_pair (e_unit ()) (e_unit ()) in
|
||||
expect_fail program "main" make_input
|
||||
|
||||
let assert_mligo () : unit result =
|
||||
let%bind program = mtype_file "./contracts/assert.mligo" in
|
||||
let make_input b = e_pair (e_bool b) (e_unit ()) in
|
||||
@ -1048,6 +1298,14 @@ let assert_mligo () : unit result =
|
||||
let%bind _ = expect_eq program "main" (make_input true) make_expected in
|
||||
ok ()
|
||||
|
||||
let assert_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/assert.religo" in
|
||||
let make_input b = e_pair (e_bool b) (e_unit ()) in
|
||||
let make_expected = e_pair (e_typed_list [] t_operation) (e_unit ()) in
|
||||
let%bind _ = expect_fail program "main" (make_input false) in
|
||||
let%bind _ = expect_eq program "main" (make_input true) make_expected in
|
||||
ok ()
|
||||
|
||||
let guess_the_hash_mligo () : unit result =
|
||||
let%bind program = mtype_file "./contracts/new-syntax.mligo" in
|
||||
let make_input = fun n-> e_pair (e_int n) (e_int 42) in
|
||||
@ -1055,7 +1313,7 @@ let guess_the_hash_mligo () : unit result =
|
||||
expect_eq_n program "main" make_input make_expected
|
||||
|
||||
let guess_string_mligo () : unit result =
|
||||
let%bind program = mtype_file "./contracts/guess_string.mligo" in
|
||||
let%bind program = type_file "./contracts/guess_string.mligo" in
|
||||
let make_input = fun n -> e_pair (e_int n) (e_int 42) in
|
||||
let make_expected = fun n -> e_pair (e_typed_list [] t_operation) (e_int (42 + n))
|
||||
in expect_eq_n program "main" make_input make_expected
|
||||
@ -1064,12 +1322,23 @@ let basic_mligo () : unit result =
|
||||
let%bind typed = mtype_file "./contracts/basic.mligo" in
|
||||
expect_eq_evaluate typed "foo" (e_int (42+127))
|
||||
|
||||
let basic_religo () : unit result =
|
||||
let%bind typed = retype_file "./contracts/basic.religo" in
|
||||
expect_eq_evaluate typed "foo" (e_int (42+127))
|
||||
|
||||
let counter_mligo () : unit result =
|
||||
let%bind program = mtype_file "./contracts/counter.mligo" in
|
||||
let make_input n = e_pair (e_int n) (e_int 42) in
|
||||
let make_expected n = e_pair (e_typed_list [] t_operation) (e_int (42 + n)) in
|
||||
expect_eq_n program "main" make_input make_expected
|
||||
|
||||
let counter_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/counter.religo" in
|
||||
let make_input n = e_pair (e_int n) (e_int 42) in
|
||||
let make_expected n = e_pair (e_typed_list [] t_operation) (e_int (42 + n)) in
|
||||
expect_eq_n program "main" make_input make_expected
|
||||
|
||||
|
||||
let let_in_mligo () : unit result =
|
||||
let%bind program = mtype_file "./contracts/letin.mligo" in
|
||||
let make_input n = e_pair (e_int n) (e_pair (e_int 3) (e_int 5)) in
|
||||
@ -1077,6 +1346,14 @@ let let_in_mligo () : unit result =
|
||||
e_pair (e_typed_list [] t_operation) (e_pair (e_int (7+n)) (e_int (3+5)))
|
||||
in expect_eq_n program "main" make_input make_expected
|
||||
|
||||
let let_in_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/letin.religo" in
|
||||
let make_input n = e_pair (e_int n) (e_pair (e_int 3) (e_int 5)) in
|
||||
let make_expected n =
|
||||
e_pair (e_typed_list [] t_operation) (e_pair (e_int (7+n)) (e_int (3+5)))
|
||||
in expect_eq_n program "main" make_input make_expected
|
||||
|
||||
|
||||
let match_variant () : unit result =
|
||||
let%bind program = mtype_file "./contracts/match.mligo" in
|
||||
let%bind () =
|
||||
@ -1107,6 +1384,15 @@ let match_variant () : unit result =
|
||||
expect_eq_n program "match_option" make_input make_expected in
|
||||
ok ()
|
||||
|
||||
let match_variant_re () : unit result =
|
||||
let%bind program = retype_file "./contracts/match.religo" in
|
||||
let make_input n =
|
||||
e_pair (e_constructor "Sub" (e_int n)) (e_int 3) in
|
||||
let make_expected n =
|
||||
e_pair (e_typed_list [] t_operation) (e_int (3-n))
|
||||
in expect_eq_n program "main" make_input make_expected
|
||||
|
||||
|
||||
let match_matej () : unit result =
|
||||
let%bind program = mtype_file "./contracts/match_bis.mligo" in
|
||||
let make_input n =
|
||||
@ -1115,6 +1401,15 @@ let match_matej () : unit result =
|
||||
e_pair (e_typed_list [] t_operation) (e_int (3-n))
|
||||
in expect_eq_n program "main" make_input make_expected
|
||||
|
||||
let match_matej_re () : unit result =
|
||||
let%bind program = retype_file "./contracts/match_bis.religo" in
|
||||
let make_input n =
|
||||
e_pair (e_constructor "Decrement" (e_int n)) (e_int 3) in
|
||||
let make_expected n =
|
||||
e_pair (e_typed_list [] t_operation) (e_int (3-n))
|
||||
in expect_eq_n program "main" make_input make_expected
|
||||
|
||||
|
||||
let mligo_list () : unit result =
|
||||
let%bind program = mtype_file "./contracts/list.mligo" in
|
||||
let aux lst = e_list @@ List.map e_int lst in
|
||||
@ -1136,12 +1431,40 @@ let mligo_list () : unit result =
|
||||
let%bind () = expect_eq program "iter_op" (aux [2 ; 3 ; 4 ; 5]) (e_unit ()) in
|
||||
ok ()
|
||||
|
||||
let religo_list () : unit result =
|
||||
let%bind program = retype_file "./contracts/list.religo" in
|
||||
let aux lst = e_list @@ List.map e_int lst in
|
||||
let%bind () = expect_eq program "fold_op" (aux [ 1 ; 2 ; 3 ]) (e_int 16) in
|
||||
let%bind () =
|
||||
let make_input n =
|
||||
e_pair (e_list [e_int n; e_int (2*n)])
|
||||
(e_pair (e_int 3) (e_list [e_int 8])) in
|
||||
let make_expected n =
|
||||
e_pair (e_typed_list [] t_operation)
|
||||
(e_pair (e_int (n+3)) (e_list [e_int (2*n)]))
|
||||
in
|
||||
expect_eq_n program "main" make_input make_expected
|
||||
in
|
||||
let%bind () = expect_eq_evaluate program "x" (e_list []) in
|
||||
let%bind () = expect_eq_evaluate program "y" (e_list @@ List.map e_int [3 ; 4 ; 5]) in
|
||||
let%bind () = expect_eq_evaluate program "z" (e_list @@ List.map e_int [2 ; 3 ; 4 ; 5]) in
|
||||
let%bind () = expect_eq program "map_op" (aux [2 ; 3 ; 4 ; 5]) (aux [3 ; 4 ; 5 ; 6]) in
|
||||
let%bind () = expect_eq program "iter_op" (aux [2 ; 3 ; 4 ; 5]) (e_unit ()) in
|
||||
ok ()
|
||||
|
||||
let lambda_mligo () : unit result =
|
||||
let%bind program = mtype_file "./contracts/lambda.mligo" in
|
||||
let make_input = e_pair (e_unit ()) (e_unit ()) in
|
||||
let make_expected = (e_unit ()) in
|
||||
expect_eq program "main" make_input make_expected
|
||||
|
||||
let lambda_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/lambda.religo" in
|
||||
let make_input = e_pair (e_unit ()) (e_unit ()) in
|
||||
let make_expected = (e_unit ()) in
|
||||
expect_eq program "main" make_input make_expected
|
||||
|
||||
|
||||
let lambda_ligo () : unit result =
|
||||
let%bind program = type_file "./contracts/lambda.ligo" in
|
||||
let make_input = e_pair (e_unit ()) (e_unit ()) in
|
||||
@ -1154,6 +1477,13 @@ let lambda2_mligo () : unit result =
|
||||
let make_expected = (e_unit ()) in
|
||||
expect_eq program "main" make_input make_expected
|
||||
|
||||
let lambda2_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/lambda2.religo" in
|
||||
let make_input = e_pair (e_unit ()) (e_unit ()) in
|
||||
let make_expected = (e_unit ()) in
|
||||
expect_eq program "main" make_input make_expected
|
||||
|
||||
|
||||
let fibo_mligo () : unit result =
|
||||
let%bind program = mtype_file "./contracts/fibo.mligo" in
|
||||
let make_input = e_pair (e_unit ()) (e_unit ()) in
|
||||
@ -1209,6 +1539,17 @@ let website2_mligo () : unit result =
|
||||
e_pair (e_typed_list [] t_operation) (e_int (op 42 n)) in
|
||||
expect_eq_n program "main" make_input make_expected
|
||||
|
||||
let website2_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/website2.religo" in
|
||||
let make_input = fun n ->
|
||||
let action = if n mod 2 = 0 then "Increment" else "Decrement" in
|
||||
e_pair (e_constructor action (e_int n)) (e_int 42) in
|
||||
let make_expected = fun n ->
|
||||
let op = if n mod 2 = 0 then (+) else (-) in
|
||||
e_pair (e_typed_list [] t_operation) (e_int (op 42 n)) in
|
||||
expect_eq_n program "main" make_input make_expected
|
||||
|
||||
|
||||
let mligo_let_multiple () : unit result =
|
||||
let%bind program = mtype_file "./contracts/let_multiple.mligo" in
|
||||
let%bind () =
|
||||
@ -1243,6 +1584,25 @@ let mligo_let_multiple () : unit result =
|
||||
in
|
||||
ok ()
|
||||
|
||||
let religo_let_multiple () : unit result =
|
||||
let%bind program = retype_file "./contracts/let_multiple.religo" in
|
||||
let%bind () =
|
||||
let input = e_unit () in
|
||||
let expected = e_int 3 in
|
||||
expect_eq program "main" input expected
|
||||
in
|
||||
let%bind () =
|
||||
let input = e_unit () in
|
||||
let expected = e_int 6 in
|
||||
expect_eq program "main_paren" input expected
|
||||
in
|
||||
let%bind () =
|
||||
let input = e_unit () in
|
||||
let expected = e_int 65 in
|
||||
expect_eq program "non_tuple_rhs" input expected
|
||||
in
|
||||
ok ()
|
||||
|
||||
let balance_constant () : unit result =
|
||||
let%bind program = type_file "./contracts/balance_constant.ligo" in
|
||||
let input = e_tuple [e_unit () ; e_mutez 0] in
|
||||
@ -1256,6 +1616,13 @@ let balance_constant_mligo () : unit result =
|
||||
let expected = e_tuple [e_list []; e_mutez 4000000000000] in
|
||||
expect_eq program "main" input expected
|
||||
|
||||
let balance_constant_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/balance_constant.religo" in
|
||||
let input = e_tuple [e_unit () ; e_mutez 0] in
|
||||
let expected = e_tuple [e_list []; e_mutez 4000000000000] in
|
||||
expect_eq program "main" input expected
|
||||
|
||||
|
||||
let address () : unit result =
|
||||
let%bind _ = type_file "./contracts/address.ligo" in
|
||||
ok ()
|
||||
@ -1264,6 +1631,11 @@ let address_mligo () : unit result =
|
||||
let%bind _ = mtype_file "./contracts/address.mligo" in
|
||||
ok ()
|
||||
|
||||
let address_religo () : unit result =
|
||||
let%bind _ = retype_file "./contracts/address.religo" in
|
||||
ok ()
|
||||
|
||||
|
||||
let self_address () : unit result =
|
||||
let%bind _ = type_file "./contracts/self_address.ligo" in
|
||||
ok ()
|
||||
@ -1272,6 +1644,10 @@ let self_address_mligo () : unit result =
|
||||
let%bind _ = mtype_file "./contracts/self_address.mligo" in
|
||||
ok ()
|
||||
|
||||
let self_address_religo () : unit result =
|
||||
let%bind _ = retype_file "./contracts/self_address.religo" in
|
||||
ok ()
|
||||
|
||||
let implicit_account () : unit result =
|
||||
let%bind _ = type_file "./contracts/implicit_account.ligo" in
|
||||
ok ()
|
||||
@ -1280,6 +1656,15 @@ let implicit_account_mligo () : unit result =
|
||||
let%bind _ = mtype_file "./contracts/implicit_account.mligo" in
|
||||
ok ()
|
||||
|
||||
|
||||
let implicit_account_religo () : unit result =
|
||||
let%bind _ = retype_file "./contracts/implicit_account.religo" in
|
||||
ok ()
|
||||
|
||||
let tuples_sequences_functions_religo () : unit result =
|
||||
let%bind _ = retype_file "./contracts/tuples_sequences_functions.religo" in
|
||||
ok ()
|
||||
|
||||
let is_nat () : unit result =
|
||||
let%bind program = type_file "./contracts/isnat.ligo" in
|
||||
let%bind () =
|
||||
@ -1306,6 +1691,20 @@ let is_nat_mligo () : unit result =
|
||||
expect_eq program "main" input expected
|
||||
in ok ()
|
||||
|
||||
let is_nat_religo () : unit result =
|
||||
let%bind program = retype_file "./contracts/isnat.religo" in
|
||||
let%bind () =
|
||||
let input = e_int 10 in
|
||||
let expected = e_some (e_nat 10) in
|
||||
expect_eq program "main" input expected
|
||||
in
|
||||
let%bind () =
|
||||
let input = e_int (-10) in
|
||||
let expected = e_none () in
|
||||
expect_eq program "main" input expected
|
||||
in ok ()
|
||||
|
||||
|
||||
let simple_access_ligo () : unit result =
|
||||
let%bind program = type_file "./contracts/simple_access.ligo" in
|
||||
let make_input = e_tuple [e_int 0; e_int 1] in
|
||||
@ -1370,46 +1769,63 @@ let main = test_suite "Integration (End to End)" [
|
||||
test "various applications" application ;
|
||||
test "closure" closure ;
|
||||
test "closure (mligo)" closure_mligo ;
|
||||
test "closure (religo)" closure_religo ;
|
||||
test "shared function" shared_function ;
|
||||
test "shared function (mligo)" shared_function_mligo ;
|
||||
test "shared function (religo)" shared_function_religo ;
|
||||
test "higher order" higher_order ;
|
||||
test "higher order (mligo)" higher_order_mligo ;
|
||||
test "higher order (religo)" higher_order_religo ;
|
||||
test "variant" variant ;
|
||||
test "variant (mligo)" variant_mligo ;
|
||||
test "variant (religo)" variant_religo ;
|
||||
test "variant matching" variant_matching ;
|
||||
test "tuple" tuple ;
|
||||
test "tuple (mligo)" tuple_mligo ;
|
||||
test "tuple (religo)" tuple_religo ;
|
||||
test "record" record ;
|
||||
test "condition simple" condition_simple ;
|
||||
test "condition (ligo)" condition ;
|
||||
test "condition (mligo)" condition_mligo ;
|
||||
test "condition (religo)" condition_religo ;
|
||||
test "shadow" shadow ;
|
||||
test "annotation" annotation ;
|
||||
test "multiple parameters" multiple_parameters ;
|
||||
test "multiple parameters (mligo)" multiple_parameters_mligo ;
|
||||
test "multiple parameters (religo)" multiple_parameters_religo ;
|
||||
test "bool" bool_expression ;
|
||||
test "bool (mligo)" bool_expression_mligo ;
|
||||
test "bool (religo)" bool_expression_religo ;
|
||||
test "arithmetic" arithmetic ;
|
||||
test "arithmetic (mligo)" arithmetic_mligo ;
|
||||
test "arithmetic (religo)" arithmetic_religo ;
|
||||
test "bitwise_arithmetic" bitwise_arithmetic ;
|
||||
test "bitwise_arithmetic (mligo)" bitwise_arithmetic_mligo;
|
||||
test "bitwise_arithmetic (religo)" bitwise_arithmetic_religo;
|
||||
test "string_arithmetic" string_arithmetic ;
|
||||
test "string_arithmetic (mligo)" string_arithmetic_mligo ;
|
||||
test "string_arithmetic (religo)" string_arithmetic_religo ;
|
||||
test "bytes_arithmetic" bytes_arithmetic ;
|
||||
test "bytes_arithmetic (mligo)" bytes_arithmetic_mligo ;
|
||||
test "bytes_arithmetic (religo)" bytes_arithmetic_religo ;
|
||||
test "set_arithmetic" set_arithmetic ;
|
||||
test "set_arithmetic (mligo)" set_arithmetic_mligo ;
|
||||
test "set_arithmetic (religo)" set_arithmetic_religo ;
|
||||
test "unit" unit_expression ;
|
||||
test "string" string_expression ;
|
||||
test "option" option ;
|
||||
test "option (mligo)" moption ;
|
||||
test "option (religo)" reoption ;
|
||||
test "map" map ;
|
||||
test "map (mligo)" mmap ;
|
||||
test "map (religo)" remap ;
|
||||
test "big_map" big_map ;
|
||||
test "big_map (mligo)" mbig_map ;
|
||||
test "big_map (religo)" rebig_map ;
|
||||
test "list" list ;
|
||||
test "loop" loop ;
|
||||
test "loop (mligo)" loop_mligo ;
|
||||
test "loop (religo)" loop_religo ;
|
||||
test "matching" matching ;
|
||||
test "declarations" declarations ;
|
||||
test "quote declaration" quote_declaration ;
|
||||
@ -1420,21 +1836,30 @@ let main = test_suite "Integration (End to End)" [
|
||||
test "super counter contract" super_counter_contract_mligo ;
|
||||
test "dispatch counter contract" dispatch_counter_contract ;
|
||||
test "basic (mligo)" basic_mligo ;
|
||||
test "basic (religo)" basic_religo ;
|
||||
test "counter contract (mligo)" counter_mligo ;
|
||||
test "counter contract (religo)" counter_religo ;
|
||||
test "let-in (mligo)" let_in_mligo ;
|
||||
test "let-in (religo)" let_in_religo ;
|
||||
test "match variant (mligo)" match_variant ;
|
||||
test "match variant (religo)" match_variant_re ;
|
||||
test "match variant 2 (mligo)" match_matej ;
|
||||
test "match variant 2 (religo)" match_matej_re ;
|
||||
(* test "list matching (mligo)" mligo_list ; *)
|
||||
test "list matching (mligo)" mligo_list ;
|
||||
test "list matching (religo)" religo_list ;
|
||||
(* test "guess the hash mligo" guess_the_hash_mligo ; WIP? *)
|
||||
test "failwith ligo" failwith_ligo ;
|
||||
test "failwith mligo" failwith_mligo ;
|
||||
test "assert mligo" assert_mligo ;
|
||||
(* test "guess string mligo" guess_string_mligo ; WIP? *)
|
||||
test "lambda mligo" lambda_mligo ;
|
||||
test "lambda religo" lambda_religo ;
|
||||
test "lambda ligo" lambda_ligo ;
|
||||
test "tez (ligo)" tez_ligo ;
|
||||
test "tez (mligo)" tez_mligo ;
|
||||
test "lambda2 mligo" lambda2_mligo ;
|
||||
test "lambda2 religo" lambda2_religo ;
|
||||
(* test "fibo (mligo)" fibo_mligo ; *)
|
||||
(* test "fibo2 (mligo)" fibo2_mligo ; *)
|
||||
(* test "fibo3 (mligo)" fibo3_mligo ; *)
|
||||
@ -1442,17 +1867,25 @@ let main = test_suite "Integration (End to End)" [
|
||||
test "website1 ligo" website1_ligo ;
|
||||
test "website2 ligo" website2_ligo ;
|
||||
test "website2 (mligo)" website2_mligo ;
|
||||
test "website2 (religo)" website2_religo ;
|
||||
test "let multiple (mligo)" mligo_let_multiple ;
|
||||
test "let multiple (religo)" religo_let_multiple ;
|
||||
test "balance constant" balance_constant ;
|
||||
test "balance constant (mligo)" balance_constant_mligo ;
|
||||
test "balance constant (religo)" balance_constant_religo ;
|
||||
test "address" address ;
|
||||
test "address_mligo" address_mligo ;
|
||||
test "address (mligo)" address_mligo ;
|
||||
test "address (religo)" address_religo ;
|
||||
test "self address" self_address ;
|
||||
test "self address (mligo)" self_address_mligo ;
|
||||
test "self address (religo)" self_address_religo ;
|
||||
test "implicit account" implicit_account ;
|
||||
test "implicit account (mligo)" implicit_account_mligo ;
|
||||
test "implicit account (religo)" implicit_account_religo ;
|
||||
test "is_nat" is_nat ;
|
||||
test "is_not (mligo)" is_nat_mligo ;
|
||||
test "is_nat (mligo)" is_nat_mligo ;
|
||||
test "is_nat (religo)" is_nat_religo ;
|
||||
test "tuples_sequences_functions (religo)" tuples_sequences_functions_religo ;
|
||||
test "simple_access (ligo)" simple_access_ligo;
|
||||
test "deep_access (ligo)" deep_access_ligo;
|
||||
test "entrypoints (ligo)" entrypoints_ligo ;
|
||||
|
8
vendors/ligo-utils/simple-utils/pos.ml
vendored
8
vendors/ligo-utils/simple-utils/pos.ml
vendored
@ -126,13 +126,7 @@ let from_byte byte =
|
||||
|
||||
let ghost = make ~byte:Lexing.dummy_pos ~point_num:(-1) ~point_bol:(-1)
|
||||
|
||||
let min =
|
||||
let byte = Lexing.{
|
||||
pos_fname = "";
|
||||
pos_lnum = 1;
|
||||
pos_bol = 0;
|
||||
pos_cnum = 0}
|
||||
in make ~byte ~point_num:0 ~point_bol:0
|
||||
let min = make ~byte:Lexing.dummy_pos ~point_num:0 ~point_bol:0
|
||||
|
||||
(* Comparisons *)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user