Mercurial > hg > Members > nobuyasu > myCompiler
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Bison-Flex/BasicCompiler-MemoryBase/vm.h Tue May 17 08:00:38 2011 +0900 @@ -0,0 +1,424 @@ +#ifndef __VM_H__ +#define __VM_H__ + +#include <vector> +#include "vm_value.h" + +#define VM_ENUMDEF +enum { +#include "vm_code.h" + VM_MAXCOMMAND, +} ; +#undef VM_ENUMDEF + +namespace vm { + + class data { + public: + data(): command_(0) + { + } + ~data() + { + delete[] command_; + } + + public: + unsigned char *command_; // コマンドテーブル + int command_size_; // コマンドサイズ + int value_size_; // グローバル変数サイズ + } ; + + // 0除算例外 + class devide_by_zero: public std::exception { + public: + const char *what() const throw() + { + return "devide by zero"; + } + } ; + + // 仮想マシン + class vcpu { + public: + const static int STACK_SIZE = 1000; + + public: + vcpu(data &mem) + : data_(mem) + { + } + ~vcpu() + { + } + + int run(); + + private: + // 定数Push + void PushConst(int value) + { + push(value); + } + + // 変数Push + void PushValue(int value) + { + push(global_value[value]); + } + + // 変数にPop + void PopValue(int value) + { + global_value[value] = top(); pop(); + } + + // 空Pop(スタックトップを捨てる) + void OpPop() + { + pop(); + } + + // 代入 + void OpMovC(int result, int arg) + { + global_value[result] = arg; + } + + void OpMovV(int result, int arg) + { + global_value[result] = global_value[arg]; + } + + // 単項マイナス + void OpNegC(int result, int arg) + { + global_value[result] = -arg; + } + + void OpNegV(int result, int arg) + { + global_value[result] = -global_value[arg]; + } + + // == + void OpEqCC(int result, int arg1, int arg2) + { + global_value[result] = arg1 == arg2; + } + + void OpEqVC(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] == arg2; + } + + void OpEqCV(int result, int arg1, int arg2) + { + global_value[result] = arg1 == global_value[arg2]; + } + + void OpEqVV(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] == global_value[arg2]; + } + + // != + void OpNeCC(int result, int arg1, int arg2) + { + global_value[result] = arg1 != arg2; + } + + void OpNeVC(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] != arg2; + } + + void OpNeCV(int result, int arg1, int arg2) + { + global_value[result] = arg1 != global_value[arg2]; + } + + void OpNeVV(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] != global_value[arg2]; + } + + // > + void OpGtCC(int result, int arg1, int arg2) + { + global_value[result] = arg1 > arg2; + } + + void OpGtVC(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] > arg2; + } + + void OpGtCV(int result, int arg1, int arg2) + { + global_value[result] = arg1 > global_value[arg2]; + } + + void OpGtVV(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] > global_value[arg2]; + } + + // >= + void OpGeCC(int result, int arg1, int arg2) + { + global_value[result] = arg1 >= arg2; + } + + void OpGeVC(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] >= arg2; + } + + void OpGeCV(int result, int arg1, int arg2) + { + global_value[result] = arg1 >= global_value[arg2]; + } + + void OpGeVV(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] >= global_value[arg2]; + } + + // < + void OpLtCC(int result, int arg1, int arg2) + { + global_value[result] = arg1 < arg2; + } + + void OpLtVC(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] < arg2; + } + + void OpLtCV(int result, int arg1, int arg2) + { + global_value[result] = arg1 < global_value[arg2]; + } + + void OpLtVV(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] < global_value[arg2]; + } + + // <= + void OpLeCC(int result, int arg1, int arg2) + { + global_value[result] = arg1 <= arg2; + } + + void OpLeVC(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] <= arg2; + } + + void OpLeCV(int result, int arg1, int arg2) + { + global_value[result] = arg1 <= global_value[arg2]; + } + + void OpLeVV(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] <= global_value[arg2]; + } + + // + + void OpAddCC(int result, int arg1, int arg2) + { + global_value[result] = arg1 + arg2; + } + + void OpAddVC(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] + arg2; + } + + void OpAddCV(int result, int arg1, int arg2) + { + global_value[result] = arg1 + global_value[arg2]; + } + + void OpAddVV(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] + global_value[arg2]; + } + + // - + void OpSubCC(int result, int arg1, int arg2) + { + global_value[result] = arg1 - arg2; + } + + void OpSubVC(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] - arg2; + } + + void OpSubCV(int result, int arg1, int arg2) + { + global_value[result] = arg1 - global_value[arg2]; + } + + void OpSubVV(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] - global_value[arg2]; + } + + // * + void OpMulCC(int result, int arg1, int arg2) + { + global_value[result] = arg1 * arg2; + } + + void OpMulVC(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] * arg2; + } + + void OpMulCV(int result, int arg1, int arg2) + { + global_value[result] = arg1 * global_value[arg2]; + } + + void OpMulVV(int result, int arg1, int arg2) + { + global_value[result] = global_value[arg1] * global_value[arg2]; + } + + // / + void OpDivCC(int result, int arg1, int arg2) + { + if (arg2 == 0) + throw devide_by_zero(); + global_value[result] = arg1 / arg2; + } + + void OpDivVC(int result, int arg1, int arg2) + { + if (arg2 == 0) + throw devide_by_zero(); + global_value[result] = global_value[arg1] / arg2; + } + + void OpDivCV(int result, int arg1, int arg2) + { + arg2 = global_value[arg2]; + if (arg2 == 0) + throw devide_by_zero(); + global_value[result] = arg1 / arg2; + } + + void OpDivVV(int result, int arg1, int arg2) + { + arg2 = global_value[arg2]; + if (arg2 == 0) + throw devide_by_zero(); + global_value[result] = global_value[arg1] / arg2; + } + + // % + void OpModCC(int result, int arg1, int arg2) + { + if (arg2 == 0) + throw devide_by_zero(); + global_value[result] = arg1 % arg2; + } + + void OpModVC(int result, int arg1, int arg2) + { + if (arg2 == 0) + throw devide_by_zero(); + global_value[result] = global_value[arg1] % arg2; + } + + void OpModCV(int result, int arg1, int arg2) + { + arg2 = global_value[arg2]; + if (arg2 == 0) + throw devide_by_zero(); + global_value[result] = arg1 % arg2; + } + + void OpModVV(int result, int arg1, int arg2) + { + arg2 = global_value[arg2]; + if (arg2 == 0) + throw devide_by_zero(); + global_value[result] = global_value[arg1] % arg2; + } + + // 無条件ジャンプ + void OpJmp(int addr) + { + jmp(addr); + } + + // 真の時ジャンプ + void OpJmpC(int addr, int arg) + { + if (global_value[arg]) + jmp(addr); + } + + // 偽の時ジャンプ + void OpJmpNC(int addr, int arg) + { + if (!global_value[arg]) + jmp(addr); + } + + // 仮想CPUプログラム停止 + void OpHalt() + { + } + + // 乱数 + void OpRandC(int result, int arg) + { + global_value[result] = (arg <= 0)? 0: (rand() % arg); + } + + void OpRandV(int result, int arg) + { + arg = global_value[arg]; + global_value[result] = (arg <= 0)? 0: (rand() % arg); + } + + void OpPrint(int count) + { + while (count--) { + std::cout << top(); + pop(); + if (count) + std::cout << ", "; + } + std::cout << std::endl; + } + + private: + const int *value(int n) { const int *v = (const int *)command_ptr_; command_ptr_ += 4 * n; return v; } + int addr() const { return (int)(command_ptr_ - command_); } + void jmp(int addr) { command_ptr_ = command_ + addr; } + void push(int v) { stack.push(v); } + void pop() { stack.pop(); } + const int top() const { return stack.top(); } + int &top() { return stack.top(); } + + private: + data &data_; + unsigned char *command_; + unsigned char *command_ptr_; + int command_size_; + + vm::stack<int, STACK_SIZE> stack; + std::vector<int> global_value; + } ; + +} + +#endif