Bläddra i källkod

Validate documentation examples on CI (#1077)

Signed-off-by: xermicus <cyrill@parity.io>
Cyrill Leutwiler 3 år sedan
förälder
incheckning
2e7cd3db20
100 ändrade filer med 1570 tillägg och 95 borttagningar
  1. 1 0
      Cargo.toml
  2. 12 95
      docs/code_gen_options.rst
  3. 7 0
      docs/examples/abi_encode_call.sol
  4. 3 0
      docs/examples/abstract_contract.sol
  5. 15 0
      docs/examples/abstract_contract_inheritance.sol
  6. 7 0
      docs/examples/array_bounds_check_optimization.sol
  7. 11 0
      docs/examples/array_type_dynamic.sol
  8. 15 0
      docs/examples/array_type_dynamic_push.sol
  9. 18 0
      docs/examples/array_type_dynamic_storage.sol
  10. 16 0
      docs/examples/array_type_fixed_length.sol
  11. 7 0
      docs/examples/array_type_initialized.sol
  12. 14 0
      docs/examples/array_type_references.sol
  13. 7 0
      docs/examples/assert.sol
  14. 27 0
      docs/examples/base_contract_function_call.sol
  15. 12 0
      docs/examples/common_subexpression_elimination.sol
  16. 19 0
      docs/examples/contract_inheritance.sol
  17. 22 0
      docs/examples/contract_multiple_inheritance.sol
  18. 20 0
      docs/examples/contract_new.sol
  19. 19 0
      docs/examples/contract_recursive_inheritance.sol
  20. 7 0
      docs/examples/contract_storage.sol
  21. 9 0
      docs/examples/contract_storage_accessor.sol
  22. 9 0
      docs/examples/contract_storage_accessor_override.sol
  23. 13 0
      docs/examples/contract_storage_clear.sol
  24. 12 0
      docs/examples/contract_storage_immutable.sol
  25. 13 0
      docs/examples/contract_type.sol
  26. 5 0
      docs/examples/contract_type_cast_address.sol
  27. 15 0
      docs/examples/dead_storage_elimination.sol
  28. 10 0
      docs/examples/dynamic_bytes_type.sol
  29. 15 0
      docs/examples/enum_type.sol
  30. 42 0
      docs/examples/enum_type_external.sol
  31. 19 0
      docs/examples/event_positional_fields.sol
  32. 11 0
      docs/examples/events.sol
  33. 6 0
      docs/examples/expression_this.sol
  34. 9 0
      docs/examples/expression_this_external_call.sol
  35. 7 0
      docs/examples/expression_unchecked.sol
  36. 14 0
      docs/examples/function_arguments.sol
  37. 29 0
      docs/examples/function_call.sol
  38. 16 0
      docs/examples/function_call_external.sol
  39. 14 0
      docs/examples/function_destructing_arguments.sol
  40. 13 0
      docs/examples/function_modifier.sol
  41. 11 0
      docs/examples/function_modifier_arguments.sol
  42. 19 0
      docs/examples/function_multiple_modifiers.sol
  43. 23 0
      docs/examples/function_overloading.sol
  44. 26 0
      docs/examples/function_override_modifiers.sol
  45. 5 0
      docs/examples/function_selector_override.sol
  46. 25 0
      docs/examples/function_type.sol
  47. 24 0
      docs/examples/function_type_callback.sol
  48. 23 0
      docs/examples/functions.sol
  49. 19 0
      docs/examples/inherited_constructor_arguments.sol
  50. 19 0
      docs/examples/inherited_constructor_runtime_arguments.sol
  51. 27 0
      docs/examples/inline_assembly.sol
  52. 23 0
      docs/examples/inline_assembly_calldata.sol
  53. 16 0
      docs/examples/inline_assembly_external_functions.sol
  54. 20 0
      docs/examples/inline_assembly_storage.sol
  55. 41 0
      docs/examples/interface.sol
  56. 11 0
      docs/examples/library.sol
  57. 19 0
      docs/examples/library_using_for.sol
  58. 26 0
      docs/examples/mapping_type.sol
  59. 13 0
      docs/examples/multiple_contracts.sol
  60. 5 0
      docs/examples/print.sol
  61. 5 0
      docs/examples/require.sol
  62. 11 0
      docs/examples/retrieve_contract_code.sol
  63. 5 0
      docs/examples/revert.sol
  64. 13 0
      docs/examples/scoping.sol
  65. 9 0
      docs/examples/shadowing.sol
  66. 24 0
      docs/examples/solana/accountinfo.sol
  67. 9 0
      docs/examples/solana/builtin_create_program_address.sol
  68. 9 0
      docs/examples/solana/builtin_try_find_program_address.sol
  69. 16 0
      docs/examples/solana/call_anchor.sol
  70. 14 0
      docs/examples/solana/contract_space.sol
  71. 31 0
      docs/examples/solana/function_call_external_accounts.sol
  72. 18 0
      docs/examples/solana/function_call_external_seeds.sol
  73. 10 0
      docs/examples/statement_destructing.sol
  74. 5 0
      docs/examples/statement_destructing_conditional.sol
  75. 7 0
      docs/examples/statement_destructing_swapping.sol
  76. 23 0
      docs/examples/statement_do_while.sol
  77. 7 0
      docs/examples/statement_for.sol
  78. 11 0
      docs/examples/statement_for_abort.sol
  79. 12 0
      docs/examples/statement_if.sol
  80. 9 0
      docs/examples/statement_if_else.sol
  81. 7 0
      docs/examples/statement_while.sol
  82. 26 0
      docs/examples/statement_while_break.sol
  83. 36 0
      docs/examples/storage_ref_type.sol
  84. 12 0
      docs/examples/strength_reduce.sol
  85. 11 0
      docs/examples/string_type.sol
  86. 45 0
      docs/examples/struct_type.sol
  87. 36 0
      docs/examples/struct_type_arguments.sol
  88. 17 0
      docs/examples/struct_type_arguments_external.sol
  89. 21 0
      docs/examples/struct_type_variable_references.sol
  90. 3 0
      docs/examples/substrate/constructor_named.sol
  91. 20 0
      docs/examples/substrate/contract_gas_limit.sol
  92. 20 0
      docs/examples/substrate/contract_payable.sol
  93. 13 0
      docs/examples/substrate/function_call_external_gas.sol
  94. 15 0
      docs/examples/substrate/function_fallback_and_receive.sol
  95. 20 0
      docs/examples/substrate/function_name_mangling.sol
  96. 10 0
      docs/examples/substrate/hash_type.sol
  97. 21 0
      docs/examples/substrate/statement_try_catch_call.sol
  98. 21 0
      docs/examples/substrate/statement_try_catch_constructor.sol
  99. 17 0
      docs/examples/substrate/statement_try_catch_no_error_handling.sol
  100. 16 0
      docs/examples/super_contract_function_call.sol

+ 1 - 0
Cargo.toml

@@ -78,6 +78,7 @@ path-slash = "0.2"
 pretty_assertions = "1.2"
 byte-slice-cast = "1.2.1"
 borsh = "0.9.3"
+rayon = "1"
 
 [package.metadata.docs.rs]
 no-default-features = true

+ 12 - 95
docs/code_gen_options.rst

@@ -45,20 +45,8 @@ of arithmetic may be replaced:
 - 256 or 128 bit divide maybe replaced by 64 bit divide or shift
 - 256 or 128 bit modulo maybe replaced by 64 bit modulo or bitwise and
 
-.. code-block:: solidity
-
-    contract test {
-        function f() public {
-            for (uint i = 0; i < 10; i++) {
-                // this multiply can be done with a 64 bit instruction
-                g(i * 100));
-            }
-        }
-
-        function g(uint256 v) internal {
-            // ...
-        }
-    }
+.. include:: ./examples/strength_reduce.sol
+  :code: solidity
 
 Solang uses reaching definitions to track the known bits of the variables; here solang knows that i can have
 the values 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and the other operand is always 100. So, the multiplication can be
