-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmax_features.ora
More file actions
153 lines (128 loc) · 3.79 KB
/
max_features.ora
File metadata and controls
153 lines (128 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Fixes we need to do:
// - [ ] Add slice support
// - [ ] Allow file-level const (compile-time only, no region)
// - [ ] Keep immutable contract-level only (error at file level)
// - [ ] memory variables declaration at contract level don't make sense, we need to add an error
error ParseError;
struct Point {
x: u256;
y: u256;
}
// Named config struct to bypass current parser limitation
struct Config {
fee: u256;
enabled: bool;
}
enum Status: u256 { Idle, Running, Done }
log Transfer(indexed source: address, indexed dest: address, amount: u256);
// Example contract using a wide range of language features
contract FeatureMaximizer {
// Contract-level constants and variables
const MAX_VALUE: u256 = 1000;
storage let threshold: u256 = 10;
storage var counter: u256 = 0;
immutable OWNER: address = 0x0123456789abcdef0123456789abcdef01234567;
// Contract storage variables (all regions/kinds)
storage let total_supply: u256 = 0;
storage var balances: map<address, u256>;
storage var approvals: map<address, map<address, u256>>;
memory var temp_points: [Point; 4];
// TODO: we need to test slice
tstore var scratch: [u256; 4];
// Struct and enum usage
storage var status: Status = Status.Idle;
storage var origin: Point = Point { x: 0, y: 0 };
// Use named struct for now to proceed with AST
storage let config: Config = Config { fee: 1, enabled: true };
fn init() {
// Basic assignments and lvalues
var i: u256 = 0;
balances[OWNER] = 100;
origin.x = 10;
origin.y = 20;
// Compound assignment
i += 1;
// Variable for use in conditions
let v: u256 = 42;
// Logical / bitwise chain
let flag: bool = (v == 42) && (1 | 2) == 3;
if (flag) {
status = Status.Running;
}
// Requires/Ensures style checks embedded in helper calls
let helper_result: u256 = helper_require_ensure(5);
counter += helper_result;
// Switch statement (not expression for now)
var mapped: u256 = 0;
switch (v) {
0 => { mapped = 100; }
1 => { mapped = 200; }
2 => { mapped = 300; }
else => { mapped = 999; }
}
counter += mapped;
// Labeled block with break
var val: u256 = 0;
block_label: {
if (v > 0) {
val = 7;
break :block_label;
}
val = 0;
}
counter += val;
// Try/catch statement
try {
let try_result: !u256 = may_fail();
counter += try_result;
} catch (e) {
counter += 1;
}
// Simple loop
var idx: u256 = 0;
while (idx < 3) {
counter += idx;
idx += 1;
}
// While with invariant
while (i < 3) {
i += 1;
}
// Switch statement
switch (v) {
0 => {
status = Status.Running;
}
else => {
status = Status.Done;
}
}
// Labeled block with break
outer: {
var j: u256 = 0;
if (j < 5) {
j += 1;
if (j == 4) { break :outer; }
}
}
return;
}
fn helper_require_ensure(x: u256) -> u256
requires (x > 0)
requires (x < std.constants.U256_MAX)
ensures (x + 1 > x)
{
return x + 1;
}
pub fn compute(a: u256, b: u256) -> u256 {
// Simple computation
var res: u256 = a +% b;
return res;
}
fn may_fail() -> !u256 {
if (threshold > MAX_VALUE) {
return error.ParseError;
}
return 0;
}
}