From e91661189b63aca41869aa645493e3c39f61e2cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jev=20Bj=C3=B6rsell?= Date: Mon, 2 Mar 2020 16:57:29 -0800 Subject: [PATCH 01/12] Prevent IDE jobs running when the ide code has no changes --- .gitlab-ci.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b3deaa2d9..671998b46 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -224,9 +224,10 @@ run-webide-unit-tests: - cd tools/webide/packages/server - npm ci - npm run test - only: - changes: + rules: + - changes: - tools/webide/** + when: always build-publish-ide-image: stage: build_and_deploy @@ -246,7 +247,8 @@ build-publish-ide-image: . - docker push "${WEBIDE_IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}" rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + - changes: + - tools/webide/** when: always - if: '$CI_COMMIT_REF_NAME == "dev"' when: always @@ -260,7 +262,8 @@ run-webide-e2e-tests: - export WEBIDE_IMAGE="${WEBIDE_IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}" - docker-compose run e2e rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + - changes: + - tools/webide/** when: always - if: '$CI_COMMIT_REF_NAME == "dev"' when: always From 3260e87d67b51eaa15d5c9c2271694413c4111fe Mon Sep 17 00:00:00 2001 From: Lesenechal Remi Date: Thu, 27 Feb 2020 12:49:38 +0100 Subject: [PATCH 02/12] new constant : C_CREATE_CONTRACT --- src/stages/common/PP.ml | 1 + src/stages/common/types.ml | 1 + src/stages/mini_c/PP.ml | 1 + 3 files changed, 3 insertions(+) diff --git a/src/stages/common/PP.ml b/src/stages/common/PP.ml index a04d303a7..14cde83d5 100644 --- a/src/stages/common/PP.ml +++ b/src/stages/common/PP.ml @@ -146,6 +146,7 @@ let constant ppf : constant' -> unit = function | C_SELF_ADDRESS -> fprintf ppf "SELF_ADDRESS" | C_IMPLICIT_ACCOUNT -> fprintf ppf "IMPLICIT_ACCOUNT" | C_SET_DELEGATE -> fprintf ppf "SET_DELEGATE" + | C_CREATE_CONTRACT -> fprintf ppf "CREATE_CONTRACT" let literal ppf (l : literal) = match l with diff --git a/src/stages/common/types.ml b/src/stages/common/types.ml index e923bc924..d6b0839fd 100644 --- a/src/stages/common/types.ml +++ b/src/stages/common/types.ml @@ -288,3 +288,4 @@ and constant' = | C_SELF_ADDRESS | C_IMPLICIT_ACCOUNT | C_SET_DELEGATE + | C_CREATE_CONTRACT diff --git a/src/stages/mini_c/PP.ml b/src/stages/mini_c/PP.ml index 0fde6061c..46899c212 100644 --- a/src/stages/mini_c/PP.ml +++ b/src/stages/mini_c/PP.ml @@ -242,6 +242,7 @@ and constant ppf : constant' -> unit = function | C_SELF_ADDRESS -> fprintf ppf "SELF_ADDRESS" | C_IMPLICIT_ACCOUNT -> fprintf ppf "IMPLICIT_ACCOUNT" | C_SET_DELEGATE -> fprintf ppf "SET_DELEGATE" + | C_CREATE_CONTRACT -> fprintf ppf "CREATE_CONTRACT" let%expect_test _ = Format.printf "%a" value (D_bytes (Bytes.of_string "foo")) ; From 4e48026daa0747b09df8e5b4c4bca9247c82c0fb Mon Sep 17 00:00:00 2001 From: Lesenechal Remi Date: Thu, 27 Feb 2020 12:49:50 +0100 Subject: [PATCH 03/12] typer: typing C_CREATE_CONTRACT --- src/passes/operators/operators.ml | 26 ++++++++++++++------------ src/passes/operators/operators.mli | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/passes/operators/operators.ml b/src/passes/operators/operators.ml index 7cc7f556d..3537e1d89 100644 --- a/src/passes/operators/operators.ml +++ b/src/passes/operators/operators.ml @@ -88,6 +88,7 @@ module Simplify = struct | "source" -> ok C_SOURCE (* Deprecated *) | "Tezos.failwith" -> ok C_FAILWITH | "failwith" -> ok C_FAILWITH + | "Tezos.create_contract" -> ok C_CREATE_CONTRACT | "Tezos.transaction" -> ok C_CALL | "transaction" -> ok C_CALL (* Deprecated *) @@ -287,6 +288,7 @@ module Simplify = struct | "Operation.get_entrypoint" -> ok C_CONTRACT_ENTRYPOINT (* Deprecated *) | "Tezos.get_entrypoint_opt" -> ok C_CONTRACT_ENTRYPOINT_OPT | "Operation.get_entrypoint_opt" -> ok C_CONTRACT_ENTRYPOINT_OPT (* Deprecated *) + | "Tezos.create_contract" -> ok C_CREATE_CONTRACT | "Michelson.is_nat" -> ok C_IS_NAT (* Deprecated *) | "is_nat" -> ok C_IS_NAT @@ -800,18 +802,17 @@ module Typer = struct let%bind () = assert_type_expression_eq (param , contract_param) in ok @@ t_operation () - let originate = typer_6 "ORIGINATE" @@ fun manager delegate_opt spendable delegatable init_balance code -> - let%bind () = assert_eq_1 manager (t_key_hash ()) in - let%bind () = assert_eq_1 delegate_opt (t_option (t_key_hash ()) ()) in - let%bind () = assert_eq_1 spendable (t_bool ()) in - let%bind () = assert_eq_1 delegatable (t_bool ()) in - let%bind () = assert_t_mutez init_balance in - let%bind (arg , res) = get_t_function code in - let%bind (_param , storage) = get_t_pair arg in - let%bind (storage' , op_lst) = get_t_pair res in - let%bind () = assert_eq_1 storage storage' in - let%bind () = assert_eq_1 op_lst (t_list (t_operation ()) ()) in - ok @@ (t_pair (t_operation ()) (t_address ()) ()) + let create_contract = typer_4 "CREATE_CONTRACT" @@ fun f kh_opt amount init_storage -> + let%bind (args , ret) = get_t_function f in + let%bind (_,s) = get_t_pair args in + let%bind (oplist,s') = get_t_pair ret in + let%bind () = assert_t_mutez amount in + let%bind (delegate) = get_t_option kh_opt in + let%bind () = assert_type_expression_eq (s,s') in + let%bind () = assert_type_expression_eq (s,init_storage) in + let%bind () = assert_t_list_operation oplist in + let%bind () = assert_t_key_hash delegate in + ok @@ t_pair (t_operation ()) (t_address ()) () let get_contract = typer_1_opt "CONTRACT" @@ fun addr_tv tv_opt -> if not (type_expression_eq (addr_tv, t_address ())) @@ -1229,6 +1230,7 @@ module Typer = struct | C_SELF_ADDRESS -> ok @@ self_address; | C_IMPLICIT_ACCOUNT -> ok @@ implicit_account; | C_SET_DELEGATE -> ok @@ set_delegate ; + | C_CREATE_CONTRACT -> ok @@ create_contract ; | _ -> simple_fail @@ Format.asprintf "Typer not implemented for consant %a" PP.constant c diff --git a/src/passes/operators/operators.mli b/src/passes/operators/operators.mli index 2adb00b5b..77ce53196 100644 --- a/src/passes/operators/operators.mli +++ b/src/passes/operators/operators.mli @@ -140,7 +140,7 @@ module Typer : sig val now : typer val transaction : typer *) - val originate : typer + val create_contract : typer (* val get_contract : typer *) From ad7024c62b442f19a88ce6461f971aa7fb4502fe Mon Sep 17 00:00:00 2001 From: Lesenechal Remi Date: Fri, 28 Feb 2020 18:11:02 +0100 Subject: [PATCH 04/12] compiler: compile CREATE_CONTRACT --- src/passes/8-compiler/compiler_program.ml | 21 +++++++++++++++++++-- src/stages/mini_c/combinators.ml | 2 +- src/stages/mini_c/combinators.mli | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/passes/8-compiler/compiler_program.ml b/src/passes/8-compiler/compiler_program.ml index a93b58299..a4ffbd0e0 100644 --- a/src/passes/8-compiler/compiler_program.ml +++ b/src/passes/8-compiler/compiler_program.ml @@ -27,7 +27,7 @@ end open Errors (* This does not makes sense to me *) -let get_operator : constant' -> type_value -> expression list -> predicate result = fun s ty lst -> +let rec get_operator : constant' -> type_value -> expression list -> predicate result = fun s ty lst -> match Operators.Compiler.get_operators s with | Ok (x,_) -> ok x | Error _ -> ( @@ -114,10 +114,23 @@ let get_operator : constant' -> type_value -> expression list -> predicate resul i_drop ; (* drop the entrypoint... *) prim ~annot:[entry] ~children:[r_ty] I_CONTRACT ; ] + | C_CREATE_CONTRACT -> + let%bind ch = match lst with + | { content= E_closure {body;binder} ; type_value = T_function (T_pair ((_,p),(_,s)) as tin,_)} :: _ -> + let%bind closure = translate_function_body {body;binder} [] tin in + let%bind (p',s') = bind_map_pair Compiler_type.type_ (p,s) in + ok @@ contract p' s' closure + | _ -> fail @@ corner_case ~loc:__LOC__ "mini_c . CREATE_CONTRACT" + in + ok @@ simple_tetrary @@ seq [ + i_drop ; + prim ~children:[ch] I_CREATE_CONTRACT ; + i_pair ; + ] | x -> simple_fail (Format.asprintf "predicate \"%a\" doesn't exist" PP.constant x) ) -let rec translate_value (v:value) ty : michelson result = match v with +and translate_value (v:value) ty : michelson result = match v with | D_bool b -> ok @@ prim (if b then D_True else D_False) | D_int n -> ok @@ int (Z.of_int n) | D_nat n -> ok @@ int (Z.of_int n) @@ -249,6 +262,10 @@ and translate_expression (expr:expression) (env:environment) : michelson result pre_code ; f ; ] + | Tetrary f, 4 -> ok @@ seq [ + pre_code ; + f ; + ] | _ -> simple_fail (Format.asprintf "bad arity for %a" PP.constant str) in let error = diff --git a/src/stages/mini_c/combinators.ml b/src/stages/mini_c/combinators.ml index 2912aec93..019a111be 100644 --- a/src/stages/mini_c/combinators.ml +++ b/src/stages/mini_c/combinators.ml @@ -152,7 +152,7 @@ let get_t_contract t = match t with | _ -> fail @@ wrong_type "contract" t let get_t_operation t = match t with - | T_base TC_operation -> ok () + | T_base TC_operation -> ok t | _ -> fail @@ wrong_type "operation" t let get_operation (v:value) = match v with diff --git a/src/stages/mini_c/combinators.mli b/src/stages/mini_c/combinators.mli index 3f9b1552e..d61620589 100644 --- a/src/stages/mini_c/combinators.mli +++ b/src/stages/mini_c/combinators.mli @@ -49,7 +49,7 @@ val wrong_type : string -> type_value -> unit -> error val get_t_left : type_value -> type_value result val get_t_right : type_value -> type_value result val get_t_contract : type_value -> type_value result -val get_t_operation : type_value -> unit result +val get_t_operation : type_value -> type_value result val get_operation : value -> Memory_proto_alpha.Protocol.Alpha_context.packed_internal_operation result val t_int : type_value From ffd792e2f8248841f7a3bd6bdad10e89ab6cdbfe Mon Sep 17 00:00:00 2001 From: Lesenechal Remi Date: Fri, 28 Feb 2020 19:30:09 +0100 Subject: [PATCH 05/12] CREATE_CONTRACT: add a check in the typer to allow only closures --- src/passes/4-typer-old/typer.ml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/passes/4-typer-old/typer.ml b/src/passes/4-typer-old/typer.ml index 2d5d70a12..e966b5a52 100644 --- a/src/passes/4-typer-old/typer.ml +++ b/src/passes/4-typer-old/typer.ml @@ -154,6 +154,15 @@ module Errors = struct ] in error ~data title message () + let fvs_in_create_contract_lambda (e : I.expression) (case : Ast_typed.expression_variable) () = + let title = (thunk "No free variable allowed in this lambda") in + let message () = Format.asprintf "%a " Var.pp case in + let data = [ + ("expression" , fun () -> Format.asprintf "%a" I.PP.expression e) ; + ("location" , fun () -> Format.asprintf "%a" Location.pp e.location) + ] in + error ~data title message () + let type_error_approximate ?(msg="") ~(expected: string) ~(actual: O.type_expression) ~(expression : I.expression) (loc:Location.t) () = let title = (thunk "type error") in let message () = msg in @@ -696,6 +705,20 @@ and type_expression' : environment -> ?tv_opt:O.type_expression -> I.expression let%bind (opname',tv) = type_constant opname tv_lst tv_opt in Format.printf "Typed constant : %a \n%!" O.PP.type_expression tv; return (E_constant {cons_name=opname';arguments=lst'}) tv + | E_constant {cons_name=C_CREATE_CONTRACT as cons_name;arguments} -> + let%bind lst' = bind_list @@ List.map (type_expression' e) arguments in + let%bind () = match lst' with + | { expression_content = O.E_lambda l ; _ } :: _ -> + let open Ast_typed.Misc in + let fvs = Free_variables.lambda [] l in + if List.length fvs = 0 then ok () + else fail @@ fvs_in_create_contract_lambda ae (List.hd fvs) + | _ -> ok () + in + let tv_lst = List.map get_type_expression lst' in + let%bind (name', tv) = + type_constant cons_name tv_lst tv_opt in + return (E_constant {cons_name=name';arguments=lst'}) tv | E_constant {cons_name;arguments} -> let%bind lst' = bind_list @@ List.map (type_expression' e) arguments in let tv_lst = List.map get_type_expression lst' in From 9a30eb67c1016ac6a11846e95e64b52c7ae50366 Mon Sep 17 00:00:00 2001 From: Lesenechal Remi Date: Fri, 28 Feb 2020 19:49:51 +0100 Subject: [PATCH 06/12] create_contract: add some tests --- src/bin/expect_tests/contract_tests.ml | 49 ++++++++++++++++++- src/test/contracts/create_contract.mligo | 10 ++++ .../negative/create_contract_toplevel.mligo | 10 ++++ .../negative/create_contract_var.mligo | 12 +++++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/test/contracts/create_contract.mligo create mode 100644 src/test/contracts/negative/create_contract_toplevel.mligo create mode 100644 src/test/contracts/negative/create_contract_var.mligo diff --git a/src/bin/expect_tests/contract_tests.ml b/src/bin/expect_tests/contract_tests.ml index facee666d..795e554ea 100644 --- a/src/bin/expect_tests/contract_tests.ml +++ b/src/bin/expect_tests/contract_tests.ml @@ -1144,4 +1144,51 @@ 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' |}] \ No newline at end of file + * Check the changelog by running 'ligo changelog' |}] + +let%expect_test _ = + run_ligo_bad [ "compile-contract" ; bad_contract "create_contract_toplevel.mligo" ; "main" ] ; + [%expect {| + ligo: in file "create_contract_toplevel.mligo", line 4, character 35 to line 8, character 8. No free variable allowed in this lambda: store {"expression":"CREATE_CONTRACT(lambda (#P : ( nat * string ):Some(( nat * string ))) : None return let rhs#752 = #P in let p = rhs#752.0 in let s = rhs#752.1 in ( list[] : (TO_list(operation)) , store ) , NONE() : (TO_option(key_hash)) , 300000000mutez , \"un\")","location":"in file \"create_contract_toplevel.mligo\", line 4, character 35 to line 8, character 8"} + + + 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 "create_contract_var.mligo" ; "main" ] ; + [%expect {| + ligo: in file "create_contract_var.mligo", line 6, character 35 to line 10, character 5. No free variable allowed in this lambda: a {"expression":"CREATE_CONTRACT(lambda (#P : ( nat * int ):Some(( nat * int ))) : None return let rhs#755 = #P in let p = rhs#755.0 in let s = rhs#755.1 in ( list[] : (TO_list(operation)) , a ) , NONE() : (TO_option(key_hash)) , 300000000mutez , 1)","location":"in file \"create_contract_var.mligo\", line 6, character 35 to line 10, character 5"} + + + 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_good [ "compile-contract" ; contract "create_contract.mligo" ; "main" ] ; + [%expect {| + { parameter string ; + storage string ; + code { PUSH string "un" ; + PUSH mutez 300000000 ; + NONE key_hash ; + CREATE_CONTRACT + { parameter nat ; + storage string ; + code { PUSH string "one" ; NIL operation ; PAIR ; DIP { DROP } } } ; + PAIR ; + DUP ; + CAR ; + NIL operation ; + SWAP ; + CONS ; + DIP { DIP { DUP } ; SWAP ; CDR } ; + PAIR ; + DIP { DROP 2 } } } |}] diff --git a/src/test/contracts/create_contract.mligo b/src/test/contracts/create_contract.mligo new file mode 100644 index 000000000..8c405102c --- /dev/null +++ b/src/test/contracts/create_contract.mligo @@ -0,0 +1,10 @@ +type return = operation list * string + +let main (action, store : string * string) : return = + let toto : operation * address = Tezos.create_contract + (fun (p, s : nat * string) -> (([] : operation list), "one")) + (None: key_hash option) + 300tz + "un" + in + ([toto.0], store) \ No newline at end of file diff --git a/src/test/contracts/negative/create_contract_toplevel.mligo b/src/test/contracts/negative/create_contract_toplevel.mligo new file mode 100644 index 000000000..051464c11 --- /dev/null +++ b/src/test/contracts/negative/create_contract_toplevel.mligo @@ -0,0 +1,10 @@ +type return = operation list * string + +let main (action, store : string * string) : return = + let toto : operation * address = Tezos.create_contract + (fun (p, s : nat * string) -> (([] : operation list), store)) + (None: key_hash option) + 300tz + "un" + in + ([toto.0], store) \ No newline at end of file diff --git a/src/test/contracts/negative/create_contract_var.mligo b/src/test/contracts/negative/create_contract_var.mligo new file mode 100644 index 000000000..9bd0a3ffb --- /dev/null +++ b/src/test/contracts/negative/create_contract_var.mligo @@ -0,0 +1,12 @@ +type return = operation list * string + +let a : int = 2 + +let main (action, store : string * string) : return = + let toto : operation * address = Tezos.create_contract + (fun (p, s : nat * int) -> (([] : operation list), a)) + (None: key_hash option) + 300tz + 1 + in + ([toto.0], store) \ No newline at end of file From 1e5abda3eed2c66f005457293c9924a4600ddd32 Mon Sep 17 00:00:00 2001 From: Lesenechal Remi Date: Mon, 2 Mar 2020 12:53:03 +0100 Subject: [PATCH 07/12] create contract : conservative restrictions & errors in typer, before inlining/beta optimizations --- src/passes/4-typer-old/typer.ml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/passes/4-typer-old/typer.ml b/src/passes/4-typer-old/typer.ml index e966b5a52..1b220754f 100644 --- a/src/passes/4-typer-old/typer.ml +++ b/src/passes/4-typer-old/typer.ml @@ -154,9 +154,18 @@ module Errors = struct ] in error ~data title message () - let fvs_in_create_contract_lambda (e : I.expression) (case : Ast_typed.expression_variable) () = + let fvs_in_create_contract_lambda (e : I.expression) (fvar : Ast_typed.expression_variable) () = let title = (thunk "No free variable allowed in this lambda") in - let message () = Format.asprintf "%a " Var.pp case in + let message () = Format.asprintf "variable '%a'" Var.pp fvar in + let data = [ + ("expression" , fun () -> Format.asprintf "%a" I.PP.expression e) ; + ("location" , fun () -> Format.asprintf "%a" Location.pp e.location) + ] in + error ~data title message () + + let create_contract_lambda (cst : I.constant') (e : I.expression) () = + let title () = Format.asprintf "%a first argument must be inlined" I.PP.constant cst in + let message () = Format.asprintf "contract code can be inlined using a lambda" in let data = [ ("expression" , fun () -> Format.asprintf "%a" I.PP.expression e) ; ("location" , fun () -> Format.asprintf "%a" Location.pp e.location) @@ -713,7 +722,7 @@ and type_expression' : environment -> ?tv_opt:O.type_expression -> I.expression let fvs = Free_variables.lambda [] l in if List.length fvs = 0 then ok () else fail @@ fvs_in_create_contract_lambda ae (List.hd fvs) - | _ -> ok () + | _ -> fail @@ create_contract_lambda C_CREATE_CONTRACT ae in let tv_lst = List.map get_type_expression lst' in let%bind (name', tv) = From cf383fe3274cc93b9bd44afb1e74f6449ccd92fa Mon Sep 17 00:00:00 2001 From: Lesenechal Remi Date: Mon, 2 Mar 2020 12:53:10 +0100 Subject: [PATCH 08/12] more tests --- src/bin/expect_tests/contract_tests.ml | 18 ++++++++++++++++-- .../negative/create_contract_no_inline.mligo | 11 +++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/test/contracts/negative/create_contract_no_inline.mligo diff --git a/src/bin/expect_tests/contract_tests.ml b/src/bin/expect_tests/contract_tests.ml index 795e554ea..0706ceda8 100644 --- a/src/bin/expect_tests/contract_tests.ml +++ b/src/bin/expect_tests/contract_tests.ml @@ -1149,7 +1149,7 @@ let%expect_test _ = let%expect_test _ = run_ligo_bad [ "compile-contract" ; bad_contract "create_contract_toplevel.mligo" ; "main" ] ; [%expect {| - ligo: in file "create_contract_toplevel.mligo", line 4, character 35 to line 8, character 8. No free variable allowed in this lambda: store {"expression":"CREATE_CONTRACT(lambda (#P : ( nat * string ):Some(( nat * string ))) : None return let rhs#752 = #P in let p = rhs#752.0 in let s = rhs#752.1 in ( list[] : (TO_list(operation)) , store ) , NONE() : (TO_option(key_hash)) , 300000000mutez , \"un\")","location":"in file \"create_contract_toplevel.mligo\", line 4, character 35 to line 8, character 8"} + ligo: in file "create_contract_toplevel.mligo", line 4, character 35 to line 8, character 8. No free variable allowed in this lambda: variable 'store' {"expression":"CREATE_CONTRACT(lambda (#P : ( nat * string ):Some(( nat * string ))) : None return let rhs#752 = #P in let p = rhs#752.0 in let s = rhs#752.1 in ( list[] : (TO_list(operation)) , store ) , NONE() : (TO_option(key_hash)) , 300000000mutez , \"un\")","location":"in file \"create_contract_toplevel.mligo\", line 4, character 35 to line 8, character 8"} If you're not sure how to fix this error, you can @@ -1162,7 +1162,7 @@ let%expect_test _ = run_ligo_bad [ "compile-contract" ; bad_contract "create_contract_var.mligo" ; "main" ] ; [%expect {| - ligo: in file "create_contract_var.mligo", line 6, character 35 to line 10, character 5. No free variable allowed in this lambda: a {"expression":"CREATE_CONTRACT(lambda (#P : ( nat * int ):Some(( nat * int ))) : None return let rhs#755 = #P in let p = rhs#755.0 in let s = rhs#755.1 in ( list[] : (TO_list(operation)) , a ) , NONE() : (TO_option(key_hash)) , 300000000mutez , 1)","location":"in file \"create_contract_var.mligo\", line 6, character 35 to line 10, character 5"} + ligo: in file "create_contract_var.mligo", line 6, character 35 to line 10, character 5. No free variable allowed in this lambda: variable 'a' {"expression":"CREATE_CONTRACT(lambda (#P : ( nat * int ):Some(( nat * int ))) : None return let rhs#755 = #P in let p = rhs#755.0 in let s = rhs#755.1 in ( list[] : (TO_list(operation)) , a ) , NONE() : (TO_option(key_hash)) , 300000000mutez , 1)","location":"in file \"create_contract_var.mligo\", line 6, character 35 to line 10, character 5"} If you're not sure how to fix this error, you can @@ -1172,6 +1172,20 @@ let%expect_test _ = * 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 "create_contract_no_inline.mligo" ; "main" ] ; + [%expect {| + ligo: in file "create_contract_no_inline.mligo", line 9, characters 19-89. CREATE_CONTRACT first argument must be inlined: contract code can be inlined using a lambda {"expression":"CREATE_CONTRACT(dummy_contract , NONE() : (TO_option(key_hash)) , 300000000mutez , 1)","location":"in file \"create_contract_no_inline.mligo\", line 9, characters 19-89"} + + + 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_good [ "compile-contract" ; contract "create_contract.mligo" ; "main" ] ; [%expect {| { parameter string ; diff --git a/src/test/contracts/negative/create_contract_no_inline.mligo b/src/test/contracts/negative/create_contract_no_inline.mligo new file mode 100644 index 000000000..ba5a30cd0 --- /dev/null +++ b/src/test/contracts/negative/create_contract_no_inline.mligo @@ -0,0 +1,11 @@ +let foo : int = 42 + +let dummy_contract (p, s : nat * int) : return = + (([] : operation list), foo) + +type return = operation list * string + +let main (action, store : int * int) : return = + let (op, addr) = Tezos.create_contract dummy_contract ((None: key_hash option)) 300tz 1 in + let toto : operation list = [ op ] in + (toto, foo) From a4fece03d66e9b957c1049416763e023ad668e7b Mon Sep 17 00:00:00 2001 From: Lesenechal Remi Date: Mon, 2 Mar 2020 13:35:26 +0100 Subject: [PATCH 09/12] doc & changelog --- CHANGELOG.md | 4 ++ .../docs/language-basics/tezos-specific.md | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b40924f28..fe908e334 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +## [Add crypto reference page to docs](https://gitlab.com/ligolang/ligo/-/merge_requests/459) +### Added +- support for `Tezos.create_contract` origination + ## [9164206ef1fcf3e577820442b5afbad92d03ffa4] - 2020-02-09 ### Changed - Mutation of variables inside lambdas passed to list_iter do not have effect anymore. Side-effects used to survive iterations of list_iter via a quirk in the Michelson list_iter. Now, either use a list_fold and explicitly pass through the updated variables (e.g. storage) to the next iteration, or use a `for` loop which automatically detects mutations within the loop body and lifts the affected variables to a record that is passed from iteration to iteration. diff --git a/gitlab-pages/docs/language-basics/tezos-specific.md b/gitlab-pages/docs/language-basics/tezos-specific.md index 9fed6760a..99b980f44 100644 --- a/gitlab-pages/docs/language-basics/tezos-specific.md +++ b/gitlab-pages/docs/language-basics/tezos-specific.md @@ -154,3 +154,42 @@ let current_addr : address = Tezos.self_address; ``` + +## Origination of a contract + +`Tezos.create_contract` allows you to originate a contract given its code, delegate (if any), initial balance and initial storage. +The return value is a pair of type `(operation * address)`. + +> ⚠️ Due to limitations in Michelson, `Tezos.create_contract` first argument +> must be inlined and must not contain references to free variables + + + + +```pascaligo group=e +const origination : operation * address = Tezos.create_contract ( + function (const p : nat; const s : string): list(operation) * string is ((nil : list(operation)), s), + (None : option(key_hash)), + 3tz, + "initial_storage") +``` + + +```cameligo group=e +let origination : operation * address = Tezos.create_contract + (fun (p, s : nat * string) -> (([] : operation list), s)) + (None: key_hash option) + 3tz + "initial_storage" +``` + + +```reasonligo group=e +let origination : (operation, address) = Tezos.create_contract ( + ((p, s) : (nat,string)) : (list(operation),string) => (([] : list(operation)), s), + None: option(key_hash), + 3tz, + "initial_storage") +``` + + From e27dfa1bcec670418ec53a679ec24a89d8aad83e Mon Sep 17 00:00:00 2001 From: Maksym Bykovskyy Date: Tue, 3 Mar 2020 22:41:16 +0000 Subject: [PATCH 10/12] Moved examples folder --- .gitlab-ci.yml | 9 +- .../cameligo/arithmetic-contract.ligo | 0 .../pascaligo/arithmetic-contract.ligo | 0 src/test/examples/pascaligo/fa-1.2.ligo | 164 ++++++++++++++++++ .../reasonligo/arithmetic-contract.ligo | 0 tools/webide/Dockerfile | 10 +- .../packages/client/package-examples.js | 19 +- .../client/src/components/examples.tsx | 45 ++--- 8 files changed, 206 insertions(+), 41 deletions(-) rename {tools/webide/packages/client => src/test}/examples/cameligo/arithmetic-contract.ligo (100%) rename {tools/webide/packages/client => src/test}/examples/pascaligo/arithmetic-contract.ligo (100%) create mode 100644 src/test/examples/pascaligo/fa-1.2.ligo rename {tools/webide/packages/client => src/test}/examples/reasonligo/arithmetic-contract.ligo (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b3deaa2d9..c94a01ddf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -23,8 +23,8 @@ dont-merge-to-master: only: - master -.build_binary: &build_binary - # To run in sequence and save CPU usage, use stage: build_and_package_binaries +.build_binary: + &build_binary # To run in sequence and save CPU usage, use stage: build_and_package_binaries stage: test script: - $build_binary_script "$target_os_family" "$target_os" "$target_os_version" @@ -71,8 +71,6 @@ dont-merge-to-master: # move internal odoc documentation to the website folder - mkdir -p build/ligo/ - mv ../../_build/default/_doc/_html/ build/ligo/odoc - - pwd # for debug - - ls build/ligo/ # for debug after_script: - cp -r gitlab-pages/website/build/ligo public artifacts: @@ -84,7 +82,6 @@ dont-merge-to-master: services: - docker:19.03.5-dind - .before_script: &before_script before_script: # Install dependencies @@ -236,6 +233,7 @@ build-publish-ide-image: - find dist/ - find dist/package/ -name '*ligo_*deb' - mv $(realpath dist/package/debian-10/*.deb) tools/webide/ligo_deb10.deb + - cp -r src/test/examples tools/webide/packages/client/examples - cd tools/webide - echo "${CI_BUILD_TOKEN}" | docker login -u gitlab-ci-token --password-stdin registry.gitlab.com - > @@ -243,6 +241,7 @@ build-publish-ide-image: -t "${WEBIDE_IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}" --build-arg GIT_TAG="${CI_COMMIT_SHA}" --build-arg GIT_COMMIT="${CI_COMMIT_SHORT_SHA}" + --build-arg EXAMPLES_DIR_SRC=packages/client/examples . - docker push "${WEBIDE_IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}" rules: diff --git a/tools/webide/packages/client/examples/cameligo/arithmetic-contract.ligo b/src/test/examples/cameligo/arithmetic-contract.ligo similarity index 100% rename from tools/webide/packages/client/examples/cameligo/arithmetic-contract.ligo rename to src/test/examples/cameligo/arithmetic-contract.ligo diff --git a/tools/webide/packages/client/examples/pascaligo/arithmetic-contract.ligo b/src/test/examples/pascaligo/arithmetic-contract.ligo similarity index 100% rename from tools/webide/packages/client/examples/pascaligo/arithmetic-contract.ligo rename to src/test/examples/pascaligo/arithmetic-contract.ligo diff --git a/src/test/examples/pascaligo/fa-1.2.ligo b/src/test/examples/pascaligo/fa-1.2.ligo new file mode 100644 index 000000000..62f8d7c98 --- /dev/null +++ b/src/test/examples/pascaligo/fa-1.2.ligo @@ -0,0 +1,164 @@ +(*_* + name: FA1.2 PascaLIGO implementation + language: pascaligo + compile: + entrypoint: main + dryRun: + entrypoint: main + parameters: "" + storage: "" + deploy: + entrypoint: main + storage: "" + evaluateValue: + entrypoint: "" + evaluateFunction: + entrypoint: "" + parameters: "" +*_*) +// This is an implimentation of the FA1.2 specification in PascaLIGO + +type amt is nat; + +type account is record + balance : amt; + allowances: map(address, amt); +end + +type action is +| Transfer of (address * address * amt) +| Approve of (address * amt) +| GetAllowance of (address * address * contract(amt)) +| GetBalance of (address * contract(amt)) +| GetTotalSupply of (unit * contract(amt)) + +type contract_storage is record + totalSupply: amt; + ledger: big_map(address, account); +end + +function isAllowed ( const src : address ; const value : amt ; var s : contract_storage) : bool is + begin + var allowed: bool := False; + if sender =/= source then block { + const src: account = get_force(src, s.ledger); + const allowanceAmount: amt = get_force(sender, src.allowances); + allowed := allowanceAmount >= value; + }; + else allowed := True; + end with allowed + +// Transfer a specific amount of tokens from the accountFrom address to a destination address +// Pre conditions: +// The sender address is the account owner or is allowed to spend x in the name of accountFrom +// The accountFrom account has a balance higher than amount +// Post conditions: +// The balance of accountFrom is decreased by amount +// The balance of destination is increased by amount +function transfer (const accountFrom : address ; const destination : address ; const value : amt ; var s : contract_storage) : contract_storage is + begin + // If accountFrom = destination transfer is not necessary + if accountFrom = destination then skip; + else block { + // Is sender allowed to spend value in the name of source + case isAllowed(accountFrom, value, s) of + | False -> failwith ("Sender not allowed to spend token from source") + | True -> skip + end; + + // Fetch src account + const src: account = get_force(accountFrom, s.ledger); + + // Check that the source can spend that much + if value > src.balance + then failwith ("Source balance is too low"); + else skip; + + // Update the source balance + // Using the abs function to convert int to nat + src.balance := abs(src.balance - value); + + s.ledger[accountFrom] := src; + + // Fetch dst account or add empty dst account to ledger + var dst: account := record + balance = 0n; + allowances = (map end : map(address, amt)); + end; + case s.ledger[destination] of + | None -> skip + | Some(n) -> dst := n + end; + + // Update the destination balance + dst.balance := dst.balance + value; + + // Decrease the allowance amount if necessary + if accountFrom =/= sender then block { + const allowanceAmount: amt = get_force(sender, src.allowances); + if allowanceAmount - value < 0 then failwith ("Allowance amount cannot be negative"); + else src.allowances[sender] := abs(allowanceAmount - value); + } else skip; + + s.ledger[destination] := dst; + } + end with s + +// Approve an amount to be spent by another address in the name of the sender +// Pre conditions: +// The spender account is not the sender account +// Post conditions: +// The allowance of spender in the name of sender is value +function approve (const spender : address ; const value : amt ; var s : contract_storage) : contract_storage is + begin + // If sender is the spender approving is not necessary + if sender = spender then skip; + else block { + const src: account = get_force(sender, s.ledger); + src.allowances[spender] := value; + s.ledger[sender] := src; // Not sure if this last step is necessary + } + end with s + +// View function that forwards the allowance amount of spender in the name of tokenOwner to a contract +// Pre conditions: +// None +// Post conditions: +// The state is unchanged +function getAllowance (const owner : address ; const spender : address ; const contr : contract(amt) ; var s : contract_storage) : list(operation) is + begin + const src: account = get_force(owner, s.ledger); + const destAllowance: amt = get_force(spender, src.allowances); + end with list [transaction(destAllowance, 0tz, contr)] + +// View function that forwards the balance of source to a contract +// Pre conditions: +// None +// Post conditions: +// The state is unchanged +function getBalance (const src : address ; const contr : contract(amt) ; var s : contract_storage) : list(operation) is + begin + const src: account = get_force(src, s.ledger); + end with list [transaction(src.balance, 0tz, contr)] + +// View function that forwards the totalSupply to a contract +// Pre conditions: +// None +// Post conditions: +// The state is unchanged +function getTotalSupply (const contr : contract(amt) ; var s : contract_storage) : list(operation) is + list [transaction(s.totalSupply, 0tz, contr)] + +function main (const p : action ; const s : contract_storage) : + (list(operation) * contract_storage) is + block { + // Reject any transaction that try to transfer token to this contract + if amount =/= 0tz then failwith ("This contract do not accept token"); + else skip; + } with case p of + | Transfer(n) -> ((nil : list(operation)), transfer(n.0, n.1, n.2, s)) + | Approve(n) -> ((nil : list(operation)), approve(n.0, n.1, s)) + | GetAllowance(n) -> (getAllowance(n.0, n.1, n.2, s), s) + | GetBalance(n) -> (getBalance(n.0, n.1, s), s) + | GetTotalSupply(n) -> (getTotalSupply(n.1, s), s) + end diff --git a/tools/webide/packages/client/examples/reasonligo/arithmetic-contract.ligo b/src/test/examples/reasonligo/arithmetic-contract.ligo similarity index 100% rename from tools/webide/packages/client/examples/reasonligo/arithmetic-contract.ligo rename to src/test/examples/reasonligo/arithmetic-contract.ligo diff --git a/tools/webide/Dockerfile b/tools/webide/Dockerfile index 4dfa9963a..cf259c68c 100644 --- a/tools/webide/Dockerfile +++ b/tools/webide/Dockerfile @@ -1,16 +1,20 @@ FROM node:12-alpine as builder +ARG EXAMPLES_DIR_SRC +ARG EXAMPLES_DIR_DEST=packages/client/examples + WORKDIR /app COPY package.json package.json COPY yarn.lock yarn.lock +COPY tsconfig.json tsconfig.json COPY packages/client packages/client COPY packages/server packages/server +COPY $EXAMPLES_DIR_SRC $EXAMPLES_DIR_DEST + +ENV EXAMPLES_DIR=/app/$EXAMPLES_DIR_DEST RUN yarn install - -COPY tsconfig.json tsconfig.json - RUN yarn workspaces run build FROM node:12-buster diff --git a/tools/webide/packages/client/package-examples.js b/tools/webide/packages/client/package-examples.js index 848721660..04146b7f4 100644 --- a/tools/webide/packages/client/package-examples.js +++ b/tools/webide/packages/client/package-examples.js @@ -98,20 +98,27 @@ async function main() { throw error; }); - const EXAMPLES_DEST_DIR = join(process.cwd(), 'build', 'static', 'examples'); - const EXAMPLES_DIR = join(process.cwd(), 'examples'); - const EXAMPLES_GLOB = '**/*.ligo'; - const EXAMPLES_LIST_FILE = 'list'; + const EXAMPLES_DIR = process.env['EXAMPLES_DIR'] || join(process.cwd(), '../../../../src/test/examples'); + // const EXAMPLES_GLOB = '**/*.ligo'; + // const files = await findFiles(EXAMPLES_GLOB, EXAMPLES_DIR); + + const CURATED_EXAMPLES = [ + 'cameligo/arithmetic-contract.ligo', + 'pascaligo/arithmetic-contract.ligo', + 'reasonligo/arithmetic-contract.ligo' + ]; + + const EXAMPLES_DEST_DIR = join(process.cwd(), 'build', 'static', 'examples'); fs.mkdirSync(EXAMPLES_DEST_DIR, { recursive: true }); - const files = await findFiles(EXAMPLES_GLOB, EXAMPLES_DIR); const examples = await processExamples( EXAMPLES_DIR, - files, + CURATED_EXAMPLES, EXAMPLES_DEST_DIR ); + const EXAMPLES_LIST_FILE = 'list'; await writeFile(join(EXAMPLES_DEST_DIR, EXAMPLES_LIST_FILE), examples); } diff --git a/tools/webide/packages/client/src/components/examples.tsx b/tools/webide/packages/client/src/components/examples.tsx index cecd2a4ee..9662b6618 100644 --- a/tools/webide/packages/client/src/components/examples.tsx +++ b/tools/webide/packages/client/src/components/examples.tsx @@ -7,34 +7,18 @@ import { ChangeDirtyAction, EditorState } from '../redux/editor'; import { ChangeSelectedAction, ExamplesState } from '../redux/examples'; import { getExample } from '../services/api'; -const bgColor = 'transparent'; -const borderSize = '5px'; -const verticalPadding = '0.6em'; - const Container = styled.div` flex: 0.5; display: flex; flex-direction: column; + min-width: 0; `; -const MenuItem = styled.div<{ selected?: boolean }>` - padding: ${verticalPadding} 0 ${verticalPadding} 1em; - height: 1em; +const Header = styled.div` + min-height: 2.5em; display: flex; align-items: center; - cursor: pointer; - background-color: ${props => - props.selected ? 'var(--blue_trans1)' : bgColor}; - border-left: ${`${borderSize} solid ${bgColor}`}; - border-left-color: ${props => (props.selected ? 'var(--blue)' : bgColor)}; - - :hover { - background-color: ${props => - props.selected ? 'var(--blue_trans1)' : 'var(--blue_trans2)'}; - border-left: ${`${borderSize} solid ${bgColor}`}; - border-left-color: ${props => - props.selected ? 'var(--blue)' : 'transparent'}; - } + font-weight: 600; `; const MenuContainer = styled.div` @@ -42,15 +26,22 @@ const MenuContainer = styled.div` flex-direction: column; overflow-y: auto; height: var(--content_height); - box-sizing: border-box; + font-size: 0.8em; `; -const Header = styled.div` - min-height: 2.5em; - padding: 0 10px; - display: flex; - align-items: center; - font-weight: 600; +const MenuItem = styled.span` + height: 1em; + padding: 0.6em; + cursor: pointer; + background-color: transparent; + + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + :hover { + background-color: var(--blue_trans2); + } `; export const Examples = () => { From ac374ed2ba0f5ec5db3be86d7b72dc426c7a788f Mon Sep 17 00:00:00 2001 From: Tom Jack Date: Tue, 3 Mar 2020 23:47:10 -0600 Subject: [PATCH 11/12] Remove debug printfs --- src/passes/4-typer-old/typer.ml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/passes/4-typer-old/typer.ml b/src/passes/4-typer-old/typer.ml index 1b220754f..2e13a76ab 100644 --- a/src/passes/4-typer-old/typer.ml +++ b/src/passes/4-typer-old/typer.ml @@ -698,21 +698,16 @@ and type_expression' : environment -> ?tv_opt:O.type_expression -> I.expression location = _ }) as _lambda ; init_record ; ]} -> - Format.printf "typing foldwhile \n %!"; let%bind v_initr = type_expression' e init_record in let tv_out = get_type_expression v_initr in let input_type = tv_out in let e' = Environment.add_ez_binder lname input_type e in - Format.printf "typing foldwhile %a\n %a\n %!" Ast_typed.PP.type_expression tv_out I.PP.expression result; let%bind body = type_expression' e' result in - Format.printf "typing foldwhile %a\n %!" O.PP.expression body; let output_type = body.type_expression in let lambda' = make_a_e (E_lambda {binder = lname ; result=body}) (t_function input_type output_type ()) e' in let lst' = [lambda';v_initr] in let tv_lst = List.map get_type_expression lst' in - Format.printf "Typing constant : %a \n%!" (Ast_typed.PP.list_sep_d Ast_typed.PP.type_expression) tv_lst; let%bind (opname',tv) = type_constant opname tv_lst tv_opt in - Format.printf "Typed constant : %a \n%!" O.PP.type_expression tv; return (E_constant {cons_name=opname';arguments=lst'}) tv | E_constant {cons_name=C_CREATE_CONTRACT as cons_name;arguments} -> let%bind lst' = bind_list @@ List.map (type_expression' e) arguments in From 8f60accc24e3cebc45a7ea871d0ed82fa3f2f6b5 Mon Sep 17 00:00:00 2001 From: Sander Date: Wed, 4 Mar 2020 13:19:00 +0000 Subject: [PATCH 12/12] - Improve darkmode support - Reenable code block tabs - Reeneble code blocks highlighting --- gitlab-pages/Dockerfile | 2 +- gitlab-pages/docker-compose.yml | 15 +- .../docs/advanced/entrypoints-contracts.md | 100 ++++-- gitlab-pages/docs/advanced/first-contract.md | 54 ++- gitlab-pages/docs/advanced/include.md | 34 +- .../docs/advanced/timestamps-addresses.md | 118 +++++-- gitlab-pages/docs/api/cheat-sheet.md | 20 +- gitlab-pages/docs/intro/what-and-why.md | 19 +- .../docs/language-basics/boolean-if-else.md | 92 ++++-- .../docs/language-basics/functions.md | 47 ++- gitlab-pages/docs/language-basics/loops.md | 19 +- .../docs/language-basics/maps-records.md | 307 ++++++++++++------ .../docs/language-basics/math-numbers-tez.md | 115 +++++-- .../docs/language-basics/sets-lists-tuples.md | 199 ++++++++---- gitlab-pages/docs/language-basics/strings.md | 73 +++-- .../docs/language-basics/tezos-specific.md | 79 +++-- gitlab-pages/docs/language-basics/types.md | 64 ++-- .../unit-option-pattern-matching.md | 81 +++-- .../variables-and-constants.md | 34 +- gitlab-pages/docs/reference/big_map.md | 103 ++++-- gitlab-pages/docs/reference/bytes.md | 59 ++-- gitlab-pages/docs/reference/crypto.md | 76 +++-- gitlab-pages/docs/reference/current.md | 179 ++++++---- gitlab-pages/docs/reference/list.md | 90 +++-- gitlab-pages/docs/reference/map.md | 162 ++++++--- gitlab-pages/docs/reference/set.md | 122 +++++-- gitlab-pages/docs/reference/string.md | 53 ++- .../get-started/tezos-taco-shop-payout.md | 6 +- .../tezos-taco-shop-smart-contract.md | 25 +- gitlab-pages/website/.gitignore | 20 ++ ...> 2019-06-13-public-launch-of-ligo.md.old} | 0 ...pdate.md => 2019-07-11-ligo-update.md.old} | 0 gitlab-pages/website/core/CodeExamples.js | 131 +++++--- gitlab-pages/website/core/Footer.js | 2 + gitlab-pages/website/docusaurus.config.js | 226 +++++++++++++ gitlab-pages/website/package.json | 29 +- gitlab-pages/website/pages/en/index.js | 100 ------ gitlab-pages/website/pages/en/versions.js | 113 ------- gitlab-pages/website/siteConfig.js | 158 --------- .../en/404.js => src/pages/404.js.fixme} | 0 .../{pages/en => src/pages}/contact.js | 46 ++- gitlab-pages/website/src/pages/index.js | 184 +++++++++++ .../website/src/pages/versions.js.fixme | 113 +++++++ .../website/src/theme/CodeBlock/index.js | 194 +++++++++++ .../src/theme/CodeBlock/styles.module.css | 45 +++ .../website/src/theme/DocPage/index.js | 77 +++++ .../src/theme/DocPage/styles.module.css | 28 ++ .../website/src/theme/DocSidebar/index.js | 229 +++++++++++++ .../src/theme/DocSidebar/styles.module.css | 90 +++++ .../website/src/theme/Navbar/index.js | 201 ++++++++++++ .../src/theme/Navbar/styles.module.css | 26 ++ .../website/src/theme/Syntax/SyntaxContext.js | 6 + .../website/src/theme/Syntax/SyntaxSwitch.js | 15 + .../website/src/theme/Syntax/index.js | 18 + .../src/theme/Syntax/styles.module.css | 37 +++ gitlab-pages/website/static/css/custom.css | 107 ++++-- .../website/static/fonts/Inter-Black.woff | Bin 0 -> 140036 bytes .../website/static/fonts/Inter-Black.woff2 | Bin 0 -> 104524 bytes .../static/fonts/Inter-BlackItalic.woff | Bin 0 -> 145924 bytes .../static/fonts/Inter-BlackItalic.woff2 | Bin 0 -> 109900 bytes .../website/static/fonts/Inter-Bold.woff | Bin 0 -> 143708 bytes .../website/static/fonts/Inter-Bold.woff2 | Bin 0 -> 107400 bytes .../static/fonts/Inter-BoldItalic.woff | Bin 0 -> 149420 bytes .../static/fonts/Inter-BoldItalic.woff2 | Bin 0 -> 112580 bytes .../website/static/fonts/Inter-ExtraBold.woff | Bin 0 -> 143552 bytes .../static/fonts/Inter-ExtraBold.woff2 | Bin 0 -> 107552 bytes .../static/fonts/Inter-ExtraBoldItalic.woff | Bin 0 -> 149196 bytes .../static/fonts/Inter-ExtraBoldItalic.woff2 | Bin 0 -> 112876 bytes .../static/fonts/Inter-ExtraLight.woff | Bin 0 -> 141864 bytes .../static/fonts/Inter-ExtraLight.woff2 | Bin 0 -> 105960 bytes .../static/fonts/Inter-ExtraLightItalic.woff | Bin 0 -> 148688 bytes .../static/fonts/Inter-ExtraLightItalic.woff2 | Bin 0 -> 112056 bytes .../website/static/fonts/Inter-Italic.woff | Bin 0 -> 142744 bytes .../website/static/fonts/Inter-Italic.woff2 | Bin 0 -> 107508 bytes .../website/static/fonts/Inter-Light.woff | Bin 0 -> 141528 bytes .../website/static/fonts/Inter-Light.woff2 | Bin 0 -> 105640 bytes .../static/fonts/Inter-LightItalic.woff | Bin 0 -> 148436 bytes .../static/fonts/Inter-LightItalic.woff2 | Bin 0 -> 111968 bytes .../website/static/fonts/Inter-Medium.woff | Bin 0 -> 142836 bytes .../website/static/fonts/Inter-Medium.woff2 | Bin 0 -> 106720 bytes .../static/fonts/Inter-MediumItalic.woff | Bin 0 -> 149184 bytes .../static/fonts/Inter-MediumItalic.woff2 | Bin 0 -> 112504 bytes .../website/static/fonts/Inter-Regular.woff | Bin 0 -> 134652 bytes .../website/static/fonts/Inter-Regular.woff2 | Bin 0 -> 100124 bytes .../website/static/fonts/Inter-SemiBold.woff | Bin 0 -> 143248 bytes .../website/static/fonts/Inter-SemiBold.woff2 | Bin 0 -> 107232 bytes .../static/fonts/Inter-SemiBoldItalic.woff | Bin 0 -> 149276 bytes .../static/fonts/Inter-SemiBoldItalic.woff2 | Bin 0 -> 112552 bytes .../website/static/fonts/Inter-Thin.woff | Bin 0 -> 136952 bytes .../website/static/fonts/Inter-Thin.woff2 | Bin 0 -> 101408 bytes .../static/fonts/Inter-ThinItalic.woff | Bin 0 -> 144412 bytes .../static/fonts/Inter-ThinItalic.woff2 | Bin 0 -> 107496 bytes .../static/fonts/Inter-italic.var.woff2 | Bin 0 -> 240688 bytes .../static/fonts/Inter-roman.var.woff2 | Bin 0 -> 226368 bytes gitlab-pages/website/static/fonts/inter.css | 16 + gitlab-pages/website/static/img/circle.svg | 27 ++ .../website/static/img/logo-night.svg | 31 ++ gitlab-pages/website/static/img/logo-old.svg | 52 +++ gitlab-pages/website/static/img/logo.svg | 90 +++-- .../version-next/api-cli-commands.md | 48 --- .../contributors/big-picture/back-end.md | 19 -- .../contributors/big-picture/front-end.md | 16 - .../contributors/big-picture/middle-end.md | 17 - .../contributors/big-picture/overview.md | 17 - .../contributors/big-picture/vendors.md | 22 -- .../version-next/contributors/origin.md | 11 - .../version-next/contributors/philosophy.md | 45 --- .../contributors/road-map/long-term.md | 21 -- .../contributors/road-map/short-term.md | 21 -- .../version-next-sidebars.json | 65 ---- .../website/{versions.json => versions._} | 0 111 files changed, 3482 insertions(+), 1578 deletions(-) create mode 100644 gitlab-pages/website/.gitignore rename gitlab-pages/website/blog/{2019-06-13-public-launch-of-ligo.md => 2019-06-13-public-launch-of-ligo.md.old} (100%) rename gitlab-pages/website/blog/{2019-07-11-ligo-update.md => 2019-07-11-ligo-update.md.old} (100%) create mode 100644 gitlab-pages/website/docusaurus.config.js delete mode 100644 gitlab-pages/website/pages/en/index.js delete mode 100644 gitlab-pages/website/pages/en/versions.js delete mode 100644 gitlab-pages/website/siteConfig.js rename gitlab-pages/website/{pages/en/404.js => src/pages/404.js.fixme} (100%) rename gitlab-pages/website/{pages/en => src/pages}/contact.js (73%) create mode 100644 gitlab-pages/website/src/pages/index.js create mode 100644 gitlab-pages/website/src/pages/versions.js.fixme create mode 100644 gitlab-pages/website/src/theme/CodeBlock/index.js create mode 100644 gitlab-pages/website/src/theme/CodeBlock/styles.module.css create mode 100644 gitlab-pages/website/src/theme/DocPage/index.js create mode 100644 gitlab-pages/website/src/theme/DocPage/styles.module.css create mode 100644 gitlab-pages/website/src/theme/DocSidebar/index.js create mode 100644 gitlab-pages/website/src/theme/DocSidebar/styles.module.css create mode 100644 gitlab-pages/website/src/theme/Navbar/index.js create mode 100644 gitlab-pages/website/src/theme/Navbar/styles.module.css create mode 100644 gitlab-pages/website/src/theme/Syntax/SyntaxContext.js create mode 100644 gitlab-pages/website/src/theme/Syntax/SyntaxSwitch.js create mode 100644 gitlab-pages/website/src/theme/Syntax/index.js create mode 100644 gitlab-pages/website/src/theme/Syntax/styles.module.css create mode 100644 gitlab-pages/website/static/fonts/Inter-Black.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-Black.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-BlackItalic.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-BlackItalic.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-Bold.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-Bold.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-BoldItalic.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-BoldItalic.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-ExtraBold.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-ExtraBold.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-ExtraBoldItalic.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-ExtraBoldItalic.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-ExtraLight.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-ExtraLight.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-ExtraLightItalic.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-ExtraLightItalic.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-Italic.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-Italic.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-Light.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-Light.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-LightItalic.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-LightItalic.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-Medium.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-Medium.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-MediumItalic.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-MediumItalic.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-Regular.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-Regular.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-SemiBold.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-SemiBold.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-SemiBoldItalic.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-SemiBoldItalic.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-Thin.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-Thin.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-ThinItalic.woff create mode 100644 gitlab-pages/website/static/fonts/Inter-ThinItalic.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-italic.var.woff2 create mode 100644 gitlab-pages/website/static/fonts/Inter-roman.var.woff2 create mode 100644 gitlab-pages/website/static/fonts/inter.css create mode 100644 gitlab-pages/website/static/img/circle.svg create mode 100644 gitlab-pages/website/static/img/logo-night.svg create mode 100644 gitlab-pages/website/static/img/logo-old.svg delete mode 100644 gitlab-pages/website/versioned_docs/version-next/api-cli-commands.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/contributors/big-picture/back-end.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/contributors/big-picture/front-end.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/contributors/big-picture/middle-end.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/contributors/big-picture/overview.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/contributors/big-picture/vendors.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/contributors/origin.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/contributors/philosophy.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/contributors/road-map/long-term.md delete mode 100644 gitlab-pages/website/versioned_docs/version-next/contributors/road-map/short-term.md delete mode 100644 gitlab-pages/website/versioned_sidebars/version-next-sidebars.json rename gitlab-pages/website/{versions.json => versions._} (100%) diff --git a/gitlab-pages/Dockerfile b/gitlab-pages/Dockerfile index d369844d5..93c4179f2 100644 --- a/gitlab-pages/Dockerfile +++ b/gitlab-pages/Dockerfile @@ -1,4 +1,4 @@ -FROM node:8.11.4 +FROM node:12.16 WORKDIR /app/website diff --git a/gitlab-pages/docker-compose.yml b/gitlab-pages/docker-compose.yml index 90c32ea95..af12b7af7 100644 --- a/gitlab-pages/docker-compose.yml +++ b/gitlab-pages/docker-compose.yml @@ -8,15 +8,16 @@ services: - 35729:35729 volumes: - ./docs:/app/docs - - ./website/blog:/app/website/blog + # - ./website/blog:/app/website/blog - ./website/core:/app/website/core - - ./website/i18n:/app/website/i18n - - ./website/pages:/app/website/pages + # - ./website/i18n:/app/website/i18n + - ./website/src:/app/website/src - ./website/static:/app/website/static - - ./website/versioned_sidebars:/app/website/versioned_sidebars - - ./website/versioned_docs:/app/website/versioned_docs + # - ./website/versioned_sidebars:/app/website/versioned_sidebars + # - ./website/versioned_docs:/app/website/versioned_docs - ./website/sidebars.json:/app/website/sidebars.json - - ./website/siteConfig.js:/app/website/siteConfig.js + - ./website/docusaurus.config.js:/app/website/docusaurus.config.js - ./website/versions.json:/app/website/versions.json - - ./website/node_modules/reason-highlightjs:/app/website/node_modules/reason-highlightjs + # - ./website/core/AlgoliaSearch.js:/app/website/core/AlgoliaSearch.js + working_dir: /app/website diff --git a/gitlab-pages/docs/advanced/entrypoints-contracts.md b/gitlab-pages/docs/advanced/entrypoints-contracts.md index 429962a33..499d07c58 100644 --- a/gitlab-pages/docs/advanced/entrypoints-contracts.md +++ b/gitlab-pages/docs/advanced/entrypoints-contracts.md @@ -3,6 +3,8 @@ id: entrypoints-contracts title: Main function and Entrypoints --- +import Syntax from '@theme/Syntax'; + ## Access Functions A LIGO contract is made of a series of constant and function @@ -22,25 +24,33 @@ type of a main function is as follows, assuming that the type `storage` has been defined elsewhere. (Note that you can use any type with any name for the storage.) - - + + + ```pascaligo skip type storage is ... // Any name, any type type return is list (operation) * storage ``` - + + + ```cameligo skip type storage = ... // Any name, any type type return = operation list * storage ``` - + + + ```reasonligo skip type storage = ...; // Any name, any type type return = (list (operation), storage); ``` - + + + + The contract storage can only be modified by activating a main function: given the state of the storage *on-chain*, a main function @@ -50,9 +60,9 @@ contract's parameter. Here is an example where the storage is a single natural number that is updated by the parameter. - - + + ```pascaligo group=a type parameter is nat @@ -62,8 +72,9 @@ type return is list (operation) * storage function save (const action : parameter; const store : storage) : return is ((nil : list (operation)), store) ``` + + - ```cameligo group=a type parameter = nat type storage = nat @@ -73,7 +84,9 @@ let save (action, store: parameter * storage) : return = (([] : operation list), store) ``` - + + + ```reasonligo group=a type parameter = nat; type storage = nat; @@ -82,7 +95,9 @@ type return = (list (operation), storage); let main = ((action, store): (parameter, storage)) : return => (([] : list (operation)), store); ``` - + + + ## Entrypoints @@ -105,9 +120,10 @@ In the following example, the storage contains a counter of type `nat` and a name of type `string`. Depending on the parameter of the contract, either the counter or the name is updated. - - + + + ```pascaligo group=b type parameter is Action_A of nat @@ -133,7 +149,9 @@ function main (const action : parameter; const store : storage): return is end ``` - + + + ```cameligo group=b type parameter = Action_A of nat @@ -158,7 +176,9 @@ let main (action, store: parameter * storage) : return = | Action_B s -> entry_B (s, store) ``` - + + + ```reasonligo group=b type parameter = | Action_A (nat) @@ -183,7 +203,9 @@ let main = ((action, store): (parameter, storage)) : return => | Action_B (s) => entry_B ((s, store)) }; ``` - + + + ## Tezos-specific Built-ins @@ -198,8 +220,9 @@ This example shows how `Tezos.amount` and `failwith` can be used to decline any transaction that sends more tez than `0tez`, that is, no incoming tokens are accepted. - - + + + ```pascaligo group=c type parameter is unit type storage is unit @@ -213,7 +236,10 @@ function deny (const action : parameter; const store : storage) : return is > Note that `amount` is *deprecated*. - + + + + ```cameligo group=c type parameter = unit type storage = unit @@ -227,7 +253,9 @@ let deny (action, store : parameter * storage) : return = > Note that `amount` is *deprecated*. - + + + ```reasonligo group=c type parameter = unit; type storage = unit; @@ -242,15 +270,17 @@ let deny = ((action, store): (parameter, storage)) : return => { > Note that `amount` is *deprecated*. - + + ### Access Control This example shows how `Tezos.source` can be used to deny access to an entrypoint. - - + + + ```pascaligo group=c const owner : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address); @@ -261,7 +291,9 @@ function main (const action : parameter; const store : storage) : return is > Note that `source` is *deprecated*. - + + + ```cameligo group=c let owner : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address) @@ -272,7 +304,9 @@ let main (action, store: parameter * storage) : return = > Note that `source` is *deprecated*. - + + + ```reasonligo group=c let owner : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx": address); @@ -284,7 +318,8 @@ let main = ((action, store) : (parameter, storage)) : storage => { > Note that `source` is *deprecated*. - + + ### Inter-Contract Invocations @@ -310,9 +345,10 @@ of type `parameter`, and we have a `proxy.ligo` contract that accepts the same parameter type, and forwards the call to the deployed counter contract. - - + + + ```pascaligo skip // counter.ligo type parameter is @@ -354,7 +390,9 @@ function proxy (const action : parameter; const store : storage): return is } with (ops, store) ``` - + + + ```cameligo skip // counter.mligo @@ -395,7 +433,8 @@ let proxy (action, store : parameter * storage) : return = > Note that `Operation.get_contract` and `Operation.transaction` are > *deprecated*. - + + ```reasonligo skip // counter.religo @@ -438,4 +477,5 @@ let proxy = ((action, store): (parameter, storage)) : return => { > Note that `Operation.get_contract` and `Operation.transaction` are > *deprecated*. - + + diff --git a/gitlab-pages/docs/advanced/first-contract.md b/gitlab-pages/docs/advanced/first-contract.md index eb63a25c4..a22abd5a2 100644 --- a/gitlab-pages/docs/advanced/first-contract.md +++ b/gitlab-pages/docs/advanced/first-contract.md @@ -3,6 +3,8 @@ id: first-contract title: First contract --- +import Syntax from '@theme/Syntax'; + So far so good, we have learned enough of the LIGO language, we are confident enough to write out first smart contract. @@ -23,16 +25,15 @@ following: Here is a full example: - - -``` + +```shell ligo dry-run src/basic.ligo main Unit Unit // Outputs: // tuple[ list[] // Unit // ] ``` - + Output of the `dry-run` is the return value of our main function, we can see the operations emitted (in our case an empty list, and the new @@ -45,9 +46,9 @@ will accept an `action` variant in order to re-route our single `main` function to two entrypoints for `add` (addition) and `sub` (subtraction). - - -``` + + +```pascaligo type parameter is Increment of int | Decrement of int @@ -67,7 +68,9 @@ function main (const action : parameter; const store : storage) : return is end) ``` - + + + ```cameligo type parameter = Increment of int @@ -87,7 +90,10 @@ let main (action, store : parameter * storage) : operation list * storage = | Decrement n -> sub (n, store))) ``` - + + + + ```reasonligo type parameter = Increment (int) @@ -109,21 +115,18 @@ let main = ((action, store) : (parameter, storage)) : return => })); ``` - + To dry-run the counter contract, we will provide the `main` function with a variant parameter of value `Increment (5)` and an initial storage value of `5`. - - -``` +```shell ligo dry-run src/counter.ligo main "Increment(5)" 5 // tuple[ list[] // 10 // ] ``` - Our contract's storage has been successfuly incremented to `10`. @@ -134,19 +137,14 @@ In order to deploy the counter contract to a real Tezos network, we'd have to compile it first, this can be done with the help of the `compile-contract` CLI command: - - -``` +```shell ligo compile-contract src/counter.ligo main ``` - - Command above will output the following Michelson code: - - -``` + +```michelson { parameter (or (int %decrement) (int %increment)) ; storage int ; code { DUP ; @@ -175,20 +173,16 @@ Command above will output the following Michelson code: PAIR ; DIP { DROP 2 } } } ``` - However in order to originate a Michelson contract on Tezos, we also need to provide the initial storage value, we can use `compile-storage` to compile the LIGO representation of the storage to Michelson. - - -``` +```shell ligo compile-storage src/counter.ligo main 5 // Outputs: 5 ``` - In our case the LIGO storage value maps 1:1 to its Michelson representation, however this will not be the case once the parameter @@ -200,13 +194,11 @@ Same rules apply for parameters, as apply for translating LIGO storage values to Michelson. We will need to use `compile-parameter` to compile our `action` variant into Michelson, here's how: - - -``` +```shell ligo compile-parameter src/counter.ligo main 'Increment(5)' // Outputs: (Right 5) ``` - + Now we can use `(Right 5)` which is a Michelson value, to invoke our contract - e.g., via `tezos-client` diff --git a/gitlab-pages/docs/advanced/include.md b/gitlab-pages/docs/advanced/include.md index 21094102e..6b82a89df 100644 --- a/gitlab-pages/docs/advanced/include.md +++ b/gitlab-pages/docs/advanced/include.md @@ -3,6 +3,8 @@ id: include title: Including Other Contracts --- +import Syntax from '@theme/Syntax'; + Let us say that we have a contract that is getting a too large. If it has a modular structure, you might find it useful to use the `#include` statement to split the contract up over multiple files. @@ -10,9 +12,10 @@ has a modular structure, you might find it useful to use the You take the code that you want to include and put it in a separate file, for example `included.ligo`: - - + + + ```pascaligo // Demonstrate PascaLIGO inclusion statements, see includer.ligo @@ -20,46 +23,57 @@ file, for example `included.ligo`: const foo : int = 144 ``` - + + + ```cameligo // Demonstrate CameLIGO inclusion statements, see includer.mligo let foo : int = 144 ``` - + + + ```reasonligo // Demonstrate ReasonLIGO inclusion statements, see includer.religo let foo : int = 144; ``` - + + And then you can include this code using the `#include` statement like so: - - + + + ```pascaligo #include "included.ligo" const bar : int = foo ``` - + + + ```cameligo #include "included.mligo" let bar : int = foo ``` - + + + ```reasonligo #include "included.religo" let bar : int = foo; ``` - + + diff --git a/gitlab-pages/docs/advanced/timestamps-addresses.md b/gitlab-pages/docs/advanced/timestamps-addresses.md index b3a4d2391..30f0b55b0 100644 --- a/gitlab-pages/docs/advanced/timestamps-addresses.md +++ b/gitlab-pages/docs/advanced/timestamps-addresses.md @@ -3,6 +3,8 @@ id: timestamps-addresses title: Timestamps, Addresses --- +import Syntax from '@theme/Syntax'; + ## Timestamps LIGO features timestamps, as Michelson does, while bakers baking the @@ -15,29 +17,35 @@ You can obtain the current time using the built-in syntax specific expression, please be aware that it is up to the baker to set the current timestamp value. - - + + + ```pascaligo group=a const today : timestamp = Tezos.now ``` > Note that `now` is *deprecated*. - + + + ```cameligo group=a let today : timestamp = Tezos.now ``` > Note that `Current.time` is *deprecated*. - + + + ```reasonligo group=a let today : timestamp = Tezos.now; ``` > Note that `Current.time` is *deprecated*. - + + > When running code, the LIGO CLI option `--predecessor-timestamp` > allows you to control what `Tezos.now` returns. @@ -49,8 +57,9 @@ constraints on your smart contracts. Consider the following scenarios. #### In 24 hours - - + + + ```pascaligo group=b const today : timestamp = Tezos.now const one_day : int = 86400 @@ -61,7 +70,9 @@ const one_day_later : timestamp = some_date + one_day > Note that `now` is *deprecated*. - + + + ```cameligo group=b let today : timestamp = Tezos.now let one_day : int = 86400 @@ -72,7 +83,9 @@ let one_day_later : timestamp = some_date + one_day > Note that `Current.time` is *deprecated*. - + + + ```reasonligo group=b let today : timestamp = Tezos.now; let one_day : int = 86400; @@ -83,12 +96,14 @@ let one_day_later : timestamp = some_date + one_day; > Note that `Current.time` is *deprecated*. - + + #### 24 hours Ago - - + + + ```pascaligo group=c const today : timestamp = Tezos.now const one_day : int = 86400 @@ -97,7 +112,9 @@ const in_24_hrs : timestamp = today - one_day > Note that `now` is *deprecated*. - + + + ```cameligo group=c let today : timestamp = Tezos.now let one_day : int = 86400 @@ -106,7 +123,9 @@ let in_24_hrs : timestamp = today - one_day > Note that `Current.time` is *deprecated*. - + + + ```reasonligo group=c let today : timestamp = Tezos.now; let one_day : int = 86400; @@ -115,38 +134,43 @@ let in_24_hrs : timestamp = today - one_day; > Note that `Current.time` is *deprecated*. + - ### Comparing Timestamps You can compare timestamps using the same comparison operators applying to numbers. - - + + + ```pascaligo group=c const not_tommorow : bool = (Tezos.now = in_24_hrs) ``` > Note that `now` is *deprecated*. - + + + ```cameligo group=c let not_tomorrow : bool = (Tezos.now = in_24_hrs) ``` > Note that `Current.time` is *deprecated*. - + + + ```reasonligo group=c let not_tomorrow : bool = (Tezos.now == in_24_hrs); ``` > Note that `Current.time` is *deprecated*. + - ## Addresses @@ -155,26 +179,32 @@ KT1, ...). Currently, addresses are created by casting a string to the `address` type. Beware of failures if the address is invalid. Consider the following examples. - - + + + ```pascaligo group=d const my_account : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) ``` - + + + ```cameligo group=d let my_account : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) ``` - + + + ```reasonligo group=d let my_account : address = ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address); ``` - + + ## Signatures @@ -184,26 +214,35 @@ failure if the signature is invalid. Here is how you can define a signature: - - + + + ```pascaligo group=e const my_sig : signature = ("edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" : signature) ``` - + + + + ```cameligo group=e let my_sig : signature = ("edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" : signature) ``` - + + + + ```reasonligo group=e let my_sig : signature = ("edsigthTzJ8X7MPmNeEwybRAvdxS1pupqcM5Mk4uCuyZAe7uEk68YpuGDeViW8wSXMrCi5CwoNgqs8V2w8ayB5dMJzrYCHhD8C7" : signature); ``` - + + + ## Keys @@ -213,20 +252,29 @@ failure if the key is invalid. Here is how you can define a key. - - + + + ```pascaligo group=f const my_key : key = ("edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" : key) ``` - + + + + ```cameligo group=f let my_key : key = ("edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" : key) ``` - + + + + ```reasonligo group=f let my_key : key = ("edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav" : key); ``` - + + + diff --git a/gitlab-pages/docs/api/cheat-sheet.md b/gitlab-pages/docs/api/cheat-sheet.md index 9e7020177..412ba5bd5 100644 --- a/gitlab-pages/docs/api/cheat-sheet.md +++ b/gitlab-pages/docs/api/cheat-sheet.md @@ -2,14 +2,17 @@ id: cheat-sheet title: Cheat Sheet --- -
+ +import Syntax from '@theme/Syntax'; + +
- - + + |Primitive |Example| |--- |---| @@ -33,7 +36,7 @@ Note that this table is not compiled before production and currently needs to be | 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

*⚠️ This feature is not supported at the top-level scope, you can use it e.g. within functions. Works for Records and Maps as well.*| ```age := 18;```, ```p.age := 21``` | +|Assignment on an existing variable
*⚠️ This feature is not supported at the top-level scope, you can use it e.g. within functions. Works for Records and Maps as well.*| ```age := 18;```, ```p.age := 21``` | |Type Annotations| ```("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address)```| |Variants|
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
| @@ -43,7 +46,8 @@ Note that this table is not compiled before production and currently needs to be |Transactions|
const payment : operation = transaction(unit, amount, receiver);
| |Exception/Failure|`failwith ("Your descriptive error message for the user goes here.")`| - +
+ |Primitive |Example| |--- |---| @@ -75,7 +79,8 @@ Note that this table is not compiled before production and currently needs to be |Transactions|
let payment : operation = 
Tezos.transaction unit amount receiver
| |Exception/Failure|`failwith ("Your descriptive error message for the user goes here.")`| - +
+ |Primitive |Example| |--- |---| @@ -107,7 +112,8 @@ Note that this table is not compiled before production and currently needs to be |Transactions|
let payment : operation = 
Tezos.transaction (unit, amount, receiver);
| |Exception/Failure|`failwith ("Your descriptive error message for the user goes here.");`| +
+ -
diff --git a/gitlab-pages/docs/intro/what-and-why.md b/gitlab-pages/docs/intro/what-and-why.md index f195b97a7..4a68141da 100644 --- a/gitlab-pages/docs/intro/what-and-why.md +++ b/gitlab-pages/docs/intro/what-and-why.md @@ -3,6 +3,8 @@ id: what-and-why title: Michelson and LIGO --- +import Syntax from '@theme/Syntax'; + Before we get into what LIGO is and why LIGO needs to exist, let us take a look at what options the Tezos blockchain offers us out of the box. If you want to implement smart contracts natively on Tezos, you @@ -161,8 +163,9 @@ Let us decline the same LIGO contract in the three flavours above. Do not worry if it is a little confusing at first; we will explain all the syntax in the upcoming sections of the documentation. - - + + + ```pascaligo group=a type storage is int @@ -182,7 +185,9 @@ function main (const action : parameter; const store : storage) : return is end) ``` - + + + ```cameligo group=a type storage = int @@ -201,7 +206,9 @@ let main (action, store : parameter * storage) : return = | Reset -> 0) ``` - + + + ```reasonligo group=a type storage = int; @@ -220,7 +227,9 @@ let main = ((action, store): (parameter, storage)) : return => { | Reset => 0})); }; ``` - + + + - + + + ```pascaligo group=a const a : bool = True // Also: true const b : bool = False // Also: false ``` - + + + + ```cameligo group=a let a : bool = true let b : bool = false ``` - + + + + ```reasonligo group=a let a : bool = true; let b : bool = false; ``` - + + + ## Comparing Values @@ -39,31 +50,41 @@ function. ### Comparing Strings - - + + + ```pascaligo group=b const a : string = "Alice" const b : string = "Alice" const c : bool = (a = b) // True ``` - + + + + ```cameligo group=b let a : string = "Alice" let b : string = "Alice" let c : bool = (a = b) // true ``` - + + + + ```reasonligo group=b let a : string = "Alice"; let b : string = "Alice"; let c : bool = (a == b); // true ``` - + + + ### Comparing numbers - - + + + ```pascaligo group=c const a : int = 5 const b : int = 4 @@ -74,7 +95,10 @@ const f : bool = (a <= b) const g : bool = (a >= b) const h : bool = (a =/= b) ``` - + + + + ```cameligo group=c let a : int = 5 let b : int = 4 @@ -86,7 +110,9 @@ let g : bool = (a >= b) let h : bool = (a <> b) ``` - + + + ```reasonligo group=c let a : int = 5; let b : int = 4; @@ -97,33 +123,43 @@ let f : bool = (a <= b); let g : bool = (a >= b); let h : bool = (a != b); ``` - + + + ### Comparing tez > 💡 Comparing `tez` values is especially useful when dealing with an > amount sent in a transaction. - - + + + ```pascaligo group=d const a : tez = 5mutez const b : tez = 10mutez const c : bool = (a = b) // False ``` - + + + + ```cameligo group=d let a : tez = 5mutez let b : tez = 10mutez let c : bool = (a = b) // false ``` - + + + ```reasonligo group=d let a : tez = 5mutez; let b : tez = 10mutez; let c : bool = (a == b); // false ``` - + + + ## Conditionals @@ -131,8 +167,9 @@ let c : bool = (a == b); // false Conditional logic enables forking the control flow depending on the state. - - + + + ```pascaligo group=e type magnitude is Small | Large // See variant types. @@ -171,7 +208,9 @@ if x < y then { else skip; ``` - + + + ```cameligo group=e type magnitude = Small | Large // See variant types. @@ -192,8 +231,9 @@ gitlab-pages/docs/language-basics/boolean-if-else/cond.mligo compare 21n' > *dangling else* problem is parsed by associating any `else` to the > closest previous `then`. + + - ```reasonligo group=e type magnitude = Small | Large; // See variant types. @@ -208,4 +248,6 @@ ligo run-function gitlab-pages/docs/language-basics/boolean-if-else/cond.religo compare 21n' # Outputs: Large ``` - + + + diff --git a/gitlab-pages/docs/language-basics/functions.md b/gitlab-pages/docs/language-basics/functions.md index b4c81beb1..c0fc83153 100644 --- a/gitlab-pages/docs/language-basics/functions.md +++ b/gitlab-pages/docs/language-basics/functions.md @@ -3,6 +3,8 @@ id: functions title: Functions --- +import Syntax from '@theme/Syntax'; + LIGO functions are the basic building block of contracts. For example, entrypoints are functions and each smart contract needs a main function that dispatches control to the entrypoints (it is not already @@ -16,8 +18,8 @@ mutations inside the functions will be. ## Declaring Functions - - + + There are two ways in PascaLIGO to define functions: with or without a *block*. @@ -91,7 +93,8 @@ ligo run-function gitlab-pages/docs/language-basics/src/functions/blockless.ligo # Outputs: 3 ``` - + + Functions in CameLIGO are defined using the `let` keyword, like other values. The difference is that a succession of parameters is provided @@ -145,7 +148,8 @@ ligo run-function gitlab-pages/docs/language-basics/src/functions/curry.mligo in The function body is a single expression, whose value is returned. - + + Functions in ReasonLIGO are defined using the `let` keyword, like other values. The difference is that a tuple of parameters is provided @@ -176,7 +180,8 @@ let myFun = ((x, y) : (int, int)) : int => { }; ``` - + + ## Anonymous functions (a.k.a. lambdas) @@ -186,8 +191,9 @@ a key in a record or a map. Here is how to define an anonymous function: - - + + + ```pascaligo group=c function increment (const b : int) : int is (function (const a : int) : int is a + 1) (b) @@ -201,7 +207,9 @@ ligo evaluate-value gitlab-pages/docs/language-basics/src/functions/anon.ligo a # Outputs: 2 ``` - + + + ```cameligo group=c let increment (b : int) : int = (fun (a : int) -> a + 1) b let a : int = increment 1 // a = 2 @@ -214,7 +222,9 @@ ligo evaluate-value gitlab-pages/docs/language-basics/src/functions/anon.mligo a # Outputs: 2 ``` - + + + ```reasonligo group=c let increment = (b : int) : int => ((a : int) : int => a + 1) (b); let a : int = increment (1); // a == 2 @@ -227,15 +237,17 @@ ligo evaluate-value gitlab-pages/docs/language-basics/src/functions/anon.religo # Outputs: 2 ``` - + + If the example above seems contrived, here is a more common design pattern for lambdas: to be used as parameters to functions. Consider the use case of having a list of integers and mapping the increment function to all its elements. - - + + + ```pascaligo group=c function incr_map (const l : list (int)) : list (int) is List.map (function (const i : int) : int is i + 1, l) @@ -253,7 +265,9 @@ gitlab-pages/docs/language-basics/src/functions/incr_map.ligo incr_map # Outputs: [ 2 ; 3 ; 4 ] ``` - + + + ```cameligo group=c let incr_map (l : int list) : int list = List.map (fun (i : int) -> i + 1) l @@ -267,7 +281,9 @@ gitlab-pages/docs/language-basics/src/functions/incr_map.mligo incr_map # Outputs: [ 2 ; 3 ; 4 ] ``` - + + + ```reasonligo group=c let incr_map = (l : list (int)) : list (int) => List.map ((i : int) => i + 1, l); @@ -281,4 +297,5 @@ gitlab-pages/docs/language-basics/src/functions/incr_map.religo incr_map # Outputs: [ 2 ; 3 ; 4 ] ``` - + + diff --git a/gitlab-pages/docs/language-basics/loops.md b/gitlab-pages/docs/language-basics/loops.md index ffe27c17e..8f81c93ae 100644 --- a/gitlab-pages/docs/language-basics/loops.md +++ b/gitlab-pages/docs/language-basics/loops.md @@ -3,11 +3,13 @@ id: loops title: Loops --- +import Syntax from '@theme/Syntax'; + ## General Iteration - - + + General iteration in PascaLIGO takes the shape of general loops, which should be familiar to programmers of imperative languages as "while @@ -47,7 +49,8 @@ gitlab-pages/docs/language-basics/src/loops/gcd.ligo gcd '(2n*2n*3n*11n, 2n*2n*2 # Outputs: +12 ``` - + + CameLIGO is a functional language where user-defined values are constant, therefore it makes no sense in CameLIGO to feature loops, @@ -103,7 +106,8 @@ gitlab-pages/docs/language-basics/src/loops/gcd.mligo gcd (2n*2n*3n*11n, 2n*2n*2 # Outputs: +12 ``` - + + ReasonLIGO is a functional language where user-defined values are constant, therefore it makes no sense in ReasonLIGO to feature loops, @@ -153,7 +157,8 @@ let gcd = ((x,y) : (nat, nat)) : nat => { > Note that `stop` and `continue` (now `Loop.resume`) are > *deprecated*. - + + ## Bounded Loops @@ -185,8 +190,8 @@ gitlab-pages/docs/language-basics/src/loops/sum.ligo sum 7n PascaLIGO "for" loops can also iterate through the contents of a collection, that is, a list, a set or a map. This is done with a loop -of the form `for in -`, where `` is any of the following keywords: +of the form `for in `, +where `` is any of the following keywords: `list`, `set` or `map`. Here is an example where the integers in a list are summed up. diff --git a/gitlab-pages/docs/language-basics/maps-records.md b/gitlab-pages/docs/language-basics/maps-records.md index c9837fb26..b4d7db1c1 100644 --- a/gitlab-pages/docs/language-basics/maps-records.md +++ b/gitlab-pages/docs/language-basics/maps-records.md @@ -3,6 +3,8 @@ id: maps-records title: Records and Maps --- +import Syntax from '@theme/Syntax'; + So far we have seen pretty basic data types. LIGO also offers more complex built-in constructs, such as *records* and *maps*. @@ -16,9 +18,10 @@ special operator (`.`). Let us first consider and example of record type declaration. - - + + + ```pascaligo group=records1 type user is record [ @@ -28,7 +31,9 @@ type user is ] ``` - + + + ```cameligo group=records1 type user = { id : nat; @@ -37,7 +42,9 @@ type user = { } ``` - + + + ```reasonligo group=records1 type user = { id : nat, @@ -45,12 +52,15 @@ type user = { name : string }; ``` - + + + And here is how a record value is defined: - - + + + ```pascaligo group=records1 const alice : user = record [ @@ -60,7 +70,9 @@ const alice : user = ] ``` - + + + ```cameligo group=records1 let alice : user = { id = 1n; @@ -69,7 +81,9 @@ let alice : user = { } ``` - + + + ```reasonligo group=records1 let alice : user = { id : 1n, @@ -77,29 +91,38 @@ let alice : user = { name : "Alice" }; ``` - + + + ### Accessing Record Fields If we want the contents of a given field, we use the (`.`) infix operator, like so: - - + + + ```pascaligo group=records1 const alice_admin : bool = alice.is_admin ``` - + + + ```cameligo group=records1 let alice_admin : bool = alice.is_admin ``` - + + + ```reasonligo group=records1 let alice_admin : bool = alice.is_admin; ``` - + + + ### Functional Updates @@ -115,12 +138,13 @@ updated record. Let us consider defining a function that translates three-dimensional points on a plane. - - -In PascaLIGO, the shape of that expression is ` with -`. The record variable is the record to update and the + + +In PascaLIGO, the shape of that expression is +` with `. +The record variable is the record to update and the record value is the update itself. ```pascaligo group=records2 @@ -146,7 +170,8 @@ You have to understand that `p` has not been changed by the functional update: a namless new version of it has been created and returned by the blockless function. - + + The syntax for the functional updates of record in CameLIGO follows that of OCaml: @@ -174,7 +199,8 @@ xy_translate "({x=2;y=3;z=1}, {dx=3;dy=4})" > functional update: a nameless new version of it has been created and > returned. - + + The syntax for the functional updates of record in ReasonLIGO follows that of ReasonML: @@ -188,7 +214,9 @@ let origin : point = {x : 0, y : 0, z : 0}; let xy_translate = ((p, vec) : (point, vector)) : point => {...p, x : p.x + vec.dx, y : p.y + vec.dy}; ``` - + + + You can call the function `xy_translate` defined above by running the following command of the shell: @@ -303,55 +331,69 @@ sense. Here is how a custom map from addresses to a pair of integers is defined. - - + + + ```pascaligo group=maps type move is int * int type register is map (address, move) ``` - + + + ```cameligo group=maps type move = int * int type register = (address, move) map ``` - + + + ```reasonligo group=maps type move = (int, int); type register = map (address, move); ``` - + + + ### Creating an Empty Map Here is how to create an empty map. - - + + + ```pascaligo group=maps const empty : register = map [] ``` - + + + ```cameligo group=maps let empty : register = Map.empty ``` - + + + ```reasonligo group=maps let empty : register = Map.empty ``` - + + + ### Creating a Non-empty Map And here is how to create a non-empty map value: - - + + ```pascaligo group=maps const moves : register = @@ -365,7 +407,9 @@ individual map entries. The annotated value `("" : address)` means that we cast a string into an address. Also, `map` is a keyword. - + + + ```cameligo group=maps let moves : register = Map.literal [ @@ -378,7 +422,9 @@ key-value pair tuples, `(, )`. Note also the `;` to separate individual map entries. `("": address)` means that we type-cast a string into an address. --> - + + + ```reasonligo group=maps let moves : register = Map.literal ([ @@ -391,12 +437,13 @@ key-value pair tuples, `(, )`. Note also the `;` to separate individual map entries. `("": address)` means that we type-cast a string into an address. --> - + + ### Accessing Map Bindings - - + + In PascaLIGO, we can use the postfix `[]` operator to read the `move` value associated to a given key (`address` here) in the register. Here @@ -407,26 +454,33 @@ const my_balance : option (move) = moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)] ``` - + + + ```cameligo group=maps let my_balance : move option = Map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) moves ``` - + + + ```reasonligo group=maps let my_balance : option (move) = Map.find_opt (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), moves); ``` - + + + Notice how the value we read is an optional value: this is to force the reader to account for a missing key in the map. This requires *pattern matching*. - - + + + ```pascaligo group=maps function force_access (const key : address; const moves : register) : move is case moves[key] of @@ -435,7 +489,9 @@ function force_access (const key : address; const moves : register) : move is end ``` - + + + ```cameligo group=maps let force_access (key, moves : address * register) : move = match Map.find_opt key moves with @@ -443,7 +499,9 @@ let force_access (key, moves : address * register) : move = | None -> (failwith "No move." : move) ``` - + + + ```reasonligo group=maps let force_access = ((key, moves) : (address, register)) : move => { switch (Map.find_opt (key, moves)) { @@ -452,7 +510,9 @@ let force_access = ((key, moves) : (address, register)) : move => { } }; ``` - + + + ### Updating a Map @@ -461,9 +521,9 @@ Given a map, we may want to add a new binding, remove one, or modify one by changing the value associated to an already existing key. All those operations are called *updates*. - - + + The values of a PascaLIGO map can be updated using the usual assignment syntax `[] := `. Let us @@ -491,7 +551,8 @@ function assignments (var m : register) : register is See further for the removal of bindings. - + + We can update a binding in a map in CameLIGO by means of the `Map.update` built-in function: @@ -513,7 +574,8 @@ let add (m : register) : register = ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (4,9) m ``` - + + We can update a binding in a map in ReasonLIGO by means of the `Map.update` built-in function: @@ -535,13 +597,14 @@ let add = (m : register) : register => (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (4,9), m); ``` - + + To remove a binding from a map, we need its key. - - + + In PascaLIGO, there is a special instruction to remove a binding from a map. @@ -552,7 +615,8 @@ function delete (const key : address; var moves : register) : register is } with moves ``` - + + In CameLIGO, we use the predefined function `Map.remove` as follows: @@ -561,7 +625,8 @@ let delete (key, moves : address * register) : register = Map.remove key moves ``` - + + In ReasonLIGO, we use the predefined function `Map.remove` as follows: @@ -570,7 +635,8 @@ let delete = ((key, moves) : (address, register)) : register => Map.remove (key, moves); ``` - + + ### Functional Iteration over Maps @@ -596,9 +662,9 @@ over maps is called `Map.iter`. In the following example, the register of moves is iterated to check that the start of each move is above `3`. - - + + ```pascaligo group=maps function iter_op (const m : register) : unit is @@ -610,7 +676,8 @@ function iter_op (const m : register) : unit is > Note that `map_iter` is *deprecated*. - + + ```cameligo group=maps let iter_op (m : register) : unit = @@ -618,7 +685,8 @@ let iter_op (m : register) : unit = in Map.iter predicate m ``` - + + ```reasonligo group=maps let iter_op = (m : register) : unit => { @@ -626,7 +694,9 @@ let iter_op = (m : register) : unit => { Map.iter (predicate, m); }; ``` - + + + #### Map Operations over Maps @@ -637,9 +707,9 @@ implementing the map operation over maps is called `Map.map`. In the following example, we add `1` to the ordinate of the moves in the register. - - + + ```pascaligo group=maps function map_op (const m : register) : register is @@ -651,7 +721,8 @@ function map_op (const m : register) : register is > Note that `map_map` is *deprecated*. - + + ```cameligo group=maps let map_op (m : register) : register = @@ -659,7 +730,8 @@ let map_op (m : register) : register = in Map.map increment m ``` - + + ```reasonligo group=maps let map_op = (m : register) : register => { @@ -667,7 +739,9 @@ let map_op = (m : register) : register => { Map.map (increment, m); }; ``` - + + + #### Folded Operations over Maps @@ -680,9 +754,9 @@ traversal of the data structure is over. The predefined functional iterator implementing the folded operation over maps is called `Map.fold` and is used as follows. - - + + ```pascaligo group=maps function fold_op (const m : register) : int is @@ -694,7 +768,8 @@ function fold_op (const m : register) : int is > Note that `map_fold` is *deprecated*. - + + ```cameligo group=maps let fold_op (m : register) : register = @@ -702,7 +777,8 @@ let fold_op (m : register) : register = in Map.fold folded m 5 ``` - + + ```reasonligo group=maps let fold_op = (m : register) : register => { @@ -711,7 +787,8 @@ let fold_op = (m : register) : register => { }; ``` - + + ## Big Maps @@ -728,55 +805,69 @@ interface for big maps is analogous to the one used for ordinary maps. Here is how we define a big map: - - + + + ```pascaligo group=big_maps type move is int * int type register is big_map (address, move) ``` - + + + ```cameligo group=big_maps type move = int * int type register = (address, move) big_map ``` - + + + ```reasonligo group=big_maps type move = (int, int); type register = big_map (address, move); ``` - + + + ### Creating an Empty Big Map Here is how to create an empty big map. - - + + + ```pascaligo group=big_maps const empty : register = big_map [] ``` - + + + ```cameligo group=big_maps let empty : register = Big_map.empty ``` - + + + ```reasonligo group=big_maps let empty : register = Big_map.empty ``` - + + + ### Creating a Non-empty Map And here is how to create a non-empty map value: - - + + ```pascaligo group=big_maps const moves : register = @@ -790,7 +881,8 @@ semicolon separating individual map entries. The value annotation `("" : address)` means that we cast a string into an address. --> - + + ```cameligo group=big_maps let moves : register = @@ -804,7 +896,8 @@ list of key-value pairs `(, )`. Note also the semicolon separating individual map entries. The annotated value `(" value>" : address)` means that we cast a string into an address. - + + ```reasonligo group=big_maps let moves : register = @@ -818,8 +911,8 @@ list of key-value pairs `(, )`. Note also the semicolon separating individual map entries. The annotated value `(" value>" : address)` means that we cast a string into an address. + - ### Accessing Values @@ -828,35 +921,39 @@ postfix `[]` operator to read the associated `move` value. However, the value we read is an optional value (in our case, of type `option (move)`), to account for a missing key. Here is an example: - - + + ```pascaligo group=big_maps const my_balance : option (move) = moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)] ``` - + + ```cameligo group=big_maps let my_balance : move option = Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) moves ``` - + + ```reasonligo group=big_maps let my_balance : option (move) = Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, moves); ``` - + + + ### Updating Big Maps - - + + The values of a PascaLIGO big map can be updated using the assignment syntax for ordinary maps @@ -870,7 +967,8 @@ function add (var m : register) : register is const updated_map : register = add (moves) ``` - + + We can update a big map in CameLIGO using the `Big_map.update` built-in: @@ -881,7 +979,8 @@ let updated_map : register = ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (Some (4,9)) moves ``` - + + We can update a big map in ReasonLIGO using the `Big_map.update` built-in: @@ -892,16 +991,17 @@ let updated_map : register = (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), Some ((4,9)), moves); ``` - + + ### Removing Bindings Removing a binding in a map is done differently according to the LIGO syntax. - - + + PascaLIGO features a special syntactic construct to remove bindings from maps, of the form `remove from map `. For example, @@ -915,7 +1015,8 @@ function rem (var m : register) : register is const updated_map : register = rem (moves) ``` - + + In CameLIGO, the predefined function which removes a binding in a map is called `Map.remove` and is used as follows: @@ -925,7 +1026,8 @@ let updated_map : register = Map.remove ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) moves ``` - + + In ReasonLIGO, the predefined function which removes a binding in a map is called `Map.remove` and is used as follows: @@ -935,4 +1037,5 @@ let updated_map : register = Map.remove (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), moves) ``` - + + diff --git a/gitlab-pages/docs/language-basics/math-numbers-tez.md b/gitlab-pages/docs/language-basics/math-numbers-tez.md index 31bdeb872..c56119c64 100644 --- a/gitlab-pages/docs/language-basics/math-numbers-tez.md +++ b/gitlab-pages/docs/language-basics/math-numbers-tez.md @@ -3,6 +3,8 @@ id: math-numbers-tez title: Math, Numbers & Tez --- +import Syntax from '@theme/Syntax'; + LIGO offers three built-in numerical types: `int`, `nat` and `tez`. Values of type `int` are integers; values of type `nat` are natural numbers (integral numbers greater than or equal to zero); @@ -38,8 +40,9 @@ remain in comments as they would otherwise not compile, for example, adding a value of type `int` to a value of type `tez` is invalid. Note that adding an integer to a natural number produces an integer. - - + + + ```pascaligo group=a // int + int yields int const a : int = 5 + 10 @@ -69,7 +72,9 @@ const g : int = 1_000_000 > const sum : tez = 100_000mutez >``` - + + + ```cameligo group=a // int + int yields int let a : int = 5 + 10 @@ -99,7 +104,9 @@ let g : int = 1_000_000 >let sum : tez = 100_000mutez >``` - + + + ```reasonligo group=a // int + int yields int let a : int = 5 + 10; @@ -127,7 +134,9 @@ let g : int = 1_000_000; >```reasonligo >let sum : tex = 100_000mutez; >``` - + + + ## Subtraction @@ -135,8 +144,9 @@ Subtraction looks as follows. > ⚠️ Even when subtracting two `nats`, the result is an `int` - - + + + ```pascaligo group=b const a : int = 5 - 10 @@ -149,7 +159,9 @@ const b : int = 5n - 2n const d : tez = 5mutez - 1mutez ``` - + + + ```cameligo group=b let a : int = 5 - 10 @@ -162,7 +174,9 @@ let b : int = 5n - 2n let d : tez = 5mutez - 1mutez ``` - + + + ```reasonligo group=b let a : int = 5 - 10; @@ -175,15 +189,16 @@ let b : int = 5n - 2n; let d : tez = 5mutez - 1mutez; ``` - + + ## Multiplication You can multiply values of the same type, such as: - - + + ```pascaligo group=c const a : int = 5 * 5 @@ -193,7 +208,9 @@ const b : nat = 5n * 5n const c : tez = 5n * 5mutez ``` - + + + ```cameligo group=c let a : int = 5 * 5 let b : nat = 5n * 5n @@ -202,7 +219,9 @@ let b : nat = 5n * 5n let c : tez = 5n * 5mutez ``` - + + + ```reasonligo group=c let a : int = 5 * 5; let b : nat = 5n * 5n; @@ -211,7 +230,8 @@ let b : nat = 5n * 5n; let c : tez = 5n * 5mutez; ``` - + + ## Euclidean Division @@ -219,35 +239,42 @@ In LIGO you can divide `int`, `nat`, and `tez`. Here is how: > ⚠️ Division of two `tez` values results into a `nat` - - + + + ```pascaligo group=d const a : int = 10 / 3 const b : nat = 10n / 3n const c : nat = 10mutez / 3mutez ``` - + + + ```cameligo group=d let a : int = 10 / 3 let b : nat = 10n / 3n let c : nat = 10mutez / 3mutez ``` - + + + ```reasonligo group=d let a : int = 10 / 3; let b : nat = 10n / 3n; let c : nat = 10mutez / 3mutez; ``` - + + LIGO also allows you to compute the remainder of the Euclidean division. In LIGO, it is a natural number. - - + + + ```pascaligo group=d const a : int = 120 const b : int = 9 @@ -259,7 +286,9 @@ const rem3 : nat = c mod d // 3 const rem4 : nat = a mod d // 3 ``` - + + + ```cameligo group=d let a : int = 120 let b : int = 9 @@ -271,7 +300,9 @@ let rem3 : nat = c mod d // 3 let rem4 : nat = a mod d // 3 ``` - + + + ```reasonligo group=d let a : int = 120; let b : int = 9; @@ -283,29 +314,39 @@ let rem3 : nat = c mod d; // 3 let rem4 : nat = a mod d; // 3 ``` + + + ## From `int` to `nat` and back You can *cast* an `int` to a `nat` and vice versa. Here is how: - - + + + ```pascaligo group=e const a : int = int (1n) const b : nat = abs (1) ``` - + + + ```cameligo group=e let a : int = int (1n) let b : nat = abs (1) ``` - + + + ```reasonligo group=e let a : int = int (1n); let b : nat = abs (1); ``` - + + + ## Checking a `nat` @@ -314,20 +355,26 @@ function which accepts an `int` and returns an optional `nat`: if the result is not `None`, then the provided integer was indeed a natural number, and not otherwise. - - + + + ```pascaligo group=e const is_a_nat : option (nat) = is_nat (1) ``` - + + + ```cameligo group=e let is_a_nat : nat option = Michelson.is_nat (1) ``` - + + + ```reasonligo group=e let is_a_nat : option (nat) = Michelson.is_nat (1); ``` - + + diff --git a/gitlab-pages/docs/language-basics/sets-lists-tuples.md b/gitlab-pages/docs/language-basics/sets-lists-tuples.md index 8bcb192f6..31963eb26 100644 --- a/gitlab-pages/docs/language-basics/sets-lists-tuples.md +++ b/gitlab-pages/docs/language-basics/sets-lists-tuples.md @@ -3,6 +3,8 @@ id: sets-lists-tuples title: Tuples, Lists, Sets --- +import Syntax from '@theme/Syntax'; + Apart from complex data types such as `maps` and `records`, LIGO also features `tuples`, `lists` and `sets`. @@ -27,9 +29,9 @@ Unlike [a record](language-basics/maps-records.md), tuple types do not have to be defined before they can be used. However below we will give them names by *type aliasing*. - - + + ```pascaligo group=tuple type full_name is string * string // Alias @@ -37,7 +39,8 @@ type full_name is string * string // Alias const full_name : full_name = ("Alice", "Johnson") ``` - + + ```cameligo group=tuple type full_name = string * string // Alias @@ -45,7 +48,8 @@ type full_name = string * string // Alias let full_name : full_name = ("Alice", "Johnson") // Optional parentheses ``` - + + ```reasonligo group=tuple type full_name = (string, string); // Alias @@ -53,7 +57,8 @@ type full_name = (string, string); // Alias let full_name : full_name = ("Alice", "Johnson"); ``` - + + ### Accessing Components @@ -66,27 +71,30 @@ position in their tuple, which cannot be done in OCaml. *Tuple components are zero-indexed*, that is, the first component has index `0`. - - + + ```pascaligo group=tuple const first_name : string = full_name.0 ``` - + + ```cameligo group=tuple let first_name : string = full_name.0 ``` - + + ```reasonligo group=tuple let first_name : string = full_name[0]; ``` - + + ## Lists @@ -103,26 +111,32 @@ think of a list a *stack*, where the top is written on the left. ### Defining Lists - - + + + ```pascaligo group=lists const empty_list : list (int) = nil // Or list [] const my_list : list (int) = list [1; 2; 2] // The head is 1 ``` - + + + ```cameligo group=lists let empty_list : int list = [] let my_list : int list = [1; 2; 2] // The head is 1 ``` - + + + ```reasonligo group=lists let empty_list : list (int) = []; let my_list : list (int) = [1, 2, 2]; // The head is 1 ``` - + + ### Adding to Lists @@ -130,9 +144,9 @@ Lists can be augmented by adding an element before the head (or, in terms of stack, by *pushing an element on top*). This operation is usually called *consing* in functional languages. - - + + In PascaLIGO, the *cons operator* is infix and noted `#`. It is not symmetric: on the left lies the element to cons, and, on the right, a @@ -143,7 +157,8 @@ you of that.) const larger_list : list (int) = 5 # my_list // [5;1;2;2] ``` - + + In CameLIGO, the *cons operator* is infix and noted `::`. It is not symmetric: on the left lies the element to cons, and, on the right, a @@ -153,7 +168,8 @@ list on which to cons. let larger_list : int list = 5 :: my_list // [5;1;2;2] ``` - + + In ReasonLIGO, the *cons operator* is infix and noted `, ...`. It is not symmetric: on the left lies the element to cons, and, on the @@ -162,7 +178,9 @@ right, a list on which to cons. ```reasonligo group=lists let larger_list : list (int) = [5, ...my_list]; // [5,1,2,2] ``` - + + + ### Functional Iteration over Lists @@ -189,9 +207,9 @@ called `List.iter`. In the following example, a list is iterated to check that all its elements (integers) are strictly greater than `3`. - - + + ```pascaligo group=lists function iter_op (const l : list (int)) : unit is @@ -203,7 +221,8 @@ function iter_op (const l : list (int)) : unit is > Note that `list_iter` is *deprecated*. - + + ```cameligo group=lists let iter_op (l : int list) : unit = @@ -211,7 +230,8 @@ let iter_op (l : int list) : unit = in List.iter predicate l ``` - + + ```reasonligo group=lists let iter_op = (l : list (int)) : unit => { @@ -220,7 +240,8 @@ let iter_op = (l : list (int)) : unit => { }; ``` - + + #### Mapped Operation over Lists @@ -231,9 +252,9 @@ with the map data structure. The predefined functional iterator implementing the mapped operation over lists is called `List.map` and is used as follows. - - + + ```pascaligo group=lists function increment (const i : int): int is i + 1 @@ -244,7 +265,8 @@ const plus_one : list (int) = List.map (increment, larger_list) > Note that `list_map` is *deprecated*. - + + ```cameligo group=lists let increment (i : int) : int = i + 1 @@ -253,7 +275,8 @@ let increment (i : int) : int = i + 1 let plus_one : int list = List.map increment larger_list ``` - + + ```reasonligo group=lists let increment = (i : int) : int => i + 1; @@ -261,7 +284,9 @@ let increment = (i : int) : int => i + 1; // Creates a new list with all elements incremented by 1 let plus_one : list (int) = List.map (increment, larger_list); ``` - + + + #### Folded Operation over Lists @@ -274,9 +299,9 @@ traversal of the data structure is over. The predefined functional iterator implementing the folded operation over lists is called `List.fold` and is used as follows. - - + + ```pascaligo group=lists function sum (const acc : int; const i : int): int is acc + i @@ -285,20 +310,24 @@ const sum_of_elements : int = List.fold (sum, my_list, 0) > Note that `list_fold` is *deprecated*. - + + ```cameligo group=lists let sum (acc, i: int * int) : int = acc + i let sum_of_elements : int = List.fold sum my_list 0 ``` - + + ```reasonligo group=lists let sum = ((result, i): (int, int)): int => result + i; let sum_of_elements : int = List.fold (sum, my_list, 0); ``` - + + + ## Sets @@ -309,9 +338,9 @@ whereas they can be repeated in a *list*. ### Empty Sets - - + + In PascaLIGO, the notation for sets is similar to that for lists, except the keyword `set` is used before: @@ -319,7 +348,9 @@ except the keyword `set` is used before: ```pascaligo group=sets const my_set : set (int) = set [] ``` - + + + In CameLIGO, the empty set is denoted by the predefined value `Set.empty`. @@ -328,7 +359,8 @@ In CameLIGO, the empty set is denoted by the predefined value let my_set : int set = Set.empty ``` - + + In ReasonLIGO, the empty set is denoted by the predefined value `Set.empty`. @@ -336,13 +368,15 @@ In ReasonLIGO, the empty set is denoted by the predefined value ```reasonligo group=sets let my_set : set (int) = Set.empty; ``` - + + + ### Non-empty Sets - - + + In PascaLIGO, the notation for sets is similar to that for lists, except the keyword `set` is used before: @@ -359,7 +393,8 @@ gitlab-pages/docs/language-basics/src/sets-lists-tuples/sets.ligo my_set # Outputs: { 3 ; 2 ; 1 } ``` - + + In CameLIGO, there is no predefined syntactic construct for sets: you must build your set by adding to the empty set. (This is the way in @@ -379,7 +414,8 @@ gitlab-pages/docs/language-basics/src/sets-lists-tuples/sets.mligo my_set # Outputs: { 3 ; 2 ; 1 } ``` - + + In ReasonLIGO, there is no predefined syntactic construct for sets: you must build your set by adding to the empty set. (This is the way @@ -399,13 +435,15 @@ ligo evaluate-value gitlab-pages/docs/language-basics/src/sets-lists-tuples/sets.religo my_set # Outputs: { 3 ; 2 ; 1 } ``` - + + + ### Set Membership - - + + PascaLIGO features a special keyword `contains` that operates like an infix operator checking membership in a set. @@ -414,7 +452,8 @@ infix operator checking membership in a set. const contains_3 : bool = my_set contains 3 ``` - + + In CameLIGO, the predefined predicate `Set.mem` tests for membership in a set as follows: @@ -423,7 +462,8 @@ in a set as follows: let contains_3 : bool = Set.mem 3 my_set ``` - + + In ReasonLIGO, the predefined predicate `Set.mem` tests for membership in a set as follows: @@ -432,7 +472,8 @@ in a set as follows: let contains_3 : bool = Set.mem (3, my_set); ``` - + + ### Cardinal of Sets @@ -440,9 +481,9 @@ let contains_3 : bool = Set.mem (3, my_set); The predefined function `Set.size` returns the number of elements in a given set as follows. - - + + ```pascaligo group=sets const cardinal : nat = Set.size (my_set) @@ -450,18 +491,22 @@ const cardinal : nat = Set.size (my_set) > Note that `size` is *deprecated*. - + + ```cameligo group=sets let cardinal : nat = Set.size my_set ``` - + + + ```reasonligo group=sets let cardinal : nat = Set.size (my_set); ``` - + + ### Updating Sets @@ -469,9 +514,9 @@ let cardinal : nat = Set.size (my_set); There are two ways to update a set, that is to add or remove from it. - - + + In PascaLIGO, either we create a new set from the given one, or we modify it in-place. First, let us consider the former way: @@ -502,7 +547,8 @@ function update (var s : set (int)) : set (int) is block { const new_set : set (int) = update (my_set) ``` - + + In CameLIGO, we can use the predefined functions `Set.add` and `Set.remove`. We update a given set by creating another one, with or @@ -513,7 +559,8 @@ let larger_set : int set = Set.add 4 my_set let smaller_set : int set = Set.remove 3 my_set ``` - + + In ReasonLIGO, we can use the predefined functions `Set.add` and `Set.remove`. We update a given set by creating another one, with or @@ -523,7 +570,9 @@ without some elements. let larger_set : set (int) = Set.add (4, my_set); let smaller_set : set (int) = Set.remove (3, my_set); ``` - + + + ### Functional Iteration over Sets @@ -549,9 +598,9 @@ over sets is called `Set.iter`. In the following example, a set is iterated to check that all its elements (integers) are greater than `3`. - - + + ```pascaligo group=sets function iter_op (const s : set (int)) : unit is @@ -563,7 +612,8 @@ function iter_op (const s : set (int)) : unit is > Note that `set_iter` is *deprecated*. - + + ```cameligo group=sets let iter_op (s : int set) : unit = @@ -571,7 +621,8 @@ let iter_op (s : int set) : unit = in Set.iter predicate s ``` - + + ```reasonligo group=sets let iter_op = (s : set (int)) : unit => { @@ -580,7 +631,8 @@ let iter_op = (s : set (int)) : unit => { }; ``` - + + @@ -638,8 +690,9 @@ enables having a partial result that becomes complete when the traversal of the data structure is over. The predefined fold over sets is called `Set.fold`. - - + + + ```pascaligo group=sets function sum (const acc : int; const i : int): int is acc + i const sum_of_elements : int = Set.fold (sum, my_set, 0) @@ -658,15 +711,21 @@ function loop (const s : set (int)) : int is block { } with sum ``` - + + + ```cameligo group=sets let sum (acc, i : int * int) : int = acc + i let sum_of_elements : int = Set.fold sum my_set 0 ``` - + + + ```reasonligo group=sets let sum = ((acc, i) : (int, int)) : int => acc + i; let sum_of_elements : int = Set.fold (sum, my_set, 0); ``` - + + + diff --git a/gitlab-pages/docs/language-basics/strings.md b/gitlab-pages/docs/language-basics/strings.md index 9a4022998..be1e201c9 100644 --- a/gitlab-pages/docs/language-basics/strings.md +++ b/gitlab-pages/docs/language-basics/strings.md @@ -3,28 +3,40 @@ id: strings title: Strings --- +import Syntax from '@theme/Syntax'; + Strings are defined using the built-in `string` type like this: - - + + + ``` const a : string = "Hello Alice" ``` - + + + + ``` let a : string = "Hello Alice" ``` - + + + + ```reasonligo let a : string = "Hello Alice"; ``` - + + + ## Concatenating Strings - - + + + Strings can be concatenated using the `^` operator. ```pascaligo group=a @@ -32,7 +44,10 @@ const name : string = "Alice" const greeting : string = "Hello" const full_greeting : string = greeting ^ " " ^ name ``` - + + + + Strings can be concatenated using the `^` operator. ```cameligo group=a @@ -40,7 +55,10 @@ let name : string = "Alice" let greeting : string = "Hello" let full_greeting : string = greeting ^ " " ^ name ``` - + + + + Strings can be concatenated using the `++` operator. ```reasonligo group=a @@ -48,15 +66,18 @@ let name : string = "Alice"; let greeting : string = "Hello"; let full_greeting : string = greeting ++ " " ++ name; ``` - + + + ## Slicing Strings Strings can be sliced using a built-in function: - - + + + ```pascaligo group=b const name : string = "Alice" const slice : string = String.slice (0n, 1n, name) @@ -64,19 +85,24 @@ const slice : string = String.slice (0n, 1n, name) > Note that `string_slide` is *deprecated*. - + + + ```cameligo group=b let name : string = "Alice" let slice : string = String.slice 0n 1n name ``` - + + + ```reasonligo group=b let name : string = "Alice"; let slice : string = String.slice (0n, 1n, name); ``` - + + > ⚠️ Notice that the offset and length of the slice are natural > numbers. @@ -85,8 +111,9 @@ let slice : string = String.slice (0n, 1n, name); The length of a string can be found using a built-in function: - - + + + ```pascaligo group=c const name : string = "Alice" const length : nat = String.length (name) // length = 5 @@ -94,15 +121,21 @@ const length : nat = String.length (name) // length = 5 > Note that `size` is *deprecated*. - + + + ```cameligo group=c let name : string = "Alice" let length : nat = String.size name // length = 5 ``` - + + + ```reasonligo group=c let name : string = "Alice"; let length : nat = String.size (name); // length == 5 ``` - + + + diff --git a/gitlab-pages/docs/language-basics/tezos-specific.md b/gitlab-pages/docs/language-basics/tezos-specific.md index 99b980f44..a73698fd6 100644 --- a/gitlab-pages/docs/language-basics/tezos-specific.md +++ b/gitlab-pages/docs/language-basics/tezos-specific.md @@ -3,6 +3,8 @@ id: tezos-specific title: Tezos Domain-Specific Operations --- +import Syntax from '@theme/Syntax'; + LIGO is a programming language for writing Tezos smart contracts. It would be a little odd if it did not have any Tezos specific functions. This page will tell you about them. @@ -20,9 +22,10 @@ functionality can be accessed from within LIGO. > untrusted source or casting the result to the wrong type. Do not use > the corresponding LIGO functions without doing your homework first. - - + + + ```pascaligo group=a function id_string (const p : string) : option (string) is block { const packed : bytes = bytes_pack (p) @@ -31,14 +34,18 @@ function id_string (const p : string) : option (string) is block { > Note that `bytes_unpack` is *deprecated*. - + + + ```cameligo group=a let id_string (p : string) : string option = let packed: bytes = Bytes.pack p in (Bytes.unpack packed : string option) ``` - + + + ```reasonligo group=a let id_string = (p : string) : option (string) => { let packed : bytes = Bytes.pack (p); @@ -46,7 +53,8 @@ let id_string = (p : string) : option (string) => { }; ``` - + + ## Hashing Keys @@ -56,9 +64,10 @@ if this were not the case, hashes are much smaller than keys, and storage on blockchains comes at a cost premium. You can hash keys with a predefined functions returning a value of type `key_hash`. - - + + + ```pascaligo group=b function check_hash_key (const kh1 : key_hash; const k2 : key) : bool * key_hash is block { @@ -68,14 +77,18 @@ function check_hash_key (const kh1 : key_hash; const k2 : key) : bool * key_hash } with (ret, kh2) ``` - + + + ```cameligo group=b let check_hash_key (kh1, k2 : key_hash * key) : bool * key_hash = let kh2 : key_hash = Crypto.hash_key k2 in if kh1 = kh2 then true, kh2 else false, kh2 ``` - + + + ```reasonligo group=b let check_hash_key = ((kh1, k2) : (key_hash, key)) : (bool, key_hash) => { let kh2 : key_hash = Crypto.hash_key (k2); @@ -83,7 +96,8 @@ let check_hash_key = ((kh1, k2) : (key_hash, key)) : (bool, key_hash) => { }; ``` - + + ## Checking Signatures @@ -97,9 +111,10 @@ asynchronously. You can do this in LIGO using the `key` and > because that would require storing a private key on chain, at which > point it is not... private anymore. - - + + + ```pascaligo group=c function check_signature (const pk : key; @@ -110,20 +125,25 @@ function check_signature > Note that `crypto_check` is *deprecated*. - + + + ```cameligo group=c let check_signature (pk, signed, msg : key * signature * bytes) : bool = Crypto.check pk signed msg ``` - + + + ```reasonligo group=c let check_signature = ((pk, signed, msg) : (key, signature, bytes)) : bool => Crypto.check (pk, signed, msg); ``` - + + ## Contract's Own Address @@ -136,24 +156,29 @@ can do it with `Tezos.self_address`. > contract is only allowed at the top-level. Using it in an embedded > function will cause an error. - - + + + ```pascaligo group=d const current_addr : address = Tezos.self_address ``` - + + + ```cameligo group=d let current_addr : address = Tezos.self_address ``` - + + + ```reasonligo group=d let current_addr : address = Tezos.self_address; ``` - + ## Origination of a contract @@ -163,9 +188,8 @@ The return value is a pair of type `(operation * address)`. > ⚠️ Due to limitations in Michelson, `Tezos.create_contract` first argument > must be inlined and must not contain references to free variables - + - ```pascaligo group=e const origination : operation * address = Tezos.create_contract ( function (const p : nat; const s : string): list(operation) * string is ((nil : list(operation)), s), @@ -174,7 +198,9 @@ const origination : operation * address = Tezos.create_contract ( "initial_storage") ``` - + + + ```cameligo group=e let origination : operation * address = Tezos.create_contract (fun (p, s : nat * string) -> (([] : operation list), s)) @@ -183,7 +209,9 @@ let origination : operation * address = Tezos.create_contract "initial_storage" ``` - + + + ```reasonligo group=e let origination : (operation, address) = Tezos.create_contract ( ((p, s) : (nat,string)) : (list(operation),string) => (([] : list(operation)), s), @@ -192,4 +220,5 @@ let origination : (operation, address) = Tezos.create_contract ( "initial_storage") ``` - + + diff --git a/gitlab-pages/docs/language-basics/types.md b/gitlab-pages/docs/language-basics/types.md index 68b79357e..5a58aa0cb 100644 --- a/gitlab-pages/docs/language-basics/types.md +++ b/gitlab-pages/docs/language-basics/types.md @@ -3,6 +3,8 @@ id: types title: Types --- +import Syntax from '@theme/Syntax'; + *LIGO is strongly and statically typed.* This means that the compiler checks how your contract processes data. If it passes the test, your contract will not fail at run-time due to inconsistent assumptions on @@ -22,36 +24,41 @@ maintainability of your smart contracts. For example we can choose to alias a string type as an animal breed - this will allow us to comunicate our intent with added clarity. - - + + + ```pascaligo group=a type breed is string const dog_breed : breed = "Saluki" ``` - + + ```cameligo group=a type breed = string let dog_breed : breed = "Saluki" ``` - + + ```reasonligo group=a type breed = string; let dog_breed : breed = "Saluki"; ``` - + + > The above type definitions are aliases, which means that `breed` and > `string` are interchangable in all contexts. ## Simple types - - + + + ```pascaligo group=b // The type account_balances denotes maps from addresses to tez @@ -61,7 +68,9 @@ const ledger : account_balances = map [("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address) -> 10mutez] ``` - + + + ```cameligo group=b // The type account_balances denotes maps from addresses to tez @@ -72,7 +81,9 @@ let ledger : account_balances = [(("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address), 10mutez)] ``` - + + + ```reasonligo group=b // The type account_balances denotes maps from addresses to tez @@ -83,7 +94,8 @@ let ledger: account_balances = ([("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, 10mutez)]); ``` - + + ## Structured types @@ -96,8 +108,9 @@ types as *fields* and index them with a *field name*. In the example below you can see the definition of data types for a ledger that keeps the balance and number of previous transactions for a given account. - - + + + ```pascaligo group=c // Type aliasing @@ -124,7 +137,9 @@ const my_ledger : ledger = map [ ] ``` - + + + ```cameligo group=c // Type aliasing @@ -147,7 +162,9 @@ let my_ledger : ledger = Map.literal {balance = 10mutez; transactions = 5n})] ``` - + + + ```reasonligo group=c // Type aliasing @@ -177,7 +194,8 @@ are dual because records are a product of types (types are bundled into a record), whereas variant types are a sum of types (they are exclusive to each other). - + + ## Annotations @@ -185,9 +203,10 @@ In certain cases, the type of an expression cannot be properly inferred by the compiler. In order to help the type checker, you can annotate an expression with its desired type. Here is an example: - - + + + ```pascaligo group=d type parameter is Back | Claim | Withdraw @@ -213,7 +232,9 @@ function back (var action : unit; var store : storage) : return is end with ((nil : list (operation)), store) // Annotation ``` - + + + ```cameligo group=d type parameter = Back | Claim | Withdraw @@ -239,7 +260,9 @@ let back (param, store : unit * storage) : return = | Some (x) -> no_op, store ``` - + + + ```reasonligo group=d type parameter = | Back | Claim | Withdraw; @@ -269,4 +292,5 @@ let back = ((param, store) : (unit, storage)) : return => { }; ``` - + + diff --git a/gitlab-pages/docs/language-basics/unit-option-pattern-matching.md b/gitlab-pages/docs/language-basics/unit-option-pattern-matching.md index 881e29d56..9ae8b34f3 100644 --- a/gitlab-pages/docs/language-basics/unit-option-pattern-matching.md +++ b/gitlab-pages/docs/language-basics/unit-option-pattern-matching.md @@ -3,6 +3,9 @@ id: unit-option-pattern-matching title: Unit, Option, Pattern matching --- +import Syntax from '@theme/Syntax'; + + Optionals are a pervasive programing pattern in OCaml. Since Michelson and LIGO are both inspired by OCaml, *optional types* are available in LIGO as well. Similarly, OCaml features a *unit* type, and LIGO @@ -16,15 +19,16 @@ The `unit` type in Michelson or LIGO is a predefined type that contains only one value that carries no information. It is used when no relevant information is required or produced. Here is how it used. - - + + In PascaLIGO, the unique value of the `unit` type is `Unit`. ```pascaligo group=a const n : unit = Unit // Note the capital letter ``` - + + In CameLIGO, the unique value of the `unit` type is `()`, following the OCaml convention. @@ -32,7 +36,8 @@ the OCaml convention. let n : unit = () ``` - + + In ReasonLIGO, the unique value of the `unit` type is `()`, following the OCaml convention. @@ -40,7 +45,8 @@ the OCaml convention. let n : unit = (); ``` - + + ## Variant types @@ -52,28 +58,35 @@ the enumerated types found in Java, C++, JavaScript etc. Here is how we define a coin as being either head or tail (and nothing else): - - + + + ```pascaligo group=b type coin is Head | Tail const head : coin = Head const tail : coin = Tail ``` - + + + ```cameligo group=b type coin = Head | Tail let head : coin = Head let tail : coin = Tail ``` - + + + ```reasonligo group=b type coin = Head | Tail; let head : coin = Head; let tail : coin = Tail; ``` - + + + The names `Head` and `Tail` in the definition of the type `coin` are called *data constructors*, or *variants*. In this particular, they @@ -84,9 +97,10 @@ In general, it is interesting for variants to carry some information, and thus go beyond enumerated types. In the following, we show how to define different kinds of users of a system. - - + + + ```pascaligo group=c type id is nat @@ -99,7 +113,9 @@ const u : user = Admin (1000n) const g : user = Guest ``` - + + + ```cameligo group=c type id = nat @@ -112,7 +128,9 @@ let u : user = Admin 1000n let g : user = Guest ``` - + + + ```reasonligo group=c type id = nat; @@ -125,7 +143,8 @@ let u : user = Admin (1000n); let g : user = Guest; ``` - + + In LIGO, a constant constructor is equivalent to the same constructor taking an argument of type `unit`, so, for example, `Guest` is the @@ -141,26 +160,32 @@ type would be `None`, otherwise `Some (v)`, where `v` is some meaningful value *of any type*. An example in arithmetic is the division operation: - - + + + ```pascaligo group=d function div (const a : nat; const b : nat) : option (nat) is if b = 0n then (None: option (nat)) else Some (a/b) ``` - + + + ```cameligo group=d let div (a, b : nat * nat) : nat option = if b = 0n then (None: nat option) else Some (a/b) ``` - + + + ```reasonligo group=d let div = ((a, b) : (nat, nat)) : option (nat) => if (b == 0n) { (None: option (nat)); } else { Some (a/b); }; ``` - + + ## Pattern matching @@ -170,8 +195,9 @@ Javascript, and can be used to route the program's control flow based on the value of a variant. Consider for example the definition of a function `flip` that flips a coin. - - + + + ```pascaligo group=e type coin is Head | Tail @@ -190,7 +216,9 @@ flip "Head" # Outputs: Tail(Unit) ``` - + + + ```cameligo group=e type coin = Head | Tail @@ -208,7 +236,9 @@ flip Head # Outputs: Tail(Unit) ``` - + + + ```reasonligo group=e type coin = | Head | Tail; @@ -227,4 +257,5 @@ flip Head # Outputs: Tail(Unit) ``` - + + diff --git a/gitlab-pages/docs/language-basics/variables-and-constants.md b/gitlab-pages/docs/language-basics/variables-and-constants.md index 8c8f48577..1194d6c23 100644 --- a/gitlab-pages/docs/language-basics/variables-and-constants.md +++ b/gitlab-pages/docs/language-basics/variables-and-constants.md @@ -3,6 +3,9 @@ id: constants-and-variables title: Constants & Variables --- +import Syntax from '@theme/Syntax'; + + The next building block after types are *constants* and *variables*. ## Constants @@ -12,8 +15,9 @@ reassigned. Put in another way, they can be assigned once, at their declaration. When defining a constant you need to provide a `name`, `type` and a `value`: - - + + + ```pascaligo group=a const age : int = 25 ``` @@ -24,7 +28,10 @@ command: ligo evaluate-value gitlab-pages/docs/language-basics/src/variables-and-constants/const.ligo age # Outputs: 25 ``` - + + + + ```cameligo group=a let age : int = 25 ``` @@ -36,7 +43,9 @@ ligo evaluate-value gitlab-pages/docs/language-basics/src/variables-and-constant # Outputs: 25 ``` - + + + ```reasonligo group=a let age : int = 25; ``` @@ -48,12 +57,13 @@ ligo evaluate-value gitlab-pages/docs/language-basics/src/variables-and-constant # Outputs: 25 ``` - + + ## Variables - - + + Variables, unlike constants, are *mutable*. They cannot be declared in a *global scope*, but they can be declared and used within functions, @@ -88,7 +98,8 @@ ligo run-function gitlab-pages/docs/language-basics/src/variables-and-constants/ # Outputs: 2 ``` - + + As expected in the pure subset of a functional language, CameLIGO only features *constant values*: once they are declared, the value cannot @@ -105,7 +116,9 @@ like this: ligo run-function gitlab-pages/docs/language-basics/src/variables-and-constants/add.mligo add '(1,1)' # Outputs: 2 ``` - + + + As expected in the pure subset of a functional language, ReasonLIGO only features *constant values*: once they are declared, the value @@ -125,4 +138,5 @@ ligo run-function gitlab-pages/docs/language-basics/src/variables-and-constants/ # Outputs: 2 ``` - + + diff --git a/gitlab-pages/docs/reference/big_map.md b/gitlab-pages/docs/reference/big_map.md index 57f222dc0..952275c1c 100644 --- a/gitlab-pages/docs/reference/big_map.md +++ b/gitlab-pages/docs/reference/big_map.md @@ -3,6 +3,8 @@ id: big-map-reference title: Big Maps — Scalable Maps --- +import Syntax from '@theme/Syntax'; + Ordinary maps are fine for contracts with a finite lifespan or a bounded number of users. For many contracts however, the intention is to have a map holding *many* entries, potentially millions of @@ -14,52 +16,67 @@ interface for big maps is analogous to the one used for ordinary maps. # Declaring a Map - - + + + ```pascaligo group=big_maps type move is int * int type register is big_map (address, move) ``` - + + + ```cameligo group=big_maps type move = int * int type register = (address, move) big_map ``` - + + + ```reasonligo group=big_maps type move = (int, int); type register = big_map (address, move); ``` - + + + # Creating an Empty Big Map - - + + + ```pascaligo group=big_maps const empty : register = big_map [] ``` - + + + ```cameligo group=big_maps let empty : register = Big_map.empty ``` - + + + ```reasonligo group=big_maps let empty : register = Big_map.empty ``` - + + + # Creating a Non-empty Map - - + + + ```pascaligo group=big_maps const moves : register = big_map [ @@ -67,7 +84,9 @@ const moves : register = ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) -> (0,3)] ``` - + + + ```cameligo group=big_maps let moves : register = Big_map.literal [ @@ -75,42 +94,54 @@ let moves : register = (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))] ``` - + + + ```reasonligo group=big_maps let moves : register = Big_map.literal ([ ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)), ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]); ``` - + + + # Accessing Values - - + + + ```pascaligo group=big_maps const my_balance : option (move) = moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)] ``` - + + + ```cameligo group=big_maps let my_balance : move option = Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) moves ``` - + + + ```reasonligo group=big_maps let my_balance : option (move) = Big_map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, moves); ``` - + + + # Updating Big Maps - - + + + ```pascaligo group=big_maps function add (var m : register) : register is block { @@ -120,26 +151,33 @@ function add (var m : register) : register is const updated_map : register = add (moves) ``` - + + + ```cameligo group=big_maps let updated_map : register = Big_map.update ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (Some (4,9)) moves ``` - + + + ```reasonligo group=big_maps let updated_map : register = Big_map.update (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), Some ((4,9)), moves); ``` - + + + # Removing Bindings - - + + + ```pascaligo group=big_maps function rem (var m : register) : register is block { @@ -149,16 +187,21 @@ function rem (var m : register) : register is const updated_map : register = rem (moves) ``` - + + + ```cameligo group=big_maps let updated_map : register = Map.remove ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address) moves ``` - + + + ```reasonligo group=big_maps let updated_map : register = Map.remove (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN": address), moves) ``` - + + diff --git a/gitlab-pages/docs/reference/bytes.md b/gitlab-pages/docs/reference/bytes.md index c585ffeed..dc8dc1aec 100644 --- a/gitlab-pages/docs/reference/bytes.md +++ b/gitlab-pages/docs/reference/bytes.md @@ -3,62 +3,67 @@ id: bytes-reference title: Bytes — Manipulate bytes data --- +import Syntax from '@theme/Syntax'; + ## Bytes.concat(b1: bytes, b2: bytes) : bytes Concatenate together two `bytes` arguments and return the result. - - - + ```pascaligo function concat_op (const s : bytes) : bytes is begin skip end with bytes_concat(s , 0x7070) ``` - + + ```cameligo let concat_op (s : bytes) : bytes = Bytes.concat s 0x7070 ``` - + + ```reasonligo let concat_op = (s: bytes): bytes => Bytes.concat(s, 0x7070); ``` - + ## Bytes.slice(pos1: nat, pos2: nat, data: bytes) : bytes Extract the bytes between `pos1` and `pos2`. **Positions are zero indexed and inclusive**. For example if you gave the input "ff7a7aff" to the following: - - + + ```pascaligo function slice_op (const s : bytes) : bytes is begin skip end with bytes_slice(1n , 2n , s) ``` - + + ```cameligo let slice_op (s : bytes) : bytes = Bytes.slice 1n 2n s ``` - + + ``` let slice_op = (s: bytes): bytes => Bytes.slice(1n, 2n, s); ``` - + + It would return "7a7a" rather than "ff7a" or "ff" or "7a". @@ -68,23 +73,28 @@ Converts Michelson data structures to a binary format for serialization. > ⚠️ `PACK` and `UNPACK` are features of Michelson that are intended to be used by people that really know what they're doing. There are several failure cases (such as `UNPACK`ing a lambda from an untrusted source), most of which are beyond the scope of this document. Don't use these functions without doing your homework first. - - + + + ```pascaligo function id_string (const p : string) : option(string) is block { const packed : bytes = bytes_pack(p) ; } with (bytes_unpack(packed): option(string)) ``` - + + + ```cameligo let id_string (p: string) : string option = let packed: bytes = Bytes.pack p in ((Bytes.unpack packed): string option) ``` - + + + ```reasonligo let id_string = (p: string) : option(string) => { let packed : bytes = Bytes.pack(p); @@ -92,7 +102,8 @@ let id_string = (p: string) : option(string) => { }; ``` - + + ## Bytes.unpack(packed: bytes) : a' @@ -101,23 +112,28 @@ serialization format to the `option` type annotated on the call. > ⚠️ `PACK` and `UNPACK` are features of Michelson that are intended to be used by people that really know what they're doing. There are several failure cases (such as `UNPACK`ing a lambda from an untrusted source), most of which are beyond the scope of this document. Don't use these functions without doing your homework first. - - + + + ```pascaligo function id_string (const p : string) : option(string) is block { const packed : bytes = bytes_pack(p) ; } with (bytes_unpack(packed): option(string)) ``` - + + + ```cameligo let id_string (p: string) : string option = let packed: bytes = Bytes.pack p in ((Bytes.unpack packed): string option) ``` - + + + ```reasonligo let id_string = (p: string) : option(string) => { let packed : bytes = Bytes.pack(p); @@ -125,4 +141,5 @@ let id_string = (p: string) : option(string) => { }; ``` - + + diff --git a/gitlab-pages/docs/reference/crypto.md b/gitlab-pages/docs/reference/crypto.md index e2b0511d2..49f5a9f02 100644 --- a/gitlab-pages/docs/reference/crypto.md +++ b/gitlab-pages/docs/reference/crypto.md @@ -3,93 +3,108 @@ id: crypto-reference title: Crypto — Cryptographic functions --- +import Syntax from '@theme/Syntax'; + ## Crypto.blake2b(data: bytes): bytes Runs the [blake2b hash algorithm](https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2) over the given `bytes` data and returns a `bytes` representing the hash. - - + + ```pascaligo function hasherman_blake (const s: bytes) : bytes is blake2b(s) ``` - + + ```cameligo let hasherman_blake (s: bytes) : bytes = Crypto.blake2b s ``` - + + ```reasonligo let hasherman_blake = (s: bytes) => Crypto.blake2b(s); ``` - + + ## Crypto.sha256(data: bytes) : bytes Runs the [sha256 hash algorithm](https://en.wikipedia.org/wiki/SHA-2) over the given `bytes` data and returns a `bytes` representing the hash. - - + + + ```pascaligo function hasherman (const s : bytes) : bytes is begin skip end with sha_256(s) ``` - + + + ```cameligo let hasherman (s : bytes) : bytes = Crypto.sha256 s ``` - + + + ```reasonligo let hasherman = (s: bytes): bytes => Crypto.sha256(s); ``` - + + ## Crypto.sha512(data: bytes) : bytes Runs the [sha512 hash algorithm](https://en.wikipedia.org/wiki/SHA-2) over the given `bytes` data and returns a `bytes` representing the hash. - - + + ```pascaligo function hasherman512 (const s: bytes) : bytes is sha_512(s) ``` - + + ```cameligo let hasherman512 (s: bytes) : bytes = Crypto.sha512 s ``` - + + ```reasonligo let hasherman512 = (s: bytes) => Crypto.sha512(s); ``` - + + ## Crypto.hash_key(k: key) : key_hash Hashes a key for easy comparison and storage. - - + + + ```pascaligo function check_hash_key (const kh1 : key_hash; const k2 : key) : bool * key_hash is block { var ret : bool := False ; @@ -98,7 +113,9 @@ function check_hash_key (const kh1 : key_hash; const k2 : key) : bool * key_hash } with (ret, kh2) ``` - + + + ```cameligo let check_hash_key (kh1, k2: key_hash * key) : bool * key_hash = let kh2 : key_hash = Crypto.hash_key k2 in @@ -107,7 +124,9 @@ let check_hash_key (kh1, k2: key_hash * key) : bool * key_hash = else (false, kh2) ``` - + + + ```reasonligo let check_hash_key = ((kh1, k2): (key_hash, key)) : (bool, key_hash) => { let kh2 : key_hash = Crypto.hash_key(k2); @@ -120,7 +139,8 @@ let check_hash_key = ((kh1, k2): (key_hash, key)) : (bool, key_hash) => { }; ``` - + + ## Crypto.check(pk: key, signed: signature, data: bytes) : bool @@ -128,9 +148,10 @@ Check that a message has been signed by a particular key. > ⚠️ There is no way to *generate* a signed message in LIGO. This is because that would require storing a private key on chain, at which point it isn't very private anymore. - - + + + ```pascaligo function check_signature (const pk: key; @@ -139,17 +160,22 @@ function check_signature is crypto_check(pk, signed, msg) ``` - + + + ```cameligo let check_signature (pk, signed, msg: key * signature * bytes) : bool = Crypto.check pk signed msg ``` - + + + ```reasonligo let check_signature = ((pk, signed, msg): (key, signature, bytes)) : bool => { Crypto.check(pk, signed, msg); }; ``` - + + diff --git a/gitlab-pages/docs/reference/current.md b/gitlab-pages/docs/reference/current.md index 53fec4d7d..0b5cd7265 100644 --- a/gitlab-pages/docs/reference/current.md +++ b/gitlab-pages/docs/reference/current.md @@ -3,13 +3,16 @@ id: current-reference title: Tezos - Things relating to the current execution context --- +import Syntax from '@theme/Syntax'; + # Tezos.balance Get the balance for the contract. - - + + + ```pascaligo function main (const p : unit; const s: tez) : list (operation) * tez is ((nil : list (operation)), Tezos.balance) @@ -17,14 +20,18 @@ function main (const p : unit; const s: tez) : list (operation) * tez is > Note that `balance` and `Current.balance` are *deprecated*. - + + + ```cameligo let main (p,s : unit * tez) = ([] : operation list), Tezos.balance ``` > Note that `balance` and `Current.balance` are *deprecated*. - + + + ```reasonligo let main = ((p,s) : (unit, tez)) => ([]: list (operation), Tezos.balance); @@ -32,7 +39,8 @@ let main = ((p,s) : (unit, tez)) => > Note that `balance` and `Current.balance` are *deprecated*. - + + ## Tezos.now @@ -45,8 +53,9 @@ smart contracts like this: ### Examples #### 24 hours from now - - + + + ```pascaligo group=b const today: timestamp = Tezos.now; const one_day: int = 86_400; @@ -57,7 +66,9 @@ const one_day_later: timestamp = some_date + one_day; > Note that `now` is *deprecated*. - + + + ```cameligo group=b let today: timestamp = Tezos.now let one_day: int = 86_400 @@ -68,7 +79,9 @@ let one_day_later: timestamp = some_date + one_day > Note that `Current.time` is *deprecated*. - + + + ```reasonligo group=b let today: timestamp = Tezos.now; let one_day: int = 86_400; @@ -79,12 +92,14 @@ let one_day_later: timestamp = some_date + one_day; > Note that `Current.time` is *deprecated*. - + + #### 24 hours ago - - + + + ```pascaligo group=c const today: timestamp = Tezos.now; const one_day: int = 86_400; @@ -93,7 +108,9 @@ const in_24_hrs: timestamp = today - one_day; > Note that `now` is *deprecated*. - + + + ```cameligo group=c let today: timestamp = Tezos.now let one_day: int = 86_400 @@ -102,7 +119,9 @@ let in_24_hrs: timestamp = today - one_day > Note that `Current.time` is *deprecated*. - + + + ```reasonligo group=c let today: timestamp = Tezos.now; let one_day: int = 86_400; @@ -111,36 +130,43 @@ let in_24_hrs: timestamp = today - one_day; > Note that `Current.time` is *deprecated*. - + + #### Comparing Timestamps You can also compare timestamps using the same comparison operators as for numbers - - + + + ```pascaligo group=c const not_tommorow: bool = (Tezos.now = in_24_hrs) ``` > Note that `now` is *deprecated*. - + + + ```cameligo group=c let not_tomorrow: bool = (Tezos.now = in_24_hrs) ``` > Note that `Current.time` is *deprecated*. - + + + ```reasonligo group=c let not_tomorrow: bool = (Tezos.now == in_24_hrs); ``` > Note that `Current.time` is *deprecated*. - + + ## Amount @@ -148,9 +174,10 @@ let not_tomorrow: bool = (Tezos.now == in_24_hrs); Get the amount of tez provided by the sender to complete this transaction. - - + + + ```pascaligo function threshold (const p : unit) : int is if Tezos.amount = 100tz then 42 else 0 @@ -158,14 +185,18 @@ function threshold (const p : unit) : int is > Note that `amount` is *deprecated*. - + + + ```cameligo let threshold (p : unit) : int = if Tezos.amount = 100tz then 42 else 0 ``` > Note that `Current.amount` is *deprecated*. - + + + ```reasonligo let threshold = (p : unit) : int => if (Tezos.amount == 100tz) { 42; } else { 0; }; @@ -173,45 +204,53 @@ let threshold = (p : unit) : int => > Note that `Current.amount` is *deprecated*. - + + ## Sender Get the address that initiated the current transaction. - - + + + ```pascaligo function main (const p : unit) : address is Tezos.sender ``` > Note that `sender` is *deprecated*. - + + + ```cameligo let main (p: unit) : address = Tezos.sender ``` > Note that `Current.sender` is *deprecated*. - + + + ```reasonligo let main = (p : unit) : address => Tezos.sender; ``` > Note that `Current.sender` is *deprecated*. - + + ## Address Get the address associated with a value of type `contract`. - - + + + ```pascaligo function main (const p : key_hash) : address is block { const c : contract (unit) = Tezos.implicit_account (p) @@ -220,7 +259,9 @@ function main (const p : key_hash) : address is block { > Note that `implicit_account` and `address` are *deprecated*. - + + + ```cameligo let main (p : key_hash) = let c : unit contract = Tezos.implicit_account p @@ -230,7 +271,9 @@ let main (p : key_hash) = > Note that `Current.implicit_account` and `Current.address` are > *deprecated*. - + + + ```reasonligo let main = (p : key_hash) : address => { let c : contract (unit) = Tezos.implicit_account (p); @@ -241,36 +284,43 @@ let main = (p : key_hash) : address => { > Note that `Current.implicit_account` and `Current.address` are > *deprecated*. - + + ## Self Address Get the address of the currently running contract. - - + + + ```pascaligo function main (const p : unit) : address is Tezos.self_address ``` > Note that `self_address` is *deprecated*. - + + + ```cameligo let main (p : unit) : address = Tezos.self_address ``` > Note that `Current.self_address` is *deprecated*. - + + + ```reasonligo let main = (p : unit) : address => Tezos.self_address; ``` > Note that `Current.self_address` is *deprecated*. - + + ## Implicit Account @@ -278,9 +328,10 @@ Get the default contract associated with an on-chain key-pair. This contract does not execute code, instead it exists to receive tokens on behalf of a key's owner. - - + + + ```pascaligo function main (const kh: key_hash) : contract (unit) is Tezos.implicit_account (kh) @@ -288,14 +339,18 @@ function main (const kh: key_hash) : contract (unit) is > Note that `implicit_account` is *deprecated*. - + + + ```cameligo let main (kh : key_hash) : unit contract = Tezos.implicit_account kh ``` > Note that `Current.implicit_account` is *deprecated*. - + + + ```reasonligo let main = (kh : key_hash): contract (unit) => Tezos.implicit_account (kh); @@ -303,7 +358,8 @@ let main = (kh : key_hash): contract (unit) => > Note that `Current.implicit_account` is *deprecated*. - + + ## Source @@ -331,29 +387,36 @@ current transaction. > tezos-client to transfer to whatever KT1 delegates they had, even > if those KT1 were malicious scripts. - - + + + ```pascaligo function main (const p: unit) : address is Tezos.source ``` > Note that `source` is *deprecated*. - + + + ```cameligo let main (p : unit) : address = Tezos.source ``` > Note that `Current.source` is *deprecated*. - + + + ```reasonligo let main = (p : unit) : address => Tezos.source; ``` > Note that `Current.source` is *deprecated*. - + + + ## Failwith @@ -362,9 +425,10 @@ Cause the contract to fail with an error message. > ⚠ Using this currently requires in general a type annotation on the > `failwith` call. - - + + + ```pascaligo function main (const p : int; const s : unit) : list (operation) * unit is block { @@ -373,15 +437,20 @@ function main (const p : int; const s : unit) : list (operation) * unit is with ((nil : list (operation)), s) ``` - + + + ```cameligo let main (p,s : int * unit) = if p > 10 then failwith "Failure." ``` - + + + ```reasonligo let main = ((p,s) : (int, unit)) => if (p > 10) { failwith ("Failure."); }; ``` - + + diff --git a/gitlab-pages/docs/reference/list.md b/gitlab-pages/docs/reference/list.md index 96d733d50..cbded72e6 100644 --- a/gitlab-pages/docs/reference/list.md +++ b/gitlab-pages/docs/reference/list.md @@ -3,6 +3,8 @@ id: list-reference title: Lists — Linear Collections --- +import Syntax from '@theme/Syntax'; + Lists are linear collections of elements of the same type. Linear means that, in order to reach an element in a list, we must visit all the elements before (sequential access). Elements can be repeated, as @@ -13,52 +15,62 @@ think of a list a *stack*, where the top is written on the left. # Defining Lists - - + + + ```pascaligo group=lists const empty_list : list (int) = nil // Or list [] const my_list : list (int) = list [1; 2; 2] // The head is 1 ``` - + + + ```cameligo group=lists let empty_list : int list = [] let my_list : int list = [1; 2; 2] // The head is 1 ``` - + + + ```reasonligo group=lists let empty_list : list (int) = []; let my_list : list (int) = [1, 2, 2]; // The head is 1 ``` - + + # Adding to Lists Lists can be augmented by adding an element before the head (or, in terms of stack, by *pushing an element on top*). - - + + ```pascaligo group=lists const larger_list : list (int) = 5 # my_list // [5;1;2;2] ``` - + + ```cameligo group=lists let larger_list : int list = 5 :: my_list // [5;1;2;2] ``` - + + ```reasonligo group=lists let larger_list : list (int) = [5, ...my_list]; // [5,1,2,2] ``` - + + + # Functional Iteration over Lists @@ -78,9 +90,9 @@ The first, the *iterated operation*, is an iteration over the list with a unit return value. It is useful to enforce certain invariants on the element of a list, or fail. - - + + ```pascaligo group=lists function iter_op (const l : list (int)) : unit is @@ -92,8 +104,8 @@ function iter_op (const l : list (int)) : unit is > Note that `list_iter` is *deprecated*. - - + + ```cameligo group=lists let iter_op (l : int list) : unit = @@ -101,7 +113,8 @@ let iter_op (l : int list) : unit = in List.iter predicate l ``` - + + ```reasonligo group=lists let iter_op = (l : list (int)) : unit => { @@ -110,7 +123,8 @@ let iter_op = (l : list (int)) : unit => { }; ``` - + + ## Mapped Operation over Lists @@ -118,9 +132,9 @@ We may want to change all the elements of a given list by applying to them a function. This is called a *map operation*, not to be confused with the map data structure. - - + + ```pascaligo group=lists function increment (const i : int): int is i + 1 @@ -131,7 +145,8 @@ const plus_one : list (int) = List.map (increment, larger_list) > Note that `list_map` is *deprecated*. - + + ```cameligo group=lists let increment (i : int) : int = i + 1 @@ -140,7 +155,8 @@ let increment (i : int) : int = i + 1 let plus_one : int list = List.map increment larger_list ``` - + + ```reasonligo group=lists let increment = (i : int) : int => i + 1; @@ -148,7 +164,9 @@ let increment = (i : int) : int => i + 1; // Creates a new list with all elements incremented by 1 let plus_one : list (int) = List.map (increment, larger_list); ``` - + + + ## Folded Operation over Lists @@ -159,9 +177,9 @@ function takes two arguments: an *accumulator* and the structure enables having a partial result that becomes complete when the traversal of the data structure is over. - - + + ```pascaligo group=lists function sum (const acc : int; const i : int): int is acc + i @@ -170,42 +188,52 @@ const sum_of_elements : int = List.fold (sum, my_list, 0) > Note that `list_fold` is *deprecated*. - + + ```cameligo group=lists let sum (acc, i: int * int) : int = acc + i let sum_of_elements : int = List.fold sum my_list 0 ``` - + + ```reasonligo group=lists let sum = ((result, i): (int, int)): int => result + i; let sum_of_elements : int = List.fold (sum, my_list, 0); ``` - + + + # List Length Get the number of elements in a list. - - + + + ```pascaligo function size_of (const l : list (int)) : nat is List.length (l) ``` > Note that `size` is *deprecated*. - + + + ```cameligo let size_of (l : int list) : nat = List.length l ``` - + + + ```reasonligo let size_of = (l : list (int)) : nat => List.length (l); ``` - + + diff --git a/gitlab-pages/docs/reference/map.md b/gitlab-pages/docs/reference/map.md index df3ecbb31..d674f54e5 100644 --- a/gitlab-pages/docs/reference/map.md +++ b/gitlab-pages/docs/reference/map.md @@ -3,6 +3,8 @@ id: map-reference title: Maps --- +import Syntax from '@theme/Syntax'; + *Maps* are a data structure which associate values of the same type to values of the same type. The former are called *key* and the latter *values*. Together they make up a *binding*. An additional requirement @@ -11,51 +13,66 @@ sense. # Declaring a Map - - + + + ```pascaligo group=maps type move is int * int type register is map (address, move) ``` - + + + ```cameligo group=maps type move = int * int type register = (address, move) map ``` - + + + ```reasonligo group=maps type move = (int, int); type register = map (address, move); ``` - + + + # Creating an Empty Map - - + + + ```pascaligo group=maps const empty : register = map [] ``` - + + + ```cameligo group=maps let empty : register = Map.empty ``` - + + + ```reasonligo group=maps let empty : register = Map.empty ``` - + + + # Creating a Non-empty Map - - + + + ```pascaligo group=maps const moves : register = map [ @@ -63,7 +80,9 @@ const moves : register = ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) -> (0,3)] ``` - + + + ```cameligo group=maps let moves : register = Map.literal [ @@ -71,44 +90,56 @@ let moves : register = (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (0,3))] ``` - + + + ```reasonligo group=maps let moves : register = Map.literal ([ ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)), ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]); ``` - + + + # Accessing Map Bindings - - + + + ```pascaligo group=maps const my_balance : option (move) = moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)] ``` - + + + ```cameligo group=maps let my_balance : move option = Map.find_opt ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) moves ``` - + + + ```reasonligo group=maps let my_balance : option (move) = Map.find_opt (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), moves); ``` - + + + Notice how the value we read is an optional value: this is to force the reader to account for a missing key in the map. This requires *pattern matching*. - - + + + ```pascaligo group=maps function force_access (const key : address; const moves : register) : move is case moves[key] of @@ -117,7 +148,9 @@ function force_access (const key : address; const moves : register) : move is end ``` - + + + ```cameligo group=maps let force_access (key, moves : address * register) : move = match Map.find_opt key moves with @@ -125,7 +158,9 @@ let force_access (key, moves : address * register) : move = | None -> (failwith "No move." : move) ``` - + + + ```reasonligo group=maps let force_access = ((key, moves) : (address, register)) : move => { switch (Map.find_opt (key, moves)) { @@ -134,7 +169,9 @@ let force_access = ((key, moves) : (address, register)) : move => { } }; ``` - + + + # Updating a Map @@ -142,8 +179,9 @@ Given a map, we may want to add a new binding, remove one, or modify one by changing the value associated to an already existing key. All those operations are called *updates*. - - + + + ```pascaligo group=maps function assign (var m : register) : register is block { @@ -164,7 +202,9 @@ function assignments (var m : register) : register is } with m ``` - + + + ```cameligo group=maps let assign (m : register) : register = Map.update @@ -181,7 +221,9 @@ let add (m : register) : register = ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address) (4,9) m ``` - + + + ```reasonligo group=maps let assign = (m : register) : register => Map.update @@ -199,13 +241,15 @@ let add = (m : register) : register => (("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address), (4,9), m); ``` - + + To remove a binding from a map, we need its key. - - + + + ```pascaligo group=maps function delete (const key : address; var moves : register) : register is block { @@ -213,19 +257,24 @@ function delete (const key : address; var moves : register) : register is } with moves ``` - + + + ```cameligo group=maps let delete (key, moves : address * register) : register = Map.remove key moves ``` - + + + ```reasonligo group=maps let delete = ((key, moves) : (address, register)) : register => Map.remove (key, moves); ``` - + + # Functional Iteration over Maps @@ -246,9 +295,9 @@ no return value: its only use is to produce side-effects. This can be useful if for example you would like to check that each value inside of a map is within a certain range, and fail with an error otherwise. - - + + ```pascaligo group=maps function iter_op (const m : register) : unit is @@ -260,7 +309,8 @@ function iter_op (const m : register) : unit is > Note that `map_iter` is *deprecated*. - + + ```cameligo group=maps let iter_op (m : register) : unit = @@ -268,7 +318,8 @@ let iter_op (m : register) : unit = in Map.iter predicate m ``` - + + ```reasonligo group=maps let iter_op = (m : register) : unit => { @@ -276,7 +327,9 @@ let iter_op = (m : register) : unit => { Map.iter (predicate, m); }; ``` - + + + ## Map Operations over Maps @@ -285,9 +338,9 @@ function. This is called a *map operation*, not to be confused with the map data structure. The predefined functional iterator implementing the map operation over maps is called `Map.map`. - - + + ```pascaligo group=maps function map_op (const m : register) : register is @@ -299,7 +352,8 @@ function map_op (const m : register) : register is > Note that `map_map` is *deprecated*. - + + ```cameligo group=maps let map_op (m : register) : register = @@ -307,7 +361,8 @@ let map_op (m : register) : register = in Map.map increment m ``` - + + ```reasonligo group=maps let map_op = (m : register) : register => { @@ -315,7 +370,9 @@ let map_op = (m : register) : register => { Map.map (increment, m); }; ``` - + + + ## Folded Operations over Maps @@ -325,9 +382,9 @@ function takes two arguments: an *accumulator* and the structure enables having a partial result that becomes complete when the traversal of the data structure is over. - - + + ```pascaligo group=maps function fold_op (const m : register) : int is @@ -339,14 +396,18 @@ function fold_op (const m : register) : int is > Note that `map_fold` is *deprecated*. - + + + ```cameligo group=maps let fold_op (m : register) : register = let folded = fun (i,j : int * (address * move)) -> i + j.1.1 in Map.fold folded m 5 ``` - + + + ```reasonligo group=maps let fold_op = (m : register) : register => { let folded = ((i,j): (int, (address, move))) => i + j[1][1]; @@ -354,4 +415,5 @@ let fold_op = (m : register) : register => { }; ``` - + + diff --git a/gitlab-pages/docs/reference/set.md b/gitlab-pages/docs/reference/set.md index c989df627..eca62a741 100644 --- a/gitlab-pages/docs/reference/set.md +++ b/gitlab-pages/docs/reference/set.md @@ -3,6 +3,8 @@ id: set-reference title: Sets — Unordered unique collection of a type --- +import Syntax from '@theme/Syntax'; + Sets are unordered collections of values of the same type, like lists are ordered collections. Like the mathematical sets and lists, sets can be empty and, if not, elements of sets in LIGO are *unique*, @@ -10,92 +12,122 @@ whereas they can be repeated in a *list*. # Empty Sets - - + + + ```pascaligo group=sets const my_set : set (int) = set [] ``` - + + + ```cameligo group=sets let my_set : int set = Set.empty ``` - + + + ```reasonligo group=sets let my_set : set (int) = Set.empty; ``` - + + + # Non-empty Sets - - + + + ```pascaligo group=sets const my_set : set (int) = set [3; 2; 2; 1] ``` - + + + ```cameligo group=sets let my_set : int set = Set.add 3 (Set.add 2 (Set.add 2 (Set.add 1 (Set.empty : int set)))) ``` - + + + ```reasonligo group=sets let my_set : set (int) = Set.add (3, Set.add (2, Set.add (2, Set.add (1, Set.empty : set (int))))); ``` - + + + # Set Membership - - + + + ```pascaligo group=sets const contains_3 : bool = my_set contains 3 ``` - + + + ```cameligo group=sets let contains_3 : bool = Set.mem 3 my_set ``` - + + + ```reasonligo group=sets let contains_3 : bool = Set.mem (3, my_set); ``` - + + + # Cardinal of Sets The predefined function `Set.size` returns the number of elements in a given set as follows. - - + + + ```pascaligo group=sets const cardinal : nat = Set.size (my_set) ``` > Note that `size` is *deprecated*. - + + + ```cameligo group=sets let cardinal : nat = Set.size my_set ``` - + + + + ```reasonligo group=sets let cardinal : nat = Set.size (my_set); ``` - + + + # Updating Sets There are two ways to update a set, that is to add or remove from it. - - + + + In PascaLIGO, either we create a new set from the given one, or we modify it in-place. First, let us consider the former way: ```pascaligo group=sets @@ -118,18 +150,24 @@ function update (var s : set (int)) : set (int) is block { const new_set : set (int) = update (my_set) ``` - + + + ```cameligo group=sets let larger_set : int set = Set.add 4 my_set let smaller_set : int set = Set.remove 3 my_set ``` - + + + ```reasonligo group=sets let larger_set : set (int) = Set.add (4, my_set); let smaller_set : set (int) = Set.remove (3, my_set); ``` - + + + # Functional Iteration over Sets @@ -149,8 +187,9 @@ no return value: its only use is to produce side-effects. This can be useful if for example you would like to check that each value inside of a map is within a certain range, and fail with an error otherwise. - - + + + ```pascaligo group=sets function iter_op (const s : set (int)) : unit is block { @@ -161,21 +200,27 @@ function iter_op (const s : set (int)) : unit is > Note that `set_iter` is *deprecated*. - + + + ```cameligo group=sets let iter_op (s : int set) : unit = let predicate = fun (i : int) -> assert (i > 3) in Set.iter predicate s ``` - + + + ```reasonligo group=sets let iter_op = (s : set (int)) : unit => { let predicate = (i : int) => assert (i > 3); Set.iter (predicate, s); }; ``` - + + + ## Folded Operation @@ -185,9 +230,10 @@ function takes two arguments: an *accumulator* and the structure enables having a partial result that becomes complete when the traversal of the data structure is over. - - + + + ```pascaligo group=sets function sum (const acc : int; const i : int): int is acc + i const sum_of_elements : int = Set.fold (sum, my_set, 0) @@ -206,15 +252,21 @@ function loop (const s : set (int)) : int is block { } with sum ``` - + + + ```cameligo group=sets let sum (acc, i : int * int) : int = acc + i let sum_of_elements : int = Set.fold sum my_set 0 ``` - + + + ```reasonligo group=sets let sum = ((acc, i) : (int, int)) : int => acc + i; let sum_of_elements : int = Set.fold (sum, my_set, 0); ``` - + + + diff --git a/gitlab-pages/docs/reference/string.md b/gitlab-pages/docs/reference/string.md index b29cdec54..c75e850a4 100644 --- a/gitlab-pages/docs/reference/string.md +++ b/gitlab-pages/docs/reference/string.md @@ -3,29 +3,37 @@ id: string-reference title: String — Manipulate string data --- +import Syntax from '@theme/Syntax'; + ## String.size(s: string) : nat Get the size of a string. [Michelson only supports ASCII strings](http://tezos.gitlab.io/whitedoc/michelson.html#constants) so for now you can assume that each character takes one byte of storage. - - + + + ```pascaligo function string_size (const s: string) : nat is size(s) ``` - + + + ```cameligo let size_op (s: string) : nat = String.size s ``` - + + + ```reasonligo let size_op = (s: string): nat => String.size(s); ``` - + + ## String.length(s: string) : nat @@ -36,20 +44,29 @@ Alias for `String.size`. Get the substring of `s` between `pos1` inclusive and `pos2` inclusive. For example the string "tata" given to the function below would return "at". - - + + + ```pascaligo function slice_op (const s : string) : string is string_slice(1n , 2n , s) ``` - + + + + ```cameligo let slice_op (s: string) : string = String.slice 1n 2n s ``` - + + + + ```reasonligo let slice_op = (s: string): string => String.slice(1n, 2n, s); ``` - + + + ## String.sub(pos1: nat, pos2: nat, s: string) : string @@ -59,21 +76,27 @@ Alias for `String.slice`. Concatenate two strings and return the result. - - + + + ```pascaligo function concat_op (const s : string) : string is s ^ "toto" ``` - + + + ```cameligo let concat_syntax (s: string) = s ^ "test_literal" ``` - + + + ```reasonligo let concat_syntax = (s: string) => s ++ "test_literal"; ``` - + + diff --git a/gitlab-pages/docs/tutorials/get-started/tezos-taco-shop-payout.md b/gitlab-pages/docs/tutorials/get-started/tezos-taco-shop-payout.md index 2d02544d5..3d9330894 100644 --- a/gitlab-pages/docs/tutorials/get-started/tezos-taco-shop-payout.md +++ b/gitlab-pages/docs/tutorials/get-started/tezos-taco-shop-payout.md @@ -15,7 +15,7 @@ people have spent at his shop when buying tacos.
-
+
Icons made by Smashicons from www.flaticon.com is licensed by CC 3.0 BY
@@ -23,6 +23,7 @@ people have spent at his shop when buying tacos. ## Analyzing the Current Contract ### **`taco-shop.ligo`** + ```pascaligo group=a type taco_supply is record [ current_stock : nat; @@ -128,6 +129,7 @@ const operations : list (operation) = list [payoutOperation]; ## Finalizing the Contract ### **`taco-shop.ligo`** + ```pascaligo group=b type taco_supply is record [ current_stock : nat; @@ -190,7 +192,7 @@ ligo dry-run taco-shop.ligo --syntax pascaligo --amount 1 buy_taco 1n "map [ ``` -
+
Operation(...bytes) included in the output
diff --git a/gitlab-pages/docs/tutorials/get-started/tezos-taco-shop-smart-contract.md b/gitlab-pages/docs/tutorials/get-started/tezos-taco-shop-smart-contract.md index 48dfa29a5..986888889 100644 --- a/gitlab-pages/docs/tutorials/get-started/tezos-taco-shop-smart-contract.md +++ b/gitlab-pages/docs/tutorials/get-started/tezos-taco-shop-smart-contract.md @@ -16,7 +16,7 @@ consumers.
-
Made by Smashicons from www.flaticon.com is licensed by CC 3.0 BY
+
Made by Smashicons from www.flaticon.com is licensed by CC 3.0 BY
--- @@ -74,7 +74,7 @@ executable** through the installation script, as shown in the screenshot below: -
Installing the next version of LIGO's CLI
+
Installing the next version of LIGO's CLI
## Implementing our First `main` Function @@ -90,6 +90,7 @@ contract, but it is something to get us started and test our LIGO installation as well. ### `taco-shop.ligo` + ```pascaligo group=a function main (const parameter : int; const contractStorage : int) : list (operation) * int is @@ -150,7 +151,7 @@ ligo dry-run taco-shop.ligo --syntax pascaligo main 4 3 ``` -
Simulating contract execution with the CLI
+
Simulating contract execution with the CLI

@@ -167,6 +168,7 @@ fields. Additionally, we will want to combine our `taco_supply` type into a map, consisting of the entire offer of Pedro's shop. **Taco shop's storage** + ```pascaligo group=b type taco_supply is record [ current_stock : nat; @@ -181,6 +183,7 @@ Next step is to update the `main` function to include `parameter` to `unit` as well to clear things up. **`taco-shop.ligo`** + ```pascaligo group=b+ type taco_supply is record [ current_stock : nat; @@ -204,6 +207,7 @@ initial storage value. In our case the storage is type-checked as our storage's value will be defined as follows: **Storage value** + ```zsh map [ 1n -> record [ @@ -221,6 +225,7 @@ map [ > by their keys `1n` and `2n`. **Dry run command with a multi-line storage value** + ```zsh ligo dry-run taco-shop.ligo --syntax pascaligo main unit "map [ 1n -> record [ @@ -235,7 +240,7 @@ ligo dry-run taco-shop.ligo --syntax pascaligo main unit "map [ ``` -
Dry-run with a complex storage value
+
Dry-run with a complex storage value

@@ -264,6 +269,7 @@ Let is start by customizing our contract a bit, we will: we will want to modify it **`taco-shop.ligo`** + ```pascaligo group=c type taco_supply is record [ current_stock : nat; @@ -320,7 +326,7 @@ function buy_taco (const taco_kind_index : nat; var taco_shop_storage : taco_sho ``` -
Stock decreases after selling a taco
+
Stock decreases after selling a taco

@@ -341,6 +347,7 @@ To make sure we get paid, we will: the payment accepted **`taco-shop.ligo`** + ```pascaligo group=e type taco_supply is record [ current_stock : nat; @@ -394,14 +401,14 @@ ligo dry-run taco-shop.ligo --syntax pascaligo --amount 1 buy_taco 1n "map [ ** Purchasing a Taco with 1tez ** -
Stock decreases after selling a taco, if the right amount of tezzies is provided
+
Stock decreases after selling a taco, if the right amount of tezzies is provided

**Attempting to Purchase a Taco with 0.7tez** -
Stock does not decrease after a purchase attempt +
Stock does not decrease after a purchase attempt with an insufficient payment.

@@ -416,11 +423,13 @@ If you would like to accept tips in your contract, simply change the following line, depending on your preference. **Without tips** + ```pascaligo skip if amount =/= current_purchase_price then ``` **With tips** + ```pascaligo skip if amount >= current_purchase_price then ``` diff --git a/gitlab-pages/website/.gitignore b/gitlab-pages/website/.gitignore new file mode 100644 index 000000000..1b34df512 --- /dev/null +++ b/gitlab-pages/website/.gitignore @@ -0,0 +1,20 @@ +# dependencies +/node_modules + +# production +/build + +# generated files +.docusaurus +.cache-loader + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* \ No newline at end of file diff --git a/gitlab-pages/website/blog/2019-06-13-public-launch-of-ligo.md b/gitlab-pages/website/blog/2019-06-13-public-launch-of-ligo.md.old similarity index 100% rename from gitlab-pages/website/blog/2019-06-13-public-launch-of-ligo.md rename to gitlab-pages/website/blog/2019-06-13-public-launch-of-ligo.md.old diff --git a/gitlab-pages/website/blog/2019-07-11-ligo-update.md b/gitlab-pages/website/blog/2019-07-11-ligo-update.md.old similarity index 100% rename from gitlab-pages/website/blog/2019-07-11-ligo-update.md rename to gitlab-pages/website/blog/2019-07-11-ligo-update.md.old diff --git a/gitlab-pages/website/core/CodeExamples.js b/gitlab-pages/website/core/CodeExamples.js index 9cdf27c1c..289d14a73 100644 --- a/gitlab-pages/website/core/CodeExamples.js +++ b/gitlab-pages/website/core/CodeExamples.js @@ -1,8 +1,12 @@ -const React = require('react'); +import React from 'react'; +import Highlight, { defaultProps } from "prism-react-renderer"; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import useThemeContext from '@theme/hooks/useThemeContext'; +import defaultTheme from 'prism-react-renderer/themes/palenight'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -const pre = '```'; - -const PASCALIGO_EXAMPLE = `${pre}pascaligo +const PASCALIGO_EXAMPLE = ` type storage is int type parameter is @@ -14,8 +18,11 @@ type return is list (operation) * storage // Two entrypoints -function add (const store : storage; const delta : int) : storage is store + delta -function sub (const store : storage; const delta : int) : storage is store - delta +function add (const store : storage; const delta : int) : storage is + store + delta + +function sub (const store : storage; const delta : int) : storage is + store - delta (* Main access point that dispatches to the entrypoints according to the smart contract parameter. *) @@ -27,9 +34,9 @@ function main (const action : parameter; const store : storage) : return is | Decrement (n) -> sub (store, n) | Reset -> 0 end) -${pre}`; +`; -const CAMELIGO_EXAMPLE = `${pre}ocaml +const CAMELIGO_EXAMPLE = ` type storage = int type parameter = @@ -53,10 +60,10 @@ let main (action, store : parameter * storage) : return = Increment (n) -> add (store, n) | Decrement (n) -> sub (store, n) | Reset -> 0) -${pre}`; +`; -const REASONLIGO_EXAMPLE = `${pre}reasonligo +const REASONLIGO_EXAMPLE = ` type storage = int; type parameter = @@ -81,40 +88,82 @@ let main = ((action, store) : (parameter, storage)) : return => { | Decrement (n) => sub ((store, n)) | Reset => 0})) }; -${pre}`; +`; -module.exports = props => { - const MarkdownBlock = props.MarkdownBlock; +function CodeExamples (props) { + const { + siteConfig: { + themeConfig: {prism = {}}, + }, + } = useDocusaurusContext(); + const {isDarkTheme} = useThemeContext(); + const lightModeTheme = prism.theme || defaultTheme; + const darkModeTheme = prism.darkTheme || lightModeTheme; + const prismTheme = isDarkTheme ? darkModeTheme : lightModeTheme; return ( -
-
-
- PascaLIGO -
-
- CameLIGO -
-
- ReasonLIGO -
-
-
-
- {PASCALIGO_EXAMPLE} -
-
- {CAMELIGO_EXAMPLE} -
-
- {REASONLIGO_EXAMPLE} -
-
-
+ + + + + {({ className, style, tokens, getLineProps, getTokenProps }) => ( +
+                {tokens.map((line, i) => (
+                  
+ {line.map((token, key) => ( + + ))} +
+ ))} +
+ )} +
+
+ + + + {({ className, style, tokens, getLineProps, getTokenProps }) => ( +
+                {tokens.map((line, i) => (
+                  
+ {line.map((token, key) => ( + + ))} +
+ ))} +
+ )} +
+
+ + + + {({ className, style, tokens, getLineProps, getTokenProps }) => ( +
+                {tokens.map((line, i) => (
+                  
+ {line.map((token, key) => ( + + ))} +
+ ))} +
+ )} +
+
+ + + +
); }; + +export default CodeExamples \ No newline at end of file diff --git a/gitlab-pages/website/core/Footer.js b/gitlab-pages/website/core/Footer.js index c40de4b0a..3aae1cda0 100644 --- a/gitlab-pages/website/core/Footer.js +++ b/gitlab-pages/website/core/Footer.js @@ -1,3 +1,5 @@ +// deprecated. + const React = require('react'); const docUrl = require(`${process.cwd()}/core/UrlUtils`).docUrl; diff --git a/gitlab-pages/website/docusaurus.config.js b/gitlab-pages/website/docusaurus.config.js new file mode 100644 index 000000000..d94dd362b --- /dev/null +++ b/gitlab-pages/website/docusaurus.config.js @@ -0,0 +1,226 @@ + +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', + // taglineSub: 'Michelson was never so easy', + url: 'https://ligolang.org', // Your website URL + baseUrl: '/', // Base URL for your project */ + // For github.io type URLs, you would set the url and baseUrl like: + // url: 'https://facebook.github.io', + // baseUrl: '/test-site/', + + // Used for publishing and more + projectName: 'ligo', + organizationName: 'TBN', + // For top-level user or org sites, the organization is still the same. + // e.g., for the https://JoelMarcey.github.io site, it would be set like... + // organizationName: 'JoelMarcey' + + // For no header links in the top nav bar -> headerLinks: [], + + + // footerLinks: { + // docs: [ + // { doc: 'intro/installation', label: 'Install' }, + // { doc: 'api/cli-commands', label: 'CLI Commands' }, + // { doc: 'contributors/origin', label: 'Contribute' }, + // { href: '/odoc', label: 'API Documentation' } + // ], + // community: [ + // { + // href: 'https://forum.tezosagora.org/tag/ligo', + // label: 'Tezos Agora Forum', + // blankTarget: true + // }, + // { + // href: 'https://tezos.stackexchange.com/questions/tagged/ligo', + // label: 'Tezos Stack Exchange', + // blankTarget: true + // }, + // { + // href: 'https://t.me/LigoLang', + // label: 'Telegram', + // blankTarget: true + // }, + // { + // href: 'https://discord.gg/9rhYaEt', + // label: 'Discord', + // blankTarget: true + // } + // ], + // more: [ + // { + // doc: 'tutorials/get-started/tezos-taco-shop-smart-contract', + // label: 'Tutorials' + // }, + // { href: repoUrl, label: 'GitLab' } + // ] + // }, + + favicon: 'img/circle.svg', + + /* highlight: { + // 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, + beginKeywords: '', + keywords: { + keyword: + 'and attributes begin big_map block case const contains else' + + ' end False for from function if in is list map mod nil' + + ' not of or patch record remove set skip then to True type' + + ' var while with', + literal: 'true false unit int string Some None bool nat list' + }, + lexemes: '[a-zA-Z][a-zA-Z0-9_]*', + contains: [ + hljs.C_LINE_COMMENT_MODE, + + { + className: 'type', + begin: /[A-Z][a-z]+/ + }, + { + begin: /[*+-:;\(\)\{\}|\>\<]/ + // className: 'ignore' + } + ] + }; + }); + } + },*/ + + // Add custom scripts here that would be placed in