@@ -75,23 +63,8 @@ redundant load from and store to contract storage. If the same variable is read
 the first load is re-used. Similarly, if there is are two successive stores to the same variable, the first
 one is removed as it is redundant. For example:
 
-.. code-block:: solidity
-
-    contract test {
-        int a;
-
-        // this function reads a twice; this can be reduced to one load
-        function redundant_load() public returns (int) {
-            return a + a;
-        }
-
-        // this function writes to contract storage thrice. This can be reduced to one
-        function redundant_store() public {
-            delete a;
-            a = 1;
-            a = 2;
-        }
-    }
+.. include:: ./examples/dead_storage_elimination.sol
+  :code: solidity
 
 This optimization pass can be disabled by running `solang --no-dead-storage`. You can see the difference between
 having this optimization pass on by comparing the output of `solang --no-dead-storage --emit cfg foo.sol` with
@@ -106,29 +79,8 @@ A `bytes` or `string` variable can be stored in a vector, which is a modifyable
 which is a pointer to readonly memory and an a length. Since a vector is modifyable, each instance requires
 a allocation. For example:
 
-.. code-block:: solidity
-
-    contract test {
-        function can_be_slice() public {
-            // v can just be a pointer to constant memory and an a length indicator
-            string v = "Hello, World!";
-
-            print(v);
-        }
-
-        function must_be_vector() public {
-            // if v is a vector, then it needs to allocated and default value copied.
-            string v = "Hello, World!";
-
-            // bs is copied by reference is now modifyable
-            bytes bs = v;
-
-
-            bs[1] = 97;
-
-            print(v);
-        }
-    }
+.. include:: ./examples/vector_to_slice_optimization.sol
+  :code: solidity
 
 This optimization pass can be disabled by running `solang --no-vector-to-slice`. You can see the difference between
 having this optimization pass on by comparing the output of `solang --no-vector-to-slice --emit cfg foo.sol` with
@@ -143,22 +95,8 @@ Unused Variable Elimination
 During the semantic analysis, Solang detects unused variables and raises warnings for them.
 During codegen, we remove all assignments that have been made to this unused variable. There is an example below:
 
-.. code-block:: solidity
-
-    contract test {
-
-        function test1(int a) public pure returns (int) {
-            int x = 5;
-            x++;
-            if (a > 0) {
-                x = 5;
-            }
-
-            a = (x=3) + a*4;
-
-            return a;
-        }
-    }
+.. include:: ./examples/unused_variable_elimination.sol
+  :code: solidity
 
 The variable 'x' will be removed from the function, as it has never been used. The removal won't affect any
 expressions inside the function.
@@ -176,21 +114,8 @@ of the expression. To disable this feature, use `solang --no-cse`.
 
 Check out the example below. It contains multiple common subexpressions:
 
-.. code-block:: solidity
-
-     contract test {
-
-         function csePass(int a, int b) public pure returns (int) {
-             int x = a*b-5;
-             if (x > 0) {
-                 x = a*b-19;
-             } else {
-                 x = a*b*a;
-             }
-
-             return x+a*b;
-         }
-     }
+.. include:: ./examples/common_subexpression_elimination.sol
+  :code: solidity
 
 The expression `a*b` is repeated throughout the function and will be saved to a temporary variable.
 This temporary will be placed wherever there is an expression `a*b`. You can see the pass in action when you compile
@@ -204,16 +129,8 @@ Array Bound checks optimization
 Whenever an array access is done, there must be a check for ensuring we are not accessing
 beyond the end of an array. Sometimes, the array length could be known. For example:
 
-.. code-block::
-
-    contract c {
-    
-        function test() public returns (int256[]) {
-            int256[] array = new int256[](3);
-            array[1] = 1;
-            return array;
-        }
-    }
+.. include:: ./examples/array_bounds_check_optimization.sol
+  :code: solidity
 
 In this example we access ``array`` element 1, while the array length is 3. So, no bounds
 checks are necessary and the code will more efficient if we do not emit the bounds check in

+ 7 - 0
docs/examples/abi_encode_call.sol

@@ -0,0 +1,7 @@
+contract c {
+    function f1() public {
+        bytes foo = abi.encodeCall(c.bar, 102, true);
+    }
+
+    function bar(int256 a, bool b) public {}
+}

+ 3 - 0
docs/examples/abstract_contract.sol

@@ -0,0 +1,3 @@
+abstract contract a {
+    function func2() public virtual;
+}

+ 15 - 0
docs/examples/abstract_contract_inheritance.sol

@@ -0,0 +1,15 @@
+abstract contract a is b {
+    constructor() {}
+}
+
+contract b {
+    int256 public j;
+
+    constructor(int256 _j) {}
+}
+
+contract c is a {
+    int256 public k;
+
+    constructor(int256 k) b(k * 2) {}
+}

+ 7 - 0
docs/examples/array_bounds_check_optimization.sol

@@ -0,0 +1,7 @@
+contract c {
+    function test() public returns (int256[]) {
+        int256[] array = new int256[](3);
+        array[1] = 1;
+        return array;
+    }
+}

+ 11 - 0
docs/examples/array_type_dynamic.sol

@@ -0,0 +1,11 @@
+contract dynamicarray {
+    function test(uint32 size) public {
+        int64[] memory a = new int64[](size);
+
+        for (uint32 i = 0; i < size; i++) {
+            a[i] = 1 << i;
+        }
+
+        assert(a.length == size);
+    }
+}

+ 15 - 0
docs/examples/array_type_dynamic_push.sol

@@ -0,0 +1,15 @@
+contract example {
+    struct user {
+        address who;
+        uint32 hitcount;
+    }
+    user[] foo;
+
+    function test() public {
+        // foo.push() creates an empty entry and returns a reference to it
+        user storage x = foo.push();
+
+        x.who = address(1);
+        x.hitcount = 1;
+    }
+}

+ 18 - 0
docs/examples/array_type_dynamic_storage.sol

@@ -0,0 +1,18 @@
+contract s {
+    int64[] a;
+
+    function test() public {
+        // push takes a single argument with the item to be added
+        a.push(128);
+        // push with no arguments adds 0
+        a.push();
+        // now we have two elements in our array, 128 and 0
+        assert(a.length == 2);
+        a[0] |= 64;
+        // pop removes the last element
+        a.pop();
+        // you can assign the return value of pop
+        int64 v = a.pop();
+        assert(v == 192);
+    }
+}

