Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 93 additions & 27 deletions playground/src/examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,37 +125,68 @@ function main() returns (word) {
{
id: "option",
name: "Option",
description: "A generic optional value: checked division returns an Option instead of reverting.",
description: "A reusable Option module and a splitter contract: checked division returns an Option instead of reverting.",
entry: "main.sol",
files: [
{
path: "main.sol",
content: `import * from std;
import * from std.dispatch;
import {Option, checkedDiv, unwrapOr} from option;

contract Splitter {
// Each recipient's equal share of the pot; zero recipients yields
// zero instead of reverting on division.
function share(pot: uint256, recipients: uint256) public returns (uint256) {
return unwrapOr(checkedDiv(pot, recipients), uint256(0));
}

// What is left over after handing out equal shares.
function remainder(pot: uint256, recipients: uint256) public returns (uint256) {
match (checkedDiv(pot, recipients)) {
case Option.Some(perRecipient) { return pot - perRecipient * recipients; }
default { return pot; }
}
}
}
`,
},
{
path: "option.sol",
content: `// Candidate standard-library inventory: this module should disappear once
// std provides Option.
import * from std;
import * from std.Generic;
import * from std.StorageGeneric;

enum Option<a> {
None,
Some(a)
}

// Division by zero yields Option.None instead of reverting.
function checkedDiv(a: word, b: word) returns (Option<word>) {
if (b == 0) {
function checkedDiv(a: uint256, b: uint256) returns (Option<uint256>) {
if (b == uint256(0)) {
return Option.None;
}
return Option.Some(a / b);
}

function unwrapOr(option: Option<word>, orElse: word) returns (word) {
function unwrapOr<a>(option: Option<a>, orElse: a) returns (a) {
match (option) {
case Option.Some(value) { return value; }
default { return orElse; }
}
}

function main() returns (word) {
// 84 / 2 succeeds with Some(42); 84 / 0 would fall back to 0.
return unwrapOr(checkedDiv(84, 2), 0);
function contains<a>(option: Option<a>, value: a) returns (bool) where a: Eq {
match (option) {
case Option.Some(inner) { return inner == value; }
default { return false; }
}
}

export { Option(*), checkedDiv, unwrapOr, contains };
`,
},
],
Expand Down Expand Up @@ -234,29 +265,11 @@ contract Escrow {
path: "main.sol",
content: `import * from std;
import * from std.dispatch;
import * from std.Generic;
import * from std.StorageGeneric;
import {caller} from std.opcodes;
import {Option, contains} from option;
import {sender} from context;

// A token either has an owner or does not exist: unset mapping entries
// read back as Option.None.
enum Option<a> {
None,
Some(a)
}

function contains<a>(option: Option<a>, value: a) returns (bool) where a: Eq {
match (option) {
case Option.Some(inner) { return inner == value; }
default { return false; }
}
}

// msg.sender: the CALLER opcode lifted from word into address.
function sender() returns (address) {
return address(caller());
}

contract MiniNFT {
nextId : uint256;
owners : mapping(uint256 => Option<address>);
Expand Down Expand Up @@ -310,6 +323,59 @@ contract MiniNFT {
}
}
}
`,
},
{
path: "option.sol",
content: `// Candidate standard-library inventory: this module should disappear once
// std provides Option.
import * from std;
import * from std.Generic;
import * from std.StorageGeneric;

enum Option<a> {
None,
Some(a)
}

// Division by zero yields Option.None instead of reverting.
function checkedDiv(a: uint256, b: uint256) returns (Option<uint256>) {
if (b == uint256(0)) {
return Option.None;
}
return Option.Some(a / b);
}

function unwrapOr<a>(option: Option<a>, orElse: a) returns (a) {
match (option) {
case Option.Some(value) { return value; }
default { return orElse; }
}
}

function contains<a>(option: Option<a>, value: a) returns (bool) where a: Eq {
match (option) {
case Option.Some(inner) { return inner == value; }
default { return false; }
}
}

export { Option(*), checkedDiv, unwrapOr, contains };
`,
},
{
path: "context.sol",
content: `// Candidate standard-library inventory: this module should disappear once
// std provides transaction context helpers.
import * from std;
import {caller} from std.opcodes;

// msg.sender: the CALLER opcode lifted from word into address.
function sender() returns (address) {
return address(caller());
}

export { sender };
`,
},
],
Expand Down