Mercurial > hg > Members > nobuyasu > myCompiler
view Bison-Flex/BasicCompiler-StackBase/UTF8/node.cpp @ 2:fbe42292d479
upload test
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 10 May 2011 06:43:55 +0900 |
parents | |
children |
line wrap: on
line source
#include <functional> #include <iostream> #include <iomanip> #include "node.h" #include "compiler.h" #include "script-parser.hh" // ノード生成 // ただし、定数同士の計算は、leftノードに結果を代入し、それを返す CNode *CNode::MakeNode(compiler &c, const yy::location& l, int op, CNode *left, CNode *right) { if (right == 0) { switch (op) { case OP_NEG: if (left->op_ == OP_CONST) { // 定数演算を計算する left->value_ = -left->value_; return left; } break; } return new CNode(l, op, left); } // 定数演算を計算する if (left->op_ == OP_CONST && right->op_ == OP_CONST) { switch (op) { case OP_EQ: left->value_ = (left->value_ == right->value_)? 1: 0; break; case OP_NE: left->value_ = (left->value_ != right->value_)? 1: 0; break; case OP_GT: left->value_ = (left->value_ > right->value_)? 1: 0; break; case OP_GE: left->value_ = (left->value_ >= right->value_)? 1: 0; break; case OP_LT: left->value_ = (left->value_ < right->value_)? 1: 0; break; case OP_LE: left->value_ = (left->value_ <= right->value_)? 1: 0; break; case OP_MINUS: left->value_ -= right->value_; break; case OP_PLUS: left->value_ += right->value_; break; case OP_TIMES: left->value_ *= right->value_; break; case OP_DIVIDE: if (right->value_ == 0) { c.error(l, "定数計算を0で除算しました。"); } else { left->value_ /= right->value_; } break; case OP_MOD: if (right->value_ == 0) { c.error(l, "定数計算を0で除算しました。"); } else { left->value_ %= right->value_; } break; default: return new CNode(l, op, left, right); } delete right; return left; } return new CNode(l, op, left, right); } void CNode::push(compiler *c) const { switch (op_) { case OP_NEG: left_->push(c); c->OpNeg(); return; case OP_RANDFUNC: left_->push(c); c->OpRand(); return; case OP_CONST: c->PushConst(value_); return; } left_->push(c); right_->push(c); // 整数計算ノードの処理 switch (op_) { case OP_EQ: c->OpEq(); break; case OP_NE: c->OpNe(); break; case OP_GT: c->OpGt(); break; case OP_GE: c->OpGe(); break; case OP_LT: c->OpLt(); break; case OP_LE: c->OpLe(); break; case OP_MINUS: c->OpSub(); break; case OP_PLUS: c->OpAdd(); break; case OP_TIMES: c->OpMul(); break; case OP_DIVIDE: c->OpDiv(); break; case OP_MOD: c->OpMod(); break; default: c->error(l_, "内部エラー:処理できない計算ノードがありました。"); break; } } void CNode::pop(compiler *c) const { c->error(l_, "内部エラー:計算ノードをpopしています。"); } void CValueNode::push(compiler *c) const { if (op_ != OP_VALUE) { c->error(l_, "内部エラー:変数ノードに変数以外が登録されています。"); } else { const CValueTag *tag = c->GetValueTag(*string_); if (tag == 0) { c->error(l_, "変数 " + *string_ + " は定義されていません。"); } else { c->PushValue(tag->addr_); } } } void CValueNode::pop(compiler *c) const { if (op_ != OP_VALUE) { c->error(l_, "内部エラー:変数ノードに変数以外が登録されています。"); } else { const CValueTag *tag = c->GetValueTag(*string_); if (tag == 0) { tag = c->AddValue(*string_); } if (tag == 0) { c->error(l_, "変数 " + *string_ + " が定義できません。"); } else { c->PopValue(tag->addr_); } } } // 代入命令を生成 // // > push b // > pop a // void CAssign::analyze(compiler *c) { expr_->push(c); value_->pop(c); }