Mercurial > hg > Members > nobuyasu > myCompiler
comparison Bison-Flex/BasicCompiler-MemoryBase/node.cpp @ 4:805d39d28230
add Compiler-stackbase
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 17 May 2011 08:00:38 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:3cea2e8a0e4b | 4:805d39d28230 |
---|---|
1 #include <functional> | |
2 #include <iostream> | |
3 #include <iomanip> | |
4 #include "node.h" | |
5 #include "compiler.h" | |
6 #include "script-parser.hh" | |
7 | |
8 // コード生成用 | |
9 CNodeValue CNodeValue::MakeNodeValue(compiler *c, CNode *node) | |
10 { | |
11 switch (node->op()) { | |
12 case OP_CONST: | |
13 return CNodeValue(CONST, node->value()); | |
14 | |
15 case OP_VALUE: | |
16 { | |
17 const CValueTag *tag = c->GetValueTag(node->string()); | |
18 if (tag == 0) { | |
19 c->error(node->location(), "変数" + node->string() + "は未定義です。"); | |
20 return CNodeValue(VALUE, 0); | |
21 } | |
22 return CNodeValue(VALUE, tag->addr_); | |
23 } | |
24 } | |
25 return node->analyze(c); | |
26 } | |
27 | |
28 // 一時変数の管理 | |
29 CNodeValue CNodeValue::MakeTempValue(compiler *c, int value) | |
30 { | |
31 if (value < 0) | |
32 return CNodeValue(c, TEMP, c->AllocTempValue()); | |
33 return CNodeValue(VALUE, value); | |
34 } | |
35 | |
36 void CNodeValue::ReleaseTempValue() | |
37 { | |
38 c_->ReleaseTempValue(value_); | |
39 } | |
40 | |
41 void CNodeValue::UseTempValue() | |
42 { | |
43 c_->UseTempValue(value_); | |
44 } | |
45 | |
46 int CNodeValue::value() const | |
47 { | |
48 if (type_ == TEMP) | |
49 return c_->GetTempAddr(value_); | |
50 return value_; | |
51 } | |
52 | |
53 // ノード生成 | |
54 // ただし、定数同士の計算は、leftノードに結果を代入し、それを返す | |
55 | |
56 CNode *CNode::MakeNode(compiler &c, const yy::location& l, int op, CNode *left, CNode *right) | |
57 { | |
58 if (right == 0) { | |
59 switch (op) { | |
60 case OP_NEG: | |
61 if (left->op_ == OP_CONST) { // 定数演算を計算する | |
62 left->value_ = -left->value_; | |
63 return left; | |
64 } | |
65 break; | |
66 } | |
67 return new CNode(l, op, left); | |
68 } | |
69 | |
70 // 定数演算を計算する | |
71 if (left->op_ == OP_CONST && right->op_ == OP_CONST) { | |
72 switch (op) { | |
73 case OP_EQ: | |
74 left->value_ = (left->value_ == right->value_)? 1: 0; | |
75 break; | |
76 | |
77 case OP_NE: | |
78 left->value_ = (left->value_ != right->value_)? 1: 0; | |
79 break; | |
80 | |
81 case OP_GT: | |
82 left->value_ = (left->value_ > right->value_)? 1: 0; | |
83 break; | |
84 | |
85 case OP_GE: | |
86 left->value_ = (left->value_ >= right->value_)? 1: 0; | |
87 break; | |
88 | |
89 case OP_LT: | |
90 left->value_ = (left->value_ < right->value_)? 1: 0; | |
91 break; | |
92 | |
93 case OP_LE: | |
94 left->value_ = (left->value_ <= right->value_)? 1: 0; | |
95 break; | |
96 | |
97 case OP_MINUS: | |
98 left->value_ -= right->value_; | |
99 break; | |
100 | |
101 case OP_PLUS: | |
102 left->value_ += right->value_; | |
103 break; | |
104 | |
105 case OP_TIMES: | |
106 left->value_ *= right->value_; | |
107 break; | |
108 | |
109 case OP_DIVIDE: | |
110 if (right->value_ == 0) { | |
111 c.error(l, "定数計算を0で除算しました。"); | |
112 } | |
113 else { | |
114 left->value_ /= right->value_; | |
115 } | |
116 break; | |
117 | |
118 case OP_MOD: | |
119 if (right->value_ == 0) { | |
120 c.error(l, "定数計算を0で除算しました。"); | |
121 } | |
122 else { | |
123 left->value_ %= right->value_; | |
124 } | |
125 break; | |
126 | |
127 default: | |
128 return new CNode(l, op, left, right); | |
129 } | |
130 delete right; | |
131 return left; | |
132 } | |
133 return new CNode(l, op, left, right); | |
134 } | |
135 | |
136 CNodeValue CNode::analyze(compiler *c, int ret) | |
137 { | |
138 switch (op_) { | |
139 case OP_NEG: | |
140 return c->MakeNeg(ret, CNodeValue::MakeNodeValue(c, left_)); | |
141 | |
142 case OP_RANDFUNC: | |
143 return c->MakeRand(ret, CNodeValue::MakeNodeValue(c, left_)); | |
144 | |
145 case OP_CONST: | |
146 return c->MakeMoveC(ret, value_); | |
147 | |
148 case OP_VALUE: | |
149 return c->MakeMoveV(ret, CNodeValue::MakeNodeValue(c, this)); | |
150 } | |
151 | |
152 CNodeValue left = CNodeValue::MakeNodeValue(c, left_); | |
153 CNodeValue right = CNodeValue::MakeNodeValue(c, right_); | |
154 | |
155 // 整数計算ノードの処理 | |
156 return c->MakeOp(op_, ret, left, right); | |
157 } | |
158 | |
159 // 代入命令を生成 | |
160 // | |
161 // a = b | |
162 // > mov a, b | |
163 // | |
164 CNodeValue CAssign::analyze(compiler *c) | |
165 { | |
166 const CValueTag *tag = c->GetValueTag(value_->string()); | |
167 if (tag == 0) { | |
168 tag = c->AddValue(value_->string()); | |
169 } | |
170 if (tag == 0) { | |
171 c->error(l_, "変数 " + value_->string() + " が定義できません。"); | |
172 return CNodeValue(); | |
173 } | |
174 return expr_->analyze(c, tag->addr_); | |
175 } |