comparison Bison-Flex/Compiler-StackBase/EUC/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 //
2 // コンパイラドライバ
3 //
4 // (c)2008 Chihiro.SAKAMOTO HyperWorks
5 //
6 #ifndef __COMPILER_H__
7 #define __COMPILER_H__
8
9 #include "script-parser.hh"
10 #include "vm.h"
11 #include "node.h"
12
13 // 前方宣言
14 class compiler;
15
16 // flexの関数宣言
17 #define YY_DECL \
18 yy::script_parser::token_type \
19 yylex(yy::script_parser::semantic_type* yylval, \
20 yy::script_parser::location_type* yylloc, \
21 compiler& driver)
22
23 YY_DECL;
24
25 // 仮想マシンコード生成用
26
27 class CVMCode {
28 public:
29 CVMCode(unsigned char op) // 引数なし命令
30 : size_(1), op_(op), arg1_(0)
31 {
32 }
33 CVMCode(unsigned char op, int arg1) // 引数1つの命令
34 : size_(5), op_(op), arg1_(arg1)
35 {
36 }
37
38 unsigned char *Get(unsigned char *p) const
39 {
40 if (op_ != VM_MAXCOMMAND) { // ラベルのダミーコマンド
41 *p++ = op_;
42 if (size_ > 1) {
43 *(int *)p = arg1_;
44 p += 4;
45 }
46 }
47 return p;
48 }
49
50 public:
51 unsigned char size_;
52 unsigned char op_;
53 int arg1_;
54 } ;
55
56 // ラベル
57
58 class CLabel {
59 public:
60 CLabel(int index)
61 : index_(index), pos_(0)
62 {
63 }
64 ~CLabel()
65 {
66 }
67
68 public:
69 int index_;
70 int pos_;
71 } ;
72
73 // 変数テーブル
74
75 class CValueTag {
76 public:
77 CValueTag(): addr_(-1), type_(TYPE_INTEGER), size_(1), global_(false)
78 {
79 }
80 CValueTag(int addr, int type, int size, bool global)
81 : addr_(addr), type_(type), size_(size), global_(global)
82 {
83 }
84
85 public:
86 int addr_;
87 int type_;
88 int size_;
89 bool global_;
90 } ;
91
92 // 変数テーブル
93
94 class CValueTable {
95 private:
96 typedef std::map<std::string, CValueTag>::iterator iter;
97 typedef std::map<std::string, CValueTag>::const_iterator const_iter;
98
99 public:
100 CValueTable(int start_addr=0): addr_(start_addr), global_(false)
101 {
102 }
103
104 void set_global()
105 {
106 global_ = true;
107 }
108
109 bool add(int type, const std::string &name, int size=1)
110 {
111 std::pair<iter, bool> result = variables_.insert(make_pair(name, CValueTag(addr_, type, size, global_)));
112 if (result.second) {
113 addr_ += size;
114 return true;
115 }
116 return false;
117 }
118
119 const CValueTag *find(const std::string &name) const
120 {
121 const_iter it = variables_.find(name);
122 if (it != variables_.end())
123 return &it->second;
124 return NULL;
125 }
126
127 bool add_arg(int type, const std::string &name, int addr)
128 {
129 std::pair<iter, bool> result = variables_.insert(make_pair(name, CValueTag(addr, type, 1, false)));
130 return result.second;
131 }
132
133 int size() const { return addr_; }
134 void clear()
135 {
136 variables_.clear();
137 addr_ = 0;
138 }
139
140 #ifdef _DEBUG
141 struct dump_action {
142 void operator()(const std::pair<std::string, CValueTag> &it)
143 {
144 std::cout << it.first << ", addr = " << it.second.addr_
145 << ", type = " << it.second.type_
146 << ", size = " << it.second.size_
147 << ", global = " << it.second.global_ << std::endl;
148 }
149 } ;
150
151 void dump() const
152 {
153 std::cout << "-------- value --------" << std::endl;
154 std::for_each(variables_.begin(), variables_.end(), dump_action());
155 }
156 #endif
157
158 private:
159 std::map<std::string, CValueTag> variables_;
160 int addr_;
161 bool global_;
162 } ;
163
164 // 関数定義用
165
166 class CFunctionTag {
167 private:
168 enum {
169 flag_declaration = 1 << 0,
170 flag_definition = 1 << 1,
171 flag_system = 1 << 2,
172 } ;
173
174 public:
175 CFunctionTag()
176 {
177 }
178 CFunctionTag(int type)
179 : type_(type), flags_(0), index_(0)
180 {
181 }
182
183 void SetArg(int type)
184 {
185 args_.push_back((char)type);
186 }
187
188 void SetArgs(const CArgList *args)
189 {
190 if (args) {
191 size_t size = args->size();
192 for (size_t i=0; i < size; i++) {
193 args_.push_back((char)args->get(i)->type());
194 }
195 }
196 }
197
198 bool SetArgs(const char *args)
199 {
200 if (args) {
201 for (int i=0; args[i] != 0; i++) {
202 switch (args[i]) {
203 case 'I': case 'i':
204 args_.push_back(TYPE_INTEGER);
205 break;
206
207 case 'S': case 's':
208 args_.push_back(TYPE_STRING);
209 break;
210
211 default:
212 return false;
213 }
214 }
215 }
216 return true;
217 }
218
219 bool ChkArgList(const CArgList *args) const
220 {
221 // 引数が無い場合
222 if (args == 0)
223 return args_.empty();
224
225 // 引数の個数が異なる
226 if (args_.size() != args->size())
227 return false;
228
229 // 全引数の型をチェック
230 size_t size = args_.size();
231 for (size_t i=0; i < size; i++) {
232 if (args->get(i)->type() != (int)args_[i])
233 return false;
234 }
235 return true;
236 }
237
238 // 指定の引数の型を得る
239
240 int GetArg(int index) const
241 {
242 return args_[index];
243 }
244
245 int ArgSize() const { return args_.size(); }
246
247 void SetIndex(int index) { index_ = index; }
248 void SetDeclaration() { flags_ |= flag_declaration; } // 宣言
249 void SetDefinition() { flags_ |= flag_definition; } // 定義
250 void SetSystem() { flags_ |= flag_system; }
251
252 int GetIndex() const { return index_; }
253 bool IsDeclaration() const { return (flags_ & flag_declaration) != 0; }
254 bool IsDefinition() const { return (flags_ & flag_definition) != 0; }
255 bool IsSystem() const { return (flags_ & flag_system) != 0; }
256
257 public:
258 int type_;
259 int flags_;
260 int index_;
261 std::vector<char> args_;
262 } ;
263
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 std::string &get_filename() { return file; }
317 bool compile(const std::string &f, vm::data &data);
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(const yy::location& l, int type, CValueList *value_list);
325 void DefineFunction(const yy::location& l, int type, const std::string *name, CArgList *args);
326 void AddFunction(const yy::location& l, int type, const std::string *name, CArgList *args, CStateBlock *states);
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(const yy::location& l, int type, const std::string &name, const CNode *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 yy::location& l, const std::string& m);
376 void error(const std::string& m);
377
378 private:
379 void scan_begin();
380 void scan_end();
381
382 private:
383 CFunctionTable functions;
384 std::vector<CValueTable> variables;
385 std::vector<CVMCode> statement;
386 std::vector<CLabel> labels;
387 std::vector<char> text_table;
388
389 int break_index;
390 int error_count;
391
392 std::string current_function_name;
393 int current_function_type;
394
395 std::string file;
396 } ;
397
398 #endif