0
|
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
|