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 };
`,
},
],