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