Mercurial > hg > Members > nobuyasu > SampleSource
comparison boost-spirit/Compiler-boost-spirit/compiler.h @ 0:db40c85cad7a default tip
upload sample source
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 09 May 2011 03:11:59 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:db40c85cad7a |
---|---|
1 #ifndef __COMPILER_H__ | |
2 #define __COMPILER_H__ | |
3 | |
4 #include "vm.h" | |
5 #include "node.h" | |
6 | |
7 // 仮想マシンコード生成用 | |
8 | |
9 class CVMCode { | |
10 public: | |
11 CVMCode(unsigned char op) | |
12 : size_(1), op_(op), arg1_(0) | |
13 { | |
14 } | |
15 CVMCode(unsigned char op, int arg1) | |
16 : size_(5), op_(op), arg1_(arg1) | |
17 { | |
18 } | |
19 | |
20 unsigned char *Get(unsigned char *p) const | |
21 { | |
22 if (op_ != VM_MAXCOMMAND) { // ラベルのダミーコマンド | |
23 *p++ = op_; | |
24 if (size_ > 1) { | |
25 *(int *)p = arg1_; | |
26 p += 4; | |
27 } | |
28 } | |
29 return p; | |
30 } | |
31 | |
32 public: | |
33 unsigned char size_; | |
34 unsigned char op_; | |
35 int arg1_; | |
36 } ; | |
37 | |
38 // ラベル | |
39 | |
40 class CLabel { | |
41 public: | |
42 CLabel(int index) | |
43 : index_(index), pos_(0) | |
44 { | |
45 } | |
46 ~CLabel() | |
47 { | |
48 } | |
49 | |
50 public: | |
51 int index_; | |
52 int pos_; | |
53 } ; | |
54 | |
55 // 変数テーブル | |
56 | |
57 class CValueTag { | |
58 public: | |
59 CValueTag(): addr_(-1), type_(TYPE_INTEGER), size_(1), global_(false) | |
60 { | |
61 } | |
62 CValueTag(int addr, int type, int size, bool global) | |
63 : addr_(addr), type_(type), size_(size), global_(global) | |
64 { | |
65 } | |
66 | |
67 public: | |
68 int addr_; | |
69 int type_; | |
70 int size_; | |
71 bool global_; | |
72 } ; | |
73 | |
74 class CValueTable { | |
75 private: | |
76 typedef std::map<std::string, CValueTag>::iterator iter; | |
77 typedef std::map<std::string, CValueTag>::const_iterator const_iter; | |
78 | |
79 public: | |
80 CValueTable(int start_addr=0): addr_(start_addr), global_(false) | |
81 { | |
82 } | |
83 | |
84 void set_global() | |
85 { | |
86 global_ = true; | |
87 } | |
88 | |
89 bool add(int type, const std::string &name, int size=1) | |
90 { | |
91 std::pair<iter, bool> result = variables_.insert(make_pair(name, CValueTag(addr_, type, size, global_))); | |
92 if (result.second) { | |
93 addr_ += size; | |
94 return true; | |
95 } | |
96 return false; | |
97 } | |
98 | |
99 const CValueTag *find(const std::string &name) const | |
100 { | |
101 const_iter it = variables_.find(name); | |
102 if (it != variables_.end()) | |
103 return &it->second; | |
104 return NULL; | |
105 } | |
106 | |
107 bool add_arg(int type, const std::string &name, int addr) | |
108 { | |
109 std::pair<iter, bool> result = variables_.insert(make_pair(name, CValueTag(addr, type, 1, false))); | |
110 return result.second; | |
111 } | |
112 | |
113 int size() const { return addr_; } | |
114 void clear() | |
115 { | |
116 variables_.clear(); | |
117 addr_ = 0; | |
118 } | |
119 | |
120 #ifdef _DEBUG | |
121 struct dump_action { | |
122 void operator()(const std::pair<std::string, CValueTag> &it) | |
123 { | |
124 std::cout << it.first << ", addr = " << it.second.addr_ << ", type = " << it.second.type_ << ", size = " << it.second.size_ << ", global = " << it.second.global_ << std::endl; | |
125 } | |
126 } ; | |
127 | |
128 void dump() const | |
129 { | |
130 std::cout << "-------- value --------" << std::endl; | |
131 std::for_each(variables_.begin(), variables_.end(), dump_action()); | |
132 } | |
133 #endif | |
134 | |
135 private: | |
136 std::map<std::string, CValueTag> variables_; | |
137 int addr_; | |
138 bool global_; | |
139 } ; | |
140 | |
141 // 関数定義用 | |
142 | |
143 class CFunctionTag { | |
144 private: | |
145 enum { | |
146 flag_declaration = 1 << 0, | |
147 flag_definition = 1 << 1, | |
148 flag_system = 1 << 2, | |
149 } ; | |
150 | |
151 public: | |
152 CFunctionTag() | |
153 { | |
154 } | |
155 CFunctionTag(int type) | |
156 : type_(type), flags_(0), index_(0) | |
157 { | |
158 } | |
159 | |
160 void SetArg(int type) | |
161 { | |
162 args_.push_back((unsigned char)type); | |
163 } | |
164 | |
165 void SetArgs(const std::vector<cargdef> &args) | |
166 { | |
167 size_t size = args.size(); | |
168 for (size_t i=0; i < size; i++) { | |
169 args_.push_back((unsigned char)args[i].type()); | |
170 } | |
171 } | |
172 | |
173 void SetArgs(const std::vector<int> &args) | |
174 { | |
175 size_t size = args.size(); | |
176 for (size_t i=0; i < size; i++) { | |
177 args_.push_back((unsigned char)args[i]); | |
178 } | |
179 } | |
180 | |
181 bool SetArgs(const char *args) | |
182 { | |
183 if (args) { | |
184 for (int i=0; args[i] != 0; i++) { | |
185 switch (args[i]) { | |
186 case 'I': case 'i': | |
187 args_.push_back(TYPE_INTEGER); | |
188 break; | |
189 | |
190 case 'S': case 's': | |
191 args_.push_back(TYPE_STRING); | |
192 break; | |
193 | |
194 default: | |
195 return false; | |
196 } | |
197 } | |
198 } | |
199 return true; | |
200 } | |
201 | |
202 bool ChkArgList(const std::vector<cargdef> &args) const | |
203 { | |
204 // 引数が無い場合 | |
205 if (args.empty()) | |
206 return args_.empty(); | |
207 | |
208 // 引数の個数が異なる | |
209 if (args.size() != args_.size()) | |
210 return false; | |
211 | |
212 // 全引数の型をチェック | |
213 size_t size = args_.size(); | |
214 for (size_t i=0; i < size; i++) { | |
215 if (args[i].type() != (int)args_[i]) | |
216 return false; | |
217 } | |
218 return true; | |
219 } | |
220 | |
221 bool ChkArgList(const std::vector<int> &args) const | |
222 { | |
223 // 引数が無い場合 | |
224 if (args.empty()) | |
225 return args_.empty(); | |
226 | |
227 // 引数の個数が異なる | |
228 if (args.size() != args_.size()) | |
229 return false; | |
230 | |
231 // 全引数の型をチェック | |
232 size_t size = args_.size(); | |
233 for (size_t i=0; i < size; i++) { | |
234 if (args[i] != (int)args_[i]) | |
235 return false; | |
236 } | |
237 return true; | |
238 } | |
239 | |
240 // 指定の引数の型を得る | |
241 | |
242 int GetArg(int index) const | |
243 { | |
244 return args_[index]; | |
245 } | |
246 | |
247 int ArgSize() const { return (int)args_.size(); } | |
248 | |
249 void SetIndex(int index) { index_ = index; } | |
250 void SetDeclaration() { flags_ |= flag_declaration; } // 宣言 | |
251 void SetDefinition() { flags_ |= flag_definition; } // 定義 | |
252 void SetSystem() { flags_ |= flag_system; } | |
253 | |
254 int GetIndex() const { return index_; } | |
255 bool IsDeclaration() const { return (flags_ & flag_declaration) != 0; } | |
256 bool IsDefinition() const { return (flags_ & flag_definition) != 0; } | |
257 bool IsSystem() const { return (flags_ & flag_system) != 0; } | |
258 | |
259 public: | |
260 int type_; | |
261 int flags_; | |
262 int index_; | |
263 std::vector<unsigned char> args_; | |
264 } ; | |
265 | |
266 class CFunctionTable { | |
267 private: | |
268 typedef std::map<std::string, CFunctionTag>::iterator iter; | |
269 typedef std::map<std::string, CFunctionTag>::const_iterator const_iter; | |
270 | |
271 public: | |
272 CFunctionTable() | |
273 { | |
274 } | |
275 | |
276 CFunctionTag *add(const std::string &name, const CFunctionTag &tag) | |
277 { | |
278 std::pair<iter, bool> result = functions_.insert(make_pair(name, tag)); | |
279 if (result.second) | |
280 return &result.first->second; | |
281 return NULL; | |
282 } | |
283 | |
284 const CFunctionTag *find(const std::string &name) const | |
285 { | |
286 const_iter it = functions_.find(name); | |
287 if (it != functions_.end()) | |
288 return &it->second; | |
289 return NULL; | |
290 } | |
291 | |
292 CFunctionTag *find(const std::string &name) | |
293 { | |
294 iter it = functions_.find(name); | |
295 if (it != functions_.end()) | |
296 return &it->second; | |
297 return NULL; | |
298 } | |
299 | |
300 void clear() | |
301 { | |
302 functions_.clear(); | |
303 } | |
304 | |
305 private: | |
306 std::map<std::string, CFunctionTag> functions_; | |
307 } ; | |
308 | |
309 // コンパイラ | |
310 | |
311 class compiler { | |
312 public: | |
313 compiler(); | |
314 virtual ~compiler(); | |
315 | |
316 bool compile(const std::string &file, vm::data &data); | |
317 | |
318 #ifdef _DEBUG | |
319 void debug_dump(); | |
320 #endif | |
321 | |
322 bool add_function(int index, int type, const char *name, const char *args); | |
323 | |
324 void DefineValue(int type, const std::vector<cnode_t> &node); | |
325 void DefineFunction(int type, const std::string &name, const std::vector<int> &args); | |
326 void AddFunction(int type, const std::string &name, const std::vector<cargdef> &args, cblock_t block); | |
327 | |
328 // 変数の検索、内側のブロックから検索する。 | |
329 const CValueTag *GetValueTag(const std::string &name) const | |
330 { | |
331 int size = (int)variables.size(); | |
332 for (int i=size-1; i>=0; i--) { | |
333 const CValueTag *tag = variables[i].find(name); | |
334 if (tag) | |
335 return tag; | |
336 } | |
337 return NULL; | |
338 } | |
339 | |
340 // 関数の検索 | |
341 const CFunctionTag *GetFunctionTag(const std::string &name) const | |
342 { | |
343 return functions.find(name); | |
344 } | |
345 | |
346 // for code generator. | |
347 #define VM_CREATE | |
348 #include "vm_code.h" | |
349 #undef VM_CREATE | |
350 | |
351 void BlockIn(); | |
352 void BlockOut(); | |
353 void AllocStack(); | |
354 int LabelSetting(); | |
355 | |
356 int SetBreakLabel(int label) | |
357 { | |
358 int old_index = break_index; | |
359 break_index = label; | |
360 return old_index; | |
361 } | |
362 bool JmpBreakLabel(); | |
363 | |
364 int MakeLabel(); | |
365 | |
366 void AddValue(int type, const std::string &name, cnode_t node); | |
367 | |
368 void SetLabel(int label); | |
369 | |
370 void PushString(const std::string &name); | |
371 int GetFunctionType() const { return current_function_type; } | |
372 bool CraeteData(vm::data &data, int code_size); | |
373 | |
374 // Error handling. | |
375 void error(const std::string& m); | |
376 | |
377 private: | |
378 CFunctionTable functions; | |
379 std::vector<CValueTable> variables; | |
380 std::vector<CVMCode> statement; | |
381 std::vector<CLabel> labels; | |
382 std::vector<char> text_table; | |
383 | |
384 int break_index; | |
385 int error_count; | |
386 | |
387 std::string current_function_name; | |
388 int current_function_type; | |
389 } ; | |
390 | |
391 #endif |