diff --git a/gitlab-pages/docs/api/cheat-sheet.md b/gitlab-pages/docs/api/cheat-sheet.md index 412ba5bd5..2d7303138 100644 --- a/gitlab-pages/docs/api/cheat-sheet.md +++ b/gitlab-pages/docs/api/cheat-sheet.md @@ -7,113 +7,1071 @@ import Syntax from '@theme/Syntax';
const hasDriversLicense: bool = False;
const adult: bool = True;
|
-|Boolean Logic|(not True) == False == (False and True) == (False or False)
|
-|Mutez (micro tez)| `42mutez`, `7mutez` |
-|Address | `"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"`, `"KT1JepfBfMSqkQyf9B1ndvURghGsSB8YCLMD"`|
-|Addition |`3 + 4`, `3n + 4n`|
-|Multiplication & Division| `3 * 4`, `3n * 4n`, `10 / 5`, `10n / 5n`|
-|Modulo| `10 mod 3`|
-|Tuples| type name is (string * string);
const winner: name = ("John", "Doe");
const firstName: string = winner.0;
const lastName: string = winner.1;
|
-|Types|`type age is int`, `type name is string` |
-|Includes|```#include "library.ligo"```|
-|Functions (short form)|function add (const a : int ; const b : int) : int is
block { skip } with a + b
|
-|Functions (long form)|function add (const a : int ; const b : int) : int is
block {
const result: int = a + b;
} with result
|
-| If Statement | if age < 16
then failwith ("Too young to drive.");
else const new_id: int = prev_id + 1;
|
-|Options|type middleName is option(string);
const middleName : middleName = Some("Foo");
const middleName : middleName = None;
|
-|Assignment| ```const age: int = 5;```|
-|Assignment on an existing variable type action is
| Increment of int
| Decrement of int
|
-|Variant *(pattern)* matching|const a: action = Increment(5);
case a of
| Increment(n) -> n + 1
| Decrement(n) -> n - 1
end
|
-|Records|type person is record
age: int ;
name: string ;
end
const john : person = record
age = 18;
name = "John Doe";
end
const name: string = john.name;
|
-|Maps|type prices is map(nat, tez);
const prices : prices = map
10n -> 60mutez;
50n -> 30mutez;
100n -> 10mutez;
end
const price: option(tez) = prices[50n];
prices[200n] := 5mutez;
|
-|Contracts & Accounts|const destinationAddress : address = "tz1...";
const contract : contract(unit) = get_contract(destinationAddress);
|
-|Transactions|const payment : operation = transaction(unit, amount, receiver);
|
-|Exception/Failure|`failwith ("Your descriptive error message for the user goes here.")`|
+let has_drivers_license: bool = false
let adult: bool = true
|
-|Boolean Logic|(not true) = false = (false && true) = (false || false)
|
-|Mutez (micro tez)| `42mutez`, `7mutez` |
-|Address | `("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address)`, `("KT1JepfBfMSqkQyf9B1ndvURghGsSB8YCLMD": address)`|
-|Addition |`3 + 4`, `3n + 4n`|
-|Multiplication & Division| `3 * 4`, `3n * 4n`, `10 / 5`, `10n / 5n`|
-|Modulo| `10 mod 3`|
-|Tuples| type name = (string * string)
let winner: name = "John", "Doe"
let first_name: string = winner.0
let last_name: string = winner.1
|
-|Types|`type age = int`, `type name = string` |
-|Includes|```#include "library.mligo"```|
-|Functions |let add (a : int) (b : int) : int = a + b
|
-| If Statement | let new_id: int = if age < 16
then failwith ("Too young to drive.")
else prev_id + 1
|
-|Options|type middle_name = string option
let middle_name : middle_name = Some "Foo"
let middle_name : middle_name = None
|
-|Variable Binding | ```let age: int = 5```|
-|Type Annotations| ```("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address)```|
-|Variants|type action =
| Increment of int
| Decrement of int
|
-|Variant *(pattern)* matching|let a: action = Increment 5
match a with
| Increment n -> n + 1
| Decrement n -> n - 1
|
-|Records|type person = {
age: int ;
name: string ;
}
let john : person = {
age = 18;
name = "John Doe";
}
let name: string = john.name
|
-|Maps|type prices = (nat, tez) map
let prices : prices = Map.literal [
(10n, 60mutez);
(50n, 30mutez);
(100n, 10mutez)
]
let price: tez option = Map.find_opt 50n prices
let prices: prices = Map.update 200n (Some 5mutez) prices
|
-|Contracts & Accounts|let destination_address : address = "tz1..."
let contract : unit contract =
Tezos.get_contract destination_address
|
-|Transactions|let payment : operation =
Tezos.transaction unit amount receiver
|
-|Exception/Failure|`failwith ("Your descriptive error message for the user goes here.")`|
+let has_drivers_license: bool = false;
let adult: bool = true;
|
-|Boolean Logic|(not true) = false = (false && true) = (false || false)
|
-|Mutez (micro tez)| `42mutez`, `7mutez` |
-|Address | `("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address)`, `("KT1JepfBfMSqkQyf9B1ndvURghGsSB8YCLMD": address)`|
-|Addition |`3 + 4`, `3n + 4n`|
-|Multiplication & Division| `3 * 4`, `3n * 4n`, `10 / 5`, `10n / 5n`|
-|Modulo| `10 mod 3`|
-|Tuples| type name = (string, string);
let winner: name = ("John", "Doe");
let first_name: string = winner[0];
let last_name: string = winner[1];
|
-|Types|`type age = int;`, `type name = string;` |
-|Includes|```#include "library.mligo"```|
-|Functions |let add = (a: int, b: int) : int => a + b;
|
-| If Statement | let new_id: int = if (age < 16) {
failwith ("Too young to drive.");
} else { prev_id + 1; }
|
-|Options|type middle_name = option(string);
let middle_name : middle_name = Some("Foo");
let middle_name : middle_name = None;
|
-|Variable Binding | ```let age: int = 5;```|
-|Type Annotations| ```("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address)```|
-|Variants|type action =
| Increment(int)
| Decrement(int);
|
-|Variant *(pattern)* matching|let a: action = Increment(5);
switch(a) {
| Increment(n) => n + 1
| Decrement(n) => n - 1;
}
|
-|Records|type person = {
age: int,
name: string
}
let john : person = {
age: 18,
name: "John Doe"
};
let name: string = john.name;
|
-|Maps|type prices = map(nat, tez);
let prices : prices = Map.literal([
(10n, 60mutez),
(50n, 30mutez),
(100n, 10mutez)
]);
let price: option(tez) = Map.find_opt(50n, prices);
let prices: prices = Map.update(200n, Some (5mutez), prices);
|
-|Contracts & Accounts|let destination_address : address = "tz1...";
let contract : contract(unit) =
Tezos.get_contract(destination_address);
|
-|Transactions|let payment : operation =
Tezos.transaction (unit, amount, receiver);
|
-|Exception/Failure|`failwith ("Your descriptive error message for the user goes here.");`|
+
+
{tokens.map((line, i) => {
if (line.length === 1 && line[0].content === '') {
line[0].content = '\n'; // eslint-disable-line no-param-reassign
diff --git a/gitlab-pages/website/static/css/custom.css b/gitlab-pages/website/static/css/custom.css
index b779c2e69..476f1da98 100644
--- a/gitlab-pages/website/static/css/custom.css
+++ b/gitlab-pages/website/static/css/custom.css
@@ -989,21 +989,43 @@ a:hover {
}
}
-
-/* ReasonLIGO specific syntax highlighting */
-.language-reasonligo .hljs-operator {
- color: #a626a4;
-}
-.language-reasonligo .hljs-character {
- color: #50a14f;
-}
-.language-reasonligo .hljs-module-identifier {
- color: #00f;
-}
-.language-reasonligo .hljs-constructor {
- color: #a31515;
-}
-
.badge {
display: none;
}
+
+.codeTable {
+ display: grid;
+ grid-template-columns: 30% 70%;
+ align-items: center;
+}
+
+.codeTable > .primitive {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: right;
+ text-align: right;
+ align-items: center;
+ font-weight: bold;
+ padding-right: 1rem;
+}
+
+
+.codeTable > div:nth-child(4n+1) {
+ background-color: var(--ifm-table-stripe-background);
+}
+
+.codeTable > div:nth-child(4n+2) {
+ background-color: var(--ifm-table-stripe-background);
+}
+
+
+.codeTable > .example {
+ padding-top: var(--ifm-leading);
+}
+
+.codeTable > .example pre,
+.codeTable > .example .codeBlockLines_src-theme-CodeBlock- {
+ background-color: transparent;
+}
+
diff --git a/src/bin/cli.ml b/src/bin/cli.ml
index 1c9a60fe1..246524f1c 100644
--- a/src/bin/cli.ml
+++ b/src/bin/cli.ml
@@ -167,8 +167,8 @@ let print_cst =
let print_ast =
let f source_file syntax display_format = (
toplevel ~display_format @@
- let%bind core = Compile.Utils.to_core source_file syntax in
- ok @@ Format.asprintf "%a\n" Compile.Of_core.pretty_print core
+ let%bind imperative = Compile.Utils.to_imperatve source_file syntax in
+ ok @@ Format.asprintf "%a\n" Compile.Of_imperative.pretty_print imperative
)
in
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
@@ -176,7 +176,31 @@ let print_ast =
let doc = "Subcommand: Print the AST.\n Warning: Intended for development of LIGO and can break at any time." in
(Term.ret term, Term.info ~doc cmdname)
-let print_typed_ast =
+let print_ast_sugar =
+ let f source_file syntax display_format = (
+ toplevel ~display_format @@
+ let%bind sugar = Compile.Utils.to_sugar source_file syntax in
+ ok @@ Format.asprintf "%a\n" Compile.Of_sugar.pretty_print sugar
+ )
+ in
+ let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
+ let cmdname = "print-ast-sugar" in
+ let doc = "Subcommand: Print the AST.\n Warning: Intended for development of LIGO and can break at any time." in
+ (Term.ret term, Term.info ~doc cmdname)
+
+let print_ast_core =
+ let f source_file syntax display_format = (
+ toplevel ~display_format @@
+ let%bind core = Compile.Utils.to_core source_file syntax in
+ ok @@ Format.asprintf "%a\n" Compile.Of_core.pretty_print core
+ )
+ in
+ let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
+ let cmdname = "print-ast-core" in
+ let doc = "Subcommand: Print the AST.\n Warning: Intended for development of LIGO and can break at any time." in
+ (Term.ret term, Term.info ~doc cmdname)
+
+let print_ast_typed =
let f source_file syntax display_format = (
toplevel ~display_format @@
let%bind typed,_ = Compile.Utils.type_file source_file syntax Env in
@@ -184,7 +208,7 @@ let print_typed_ast =
)
in
let term = Term.(const f $ source_file 0 $ syntax $ display_format) in
- let cmdname = "print-typed-ast" in
+ let cmdname = "print-ast-typed" in
let doc = "Subcommand: Print the typed AST.\n Warning: Intended for development of LIGO and can break at any time." in
(Term.ret term, Term.info ~doc cmdname)
@@ -441,7 +465,9 @@ let run ?argv () =
dump_changelog ;
print_cst ;
print_ast ;
- print_typed_ast ;
+ print_ast_sugar ;
+ print_ast_core ;
+ print_ast_typed ;
print_mini_c ;
list_declarations ;
]
diff --git a/src/bin/expect_tests/contract_tests.ml b/src/bin/expect_tests/contract_tests.ml
index 3785881be..984a0163b 100644
--- a/src/bin/expect_tests/contract_tests.ml
+++ b/src/bin/expect_tests/contract_tests.ml
@@ -1344,4 +1344,56 @@ let%expect_test _ =
* Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
* Ask a question on our Discord: https://discord.gg/9rhYaEt
* Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
- * Check the changelog by running 'ligo changelog' |}]
+ * Check the changelog by running 'ligo changelog' |}];
+
+ run_ligo_bad ["compile-contract"; bad_contract "nested_bigmap_1.religo"; "main"];
+ [%expect {|
+ ligo: It looks like you have nested a big map inside another big map. This is not supported. : {}
+
+
+ If you're not sure how to fix this error, you can
+ do one of the following:
+
+ * Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
+ * Ask a question on our Discord: https://discord.gg/9rhYaEt
+ * Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
+ * Check the changelog by running 'ligo changelog' |}];
+
+ run_ligo_bad ["compile-contract"; bad_contract "nested_bigmap_2.religo"; "main"];
+ [%expect {|
+ ligo: It looks like you have nested a big map inside another big map. This is not supported. : {}
+
+
+ If you're not sure how to fix this error, you can
+ do one of the following:
+
+ * Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
+ * Ask a question on our Discord: https://discord.gg/9rhYaEt
+ * Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
+ * Check the changelog by running 'ligo changelog' |}];
+
+ run_ligo_bad ["compile-contract"; bad_contract "nested_bigmap_3.religo"; "main"];
+ [%expect {|
+ ligo: It looks like you have nested a big map inside another big map. This is not supported. : {}
+
+
+ If you're not sure how to fix this error, you can
+ do one of the following:
+
+ * Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
+ * Ask a question on our Discord: https://discord.gg/9rhYaEt
+ * Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
+ * Check the changelog by running 'ligo changelog' |}];
+
+ run_ligo_bad ["compile-contract"; bad_contract "nested_bigmap_4.religo"; "main"];
+ [%expect {|
+ ligo: It looks like you have nested a big map inside another big map. This is not supported. : {}
+
+
+ If you're not sure how to fix this error, you can
+ do one of the following:
+
+ * Visit our documentation: https://ligolang.org/docs/intro/what-and-why/
+ * Ask a question on our Discord: https://discord.gg/9rhYaEt
+ * Open a gitlab issue: https://gitlab.com/ligolang/ligo/issues/new
+ * Check the changelog by running 'ligo changelog' |}]
\ No newline at end of file
diff --git a/src/bin/expect_tests/help_tests.ml b/src/bin/expect_tests/help_tests.ml
index d1028bfab..f960cc6b9 100644
--- a/src/bin/expect_tests/help_tests.ml
+++ b/src/bin/expect_tests/help_tests.ml
@@ -57,6 +57,18 @@ let%expect_test _ =
Subcommand: Print the AST. Warning: Intended for development of
LIGO and can break at any time.
+ print-ast-core
+ Subcommand: Print the AST. Warning: Intended for development of
+ LIGO and can break at any time.
+
+ print-ast-sugar
+ Subcommand: Print the AST. Warning: Intended for development of
+ LIGO and can break at any time.
+
+ print-ast-typed
+ Subcommand: Print the typed AST. Warning: Intended for development
+ of LIGO and can break at any time.
+
print-cst
Subcommand: Print the CST. Warning: Intended for development of
LIGO and can break at any time.
@@ -65,10 +77,6 @@ let%expect_test _ =
Subcommand: Print Mini-C. Warning: Intended for development of
LIGO and can break at any time.
- print-typed-ast
- Subcommand: Print the typed AST. Warning: Intended for development
- of LIGO and can break at any time.
-
run-function
Subcommand: Run a function with the given parameter.
@@ -136,6 +144,18 @@ let%expect_test _ =
Subcommand: Print the AST. Warning: Intended for development of
LIGO and can break at any time.
+ print-ast-core
+ Subcommand: Print the AST. Warning: Intended for development of
+ LIGO and can break at any time.
+
+ print-ast-sugar
+ Subcommand: Print the AST. Warning: Intended for development of
+ LIGO and can break at any time.
+
+ print-ast-typed
+ Subcommand: Print the typed AST. Warning: Intended for development
+ of LIGO and can break at any time.
+
print-cst
Subcommand: Print the CST. Warning: Intended for development of
LIGO and can break at any time.
@@ -144,10 +164,6 @@ let%expect_test _ =
Subcommand: Print Mini-C. Warning: Intended for development of
LIGO and can break at any time.
- print-typed-ast
- Subcommand: Print the typed AST. Warning: Intended for development
- of LIGO and can break at any time.
-
run-function
Subcommand: Run a function with the given parameter.
diff --git a/src/passes/3-self_ast_imperative/entrypoints_lenght_limit.ml b/src/passes/3-self_ast_imperative/entrypoints_length_limit.ml
similarity index 100%
rename from src/passes/3-self_ast_imperative/entrypoints_lenght_limit.ml
rename to src/passes/3-self_ast_imperative/entrypoints_length_limit.ml
diff --git a/src/passes/3-self_ast_imperative/self_ast_imperative.ml b/src/passes/3-self_ast_imperative/self_ast_imperative.ml
index a10968c0c..b0270ebd0 100644
--- a/src/passes/3-self_ast_imperative/self_ast_imperative.ml
+++ b/src/passes/3-self_ast_imperative/self_ast_imperative.ml
@@ -6,7 +6,7 @@ let all_expression_mapper = [
Literals.peephole_expression ;
]
let all_type_expression_mapper = [
- Entrypoints_lenght_limit.peephole_type_expression ;
+ Entrypoints_length_limit.peephole_type_expression ;
]
let all_exp = List.map (fun el -> Helpers.Expression el) all_expression_mapper
diff --git a/src/passes/9-self_ast_typed/no_nested_big_map.ml b/src/passes/9-self_ast_typed/no_nested_big_map.ml
new file mode 100644
index 000000000..e1a130ce9
--- /dev/null
+++ b/src/passes/9-self_ast_typed/no_nested_big_map.ml
@@ -0,0 +1,56 @@
+open Ast_typed
+open Trace
+
+type contract_pass_data = Contract_passes.contract_pass_data
+
+module Errors = struct
+ let no_nested_bigmap () =
+ let title = (thunk ("It looks like you have nested a big map inside another big map. This is not supported. ")) in
+ let message () = "" in
+ let data = [
+ (* ("location" , fun () -> Format.asprintf "%a" Location.pp loc) TODO once types have an actual location *)
+ ] in
+ error ~data title message ()
+end
+
+let rec check_no_nested_bigmap is_in_bigmap e =
+ match e.type_content with
+ | T_operator (TC_big_map (_, _)) when is_in_bigmap ->
+ fail @@ Errors.no_nested_bigmap
+ | T_operator (TC_big_map (key, value)) ->
+ let%bind _ = check_no_nested_bigmap false key in
+ let%bind _ = check_no_nested_bigmap true value in
+ ok ()
+ | T_operator (TC_contract t)
+ | T_operator (TC_option t)
+ | T_operator (TC_list t)
+ | T_operator (TC_set t) ->
+ let%bind _ = check_no_nested_bigmap is_in_bigmap t in
+ ok ()
+ | T_operator (TC_map (a, b)) ->
+ let%bind _ = check_no_nested_bigmap is_in_bigmap a in
+ let%bind _ = check_no_nested_bigmap is_in_bigmap b in
+ ok ()
+ | T_operator (TC_arrow (a, b)) ->
+ let%bind _ = check_no_nested_bigmap false a in
+ let%bind _ = check_no_nested_bigmap false b in
+ ok ()
+ | T_sum s ->
+ let es = CMap.to_list s in
+ let%bind _ = bind_map_list (fun l -> check_no_nested_bigmap is_in_bigmap l) es in
+ ok ()
+ | T_record elm ->
+ let es = LMap.to_list elm in
+ let%bind _ = bind_map_list (fun l -> check_no_nested_bigmap is_in_bigmap l) es in
+ ok ()
+ | T_arrow { type1; type2 } ->
+ let%bind _ = check_no_nested_bigmap false type1 in
+ let%bind _ = check_no_nested_bigmap false type2 in
+ ok ()
+ | T_variable _
+ | T_constant _ ->
+ ok ()
+
+let self_typing : contract_pass_data -> expression -> (bool * contract_pass_data * expression) result = fun dat el ->
+ let%bind _ = check_no_nested_bigmap false el.type_expression in
+ ok (true, dat, el)
diff --git a/src/passes/9-self_ast_typed/self_ast_typed.ml b/src/passes/9-self_ast_typed/self_ast_typed.ml
index 76bfbdf90..e8dfefdce 100644
--- a/src/passes/9-self_ast_typed/self_ast_typed.ml
+++ b/src/passes/9-self_ast_typed/self_ast_typed.ml
@@ -6,6 +6,7 @@ let all_passes = [
let contract_passes = [
Contract_passes.self_typing ;
+ No_nested_big_map.self_typing ;
]
let all_program =
diff --git a/src/test/contracts/negative/nested_bigmap_1.religo b/src/test/contracts/negative/nested_bigmap_1.religo
new file mode 100644
index 000000000..b86e549b1
--- /dev/null
+++ b/src/test/contracts/negative/nested_bigmap_1.religo
@@ -0,0 +1,10 @@
+type bar = big_map (nat, int);
+
+/* this should result in an error as nested big_maps are not supported: */
+type storage = big_map (int, bar);
+
+type return = (list (operation), storage);
+
+let main = ((ignore, store): (unit, storage)): return => {
+ ([]: list(operation), store)
+};
diff --git a/src/test/contracts/negative/nested_bigmap_2.religo b/src/test/contracts/negative/nested_bigmap_2.religo
new file mode 100644
index 000000000..d8061f912
--- /dev/null
+++ b/src/test/contracts/negative/nested_bigmap_2.religo
@@ -0,0 +1,9 @@
+/* this should result in an error as nested big_maps are not supported: */
+type storage = big_map (nat, big_map (int, string));
+
+type return = (list (operation), storage);
+
+let main = ((ignore, store): (unit, storage)): return => {
+ ([]: list(operation), store)
+};
+
\ No newline at end of file
diff --git a/src/test/contracts/negative/nested_bigmap_3.religo b/src/test/contracts/negative/nested_bigmap_3.religo
new file mode 100644
index 000000000..e8941f445
--- /dev/null
+++ b/src/test/contracts/negative/nested_bigmap_3.religo
@@ -0,0 +1,15 @@
+type bar = big_map (nat, int);
+
+type foo = {
+ a: int,
+ b: bar
+};
+
+/* this should result in an error as nested big_maps are not supported: */
+type storage = big_map(nat, foo);
+
+type return = (list (operation), storage);
+
+let main = ((ignore, store): (unit, storage)): return => {
+ ([]: list(operation), store)
+};
diff --git a/src/test/contracts/negative/nested_bigmap_4.religo b/src/test/contracts/negative/nested_bigmap_4.religo
new file mode 100644
index 000000000..653908636
--- /dev/null
+++ b/src/test/contracts/negative/nested_bigmap_4.religo
@@ -0,0 +1,9 @@
+/* this should result in an error as nested big_maps are not supported: */
+type storage = map (int, big_map (nat, big_map (int, string)));
+
+type return = (list (operation), storage);
+
+let main = ((ignore, store): (unit, storage)): return => {
+ ([]: list(operation), store)
+};
+
\ No newline at end of file