Mercurial > hg > Members > nobuyasu > myCompiler
comparison Bison-Flex/BasicCompiler-MemoryBase/vm.h @ 4:805d39d28230
add Compiler-stackbase
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 17 May 2011 08:00:38 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:3cea2e8a0e4b | 4:805d39d28230 |
---|---|
1 #ifndef __VM_H__ | |
2 #define __VM_H__ | |
3 | |
4 #include <vector> | |
5 #include "vm_value.h" | |
6 | |
7 #define VM_ENUMDEF | |
8 enum { | |
9 #include "vm_code.h" | |
10 VM_MAXCOMMAND, | |
11 } ; | |
12 #undef VM_ENUMDEF | |
13 | |
14 namespace vm { | |
15 | |
16 class data { | |
17 public: | |
18 data(): command_(0) | |
19 { | |
20 } | |
21 ~data() | |
22 { | |
23 delete[] command_; | |
24 } | |
25 | |
26 public: | |
27 unsigned char *command_; // コマンドテーブル | |
28 int command_size_; // コマンドサイズ | |
29 int value_size_; // グローバル変数サイズ | |
30 } ; | |
31 | |
32 // 0除算例外 | |
33 class devide_by_zero: public std::exception { | |
34 public: | |
35 const char *what() const throw() | |
36 { | |
37 return "devide by zero"; | |
38 } | |
39 } ; | |
40 | |
41 // 仮想マシン | |
42 class vcpu { | |
43 public: | |
44 const static int STACK_SIZE = 1000; | |
45 | |
46 public: | |
47 vcpu(data &mem) | |
48 : data_(mem) | |
49 { | |
50 } | |
51 ~vcpu() | |
52 { | |
53 } | |
54 | |
55 int run(); | |
56 | |
57 private: | |
58 // 定数Push | |
59 void PushConst(int value) | |
60 { | |
61 push(value); | |
62 } | |
63 | |
64 // 変数Push | |
65 void PushValue(int value) | |
66 { | |
67 push(global_value[value]); | |
68 } | |
69 | |
70 // 変数にPop | |
71 void PopValue(int value) | |
72 { | |
73 global_value[value] = top(); pop(); | |
74 } | |
75 | |
76 // 空Pop(スタックトップを捨てる) | |
77 void OpPop() | |
78 { | |
79 pop(); | |
80 } | |
81 | |
82 // 代入 | |
83 void OpMovC(int result, int arg) | |
84 { | |
85 global_value[result] = arg; | |
86 } | |
87 | |
88 void OpMovV(int result, int arg) | |
89 { | |
90 global_value[result] = global_value[arg]; | |
91 } | |
92 | |
93 // 単項マイナス | |
94 void OpNegC(int result, int arg) | |
95 { | |
96 global_value[result] = -arg; | |
97 } | |
98 | |
99 void OpNegV(int result, int arg) | |
100 { | |
101 global_value[result] = -global_value[arg]; | |
102 } | |
103 | |
104 // == | |
105 void OpEqCC(int result, int arg1, int arg2) | |
106 { | |
107 global_value[result] = arg1 == arg2; | |
108 } | |
109 | |
110 void OpEqVC(int result, int arg1, int arg2) | |
111 { | |
112 global_value[result] = global_value[arg1] == arg2; | |
113 } | |
114 | |
115 void OpEqCV(int result, int arg1, int arg2) | |
116 { | |
117 global_value[result] = arg1 == global_value[arg2]; | |
118 } | |
119 | |
120 void OpEqVV(int result, int arg1, int arg2) | |
121 { | |
122 global_value[result] = global_value[arg1] == global_value[arg2]; | |
123 } | |
124 | |
125 // != | |
126 void OpNeCC(int result, int arg1, int arg2) | |
127 { | |
128 global_value[result] = arg1 != arg2; | |
129 } | |
130 | |
131 void OpNeVC(int result, int arg1, int arg2) | |
132 { | |
133 global_value[result] = global_value[arg1] != arg2; | |
134 } | |
135 | |
136 void OpNeCV(int result, int arg1, int arg2) | |
137 { | |
138 global_value[result] = arg1 != global_value[arg2]; | |
139 } | |
140 | |
141 void OpNeVV(int result, int arg1, int arg2) | |
142 { | |
143 global_value[result] = global_value[arg1] != global_value[arg2]; | |
144 } | |
145 | |
146 // > | |
147 void OpGtCC(int result, int arg1, int arg2) | |
148 { | |
149 global_value[result] = arg1 > arg2; | |
150 } | |
151 | |
152 void OpGtVC(int result, int arg1, int arg2) | |
153 { | |
154 global_value[result] = global_value[arg1] > arg2; | |
155 } | |
156 | |
157 void OpGtCV(int result, int arg1, int arg2) | |
158 { | |
159 global_value[result] = arg1 > global_value[arg2]; | |
160 } | |
161 | |
162 void OpGtVV(int result, int arg1, int arg2) | |
163 { | |
164 global_value[result] = global_value[arg1] > global_value[arg2]; | |
165 } | |
166 | |
167 // >= | |
168 void OpGeCC(int result, int arg1, int arg2) | |
169 { | |
170 global_value[result] = arg1 >= arg2; | |
171 } | |
172 | |
173 void OpGeVC(int result, int arg1, int arg2) | |
174 { | |
175 global_value[result] = global_value[arg1] >= arg2; | |
176 } | |
177 | |
178 void OpGeCV(int result, int arg1, int arg2) | |
179 { | |
180 global_value[result] = arg1 >= global_value[arg2]; | |
181 } | |
182 | |
183 void OpGeVV(int result, int arg1, int arg2) | |
184 { | |
185 global_value[result] = global_value[arg1] >= global_value[arg2]; | |
186 } | |
187 | |
188 // < | |
189 void OpLtCC(int result, int arg1, int arg2) | |
190 { | |
191 global_value[result] = arg1 < arg2; | |
192 } | |
193 | |
194 void OpLtVC(int result, int arg1, int arg2) | |
195 { | |
196 global_value[result] = global_value[arg1] < arg2; | |
197 } | |
198 | |
199 void OpLtCV(int result, int arg1, int arg2) | |
200 { | |
201 global_value[result] = arg1 < global_value[arg2]; | |
202 } | |
203 | |
204 void OpLtVV(int result, int arg1, int arg2) | |
205 { | |
206 global_value[result] = global_value[arg1] < global_value[arg2]; | |
207 } | |
208 | |
209 // <= | |
210 void OpLeCC(int result, int arg1, int arg2) | |
211 { | |
212 global_value[result] = arg1 <= arg2; | |
213 } | |
214 | |
215 void OpLeVC(int result, int arg1, int arg2) | |
216 { | |
217 global_value[result] = global_value[arg1] <= arg2; | |
218 } | |
219 | |
220 void OpLeCV(int result, int arg1, int arg2) | |
221 { | |
222 global_value[result] = arg1 <= global_value[arg2]; | |
223 } | |
224 | |
225 void OpLeVV(int result, int arg1, int arg2) | |
226 { | |
227 global_value[result] = global_value[arg1] <= global_value[arg2]; | |
228 } | |
229 | |
230 // + | |
231 void OpAddCC(int result, int arg1, int arg2) | |
232 { | |
233 global_value[result] = arg1 + arg2; | |
234 } | |
235 | |
236 void OpAddVC(int result, int arg1, int arg2) | |
237 { | |
238 global_value[result] = global_value[arg1] + arg2; | |
239 } | |
240 | |
241 void OpAddCV(int result, int arg1, int arg2) | |
242 { | |
243 global_value[result] = arg1 + global_value[arg2]; | |
244 } | |
245 | |
246 void OpAddVV(int result, int arg1, int arg2) | |
247 { | |
248 global_value[result] = global_value[arg1] + global_value[arg2]; | |
249 } | |
250 | |
251 // - | |
252 void OpSubCC(int result, int arg1, int arg2) | |
253 { | |
254 global_value[result] = arg1 - arg2; | |
255 } | |
256 | |
257 void OpSubVC(int result, int arg1, int arg2) | |
258 { | |
259 global_value[result] = global_value[arg1] - arg2; | |
260 } | |
261 | |
262 void OpSubCV(int result, int arg1, int arg2) | |
263 { | |
264 global_value[result] = arg1 - global_value[arg2]; | |
265 } | |
266 | |
267 void OpSubVV(int result, int arg1, int arg2) | |
268 { | |
269 global_value[result] = global_value[arg1] - global_value[arg2]; | |
270 } | |
271 | |
272 // * | |
273 void OpMulCC(int result, int arg1, int arg2) | |
274 { | |
275 global_value[result] = arg1 * arg2; | |
276 } | |
277 | |
278 void OpMulVC(int result, int arg1, int arg2) | |
279 { | |
280 global_value[result] = global_value[arg1] * arg2; | |
281 } | |
282 | |
283 void OpMulCV(int result, int arg1, int arg2) | |
284 { | |
285 global_value[result] = arg1 * global_value[arg2]; | |
286 } | |
287 | |
288 void OpMulVV(int result, int arg1, int arg2) | |
289 { | |
290 global_value[result] = global_value[arg1] * global_value[arg2]; | |
291 } | |
292 | |
293 // / | |
294 void OpDivCC(int result, int arg1, int arg2) | |
295 { | |
296 if (arg2 == 0) | |
297 throw devide_by_zero(); | |
298 global_value[result] = arg1 / arg2; | |
299 } | |
300 | |
301 void OpDivVC(int result, int arg1, int arg2) | |
302 { | |
303 if (arg2 == 0) | |
304 throw devide_by_zero(); | |
305 global_value[result] = global_value[arg1] / arg2; | |
306 } | |
307 | |
308 void OpDivCV(int result, int arg1, int arg2) | |
309 { | |
310 arg2 = global_value[arg2]; | |
311 if (arg2 == 0) | |
312 throw devide_by_zero(); | |
313 global_value[result] = arg1 / arg2; | |
314 } | |
315 | |
316 void OpDivVV(int result, int arg1, int arg2) | |
317 { | |
318 arg2 = global_value[arg2]; | |
319 if (arg2 == 0) | |
320 throw devide_by_zero(); | |
321 global_value[result] = global_value[arg1] / arg2; | |
322 } | |
323 | |
324 // % | |
325 void OpModCC(int result, int arg1, int arg2) | |
326 { | |
327 if (arg2 == 0) | |
328 throw devide_by_zero(); | |
329 global_value[result] = arg1 % arg2; | |
330 } | |
331 | |
332 void OpModVC(int result, int arg1, int arg2) | |
333 { | |
334 if (arg2 == 0) | |
335 throw devide_by_zero(); | |
336 global_value[result] = global_value[arg1] % arg2; | |
337 } | |
338 | |
339 void OpModCV(int result, int arg1, int arg2) | |
340 { | |
341 arg2 = global_value[arg2]; | |
342 if (arg2 == 0) | |
343 throw devide_by_zero(); | |
344 global_value[result] = arg1 % arg2; | |
345 } | |
346 | |
347 void OpModVV(int result, int arg1, int arg2) | |
348 { | |
349 arg2 = global_value[arg2]; | |
350 if (arg2 == 0) | |
351 throw devide_by_zero(); | |
352 global_value[result] = global_value[arg1] % arg2; | |
353 } | |
354 | |
355 // 無条件ジャンプ | |
356 void OpJmp(int addr) | |
357 { | |
358 jmp(addr); | |
359 } | |
360 | |
361 // 真の時ジャンプ | |
362 void OpJmpC(int addr, int arg) | |
363 { | |
364 if (global_value[arg]) | |
365 jmp(addr); | |
366 } | |
367 | |
368 // 偽の時ジャンプ | |
369 void OpJmpNC(int addr, int arg) | |
370 { | |
371 if (!global_value[arg]) | |
372 jmp(addr); | |
373 } | |
374 | |
375 // 仮想CPUプログラム停止 | |
376 void OpHalt() | |
377 { | |
378 } | |
379 | |
380 // 乱数 | |
381 void OpRandC(int result, int arg) | |
382 { | |
383 global_value[result] = (arg <= 0)? 0: (rand() % arg); | |
384 } | |
385 | |
386 void OpRandV(int result, int arg) | |
387 { | |
388 arg = global_value[arg]; | |
389 global_value[result] = (arg <= 0)? 0: (rand() % arg); | |
390 } | |
391 | |
392 void OpPrint(int count) | |
393 { | |
394 while (count--) { | |
395 std::cout << top(); | |
396 pop(); | |
397 if (count) | |
398 std::cout << ", "; | |
399 } | |
400 std::cout << std::endl; | |
401 } | |
402 | |
403 private: | |
404 const int *value(int n) { const int *v = (const int *)command_ptr_; command_ptr_ += 4 * n; return v; } | |
405 int addr() const { return (int)(command_ptr_ - command_); } | |
406 void jmp(int addr) { command_ptr_ = command_ + addr; } | |
407 void push(int v) { stack.push(v); } | |
408 void pop() { stack.pop(); } | |
409 const int top() const { return stack.top(); } | |
410 int &top() { return stack.top(); } | |
411 | |
412 private: | |
413 data &data_; | |
414 unsigned char *command_; | |
415 unsigned char *command_ptr_; | |
416 int command_size_; | |
417 | |
418 vm::stack<int, STACK_SIZE> stack; | |
419 std::vector<int> global_value; | |
420 } ; | |
421 | |
422 } | |
423 | |
424 #endif |