Mercurial > hg > Members > nobuyasu > myCompiler
comparison Bison-Flex/Compiler-StackBase/UTF8/vm.h @ 5:caede627f691
chage encoding
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 17 May 2011 12:45:07 +0900 |
parents | 805d39d28230 |
children | 86c0a38332fe |
comparison
equal
deleted
inserted
replaced
4:805d39d28230 | 5:caede627f691 |
---|---|
1 // | 1 // |
2 // CPU | 2 // 仮想CPU |
3 // | 3 // |
4 // (c)2008 Chihiro.SAKAMOTO HyperWorks | 4 // (c)2008 Chihiro.SAKAMOTO HyperWorks |
5 // | 5 // |
6 #ifndef __VM_H__ | 6 #ifndef __VM_H__ |
7 #define __VM_H__ | 7 #define __VM_H__ |
9 #include <vector> | 9 #include <vector> |
10 #include "vm_value.h" | 10 #include "vm_value.h" |
11 | 11 |
12 #ifdef _MSC_VER | 12 #ifdef _MSC_VER |
13 // | 13 // |
14 // VS2008Ǥϡ奢饤֥ؿ*_sˤȤ褦ٹ𤬽Фޤ | 14 // VS2008では、セキュアライブラリ関数(*_s)を使うよう警告が出ます。 |
15 // Ǥϡ̲gccбˤΤᡢ饤֥ѤƤΤǡ | 15 // ここでは、一般化(gcc等の対応)のため、旧ライブラリを使用しているので、 |
16 // ٹߤƤޤ | 16 // 警告を抑止しています。 |
17 // | 17 // |
18 #pragma warning(disable: 4996) | 18 #pragma warning(disable: 4996) |
19 #endif | 19 #endif |
20 | 20 |
21 #define VM_ENUMDEF | 21 #define VM_ENUMDEF |
42 delete[] command_; | 42 delete[] command_; |
43 delete[] text_buffer_; | 43 delete[] text_buffer_; |
44 } | 44 } |
45 | 45 |
46 public: | 46 public: |
47 unsigned char *command_; // ޥɥơ֥ | 47 unsigned char *command_; // コマンドテーブル |
48 char *text_buffer_; // ƥȥǡ | 48 char *text_buffer_; // テキストデータ |
49 int command_size_; // ޥɥ | 49 int command_size_; // コマンドサイズ |
50 int text_size_; // ƥȥ | 50 int text_size_; // テキストサイズ |
51 int value_size_; // Хѿ | 51 int value_size_; // グローバル変数サイズ |
52 int entry_point_; // ϰ | 52 int entry_point_; // 開始位置 |
53 } ; | 53 } ; |
54 | 54 |
55 | 55 |
56 // 0㳰 | 56 // 0除算例外 |
57 class devide_by_zero: public std::exception { | 57 class devide_by_zero: public std::exception { |
58 public: | 58 public: |
59 const char *what() const throw() | 59 const char *what() const throw() |
60 { | 60 { |
61 return "devide by zero"; | 61 return "devide by zero"; |
62 } | 62 } |
63 } ; | 63 } ; |
64 | 64 |
65 // ۥޥ | 65 // 仮想マシン |
66 class vcpu { | 66 class vcpu { |
67 public: | 67 public: |
68 const static int STACK_SIZE = 1000; // å | 68 const static int STACK_SIZE = 1000; // スタックサイズ |
69 const static int global_flag = 0x4000000; // ѿե饰 | 69 const static int global_flag = 0x4000000; // 外部変数フラグ |
70 const static int global_mask = 0x3ffffff; | 70 const static int global_mask = 0x3ffffff; |
71 | 71 |
72 public: | 72 public: |
73 vcpu(data &mem) | 73 vcpu(data &mem) |
74 : data_(mem) | 74 : data_(mem) |
79 } | 79 } |
80 | 80 |
81 int run(); | 81 int run(); |
82 | 82 |
83 private: | 83 private: |
84 // Push | 84 // 定数Push |
85 void PushConst(int val) | 85 void PushConst(int val) |
86 { | 86 { |
87 push(val); | 87 push(val); |
88 } | 88 } |
89 | 89 |
90 // ʸPush | 90 // 文字定数Push |
91 void PushString(int val) | 91 void PushString(int val) |
92 { | 92 { |
93 push(std::string(text_buffer_ + val)); | 93 push(std::string(text_buffer_ + val)); |
94 } | 94 } |
95 | 95 |
96 // ѿPush | 96 // 変数Push |
97 void PushValue(int val) | 97 void PushValue(int val) |
98 { | 98 { |
99 push(global_value[val]); | 99 push(global_value[val]); |
100 } | 100 } |
101 | 101 |
102 // ѿPush | 102 // ローカル変数Push |
103 void PushLocal(int val) | 103 void PushLocal(int val) |
104 { | 104 { |
105 push(stack[val + stack_base]); | 105 push(stack[val + stack_base]); |
106 } | 106 } |
107 | 107 |
108 // Push | 108 // 配列からPush |
109 void PushArray(int val) | 109 void PushArray(int val) |
110 { | 110 { |
111 int index = top().i_; pop(); | 111 int index = top().i_; pop(); |
112 push(global_value[val + index]); | 112 push(global_value[val + index]); |
113 } | 113 } |
114 | 114 |
115 // Push | 115 // ローカルの配列からPush |
116 void PushLocalArray(int val) | 116 void PushLocalArray(int val) |
117 { | 117 { |
118 int index = top().i_; pop(); | 118 int index = top().i_; pop(); |
119 push(stack[val + stack_base + index]); | 119 push(stack[val + stack_base + index]); |
120 } | 120 } |
121 | 121 |
122 // ѿ()Push | 122 // ローカル変数(参照)Push |
123 void PushLocalRef(int val) | 123 void PushLocalRef(int val) |
124 { | 124 { |
125 int addr = stack[val + stack_base].i_; | 125 int addr = stack[val + stack_base].i_; |
126 push(ref_to_value(addr)); | 126 push(ref_to_value(addr)); |
127 } | 127 } |
128 | 128 |
129 // ()Push | 129 // ローカルの配列(参照)からPush |
130 void PushLocalArrayRef(int val) | 130 void PushLocalArrayRef(int val) |
131 { | 131 { |
132 int addr = stack[val + stack_base].i_; | 132 int addr = stack[val + stack_base].i_; |
133 int index = top().i_; pop(); | 133 int index = top().i_; pop(); |
134 push(ref_to_value(addr + index)); | 134 push(ref_to_value(addr + index)); |
135 } | 135 } |
136 | 136 |
137 // ɥ쥹Push | 137 // アドレスをPush |
138 void PushAddr(int val) | 138 void PushAddr(int val) |
139 { | 139 { |
140 if ((val & global_flag) == 0) // local | 140 if ((val & global_flag) == 0) // local |
141 val += + stack_base; | 141 val += + stack_base; |
142 push(val); | 142 push(val); |
143 } | 143 } |
144 | 144 |
145 // Υɥ쥹Push | 145 // 配列のアドレスをPush |
146 void PushArrayAddr(int val) | 146 void PushArrayAddr(int val) |
147 { | 147 { |
148 if ((val & global_flag) == 0) // local | 148 if ((val & global_flag) == 0) // local |
149 val += + stack_base; | 149 val += + stack_base; |
150 int index = top().i_; pop(); | 150 int index = top().i_; pop(); |
151 push(val + index); | 151 push(val + index); |
152 } | 152 } |
153 | 153 |
154 // ѿPop | 154 // 変数にPop |
155 void PopValue(int val) | 155 void PopValue(int val) |
156 { | 156 { |
157 global_value[val] = top(); pop(); | 157 global_value[val] = top(); pop(); |
158 } | 158 } |
159 | 159 |
160 // ѿPop | 160 // ローカル変数にPop |
161 void PopLocal(int val) | 161 void PopLocal(int val) |
162 { | 162 { |
163 stack[val + stack_base] = top(); pop(); | 163 stack[val + stack_base] = top(); pop(); |
164 } | 164 } |
165 | 165 |
166 // ѿPop | 166 // 配列変数にPop |
167 void PopArray(int val) | 167 void PopArray(int val) |
168 { | 168 { |
169 int index = top().i_; pop(); | 169 int index = top().i_; pop(); |
170 global_value[val + index] = top(); pop(); | 170 global_value[val + index] = top(); pop(); |
171 } | 171 } |
172 | 172 |
173 // ѿPop | 173 // ローカルの配列変数にPop |
174 void PopLocalArray(int val) | 174 void PopLocalArray(int val) |
175 { | 175 { |
176 int index = top().i_; pop(); | 176 int index = top().i_; pop(); |
177 stack[val + stack_base + index] = top(); pop(); | 177 stack[val + stack_base + index] = top(); pop(); |
178 } | 178 } |
179 | 179 |
180 // ѿ()Pop | 180 // ローカル変数(参照)にPop |
181 void PopLocalRef(int val) | 181 void PopLocalRef(int val) |
182 { | 182 { |
183 int addr = stack[val + stack_base].i_; | 183 int addr = stack[val + stack_base].i_; |
184 set_ref(addr, top()); pop(); | 184 set_ref(addr, top()); pop(); |
185 } | 185 } |
186 | 186 |
187 // ѿ()Pop | 187 // ローカルの配列変数(参照)にPop |
188 void PopLocalArrayRef(int val) | 188 void PopLocalArrayRef(int val) |
189 { | 189 { |
190 int addr = stack[val + stack_base].i_; | 190 int addr = stack[val + stack_base].i_; |
191 int index = top().i_; pop(); | 191 int index = top().i_; pop(); |
192 set_ref(addr + index, top()); pop(); | 192 set_ref(addr + index, top()); pop(); |
193 } | 193 } |
194 | 194 |
195 // ѿ | 195 // ローカル変数を確保 |
196 void OpAllocStack(int val) | 196 void OpAllocStack(int val) |
197 { | 197 { |
198 stack.resize(stack_base + val); | 198 stack.resize(stack_base + val); |
199 } | 199 } |
200 | 200 |
201 // PopʥåȥåפΤƤ | 201 // 空Pop(スタックトップを捨てる) |
202 void OpPop() | 202 void OpPop() |
203 { | 203 { |
204 pop(); | 204 pop(); |
205 } | 205 } |
206 | 206 |
207 // ñޥʥ | 207 // 単項マイナス |
208 void OpNeg() | 208 void OpNeg() |
209 { | 209 { |
210 top().i_ = -top().i_; | 210 top().i_ = -top().i_; |
211 } | 211 } |
212 | 212 |
348 throw devide_by_zero(); | 348 throw devide_by_zero(); |
349 int lhs = top().i_; pop(); | 349 int lhs = top().i_; pop(); |
350 push(lhs % rhs); | 350 push(lhs % rhs); |
351 } | 351 } |
352 | 352 |
353 // ʸ== | 353 // 文字列の== |
354 void OpStrEq() | 354 void OpStrEq() |
355 { | 355 { |
356 const std::string &rhs = text(top()); pop(); | 356 const std::string &rhs = text(top()); pop(); |
357 const std::string &lhs = text(top()); pop(); | 357 const std::string &lhs = text(top()); pop(); |
358 | 358 |
359 push(lhs == rhs); | 359 push(lhs == rhs); |
360 } | 360 } |
361 | 361 |
362 // ʸ!= | 362 // 文字列の!= |
363 void OpStrNe() | 363 void OpStrNe() |
364 { | 364 { |
365 const std::string &rhs = text(top()); pop(); | 365 const std::string &rhs = text(top()); pop(); |
366 const std::string &lhs = text(top()); pop(); | 366 const std::string &lhs = text(top()); pop(); |
367 | 367 |
368 push(lhs != rhs); | 368 push(lhs != rhs); |
369 } | 369 } |
370 | 370 |
371 // ʸ> | 371 // 文字列の> |
372 void OpStrGt() | 372 void OpStrGt() |
373 { | 373 { |
374 const std::string &rhs = text(top()); pop(); | 374 const std::string &rhs = text(top()); pop(); |
375 const std::string &lhs = text(top()); pop(); | 375 const std::string &lhs = text(top()); pop(); |
376 | 376 |
377 push(lhs > rhs); | 377 push(lhs > rhs); |
378 } | 378 } |
379 | 379 |
380 // ʸ>= | 380 // 文字列の>= |
381 void OpStrGe() | 381 void OpStrGe() |
382 { | 382 { |
383 const std::string &rhs = text(top()); pop(); | 383 const std::string &rhs = text(top()); pop(); |
384 const std::string &lhs = text(top()); pop(); | 384 const std::string &lhs = text(top()); pop(); |
385 | 385 |
386 push(lhs >= rhs); | 386 push(lhs >= rhs); |
387 } | 387 } |
388 | 388 |
389 // ʸ< | 389 // 文字列の< |
390 void OpStrLt() | 390 void OpStrLt() |
391 { | 391 { |
392 const std::string &rhs = text(top()); pop(); | 392 const std::string &rhs = text(top()); pop(); |
393 const std::string &lhs = text(top()); pop(); | 393 const std::string &lhs = text(top()); pop(); |
394 | 394 |
395 push(lhs < rhs); | 395 push(lhs < rhs); |
396 } | 396 } |
397 | 397 |
398 // ʸ<= | 398 // 文字列の<= |
399 void OpStrLe() | 399 void OpStrLe() |
400 { | 400 { |
401 const std::string &rhs = text(top()); pop(); | 401 const std::string &rhs = text(top()); pop(); |
402 const std::string &lhs = text(top()); pop(); | 402 const std::string &lhs = text(top()); pop(); |
403 | 403 |
404 push(lhs <= rhs); | 404 push(lhs <= rhs); |
405 } | 405 } |
406 | 406 |
407 // ʸ+ | 407 // 文字列の+ |
408 void OpStrAdd() | 408 void OpStrAdd() |
409 { | 409 { |
410 const std::string &rhs = text(top()); pop(); | 410 const std::string &rhs = text(top()); pop(); |
411 const std::string &lhs = text(top()); pop(); | 411 const std::string &lhs = text(top()); pop(); |
412 | 412 |
413 push(lhs + rhs); | 413 push(lhs + rhs); |
414 } | 414 } |
415 | 415 |
416 // ̵兩 | 416 // 無条件ジャンプ |
417 void OpJmp(int val) | 417 void OpJmp(int val) |
418 { | 418 { |
419 jmp(val); | 419 jmp(val); |
420 } | 420 } |
421 | 421 |
422 // λ | 422 // 真の時ジャンプ |
423 void OpJmpC(int val) | 423 void OpJmpC(int val) |
424 { | 424 { |
425 int cond = top().i_; pop(); | 425 int cond = top().i_; pop(); |
426 if (cond) | 426 if (cond) |
427 jmp(val); | 427 jmp(val); |
428 } | 428 } |
429 | 429 |
430 // λ | 430 // 偽の時ジャンプ |
431 void OpJmpNC(int val) | 431 void OpJmpNC(int val) |
432 { | 432 { |
433 int cond = top().i_; pop(); | 433 int cond = top().i_; pop(); |
434 if (!cond) | 434 if (!cond) |
435 jmp(val); | 435 jmp(val); |
436 } | 436 } |
437 | 437 |
438 // switchʸüȽ | 438 // switch文用特殊判定 |
439 void OpTest(int val) | 439 void OpTest(int val) |
440 { | 440 { |
441 int value = top().i_; pop(); | 441 int value = top().i_; pop(); |
442 if (value == top().i_) { | 442 if (value == top().i_) { |
443 pop(); | 443 pop(); |
444 jmp(val); | 444 jmp(val); |
445 } | 445 } |
446 } | 446 } |
447 | 447 |
448 // ؿ | 448 // 関数コール |
449 void OpCall(int val) | 449 void OpCall(int val) |
450 { | 450 { |
451 push(stack_base); | 451 push(stack_base); |
452 push(addr()); // ɥ쥹Push | 452 push(addr()); // リターンアドレスをPush |
453 stack_base = stack.size(); // å١ | 453 stack_base = stack.size(); // スタックベース更新 |
454 jmp(val); | 454 jmp(val); |
455 } | 455 } |
456 | 456 |
457 // ʤ | 457 // 引数なしリターン |
458 void OpReturn() | 458 void OpReturn() |
459 { | 459 { |
460 stack.resize(stack_base); // ѿӽ | 460 stack.resize(stack_base); // ローカル変数排除 |
461 int addr = top().i_; pop(); | 461 int addr = top().i_; pop(); |
462 stack_base = top().i_; pop(); | 462 stack_base = top().i_; pop(); |
463 int arg_count = top().i_; pop(); | 463 int arg_count = top().i_; pop(); |
464 stack.pop(arg_count); | 464 stack.pop(arg_count); |
465 jmp(addr); | 465 jmp(addr); |
466 } | 466 } |
467 | 467 |
468 // դ | 468 // 引数付きリターン |
469 void OpReturnV() | 469 void OpReturnV() |
470 { | 470 { |
471 vm::value result = top(); pop(); | 471 vm::value result = top(); pop(); |
472 stack.resize(stack_base); // ѿӽ | 472 stack.resize(stack_base); // ローカル変数排除 |
473 int addr = top().i_; pop(); | 473 int addr = top().i_; pop(); |
474 stack_base = top().i_; pop(); | 474 stack_base = top().i_; pop(); |
475 int arg_count = top().i_; pop(); | 475 int arg_count = top().i_; pop(); |
476 stack.pop(arg_count); | 476 stack.pop(arg_count); |
477 push(result); | 477 push(result); |
478 jmp(addr); | 478 jmp(addr); |
479 } | 479 } |
480 | 480 |
481 // CPUץ | 481 // 仮想CPUプログラム停止 |
482 void OpHalt() | 482 void OpHalt() |
483 { | 483 { |
484 } | 484 } |
485 | 485 |
486 // ƥॳȤ߹ߴؿ | 486 // システムコール(組み込み関数) |
487 void OpSysCall(int val) | 487 void OpSysCall(int val) |
488 { | 488 { |
489 pop(); // arg_count | 489 pop(); // arg_count |
490 switch (val) { | 490 switch (val) { |
491 case SYS_PRINT: | 491 case SYS_PRINT: |
496 sys_tostr(); | 496 sys_tostr(); |
497 break; | 497 break; |
498 } | 498 } |
499 } | 499 } |
500 | 500 |
501 // ƥॳprint | 501 // システムコール(print) |
502 void sys_print() | 502 void sys_print() |
503 { | 503 { |
504 std::cout << text(top()); | 504 std::cout << text(top()); |
505 pop(); | 505 pop(); |
506 } | 506 } |
507 | 507 |
508 // ƥॳ(ͤʸѴ) | 508 // システムコール(数値を文字列に変換) |
509 void sys_tostr() | 509 void sys_tostr() |
510 { | 510 { |
511 int v = top().i_; pop(); | 511 int v = top().i_; pop(); |
512 char str[16]; | 512 char str[16]; |
513 sprintf(str, "%d", v); | 513 sprintf(str, "%d", v); |
514 push(std::string(str)); // ͤϥå | 514 push(std::string(str)); // 戻り値はスタックに入れる |
515 } | 515 } |
516 | 516 |
517 private: | 517 private: |
518 int value() { int v = *(int *)command_ptr_; command_ptr_ += 4; return v; } | 518 int value() { int v = *(int *)command_ptr_; command_ptr_ += 4; return v; } |
519 int addr() const { return (int)(command_ptr_ - command_); } | 519 int addr() const { return (int)(command_ptr_ - command_); } |