4
|
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
|