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_); }