+ 16 - 0
docs/examples/array_type_fixed_length.sol

@@ -0,0 +1,16 @@
+contract foo {
+    /// In a vote with 11 voters, do the ayes have it?
+    function f(bool[11] votes) public pure returns (bool) {
+        uint32 i;
+        uint32 ayes = 0;
+
+        for (i = 0; i < votes.length; i++) {
+            if (votes[i]) {
+                ayes += 1;
+            }
+        }
+
+        // votes.length is odd; integer truncation means that 11 / 2 = 5
+        return ayes > votes.length / 2;
+    }
+}

+ 7 - 0
docs/examples/array_type_initialized.sol

@@ -0,0 +1,7 @@
+contract primes {
+    function primenumber(uint32 n) public pure returns (uint64) {
+        uint64[10] primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];
+
+        return primes[n];
+    }
+}

+ 14 - 0
docs/examples/array_type_references.sol

@@ -0,0 +1,14 @@
+abstract contract reference {
+    function set_2(int8[4] a) private pure {
+        a[2] = 102;
+    }
+
+    function foo() private {
+        int8[4] val = [1, 2, 3, 4];
+
+        set_2(val);
+
+        // val was passed by reference, so was modified
+        assert(val[2] == 102);
+    }
+}

+ 7 - 0
docs/examples/assert.sol

@@ -0,0 +1,7 @@
+abstract contract x {
+    constructor(address foobar) {
+        if (foobar == address(0)) {
+            revert("foobar must a valid address");
+        }
+    }
+}

+ 27 - 0
docs/examples/base_contract_function_call.sol

@@ -0,0 +1,27 @@
+contract b is a {
+    function baz() public pure returns (uint64) {
+        return foo();
+    }
+
+    function foo() internal pure override returns (uint64) {
+        return 2;
+    }
+}
+
+abstract contract a {
+    function foo() internal virtual returns (uint64) {
+        return 1;
+    }
+
+    function bar() internal returns (uint64) {
+        // since foo() is virtual, is a virtual dispatch call
+        // when foo is called and a is a base contract of b, then foo in contract b will
+        // be called; foo will return 2.
+        return foo();
+    }
+
+    function bar2() internal returns (uint64) {
+        // this explicitly says "call foo of base contract a", and dispatch is not virtual
+        return a.foo();
+    }
+}

+ 12 - 0
docs/examples/common_subexpression_elimination.sol

@@ -0,0 +1,12 @@
+contract test {
+    function csePass(int256 a, int256 b) public pure returns (int256) {
+        int256 x = a * b - 5;
+        if (x > 0) {
+            x = a * b - 19;
+        } else {
+            x = a * b * a;
+        }
+
+        return x + a * b;
+    }
+}

+ 19 - 0
docs/examples/contract_inheritance.sol

@@ -0,0 +1,19 @@
+contract a is b, c {
+    constructor() {}
+}
+
+contract b {
+    int256 foo;
+
+    function func2() public {}
+
+    constructor() {}
+}
+
+contract c {
+    int256 bar;
+
+    constructor() {}
+
+    function func1() public {}
+}

+ 22 - 0
docs/examples/contract_multiple_inheritance.sol

@@ -0,0 +1,22 @@
+contract a is b1, b2 {
+    function baz() public returns (uint64) {
+        // this will return 100
+        return super.foo();
+    }
+
+    function foo() internal override(b1, b2) returns (uint64) {
+        return 2;
+    }
+}
+
+abstract contract b1 {
+    function foo() internal virtual returns (uint64) {
+        return 100;
+    }
+}
+
+abstract contract b2 {
+    function foo() internal virtual returns (uint64) {
+        return 200;
+    }
+}

+ 20 - 0
docs/examples/contract_new.sol

@@ -0,0 +1,20 @@
+contract hatchling {
+    string name;
+    address private origin;
+
+    constructor(string id, address parent) {
+        require(id != "", "name must be provided");
+        name = id;
+        origin = parent;
+    }
+
+    function root() public returns (address) {
+        return origin;
+    }
+}
+
+contract adult {
+    function test() public {
+        hatchling h = new hatchling("luna", address(this));
+    }
+}

+ 19 - 0
docs/examples/contract_recursive_inheritance.sol

@@ -0,0 +1,19 @@
+contract a is b {
+    constructor() {}
+}
+
+contract b is c {
+    int256 foo;
+
+    function func2() public {}
+
+    constructor() {}
+}
+
+contract c {
+    int256 bar;
+
+    constructor() {}
+
+    function func1() public {}
+}

+ 7 - 0
docs/examples/contract_storage.sol

@@ -0,0 +1,7 @@
+contract hitcount {
+    uint256 public counter = 1;
+
+    function hit() public {
+        counter++;
+    }
+}

+ 9 - 0
docs/examples/contract_storage_accessor.sol

@@ -0,0 +1,9 @@
+contract ethereum {
+    // As a public mapping, this creates accessor function called balance, which takes
+    // an address as an argument, and returns an uint
+    mapping(address => uint256) public balances;
+
+    // A public array takes the index as an uint argument and returns the element,
+    // in this case string.
+    string[] users;
+}

+ 9 - 0
docs/examples/contract_storage_accessor_override.sol

@@ -0,0 +1,9 @@
+contract foo is bar {
+    int256 public override baz;
+}
+
+contract bar {
+    function baz() public virtual returns (int256) {
+        return 512;
+    }
+}

+ 13 - 0
docs/examples/contract_storage_clear.sol

@@ -0,0 +1,13 @@
+contract s {
+    struct user {
+        address f1;
+        int256[] list;
+    }
+    user[1000] users;
+
+    function clear() public {
+        // delete has to iterate over 1000 users, and for each of those clear the
+        // f1 field, read the length of the list, and iterate over each of those
+        delete users;
+    }
+}

+ 12 - 0
docs/examples/contract_storage_immutable.sol

@@ -0,0 +1,12 @@
+contract foo {
+    uint256 public immutable bar;
+
+    constructor(uint256 v) {
+        bar = v;
+    }
+
+    function hit() public {
+        // this is not permitted
+        // bar++;
+    }
+}

+ 13 - 0
docs/examples/contract_type.sol

@@ -0,0 +1,13 @@
+contract child {
+    function announce() public {
+        print("Greetings from child contract");
+    }
+}
+
+contract creator {
+    function test() public {
+        child c = new child();
+
+        c.announce();
+    }
+}

+ 5 - 0
docs/examples/contract_type_cast_address.sol

@@ -0,0 +1,5 @@
+contract example {
+    function get_address() public returns (address) {
+        return address(this);
+    }
+}

+ 15 - 0
docs/examples/dead_storage_elimination.sol

@@ -0,0 +1,15 @@
+contract test {
+    int256 a;
+
+    // this function reads a twice; this can be reduced to one load
+    function redundant_load() public returns (int256) {
+        return a + a;
+    }
+
+    // this function writes to contract storage thrice. This can be reduced to one
+    function redundant_store() public {
+        delete a;
+        a = 1;
+        a = 2;
+    }
+}

