Mercurial > hg > Members > nobuyasu > myCompiler
view 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 |
line wrap: on
line source
#include <functional> #include <iostream> #include <iomanip> #include "node.h" #include "compiler.h" #include "script-parser.hh" // コード生成用 CNodeValue CNodeValue::MakeNodeValue(compiler *c, CNode *node) { switch (node->op()) { case OP_CONST: return CNodeValue(CONST, node->value()); case OP_VALUE: { const CValueTag *tag = c->GetValueTag(node->string()); if (tag == 0) { c->error(node->location(), "変数" + node->string() + "は未定義です。"); return CNodeValue(VALUE, 0); } return CNodeValue(VALUE, tag->addr_); } } return node->analyze(c); } // 一時変数の管理 CNodeValue CNodeValue::MakeTempValue(compiler *c, int value) { if (value < 0) return CNodeValue(c, TEMP, c->AllocTempValue()); return CNodeValue(VALUE, value); } void CNodeValue::ReleaseTempValue() { c_->ReleaseTempValue(value_); } void CNodeValue::UseTempValue() { c_->UseTempValue(value_); } int CNodeValue::value() const { if (type_ == TEMP) return c_->GetTempAddr(value_); return value_; } // ノード生成 // ただし、定数同士の計算は、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); } CNodeValue CNode::analyze(compiler *c, int ret) { switch (op_) { case OP_NEG: return c->MakeNeg(ret, CNodeValue::MakeNodeValue(c, left_)); case OP_RANDFUNC: return c->MakeRand(ret, CNodeValue::MakeNodeValue(c, left_)); case OP_CONST: return c->MakeMoveC(ret, value_); case OP_VALUE: return c->MakeMoveV(ret, CNodeValue::MakeNodeValue(c, this)); } CNodeValue left = CNodeValue::MakeNodeValue(c, left_); CNodeValue right = CNodeValue::MakeNodeValue(c, right_); // 整数計算ノードの処理 return c->MakeOp(op_, ret, left, right); } // 代入命令を生成 // // a = b // > mov a, b // CNodeValue CAssign::analyze(compiler *c) { const CValueTag *tag = c->GetValueTag(value_->string()); if (tag == 0) { tag = c->AddValue(value_->string()); } if (tag == 0) { c->error(l_, "変数 " + value_->string() + " が定義できません。"); return CNodeValue(); } return expr_->analyze(c, tag->addr_); }