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