+ 10 - 0
docs/examples/dynamic_bytes_type.sol

@@ -0,0 +1,10 @@
+contract b {
+    function test() public {
+        bytes a = hex"0000_00fa";
+        bytes b = new bytes(4);
+
+        b[3] = hex"fa";
+
+        assert(a == b);
+    }
+}

+ 15 - 0
docs/examples/enum_type.sol

@@ -0,0 +1,15 @@
+contract enum_example {
+    enum Weekday {
+        Monday,
+        Tuesday,
+        Wednesday,
+        Thursday,
+        Friday,
+        Saturday,
+        Sunday
+    }
+
+    function is_weekend(Weekday day) public pure returns (bool) {
+        return (day == Weekday.Saturday || day == Weekday.Sunday);
+    }
+}

+ 42 - 0
docs/examples/enum_type_external.sol

@@ -0,0 +1,42 @@
+enum planets {
+    Mercury,
+    Venus,
+    Earth,
+    Mars,
+    Jupiter,
+    Saturn,
+    Uranus,
+    Neptune
+}
+
+abstract contract timeofday {
+    enum time {
+        Night,
+        Day,
+        Dawn,
+        Dusk
+    }
+}
+
+contract stargazing {
+    function look_for(timeofday.time when) public returns (planets[]) {
+        if (when == timeofday.time.Dawn || when == timeofday.time.Dusk) {
+            planets[] x = new planets[](2);
+            x[0] = planets.Mercury;
+            x[1] = planets.Venus;
+            return x;
+        } else if (when == timeofday.time.Night) {
+            planets[] x = new planets[](5);
+            x[0] = planets.Mars;
+            x[1] = planets.Jupiter;
+            x[2] = planets.Saturn;
+            x[3] = planets.Uranus;
+            x[4] = planets.Neptune;
+            return x;
+        } else {
+            planets[] x = new planets[](1);
+            x[0] = planets.Earth;
+            return x;
+        }
+    }
+}

+ 19 - 0
docs/examples/event_positional_fields.sol

@@ -0,0 +1,19 @@
+event UserModified(
+    address user,
+    string name
+) anonymous;
+
+event UserModified(
+    address user,
+    uint64 groupid
+);
+
+contract user {
+    function set_name(string name) public {
+        emit UserModified({ user: msg.sender, name: name });
+    }
+
+    function set_groupid(uint64 id) public {
+        emit UserModified({ user: msg.sender, groupid: id });
+    }
+}

+ 11 - 0
docs/examples/events.sol

@@ -0,0 +1,11 @@
+event CounterpartySigned (
+    address indexed party,
+    address counter_party,
+    uint contract_no
+);
+
+contract Signer {
+    function sign(address counter_party, uint contract_no) public {
+        emit CounterpartySigned(address(this), counter_party, contract_no);
+    }
+}

+ 6 - 0
docs/examples/expression_this.sol

@@ -0,0 +1,6 @@
+contract kadowari {
+    function nomi() public {
+        kadowari c = this;
+        address a = address(this);
+    }
+}

+ 9 - 0
docs/examples/expression_this_external_call.sol

@@ -0,0 +1,9 @@
+contract kadowari {
+    function nomi() public {
+        this.nokogiri(102);
+    }
+
+    function nokogiri(int256 a) public {
+        // ...
+    }
+}

+ 7 - 0
docs/examples/expression_unchecked.sol

@@ -0,0 +1,7 @@
+contract foo {
+    function f(int64 n) public {
+        unchecked {
+            int64 j = n - 1;
+        }
+    }
+}

+ 14 - 0
docs/examples/function_arguments.sol

@@ -0,0 +1,14 @@
+contract foo {
+    function bar(uint32 x, bool y) public returns (uint32) {
+        if (y) {
+            return 2;
+        }
+
+        return 3;
+    }
+
+    function test() public {
+        uint32 a = bar(102, false);
+        a = bar({y: true, x: 302});
+    }
+}

+ 29 - 0
docs/examples/function_call.sol

@@ -0,0 +1,29 @@
+contract a {
+    function test() public {
+        b v = new b();
+
+        // the following four lines are equivalent to "uint32 res = v.foo(3,5);"
+
+        // Note that the signature is only hashed and not parsed. So, ensure that the
+        // arguments are of the correct type.
+        bytes data = abi.encodeWithSignature(
+            "foo(uint32,uint32)",
+            uint32(3),
+            uint32(5)
+        );
+
+        (bool success, bytes rawresult) = address(v).call(data);
+
+        assert(success == true);
+
+        uint32 res = abi.decode(rawresult, (uint32));
+
+        assert(res == 8);
+    }
+}
+
+contract b {
+    function foo(uint32 a, uint32 b) public returns (uint32) {
+        return a + b;
+    }
+}

+ 16 - 0
docs/examples/function_call_external.sol

@@ -0,0 +1,16 @@
+contract foo {
+    function bar1(uint32 x, bool y) public returns (address, bytes32) {
+        return (address(3), hex"01020304");
+    }
+
+    function bar2(uint32 x, bool y) public returns (bool) {
+        return !y;
+    }
+}
+
+contract bar {
+    function test(foo f) public {
+        (address f1, bytes32 f2) = f.bar1(102, false);
+        bool f3 = f.bar2({x: 255, y: true});
+    }
+}

+ 14 - 0
docs/examples/function_destructing_arguments.sol

@@ -0,0 +1,14 @@
+contract foo {
+    function bar1(uint32 x, bool y) public returns (address, bytes32) {
+        return (address(3), hex"01020304");
+    }
+
+    function bar2(uint32 x, bool y) public returns (bool) {
+        return !y;
+    }
+
+    function test() public {
+        (address f1, bytes32 f2) = bar1(102, false);
+        bool f3 = bar2({x: 255, y: true});
+    }
+}

+ 13 - 0
docs/examples/function_modifier.sol

@@ -0,0 +1,13 @@
+contract example {
+    address owner;
+
+    modifier only_owner() {
+        require(msg.sender == owner);
+        _;
+        // insert post conditions here
+    }
+
+    function foo() public only_owner {
+        // ...
+    }
+}

+ 11 - 0
docs/examples/function_modifier_arguments.sol

@@ -0,0 +1,11 @@
+contract example {
+    modifier check_price(int64 price) {
+        if (price >= 50) {
+            _;
+        }
+    }
+
+    function foo(int64 price) public check_price(price) {
+        // ...
+    }
+}

+ 19 - 0
docs/examples/function_multiple_modifiers.sol

@@ -0,0 +1,19 @@
+contract example {
+    address owner;
+
+    // a modifier with no arguments does not need "()" in its declaration
+    modifier only_owner() {
+        require(msg.sender == owner);
+        _;
+    }
+
+    modifier check_price(int64 price) {
+        if (price >= 50) {
+            _;
+        }
+    }
+
+    function foo(int64 price) public only_owner check_price(price) {
+        // ...
+    }
+}

