Mercurial > hg > Members > nobuyasu > myCompiler
view 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 source
#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