Mercurial > hg > Members > nobuyasu > myCompiler
comparison Bison-Flex/BasicCompiler-StackBase/UTF8/compiler.h @ 2:fbe42292d479
upload test
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 10 May 2011 06:43:55 +0900 |
parents | |
children | 3cea2e8a0e4b |
comparison
equal
deleted
inserted
replaced
1:a3ea4c73696b | 2:fbe42292d479 |
---|---|
1 #ifndef __COMPILER_H__ | |
2 #define __COMPILER_H__ | |
3 | |
4 #include <stack> | |
5 #include "script-parser.hh" | |
6 #include "vm.h" | |
7 #include "node.h" | |
8 | |
9 // Forward declarations. | |
10 class compiler; | |
11 | |
12 // flexの関数宣言 | |
13 #define YY_DECL \ | |
14 yy::script_parser::token_type \ | |
15 yylex(yy::script_parser::semantic_type* yylval, \ | |
16 yy::script_parser::location_type* yylloc, \ | |
17 compiler& driver) | |
18 | |
19 YY_DECL; | |
20 | |
21 // 仮想マシンコード生成用 | |
22 | |
23 class CVMCode { | |
24 public: | |
25 CVMCode(unsigned char op) | |
26 : size_(1), op_(op), arg1_(0) | |
27 { | |
28 } | |
29 CVMCode(unsigned char op, int arg1) | |
30 : size_(5), op_(op), arg1_(arg1) | |
31 { | |
32 } | |
33 | |
34 unsigned char *Get(unsigned char *p) const | |
35 { | |
36 if (op_ != VM_MAXCOMMAND) { // ラベルのダミーコマンド | |
37 *p++ = op_; | |
38 if (size_ > 1) { | |
39 *(int *)p = arg1_; | |
40 p += 4; | |
41 } | |
42 } | |
43 return p; | |
44 } | |
45 | |
46 public: | |
47 unsigned char size_; | |
48 unsigned char op_; | |
49 int arg1_; | |
50 } ; | |
51 | |
52 // ラベル | |
53 | |
54 class CLabel { | |
55 public: | |
56 CLabel(int index) | |
57 : index_(index), pos_(0) | |
58 { | |
59 } | |
60 ~CLabel() | |
61 { | |
62 } | |
63 | |
64 public: | |
65 int index_; | |
66 int pos_; | |
67 } ; | |
68 | |
69 // 変数テーブル | |
70 | |
71 class CValueTag { | |
72 public: | |
73 CValueTag(): addr_(-1), size_(1) | |
74 { | |
75 } | |
76 CValueTag(int addr, int size) | |
77 : addr_(addr), size_(size) | |
78 { | |
79 } | |
80 | |
81 public: | |
82 int addr_; | |
83 int size_; | |
84 } ; | |
85 | |
86 class CValueTable { | |
87 private: | |
88 typedef std::map<std::string, CValueTag>::iterator iter; | |
89 typedef std::map<std::string, CValueTag>::const_iterator const_iter; | |
90 | |
91 public: | |
92 CValueTable(int start_addr=0): addr_(start_addr) | |
93 { | |
94 } | |
95 | |
96 bool add(const std::string &name, int size=1) | |
97 { | |
98 std::pair<iter, bool> result = variables_.insert(make_pair(name, CValueTag(addr_, size))); | |
99 if (result.second) { | |
100 addr_ += size; | |
101 return true; | |
102 } | |
103 return false; | |
104 } | |
105 | |
106 const CValueTag *find(const std::string &name) const | |
107 { | |
108 const_iter it = variables_.find(name); | |
109 if (it != variables_.end()) | |
110 return &it->second; | |
111 return NULL; | |
112 } | |
113 | |
114 bool add_arg(const std::string &name, int addr) | |
115 { | |
116 std::pair<iter, bool> result = variables_.insert(make_pair(name, CValueTag(addr, 1))); | |
117 return result.second; | |
118 } | |
119 | |
120 int size() const { return addr_; } | |
121 void clear() | |
122 { | |
123 variables_.clear(); | |
124 addr_ = 0; | |
125 } | |
126 | |
127 #ifdef _DEBUG | |
128 struct dump_action { | |
129 void operator()(const std::pair<std::string, CValueTag> &it) | |
130 { | |
131 std::cout << it.first << ", addr = " << it.second.addr_ << ", size = " << it.second.size_ << std::endl; | |
132 } | |
133 } ; | |
134 | |
135 void dump() const | |
136 { | |
137 std::for_each(variables_.begin(), variables_.end(), dump_action()); | |
138 } | |
139 #endif | |
140 | |
141 private: | |
142 std::map<std::string, CValueTag> variables_; | |
143 int addr_; | |
144 } ; | |
145 | |
146 // コンパイラ | |
147 | |
148 class compiler { | |
149 private: | |
150 enum STACK_STATE { | |
151 STATE_IF, | |
152 STATE_FOR, | |
153 STATE_WHILE, | |
154 } ; | |
155 | |
156 class CState { | |
157 public: | |
158 CState(const yy::location& l, int state, int label) | |
159 : l_(l), state_(state), label1_(label), label2_(0), start_(0), end_(0), step_(0) | |
160 { | |
161 } | |
162 CState(const yy::location& l, int state, int label1, int label2) | |
163 : l_(l), state_(state), label1_(label1), label2_(label2), start_(0), end_(0), step_(0) | |
164 { | |
165 } | |
166 CState(const yy::location& l, int state, int label, CAssign *start, CNode *end, CNode *step) | |
167 : l_(l), state_(state), label1_(label), label2_(0), start_(start), end_(end), step_(step) | |
168 { | |
169 } | |
170 | |
171 public: | |
172 yy::location l_; | |
173 int state_; | |
174 int label1_; | |
175 int label2_; | |
176 CAssign *start_; | |
177 CNode *end_; | |
178 CNode *step_; | |
179 } ; | |
180 | |
181 public: | |
182 compiler(); | |
183 virtual ~compiler(); | |
184 | |
185 std::string &get_filename() { return file; } | |
186 bool compile(const std::string &f, vm::data &data); | |
187 #ifdef _DEBUG | |
188 void debug_dump(); | |
189 #endif | |
190 | |
191 // 文 | |
192 // 代入文 | |
193 void AssignStatement(const yy::location& l, CAssign *assign); | |
194 // if文 | |
195 void IfStatement(const yy::location& l, CNode *expr); | |
196 void ElseStatement(const yy::location& l); | |
197 void EndifStatement(const yy::location& l); | |
198 // for文 | |
199 void ForStatement(const yy::location& l, CAssign *start, CNode *end, CNode *step); | |
200 void NextStatement(const yy::location& l); | |
201 // while文 | |
202 void WhileStatement(const yy::location& l, CNode *expr); | |
203 void WendStatement(const yy::location& l); | |
204 // end文 | |
205 void EndStatement(const yy::location& l); | |
206 // print文 | |
207 void PrintStatement(const yy::location& l, CArgs *args); | |
208 | |
209 const CValueTag *GetValueTag(const std::string &name) const | |
210 { | |
211 return variables.find(name); | |
212 } | |
213 | |
214 const CValueTag *AddValue(const std::string &name) | |
215 { | |
216 if (variables.add(name, 1)) { | |
217 return variables.find(name); | |
218 } | |
219 return NULL; | |
220 } | |
221 | |
222 // for code generator. | |
223 #define VM_CREATE | |
224 #include "vm_code.h" | |
225 #undef VM_CREATE | |
226 | |
227 int LabelSetting(); | |
228 | |
229 int MakeLabel(); | |
230 | |
231 void SetLabel(int label); | |
232 | |
233 bool CraeteData(vm::data &data, int code_size); | |
234 | |
235 // Error handling. | |
236 void error(const yy::location& l, const std::string& m); | |
237 void error(const std::string& m); | |
238 | |
239 private: | |
240 void scan_begin(); | |
241 void scan_end(); | |
242 | |
243 private: | |
244 CValueTable variables; | |
245 std::vector<CVMCode> statement; | |
246 std::vector<CLabel> labels; | |
247 std::stack<CState> state_stack; | |
248 | |
249 int error_count; | |
250 | |
251 std::string file; | |
252 } ; | |
253 | |
254 #endif |