+ 23 - 0
docs/examples/function_overloading.sol

@@ -0,0 +1,23 @@
+contract shape {
+    int64 bar;
+
+    function abs(int256 val) public returns (int256) {
+        if (val >= 0) {
+            return val;
+        } else {
+            return -val;
+        }
+    }
+
+    function abs(int64 val) public returns (int64) {
+        if (val >= 0) {
+            return val;
+        } else {
+            return -val;
+        }
+    }
+
+    function foo(int64 x) public {
+        bar = int64(abs(x));
+    }
+}

+ 26 - 0
docs/examples/function_override_modifiers.sol

@@ -0,0 +1,26 @@
+abstract contract base {
+    address owner;
+
+    modifier only_owner() {
+        require(msg.sender == owner);
+        _;
+    }
+
+    modifier check_price(int64 price) virtual {
+        if (price >= 10) {
+            _;
+        }
+    }
+}
+
+contract example is base {
+    modifier check_price(int64 price) override {
+        if (price >= 50) {
+            _;
+        }
+    }
+
+    function foo(int64 price) public only_owner check_price(price) {
+        // ...
+    }
+}

+ 5 - 0
docs/examples/function_selector_override.sol

@@ -0,0 +1,5 @@
+contract foo {
+    function get_foo() selector=hex"01020304" public returns (int) {
+        return 102;
+    }
+}

+ 25 - 0
docs/examples/function_type.sol

@@ -0,0 +1,25 @@
+contract ft {
+    function test() public {
+        // reference to an internal function with two argments, returning bool
+        // with the default mutability (i.e. cannot be payable)
+        function(int32, bool) internal returns (bool) x;
+
+        // the local function func1 can be assigned to this type; mutability
+        // can be more restrictive than the type.
+        x = func1;
+
+        // now you can call func1 via the x
+        bool res = x(102, false);
+
+        // reference to an internal function with no return values, must be pure
+        function(int32, bool) internal pure y;
+
+        // Does not compile:
+        // Wrong number of return types and mutability is not compatible
+        // y = func1;
+    }
+
+    function func1(int32 arg, bool arg2) internal view returns (bool) {
+        return false;
+    }
+}

+ 24 - 0
docs/examples/function_type_callback.sol

@@ -0,0 +1,24 @@
+contract ft {
+    function test(paffling p) public {
+        // this.callback can be used as an external function type value
+        p.set_callback(this.callback);
+    }
+
+    function callback(int32 count, string foo) public {
+        // ...
+    }
+}
+
+contract paffling {
+    // the first visibility "external" is for the function type, the second "internal" is
+    // for the callback variables
+    function(int32, string) external internal callback;
+
+    function set_callback(function(int32, string) external c) public {
+        callback = c;
+    }
+
+    function piffle() public {
+        callback(1, "paffled");
+    }
+}

+ 23 - 0
docs/examples/functions.sol

@@ -0,0 +1,23 @@
+// get_initial_bound is called from the constructor
+function get_initial_bound() returns (uint256 value) {
+    value = 102;
+}
+
+contract foo {
+    uint256 bound = get_initial_bound();
+
+    /** set bound for get with bound */
+    function set_bound(uint256 _bound) public {
+        bound = _bound;
+    }
+
+    // Clamp a value within a bound.
+    // The bound can be set with set_bound().
+    function get_with_bound(uint256 value) public view returns (uint256) {
+        if (value < bound) {
+            return value;
+        } else {
+            return bound;
+        }
+    }
+}

+ 19 - 0
docs/examples/inherited_constructor_arguments.sol

@@ -0,0 +1,19 @@
+contract a is b(1) {
+    constructor() {}
+}
+
+contract b is c(2) {
+    int256 foo;
+
+    function func2(int256 i) public {}
+
+    constructor(int256 j) {}
+}
+
+contract c {
+    int256 bar;
+
+    constructor(int32 j) {}
+
+    function func1() public {}
+}

+ 19 - 0
docs/examples/inherited_constructor_runtime_arguments.sol

@@ -0,0 +1,19 @@
+contract a is b {
+    constructor(int256 i) b(i + 2) {}
+}
+
+contract b is c {
+    int256 foo;
+
+    function func2() public {}
+
+    constructor(int256 j) c(int32(j + 3)) {}
+}
+
+contract c {
+    int256 bar;
+
+    constructor(int32 k) {}
+
+    function func1() public {}
+}

+ 27 - 0
docs/examples/inline_assembly.sol

@@ -0,0 +1,27 @@
+contract foo {
+    struct test_stru {
+        uint256 a;
+        uint256 b;
+    }
+
+    function bar(uint64 a) public pure returns (uint64 ret) {
+        uint64 b = 6;
+        uint64[] memory vec;
+        vec.push(4);
+        string str = "cafe";
+        test_stru tts = test_stru({a: 1, b: 2});
+        assembly {
+            // The following statements modify variables directly
+            a := add(a, 3)
+            b := mul(b, 2)
+            ret := sub(a, b)
+
+            // The following modify the reference address
+            str := 5
+            vec := 6
+            tts := 7
+        }
+
+        // Any access to 'str', 'vec' or 'tts' here may crash the program.
+    }
+}

+ 23 - 0
docs/examples/inline_assembly_calldata.sol

@@ -0,0 +1,23 @@
+contract foo {
+    struct test_stru {
+        uint256 a;
+        uint256 b;
+    }
+
+    test_stru storage_struct;
+
+    function bar(int256[] calldata vl) public pure {
+        test_stru storage tts = storage_struct;
+        assembly {
+            // 'a' contains vl memory address
+            let a := vl.offset
+
+            // 'b' contains vl length
+            let b := vl.length
+
+            // This will change the reference of vl
+            vl.offset := 5
+        }
+        // Any usage of vl here may crash the program
+    }
+}

+ 16 - 0
docs/examples/inline_assembly_external_functions.sol

@@ -0,0 +1,16 @@
+contract foo {
+    function sum(uint64 a, uint64 b) public pure returns (uint64) {
+        return a + b;
+    }
+
+    function bar() public view {
+        function (uint64, uint64) external returns (uint64) fPtr = this.sum;
+        assembly {
+            // 'a' contains 'sum' selector
+            let a := fPtr.selector
+
+            // 'b' contains 'sum' address
+            let b := fPtr.address
+        }
+    }
+}

+ 20 - 0
docs/examples/inline_assembly_storage.sol

@@ -0,0 +1,20 @@
+contract foo {
+    struct test_stru {
+        uint256 a;
+        uint256 b;
+    }
+
+    test_stru storage_struct;
+
+    function bar() public pure {
+        test_stru storage tts = storage_struct;
+        assembly {
+            // The variables 'a' and 'b' contain zero
+            let a := storage_struct.offset
+            let b := tts.offset
+
+            // This changes the reference slot of 'tts'
+            tts.slot := 5
+        }
+    }
+}

+ 41 - 0
docs/examples/interface.sol

