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