diff --git a/playground/src/examples/index.ts b/playground/src/examples/index.ts index e1db06b3..9e0ed9b6 100644 --- a/playground/src/examples/index.ts +++ b/playground/src/examples/index.ts @@ -14,7 +14,7 @@ export interface PlaygroundExample { export const examples: PlaygroundExample[] = [ { id: "contract-output", - name: "Contract output", + name: "Hello contract", description: "A small contract that emits Hull, Yul, Sonatina IR, and ABI JSON.", entry: "main.sol", files: [ @@ -28,21 +28,6 @@ contract Answer { return uint256(42); } } -`, - }, - ], - }, - { - id: "hello", - name: "Hello", - description: "A minimal function returning a word literal.", - entry: "main.sol", - files: [ - { - path: "main.sol", - content: `function main() returns (word) { - return 42; -} `, }, ], @@ -50,15 +35,24 @@ contract Answer { { id: "std-usage", name: "Std usage", - description: "Imports a helper from the embedded standard library.", + description: "Calls a standard-library trait method directly; the + operator desugars to the same call.", entry: "main.sol", files: [ { path: "main.sol", - content: `import {addWord} from std; + content: `import * from std; +import * from std.dispatch; + +contract Calculator { + // The + operator is not compiler magic: it desugars to the same + // standard-library trait method called explicitly below. + function viaOperator(a: uint256, b: uint256) public returns (uint256) { + return a + b; + } -function main() returns (word) { - return addWord(1, 2); + function viaTrait(a: uint256, b: uint256) public returns (uint256) { + return Num.add(a, b); + } } `, }, @@ -67,12 +61,17 @@ function main() returns (word) { { id: "trait", name: "Trait", - description: "Defines a trait, implements it for a custom enum, and calls its method.", + description: "A trait implemented for a custom enum drives a stored on-chain state machine.", entry: "main.sol", files: [ { path: "main.sol", - content: `trait Toggle { + content: `import * from std; +import * from std.dispatch; +import * from std.Generic; +import * from std.StorageGeneric; + +trait Toggle { function toggle(value: a) returns (a); } @@ -90,8 +89,23 @@ impl Toggle { } } -function main() returns (Switch) { - return Toggle.toggle(Switch.Off); +contract LightSwitch { + state : Switch; + + constructor() { + state = Switch.Off; + } + + function flip() public { + state = Toggle.toggle(state); + } + + function isOn() public returns (bool) { + match (state) { + case Switch.On { return true; } + default { return false; } + } + } } `, }, @@ -100,23 +114,72 @@ function main() returns (Switch) { { id: "generics", name: "Generics", - description: "Uses a generic pair type and a generic function to select its second value.", + description: "A where-constrained generic max works for a user-defined Version type via its Ord impl.", entry: "main.sol", files: [ { path: "main.sol", - content: `enum Pair { - Pair(a, b) + content: `import * from std; +import * from std.dispatch; +import * from std.Generic; +import * from std.StorageGeneric; + +// One generic maximum for every ordered type, user-defined included. +// Candidate standard-library inventory: a generic max belongs in std +// eventually. +function max(x: a, y: a) returns (a) where a: Ord { + if (x > y) { return x; } + return y; +} + +enum Version { + Version(uint256, uint256) } -function second(pair: Pair) returns (b) { - match (pair) { - case Pair(_, value) { return value; } +function major(v: Version) returns (uint256) { + match (v) { + case Version.Version(value, _) { return value; } } } -function main() returns (word) { - return second(Pair(true, 42)); +function minor(v: Version) returns (uint256) { + match (v) { + case Version.Version(_, value) { return value; } + } +} + +impl Eq { + function eq(a: Version, b: Version) returns (bool) { + return major(a) == major(b) && minor(a) == minor(b); + } +} + +// Ord requires Eq: the compiler checks the trait hierarchy. +impl Ord { + function gt(a: Version, b: Version) returns (bool) { + if (major(a) == major(b)) { return minor(a) > minor(b); } + return major(a) > major(b); + } +} + +contract Registry { + newest : Version; + + constructor() { + newest = Version.Version(uint256(0), uint256(0)); + } + + function publish(maj: uint256, min: uint256) public { + newest = max(newest, Version.Version(maj, min)); + } + + function newestMajor() public returns (uint256) { + return major(newest); + } + + function newestMinor() public returns (uint256) { + return minor(newest); + } } `, }, @@ -376,32 +439,6 @@ function sender() returns (address) { } export { sender }; -`, - }, - ], - }, - { - id: "lambda", - name: "Lambda", - description: "Builds a lambda that captures a value from its enclosing function.", - entry: "main.sol", - files: [ - { - path: "main.sol", - content: `function makeAdder(value: word) returns (function(word) returns (word)) { - return lam (other: word) -> word { - let result: word; - assembly { - result := add(value, other) - } - return result; - }; -} - -function main() returns (word) { - let addTen = makeAdder(10); - return addTen(32); -} `, }, ], @@ -415,45 +452,20 @@ function main() returns (word) { { path: "main.sol", content: `import * from std; +import * from std.dispatch; -function double(comptime value: word) returns (comptime) { +// Evaluated during specialization: the deployed code contains only the +// result, not the computation. +function double(comptime value: uint256) returns (comptime) { return value + value; } -function main() returns (word) { - let answer: comptime = double(21); - return answer; -} -`, - }, - ], - }, - { - id: "multi-file", - name: "Multi-file", - description: "Imports a sibling module and calls an exported function.", - entry: "main.sol", - files: [ - { - path: "main.sol", - content: `import {double} from math; - -function main() returns (word) { - return double(21); -} -`, - }, - { - path: "math.sol", - content: `function double(x: word) returns (word) { - let res: word; - assembly { - res := add(x, x) +contract Answer { + function answer() public returns (uint256) { + let result: comptime = double(uint256(21)); + return result; } - return res; } - -export { double }; `, }, ],