@@ -0,0 +1,41 @@
+interface operator {
+    function op1(int32 a, int32 b) external returns (int32);
+
+    function op2(int32 a, int32 b) external returns (int32);
+}
+
+contract ferqu {
+    operator op;
+
+    constructor(bool do_adds) {
+        if (do_adds) {
+            op = new m1();
+        } else {
+            op = new m2();
+        }
+    }
+
+    function x(int32 b) public returns (int32) {
+        return op.op1(102, b);
+    }
+}
+
+contract m1 is operator {
+    function op1(int32 a, int32 b) public override returns (int32) {
+        return a + b;
+    }
+
+    function op2(int32 a, int32 b) public override returns (int32) {
+        return a - b;
+    }
+}
+
+contract m2 is operator {
+    function op1(int32 a, int32 b) public override returns (int32) {
+        return a * b;
+    }
+
+    function op2(int32 a, int32 b) public override returns (int32) {
+        return a / b;
+    }
+}

+ 11 - 0
docs/examples/library.sol

@@ -0,0 +1,11 @@
+contract test {
+    function foo(uint64 x) public pure returns (uint64) {
+        return ints.max(x, 65536);
+    }
+}
+
+library ints {
+    function max(uint64 a, uint64 b) public pure returns (uint64) {
+        return a > b ? a : b;
+    }
+}

+ 19 - 0
docs/examples/library_using_for.sol

@@ -0,0 +1,19 @@
+contract test {
+    using lib for int32[100];
+
+    int32[100] bar;
+
+    function foo() public {
+        bar.set(10, 571);
+    }
+}
+
+library lib {
+    function set(
+        int32[100] storage a,
+        uint256 index,
+        int32 val
+    ) internal {
+        a[index] = val;
+    }
+}

+ 26 - 0
docs/examples/mapping_type.sol

@@ -0,0 +1,26 @@
+contract b {
+    struct user {
+        bool exists;
+        address addr;
+    }
+    mapping(string => user) users;
+
+    function add(string name, address addr) public {
+        // assigning to a storage variable creates a reference
+        user storage s = users[name];
+
+        s.exists = true;
+        s.addr = addr;
+    }
+
+    function get(string name) public view returns (bool, address) {
+        // assigning to a memory variable creates a copy
+        user s = users[name];
+
+        return (s.exists, s.addr);
+    }
+
+    function rm(string name) public {
+        delete users[name];
+    }
+}

+ 13 - 0
docs/examples/multiple_contracts.sol

@@ -0,0 +1,13 @@
+contract A {
+    /// foo simply returns true
+    function foo() public returns (bool) {
+        return true;
+    }
+}
+
+contract B {
+    /// bar simply returns false
+    function bar() public returns (bool) {
+        return false;
+    }
+}

+ 5 - 0
docs/examples/print.sol

@@ -0,0 +1,5 @@
+abstract contract c {
+    constructor() {
+        print("Hello, world!");
+    }
+}

+ 5 - 0
docs/examples/require.sol

@@ -0,0 +1,5 @@
+abstract contract x {
+    constructor(address foobar) {
+        require(foobar != address(0), "foobar must a valid address");
+    }
+}

+ 11 - 0
docs/examples/retrieve_contract_code.sol

@@ -0,0 +1,11 @@
+contract example {
+    function test() public {
+        bytes runtime = type(other).runtimeCode;
+    }
+}
+
+contract other {
+    function foo() public returns (bool) {
+        return true;
+    }
+}

+ 5 - 0
docs/examples/revert.sol

@@ -0,0 +1,5 @@
+abstract contract c {
+    constructor(int256 x) {
+        assert(x > 0);
+    }
+}

+ 13 - 0
docs/examples/scoping.sol

@@ -0,0 +1,13 @@
+contract Foo {
+    function foo() public {
+        // new block is introduced with { and ends with }
+        {
+            uint256 a;
+
+            a = 102;
+        }
+
+        // ERROR: a is out of scope
+        // uint256 b = a + 5;
+    }
+}

+ 9 - 0
docs/examples/shadowing.sol

@@ -0,0 +1,9 @@
+contract test {
+    uint256 foo = 102;
+    uint256 bar;
+
+    function foobar() public {
+        // AVOID: this shadows the contract storage variable foo
+        uint256 foo = 5;
+    }
+}

+ 24 - 0
docs/examples/solana/accountinfo.sol

@@ -0,0 +1,24 @@
+import {AccountInfo} from "solana";
+
+contract SplToken {
+    function get_token_account(address token)
+        internal
+        view
+        returns (AccountInfo)
+    {
+        for (uint64 i = 0; i < tx.accounts.length; i++) {
+            AccountInfo ai = tx.accounts[i];
+            if (ai.key == token) {
+                return ai;
+            }
+        }
+
+        revert("token not found");
+    }
+
+    function total_supply(address token) public view returns (uint64) {
+        AccountInfo account = get_token_account(token);
+
+        return account.data.readUint64LE(33);
+    }
+}

+ 9 - 0
docs/examples/solana/builtin_create_program_address.sol

@@ -0,0 +1,9 @@
+import {create_program_address} from 'solana';
+
+contract pda {
+    address token = address"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
+
+    function create_pda(bytes seed2) public returns (address) {
+        return create_program_address(["kabang", seed2], token);
+    }
+}

+ 9 - 0
docs/examples/solana/builtin_try_find_program_address.sol

@@ -0,0 +1,9 @@
+import {try_find_program_address} from 'solana';
+
+contract pda {
+    address token = address"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
+
+    function create_pda(bytes seed2) public returns (address, bytes1) {
+        return try_find_program_address(["kabang", seed2], token);
+    }
+}

+ 16 - 0
docs/examples/solana/call_anchor.sol

@@ -0,0 +1,16 @@
+import "bobcat.sol";
+import "solana";
+
+contract example {
+    function test(address a, address b) public {
+        // The list of accounts to pass into the Anchor program must be passed
+        // as an array of AccountMeta with the correct writable/signer flags set
+        AccountMeta[2] am = [
+            AccountMeta({pubkey: a, is_writable: true, is_signer: false}),
+            AccountMeta({pubkey: b, is_writable: false, is_signer: false})
+        ];
+
+        // Any return values are decoded automatically
+        int64 res = bobcat.pounce{accounts: am}();
+    }
+}

+ 14 - 0
docs/examples/solana/contract_space.sol

@@ -0,0 +1,14 @@
+contract hatchling {
+    string name;
+
+    constructor(string id) payable {
+        require(id != "", "name must be provided");
+        name = id;
+    }
+}
+
+contract adult {
+    function test() public {
+        hatchling h = new hatchling{space: 10240}("luna");
+    }
+}

+ 31 - 0
docs/examples/solana/function_call_external_accounts.sol

