comparison Bison-Flex/BasicCompiler-StackBase/EUC/node.cpp @ 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 #include <functional>
2 #include <iostream>
3 #include <iomanip>
4 #include "node.h"
5 #include "compiler.h"
6 #include "script-parser.hh"
7
8 // ノード生成
9 // ただし、定数同士の計算は、leftノードに結果を代入し、それを返す
10
11 CNode *CNode::MakeNode(compiler &c, const yy::location& l, int op, CNode *left, CNode *right)
12 {
13 if (right == 0) {
14 switch (op) {
15 case OP_NEG:
16 if (left->op_ == OP_CONST) { // 定数演算を計算する
17 left->value_ = -left->value_;
18 return left;
19 }
20 break;
21 }
22 return new CNode(l, op, left);
23 }
24
25 // 定数演算を計算する
26 if (left->op_ == OP_CONST && right->op_ == OP_CONST) {
27 switch (op) {
28 case OP_EQ:
29 left->value_ = (left->value_ == right->value_)? 1: 0;
30 break;
31
32 case OP_NE:
33 left->value_ = (left->value_ != right->value_)? 1: 0;
34 break;
35
36 case OP_GT:
37 left->value_ = (left->value_ > right->value_)? 1: 0;
38 break;
39
40 case OP_GE:
41 left->value_ = (left->value_ >= right->value_)? 1: 0;
42 break;
43
44 case OP_LT:
45 left->value_ = (left->value_ < right->value_)? 1: 0;
46 break;
47
48 case OP_LE:
49 left->value_ = (left->value_ <= right->value_)? 1: 0;
50 break;
51
52 case OP_MINUS:
53 left->value_ -= right->value_;
54 break;
55
56 case OP_PLUS:
57 left->value_ += right->value_;
58 break;
59
60 case OP_TIMES:
61 left->value_ *= right->value_;
62 break;
63
64 case OP_DIVIDE:
65 if (right->value_ == 0) {
66 c.error(l, "定数計算を0で除算しました。");
67 }
68 else {
69 left->value_ /= right->value_;
70 }
71 break;
72
73 case OP_MOD:
74 if (right->value_ == 0) {
75 c.error(l, "定数計算を0で除算しました。");
76 }
77 else {
78 left->value_ %= right->value_;
79 }
80 break;
81
82 default:
83 return new CNode(l, op, left, right);
84 }
85 delete right;
86 return left;
87 }
88 return new CNode(l, op, left, right);
89 }
90
91 void CNode::push(compiler *c) const
92 {
93 switch (op_) {
94 case OP_NEG:
95 left_->push(c);
96 c->OpNeg();
97 return;
98
99 case OP_RANDFUNC:
100 left_->push(c);
101 c->OpRand();
102 return;
103
104 case OP_CONST:
105 c->PushConst(value_);
106 return;
107 }
108
109 left_->push(c);
110 right_->push(c);
111
112 // 整数計算ノードの処理
113 switch (op_) {
114 case OP_EQ:
115 c->OpEq();
116 break;
117
118 case OP_NE:
119 c->OpNe();
120 break;
121
122 case OP_GT:
123 c->OpGt();
124 break;
125
126 case OP_GE:
127 c->OpGe();
128 break;
129
130 case OP_LT:
131 c->OpLt();
132 break;
133
134 case OP_LE:
135 c->OpLe();
136 break;
137
138 case OP_MINUS:
139 c->OpSub();
140 break;
141
142 case OP_PLUS:
143 c->OpAdd();
144 break;
145
146 case OP_TIMES:
147 c->OpMul();
148 break;
149
150 case OP_DIVIDE:
151 c->OpDiv();
152 break;
153
154 case OP_MOD:
155 c->OpMod();
156 break;
157
158 default:
159 c->error(l_, "内部エラー:処理できない計算ノードがありました。");
160 break;
161 }
162 }
163
164 void CNode::pop(compiler *c) const
165 {
166 c->error(l_, "内部エラー:計算ノードをpopしています。");
167 }
168
169 void CValueNode::push(compiler *c) const
170 {
171 if (op_ != OP_VALUE) {
172 c->error(l_, "内部エラー:変数ノードに変数以外が登録されています。");
173 }
174 else {
175 const CValueTag *tag = c->GetValueTag(*string_);
176 if (tag == 0) {
177 c->error(l_, "変数 " + *string_ + " は定義されていません。");
178 }
179 else {
180 c->PushValue(tag->addr_);
181 }
182 }
183 }
184
185 void CValueNode::pop(compiler *c) const
186 {
187 if (op_ != OP_VALUE) {
188 c->error(l_, "内部エラー:変数ノードに変数以外が登録されています。");
189 }
190 else {
191 const CValueTag *tag = c->GetValueTag(*string_);
192 if (tag == 0) {
193 tag = c->AddValue(*string_);
194 }
195 if (tag == 0) {
196 c->error(l_, "変数 " + *string_ + " が定義できません。");
197 }
198 else {
199 c->PopValue(tag->addr_);
200 }
201 }
202 }
203
204 // 代入命令を生成
205 //
206 // > push b
207 // > pop a
208 //
209 void CAssign::analyze(compiler *c)
210 {
211 expr_->push(c);
212 value_->pop(c);
213 }