Mercurial > hg > Members > nobuyasu > myCompiler
view Bison-Flex/BasicCompiler-StackBase/UTF8/vm.cpp @ 2:fbe42292d479
upload test
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 10 May 2011 06:43:55 +0900 |
parents | |
children |
line wrap: on
line source
// // 仮想CPU // // 関数ポインタベースでの実装例 // // (c)2008 Chihiro.SAKAMOTO HyperWorks // #include <exception> #include "vm.h" namespace vm { // 0除算例外 class devide_by_zero: public std::exception { public: const char *what() const throw() { return "devide by zero"; } } ; void (vcpu::*vcpu::cmd_[])() = { #define VM_EXECTABLE #include "vm_code.h" #undef VM_EXECTABLE } ; // 実行 int vcpu::run() { command_ = data_.command_; // プログラム格納位置 command_size_ = data_.command_size_; // プログラムの大きさ global_value.resize(data_.value_size_); // 外部変数テーブル確保 command_ptr_ = command_; // プログラムカウンター初期化 active = true; // Haltしていない try { while (active) { // Haltするまでループ int op = *command_ptr_++; (this->*cmd_[op])(); } } catch (const std::exception &e) { std::cerr << "例外発生(" << e.what() << ")" << std::endl; return -1; } return 0; } // 定数Push void vcpu::PushConst() { push(value()); } // 変数Push void vcpu::PushValue() { push(global_value[value()]); } // 変数にPop void vcpu::PopValue() { global_value[value()] = top(); pop(); } // 空Pop(スタックトップを捨てる) void vcpu::OpPop() { pop(); } // 単項マイナス void vcpu::OpNeg() { top() = -top(); } // == void vcpu::OpEq() { int rhs = top(); pop(); int lhs = top(); pop(); push(lhs == rhs); } // != void vcpu::OpNe() { int rhs = top(); pop(); int lhs = top(); pop(); push(lhs != rhs); } // > void vcpu::OpGt() { int rhs = top(); pop(); int lhs = top(); pop(); push(lhs > rhs); } // >= void vcpu::OpGe() { int rhs = top(); pop(); int lhs = top(); pop(); push(lhs >= rhs); } // < void vcpu::OpLt() { int rhs = top(); pop(); int lhs = top(); pop(); push(lhs < rhs); } // <= void vcpu::OpLe() { int rhs = top(); pop(); int lhs = top(); pop(); push(lhs <= rhs); } // + void vcpu::OpAdd() { int rhs = top(); pop(); int lhs = top(); pop(); push(lhs + rhs); } // - void vcpu::OpSub() { int rhs = top(); pop(); int lhs = top(); pop(); push(lhs - rhs); } // * void vcpu::OpMul() { int rhs = top(); pop(); int lhs = top(); pop(); push(lhs * rhs); } // / void vcpu::OpDiv() { int rhs = top(); pop(); if (rhs == 0) throw devide_by_zero(); int lhs = top(); pop(); push(lhs / rhs); } // % void vcpu::OpMod() { int rhs = top(); pop(); if (rhs == 0) throw devide_by_zero(); int lhs = top(); pop(); push(lhs % rhs); } // 無条件ジャンプ void vcpu::OpJmp() { jmp(value()); } // 真の時ジャンプ void vcpu::OpJmpC() { int addr = value(); int cond = top(); pop(); if (cond) jmp(addr); } // 偽の時ジャンプ void vcpu::OpJmpNC() { int addr = value(); int cond = top(); pop(); if (!cond) jmp(addr); } // 仮想CPUプログラム停止 void vcpu::OpHalt() { active = false; } void vcpu::OpRand() { int range = top(); pop(); int value = (range <= 0)? 0: (rand() % range); push(value); } void vcpu::OpPrint() { int count = value(); while (count--) { std::cout << top(); pop(); if (count) std::cout << ", "; } std::cout << std::endl; } }