@@ -0,0 +1,31 @@
+import {AccountMeta} from 'solana';
+
+contract SplToken {
+    address constant tokenProgramId = address"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
+    address constant SYSVAR_RENT_PUBKEY = address"SysvarRent111111111111111111111111111111111";
+
+    struct InitializeMintInstruction {
+        uint8 instruction;
+        uint8 decimals;
+        address mintAuthority;
+        uint8 freezeAuthorityOption;
+        address freezeAuthority;
+    }
+
+    function create_mint_with_freezeauthority(uint8 decimals, address mintAuthority, address freezeAuthority) public {
+        InitializeMintInstruction instr = InitializeMintInstruction({
+            instruction: 0,
+            decimals: decimals,
+            mintAuthority: mintAuthority,
+            freezeAuthorityOption: 1,
+            freezeAuthority: freezeAuthority
+        });
+
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: instr.mintAuthority, is_writable: true, is_signer: false}),
+            AccountMeta({pubkey: SYSVAR_RENT_PUBKEY, is_writable: false, is_signer: false})
+        ];
+
+        tokenProgramId.call{accounts: metas}(instr);
+    }
+}

+ 18 - 0
docs/examples/solana/function_call_external_seeds.sol

@@ -0,0 +1,18 @@
+import 'solana';
+
+contract c {
+    address constant token = address"mv3ekLzLbnVPNxjSKvqBpU3ZeZXPQdEC3bp5MDEBG68";
+
+    function test(address addr, address addr2, bytes seed) public {
+        bytes instr = new bytes(1);
+
+        instr[0] = 1;
+
+        AccountMeta[2] metas = [
+            AccountMeta({pubkey: addr, is_writable: true, is_signer: true}),
+            AccountMeta({pubkey: addr2, is_writable: true, is_signer: true})
+        ];
+
+        token.call{accounts: metas, seeds: [ [ "test", seed ], [ "foo", "bar "] ]}(instr);
+    }
+}

+ 10 - 0
docs/examples/statement_destructing.sol

@@ -0,0 +1,10 @@
+contract destructure {
+    function func() internal returns (bool, int32, string) {
+        return (true, 5, "abcd");
+    }
+
+    function test() public {
+        string s;
+        (bool b, , s) = func();
+    }
+}

+ 5 - 0
docs/examples/statement_destructing_conditional.sol

@@ -0,0 +1,5 @@
+contract Foo {
+    function test(bool cond) public {
+        (int32 a, int32 b, int32 c) = cond ? (1, 2, 3) : (4, 5, 6);
+    }
+}

+ 7 - 0
docs/examples/statement_destructing_swapping.sol

@@ -0,0 +1,7 @@
+contract Foo {
+    function test() public {
+        (int32 a, int32 b, int32 c) = (1, 2, 3);
+
+        (b, , a) = (a, 5, b);
+    }
+}

+ 23 - 0
docs/examples/statement_do_while.sol

@@ -0,0 +1,23 @@
+contract Foo {
+    function bar(uint256 n) public returns (bool) {
+        return false;
+    }
+
+    function foo(uint256 n) public {
+        do {
+            n--;
+
+            if (n >= 100) {
+                // do not execute the if statement below, but loop again
+                continue;
+            }
+
+            if (bar(n)) {
+                // cease execution of this while loop and jump to the "n = 102" statement
+                break;
+            }
+        } while (n > 10);
+
+        n = 102;
+    }
+}

+ 7 - 0
docs/examples/statement_for.sol

@@ -0,0 +1,7 @@
+contract Foo {
+    function foo() public {
+        for (uint256 i = 0; i <= 1000; i += 100) {
+            // ...
+        }
+    }
+}

+ 11 - 0
docs/examples/statement_for_abort.sol

@@ -0,0 +1,11 @@
+contract Foo {
+    function foo(uint256 n) public {
+        // all three omitted
+        for (;;) {
+            // there must be a way out
+            if (n == 0) {
+                break;
+            }
+        }
+    }
+}

+ 12 - 0
docs/examples/statement_if.sol

@@ -0,0 +1,12 @@
+contract Foo {
+    function foo(uint32 n) public {
+        if (n > 10) {
+            // do something
+        }
+
+        // ERROR: unlike C integers can not be used as a condition
+        // if (n) {
+        //     // ...
+        // }
+    }
+}

+ 9 - 0
docs/examples/statement_if_else.sol

@@ -0,0 +1,9 @@
+contract Foo {
+    function foo(uint32 n) public {
+        if (n > 10) {
+            // do something
+        } else {
+            // do something different
+        }
+    }
+}

+ 7 - 0
docs/examples/statement_while.sol

@@ -0,0 +1,7 @@
+contract Foo {
+    function foo(uint256 n) public {
+        while (n >= 10) {
+            n -= 9;
+        }
+    }
+}

+ 26 - 0
docs/examples/statement_while_break.sol

@@ -0,0 +1,26 @@
+contract Foo {
+    function bar(uint256 n) public returns (bool) {
+        return false;
+    }
+
+    function foo(uint256 n) public {
+        while (n >= 10) {
+            n--;
+
+            if (n >= 100) {
+                // do not execute the if statement below, but loop again
+                continue;
+            }
+
+            if (bar(n)) {
+                // cease execution of this while loop and jump to the "n = 102" statement
+                break;
+            }
+
+            // only executed if both if statements were false
+            print("neither true");
+        }
+
+        n = 102;
+    }
+}

+ 36 - 0
docs/examples/storage_ref_type.sol

@@ -0,0 +1,36 @@
+contract felix {
+    enum Felines {
+        None,
+        Lynx,
+        Felis,
+        Puma,
+        Catopuma
+    }
+    Felines[100] group_a;
+    Felines[100] group_b;
+
+    function count_pumas(Felines[100] storage cats) private returns (uint32) {
+        uint32 count = 0;
+        uint32 i = 0;
+
+        for (i = 0; i < cats.length; i++) {
+            if (cats[i] == Felines.Puma) {
+                ++count;
+            }
+        }
+
+        return count;
+    }
+
+    function all_pumas() public returns (uint32) {
+        Felines[100] storage ref = group_a;
+
+        uint32 total = count_pumas(ref);
+
+        ref = group_b;
+
+        total += count_pumas(ref);
+
+        return total;
+    }
+}

+ 12 - 0
docs/examples/strength_reduce.sol

@@ -0,0 +1,12 @@
+contract test {
+    function f() public {
+        for (uint256 i = 0; i < 10; i++) {
+            // this multiply can be done with a 64 bit instruction
+            g(i * 100);
+        }
+    }
+
+    function g(uint256 v) internal {
+        // ...
+    }
+}

+ 11 - 0
docs/examples/string_type.sol

@@ -0,0 +1,11 @@
+contract example {
+    function test1(string s) public returns (bool) {
+        string str = "Hello, " + s + "!";
+
+        return (str == "Hello, World!");
+    }
+
+    function test2(string s, int64 n) public returns (string res) {
+        res = "Hello, {}! #{}".format(s, n);
+    }
+}

+ 45 - 0
docs/examples/struct_type.sol

@@ -0,0 +1,45 @@
+contract deck {
+    enum suit {
+        club,
+        diamonds,
+        hearts,
+        spades
+    }
+    enum value {
+        two,
+        three,
+        four,
+        five,
+        six,
+        seven,
+        eight,
+        nine,
+        ten,
+        jack,
+        queen,
+        king,
+        ace
+    }
+    struct card {
+        value v;
+        suit s;
+    }
+
+    function score(card c) public returns (uint32 score) {
+        if (c.s == suit.hearts) {
+            if (c.v == value.ace) {
+                score = 14;
+            }
+            if (c.v == value.king) {
+                score = 13;
+            }
+            if (c.v == value.queen) {
+                score = 12;
+            }
+            if (c.v == value.jack) {
+                score = 11;
+            }
+        }
+        // all others score 0
+    }
+}

