最后活跃于 3 weeks ago

The simplest Nova implementation I've got (so far) in C++.

june's Avatar june 修订了这个 Gist 3 weeks ago. 转到此修订

1 file changed, 8 deletions

simplest.cpp

@@ -107,7 +107,6 @@ struct snv_core {
107 107 seek('.');
108 108 }
109 109 inline void variable() {
110 - Serial.printf("VARIABLE! %c %d\n", program[cursor], cursor);
111 110 if(secondary == snv_state::LITERAL) {
112 111 secondary = snv_state::VARIABLE;
113 112 }
@@ -137,7 +136,6 @@ struct snv_core {
137 136 }
138 137 inline void insert() {
139 138 uint32_t symbol = number();
140 - Serial.printf("INSERT! %c %d\n", program[cursor], cursor);
141 139 if(secondary == snv_state::LITERAL) {
142 140 stacks[stack].push(symbol);
143 141 } else {
@@ -151,7 +149,6 @@ struct snv_core {
151 149 cursor++;
152 150 }
153 151 inline void match() {
154 - Serial.printf("MATCH! %c %d\n", program[cursor], cursor);
155 152 if(stacks[stack].empty() || stacks[stack].offset >= stacks[stack].top) {
156 153 branch();
157 154 } else {
@@ -174,7 +171,6 @@ struct snv_core {
174 171 cursor++;
175 172 }
176 173 inline void literal() {
177 - Serial.printf("LITERAL! %c %d\n", program[cursor], cursor);
178 174 if(secondary == snv_state::FETCH) {
179 175 uint32_t symbol = number();
180 176 if(primary == snv_state::REMOVE) {
@@ -193,21 +189,17 @@ struct snv_core {
193 189 }
194 190 }
195 191 inline void transition(snv_state state) {
196 - Serial.printf("TRANSITION! %c %d\n", program[cursor], cursor);
197 192 primary = state;
198 193 secondary = snv_state::FETCH;
199 194 cursor++;
200 195 }
201 196 inline void comment() {
202 - Serial.printf("COMMENT! %c %d\n", program[cursor], cursor);
203 197 cursor++; seek('`'); cursor++;
204 198 }
205 199 inline bool step() {
206 200 if(cursor >= length || cursor >= program_size) {
207 201 return true;
208 202 }
209 - Serial.printf("%d [%c]\n", cursor, program[cursor]);
210 - print();
211 203 switch(program[cursor]) {
212 204 case '+': transition(snv_state::INSERT); break;
213 205 case '?': transition(snv_state::MATCH); break;

june's Avatar june 修订了这个 Gist 3 weeks ago. 转到此修订

1 file changed, 234 insertions

simplest.cpp(文件已创建)

@@ -0,0 +1,234 @@
1 + enum snv_state {
2 + // Primary states.
3 + INSERT, MATCH, REMOVE,
4 + // Secondary states.
5 + FETCH, LITERAL, VARIABLE
6 + };
7 +
8 + template<uint32_t size>
9 + struct snv_stack {
10 + uint32_t data[size] = {};
11 + uint8_t top = 0;
12 + uint8_t offset = 0;
13 + inline void push(uint32_t symbol) {
14 + if(!full()) {
15 + data[top] = symbol;
16 + top++;
17 + }
18 + }
19 + inline uint32_t pop() {
20 + uint32_t result = 0;
21 + if(!empty()) {
22 + result = data[top];
23 + top--;
24 + }
25 + return result;
26 + }
27 + inline uint32_t peek() {
28 + if(!empty() && offset < top) {
29 + return data[(top - 1) - offset];
30 + }
31 + return 0;
32 + }
33 + inline bool empty() {
34 + return top == 0;
35 + }
36 + inline bool full() {
37 + return top >= size;
38 + }
39 + inline void reset() {
40 + offset = 0;
41 + }
42 + inline void clear() {
43 + top = 0;
44 + offset = 0;
45 + }
46 + };
47 +
48 + struct snv_variable {
49 + uint32_t symbol = 0;
50 + bool bound = false;
51 + inline void clear() {
52 + symbol = 0;
53 + bound = false;
54 + }
55 + inline bool bind(uint32_t symbol) {
56 + if(bound) {
57 + return symbol == this->symbol;
58 + }
59 + this->symbol = symbol;
60 + bound = true;
61 + return true;
62 + }
63 + };
64 +
65 + template<uint32_t stack_size, uint32_t stack_count, uint32_t variable_count, uint32_t program_size>
66 + struct snv_core {
67 + snv_stack<stack_size> stacks[stack_count] = {};
68 + snv_variable variables[variable_count] = {};
69 + char program[program_size] = {};
70 + snv_state primary = snv_state::INSERT;
71 + snv_state secondary = snv_state::FETCH;
72 + void (*hook)(snv_core*) = nullptr;
73 + uint64_t limit = ~0;
74 + uint32_t length = 0;
75 + uint32_t stack = 0;
76 + uint32_t cursor = 0;
77 + uint32_t last = program_size;
78 + snv_core(const char* program) {
79 + uint32_t cursor = 0;
80 + while(cursor < program_size && program[cursor] != '\0') {
81 + this->program[cursor] = program[cursor];
82 + cursor++;
83 + }
84 + length = cursor;
85 + }
86 + inline void seek(char instruction) {
87 + while(cursor < program_size) {
88 + if(cursor == '`' && instruction != '`') {
89 + cursor++; seek('`'); cursor++;
90 + } else if(program[cursor] == instruction || instruction == ';') {
91 + break;
92 + } else {
93 + cursor++;
94 + }
95 + }
96 + }
97 + inline void clear() {
98 + for(uint8_t variable = 0; variable < variable_count; variable++) {
99 + variables[variable].clear();
100 + }
101 + for(uint8_t stack = 0; stack < stack_count; stack++) {
102 + stacks[stack].reset();
103 + }
104 + }
105 + inline void branch() {
106 + clear();
107 + seek('.');
108 + }
109 + inline void variable() {
110 + Serial.printf("VARIABLE! %c %d\n", program[cursor], cursor);
111 + if(secondary == snv_state::LITERAL) {
112 + secondary = snv_state::VARIABLE;
113 + }
114 + cursor++;
115 + }
116 + inline void reset() {
117 + clear();
118 + cursor = 0;
119 + primary = snv_state::INSERT;
120 + secondary = snv_state::FETCH;
121 + seek('?');
122 + if(hook != nullptr) {
123 + hook(this);
124 + }
125 + }
126 + inline uint32_t number() {
127 + char instruction = program[cursor];
128 + if(instruction >= '0' && instruction <= '9') {
129 + return instruction - '0';
130 + } else if(instruction >= 'a' && instruction <= 'f') {
131 + return (instruction - 'a') + 10;
132 + } else if(instruction >= 'A' && instruction <= 'F') {
133 + return (instruction - 'A') + 10;
134 + } else {
135 + return 0;
136 + }
137 + }
138 + inline void insert() {
139 + uint32_t symbol = number();
140 + Serial.printf("INSERT! %c %d\n", program[cursor], cursor);
141 + if(secondary == snv_state::LITERAL) {
142 + stacks[stack].push(symbol);
143 + } else {
144 + if(variables[symbol].bound) {
145 + stacks[stack].push(variables[symbol].symbol);
146 + } else {
147 + stacks[stack].push(0);
148 + }
149 + }
150 + secondary = snv_state::FETCH;
151 + cursor++;
152 + }
153 + inline void match() {
154 + Serial.printf("MATCH! %c %d\n", program[cursor], cursor);
155 + if(stacks[stack].empty() || stacks[stack].offset >= stacks[stack].top) {
156 + branch();
157 + } else {
158 + uint32_t symbol = number();
159 + if(secondary == snv_state::LITERAL) {
160 + if(stacks[stack].peek() != symbol) {
161 + branch();
162 + } else {
163 + stacks[stack].offset++;
164 + }
165 + } else if(secondary == snv_state::VARIABLE) {
166 + if(!variables[symbol].bind(stacks[stack].peek())) {
167 + branch();
168 + } else {
169 + stacks[stack].offset++;
170 + }
171 + }
172 + }
173 + secondary = snv_state::FETCH;
174 + cursor++;
175 + }
176 + inline void literal() {
177 + Serial.printf("LITERAL! %c %d\n", program[cursor], cursor);
178 + if(secondary == snv_state::FETCH) {
179 + uint32_t symbol = number();
180 + if(primary == snv_state::REMOVE) {
181 + stacks[symbol].pop();
182 + } else {
183 + stack = symbol;
184 + secondary = snv_state::LITERAL;
185 + }
186 + cursor++;
187 + return;
188 + }
189 + if(primary == snv_state::INSERT) {
190 + insert();
191 + } else {
192 + match();
193 + }
194 + }
195 + inline void transition(snv_state state) {
196 + Serial.printf("TRANSITION! %c %d\n", program[cursor], cursor);
197 + primary = state;
198 + secondary = snv_state::FETCH;
199 + cursor++;
200 + }
201 + inline void comment() {
202 + Serial.printf("COMMENT! %c %d\n", program[cursor], cursor);
203 + cursor++; seek('`'); cursor++;
204 + }
205 + inline bool step() {
206 + if(cursor >= length || cursor >= program_size) {
207 + return true;
208 + }
209 + Serial.printf("%d [%c]\n", cursor, program[cursor]);
210 + print();
211 + switch(program[cursor]) {
212 + case '+': transition(snv_state::INSERT); break;
213 + case '?': transition(snv_state::MATCH); break;
214 + case '-': transition(snv_state::REMOVE); break;
215 + case '$': variable(); break;
216 + case '.': reset(); break;
217 + case ';': return true;
218 + case '`': comment(); break;
219 + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
220 + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
221 + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': literal(); break;
222 + default: cursor++;
223 + }
224 + return false;
225 + }
226 + inline void run() {
227 + bool halt = false;
228 + uint64_t steps = 0;
229 + while(!halt && steps != limit) {
230 + halt = step();
231 + steps++;
232 + }
233 + }
234 + };
上一页 下一页