comparison 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
comparison
equal deleted inserted replaced
1:a3ea4c73696b 2:fbe42292d479
1 //
2 // 仮想CPU
3 //
4 // 関数ポインタベースでの実装例
5 //
6 // (c)2008 Chihiro.SAKAMOTO HyperWorks
7 //
8 #include <exception>
9 #include "vm.h"
10
11 namespace vm {
12
13 // 0除算例外
14 class devide_by_zero: public std::exception {
15 public:
16 const char *what() const throw()
17 {
18 return "devide by zero";
19 }
20 } ;
21
22 void (vcpu::*vcpu::cmd_[])() = {
23 #define VM_EXECTABLE
24 #include "vm_code.h"
25 #undef VM_EXECTABLE
26 } ;
27
28 // 実行
29 int vcpu::run()
30 {
31 command_ = data_.command_; // プログラム格納位置
32 command_size_ = data_.command_size_; // プログラムの大きさ
33
34 global_value.resize(data_.value_size_); // 外部変数テーブル確保
35 command_ptr_ = command_; // プログラムカウンター初期化
36
37 active = true; // Haltしていない
38
39 try {
40 while (active) { // Haltするまでループ
41 int op = *command_ptr_++;
42 (this->*cmd_[op])();
43 }
44 }
45 catch (const std::exception &e) {
46 std::cerr << "例外発生(" << e.what() << ")" << std::endl;
47 return -1;
48 }
49 return 0;
50 }
51
52 // 定数Push
53 void vcpu::PushConst()
54 {
55 push(value());
56 }
57
58 // 変数Push
59 void vcpu::PushValue()
60 {
61 push(global_value[value()]);
62 }
63
64 // 変数にPop
65 void vcpu::PopValue()
66 {
67 global_value[value()] = top(); pop();
68 }
69
70 // 空Pop(スタックトップを捨てる)
71 void vcpu::OpPop()
72 {
73 pop();
74 }
75
76 // 単項マイナス
77 void vcpu::OpNeg()
78 {
79 top() = -top();
80 }
81
82 // ==
83 void vcpu::OpEq()
84 {
85 int rhs = top(); pop();
86 int lhs = top(); pop();
87 push(lhs == rhs);
88 }
89
90 // !=
91 void vcpu::OpNe()
92 {
93 int rhs = top(); pop();
94 int lhs = top(); pop();
95 push(lhs != rhs);
96 }
97
98 // >
99 void vcpu::OpGt()
100 {
101 int rhs = top(); pop();
102 int lhs = top(); pop();
103 push(lhs > rhs);
104 }
105
106 // >=
107 void vcpu::OpGe()
108 {
109 int rhs = top(); pop();
110 int lhs = top(); pop();
111 push(lhs >= rhs);
112 }
113
114 // <
115 void vcpu::OpLt()
116 {
117 int rhs = top(); pop();
118 int lhs = top(); pop();
119 push(lhs < rhs);
120 }
121
122 // <=
123 void vcpu::OpLe()
124 {
125 int rhs = top(); pop();
126 int lhs = top(); pop();
127 push(lhs <= rhs);
128 }
129
130 // +
131 void vcpu::OpAdd()
132 {
133 int rhs = top(); pop();
134 int lhs = top(); pop();
135 push(lhs + rhs);
136 }
137
138 // -
139 void vcpu::OpSub()
140 {
141 int rhs = top(); pop();
142 int lhs = top(); pop();
143 push(lhs - rhs);
144 }
145
146 // *
147 void vcpu::OpMul()
148 {
149 int rhs = top(); pop();
150 int lhs = top(); pop();
151 push(lhs * rhs);
152 }
153
154 // /
155 void vcpu::OpDiv()
156 {
157 int rhs = top(); pop();
158 if (rhs == 0)
159 throw devide_by_zero();
160 int lhs = top(); pop();
161 push(lhs / rhs);
162 }
163
164 // %
165 void vcpu::OpMod()
166 {
167 int rhs = top(); pop();
168 if (rhs == 0)
169 throw devide_by_zero();
170 int lhs = top(); pop();
171 push(lhs % rhs);
172 }
173
174 // 無条件ジャンプ
175 void vcpu::OpJmp()
176 {
177 jmp(value());
178 }
179
180 // 真の時ジャンプ
181 void vcpu::OpJmpC()
182 {
183 int addr = value();
184 int cond = top(); pop();
185 if (cond)
186 jmp(addr);
187 }
188
189 // 偽の時ジャンプ
190 void vcpu::OpJmpNC()
191 {
192 int addr = value();
193 int cond = top(); pop();
194 if (!cond)
195 jmp(addr);
196 }
197
198 // 仮想CPUプログラム停止
199 void vcpu::OpHalt()
200 {
201 active = false;
202 }
203
204 void vcpu::OpRand()
205 {
206 int range = top(); pop();
207 int value = (range <= 0)? 0: (rand() % range);
208 push(value);
209 }
210
211 void vcpu::OpPrint()
212 {
213 int count = value();
214 while (count--) {
215 std::cout << top();
216 pop();
217 if (count)
218 std::cout << ", ";
219 }
220 std::cout << std::endl;
221 }
222 }