+ 36 - 0
docs/examples/struct_type_arguments.sol

@@ -0,0 +1,36 @@
+contract deck {
+    enum suit {
+        club,
+        diamonds,
+        hearts,
+        spades
+    }
+    enum value {
+        two,
+        three,
+        four,
+        five,
+        six,
+        seven,
+        eight,
+        nine,
+        ten,
+        jack,
+        queen,
+        king,
+        ace
+    }
+    struct card {
+        value v;
+        suit s;
+    }
+
+    card card1 = card(value.two, suit.club);
+    card card2 = card({s: suit.club, v: value.two});
+
+    // This function does a lot of copying
+    function set_card1(card c) public returns (card previous) {
+        previous = card1;
+        card1 = c;
+    }
+}

+ 17 - 0
docs/examples/struct_type_arguments_external.sol

@@ -0,0 +1,17 @@
+struct user {
+    string name;
+    bool active;
+}
+
+contract auth {
+    function authenticate(string name, db.users users) public {
+        // ...
+    }
+}
+
+abstract contract db {
+    struct users {
+        user[] field1;
+        int32 count;
+    }
+}

+ 21 - 0
docs/examples/struct_type_variable_references.sol

@@ -0,0 +1,21 @@
+contract foo {
+    struct bar {
+        bytes32 f1;
+        bytes32 f2;
+        bytes32 f3;
+        bytes32 f4;
+    }
+
+    function f(bar b) public {
+        b.f4 = "foobar";
+    }
+
+    function example() public {
+        bar bar1;
+
+        // bar1 is passed by reference; just its pointer is passed
+        f(bar1);
+
+        assert(bar1.f4 == "foobar");
+    }
+}

+ 3 - 0
docs/examples/substrate/constructor_named.sol

@@ -0,0 +1,3 @@
+abstract contract Foo {
+    constructor my_new_foo() {}
+}

+ 20 - 0
docs/examples/substrate/contract_gas_limit.sol

@@ -0,0 +1,20 @@
+contract hatchling {
+    string name;
+    address private origin;
+
+    constructor(string id, address parent) {
+        require(id != "", "name must be provided");
+        name = id;
+        origin = parent;
+    }
+
+    function root() public returns (address) {
+        return origin;
+    }
+}
+
+contract adult {
+    function test() public {
+        hatchling h = new hatchling{salt: 0, gas: 10000}("luna", address(this));
+    }
+}

+ 20 - 0
docs/examples/substrate/contract_payable.sol

@@ -0,0 +1,20 @@
+contract hatchling {
+    string name;
+    address private origin;
+
+    constructor(string id, address parent) payable {
+        require(id != "", "name must be provided");
+        name = id;
+        origin = parent;
+    }
+
+    function root() public returns (address) {
+        return origin;
+    }
+}
+
+contract adult {
+    function test() public {
+        hatchling h = new hatchling{value: 500}("luna", address(this));
+    }
+}

+ 13 - 0
docs/examples/substrate/function_call_external_gas.sol

@@ -0,0 +1,13 @@
+contract foo {
+    function bar() public {
+        other o = new other();
+
+        o.feh{value: 102, gas: 5000}(102);
+    }
+}
+
+contract other {
+    function feh(uint32 x) public payable {
+        // ...
+    }
+}

+ 15 - 0
docs/examples/substrate/function_fallback_and_receive.sol

@@ -0,0 +1,15 @@
+contract test {
+    int32 bar;
+
+    function foo(int32 x) public {
+        bar = x;
+    }
+
+    fallback() external {
+        // execute if function selector does not match "foo(uint32)" and no value sent
+    }
+
+    receive() external payable {
+        // execute if function selector does not match "foo(uint32)" and value sent
+    }
+}

+ 20 - 0
docs/examples/substrate/function_name_mangling.sol

@@ -0,0 +1,20 @@
+enum E {
+    v1,
+    v2
+}
+struct S {
+    int256 i;
+    bool b;
+    address a;
+}
+
+contract C {
+    // foo_
+    function foo() public pure {}
+
+    // foo_uint256_addressArray2Array
+    function foo(uint256 i, address[2][] memory a) public pure {}
+
+    // foo_uint8Array2__int256_bool_address
+    function foo(E[2] memory e, S memory s) public pure {}
+}

+ 10 - 0
docs/examples/substrate/hash_type.sol

@@ -0,0 +1,10 @@
+import "substrate";
+
+contract c {
+    bytes32 current;
+
+    function set(Hash h) public returns (Hash) {
+        current = Hash.unwrap(h);
+        return Hash.wrap(current);
+    }
+}

+ 21 - 0
docs/examples/substrate/statement_try_catch_call.sol

@@ -0,0 +1,21 @@
+contract aborting {
+    function abort() public returns (int32, bool) {
+        revert("bar");
+    }
+}
+
+contract runner {
+    function test() public {
+        aborting abort = new aborting();
+
+        try abort.abort() returns (int32 a, bool b) {
+            // call succeeded; return values are in a and b
+        } catch Error(string x) {
+            if (x == "bar") {
+                // "bar" reason code was provided through revert() or require()
+            }
+        } catch (bytes raw) {
+            // if no error string could decoding, we end up here with the raw data
+        }
+    }
+}

+ 21 - 0
docs/examples/substrate/statement_try_catch_constructor.sol

@@ -0,0 +1,21 @@
+contract aborting {
+    constructor() {
+        revert("bar");
+    }
+
+    function never() public pure {}
+}
+
+contract runner {
+    function test() public {
+        try new aborting() returns (aborting a) {
+            // new succeeded; a holds the a reference to the new contract
+        } catch Error(string x) {
+            if (x == "bar") {
+                // "bar" revert or require was executed
+            }
+        } catch (bytes raw) {
+            // if no error string could decoding, we end up here with the raw data
+        }
+    }
+}

+ 17 - 0
docs/examples/substrate/statement_try_catch_no_error_handling.sol

@@ -0,0 +1,17 @@
+contract aborting {
+    function abort() public returns (int32, bool) {
+        revert("bar");
+    }
+}
+
+contract runner {
+    function test() public {
+        aborting abort = new aborting();
+
+        try abort.abort() returns (int32 a, bool b) {
+            // call succeeded; return values are in a and b
+        } catch (bytes raw) {
+            // call failed with raw error in raw
+        }
+    }
+}

+ 16 - 0
docs/examples/super_contract_function_call.sol

@@ -0,0 +1,16 @@
+contract a is b {
+    function baz() public returns (uint64) {
+        // this will return 1
+        return super.foo();
+    }
+
+    function foo() internal override returns (uint64) {
+        return 2;
+    }
+}
+
+abstract contract b {
+    function foo() internal virtual returns (uint64) {
+        return 1;
+    }
+}

Vissa filer visades inte eftersom för många filer har ändrats