view Bison-Flex/BasicCompiler-MemoryBase/UTF8/node.h @ 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

#ifndef __NODE_H__
#define	__NODE_H__

#include <string>
#include <vector>
#include <map>
#include <functional>
#include <algorithm>
#include "location.hh"
#include "vm.h"

class compiler;
class CNode;
class CValueNode;
class CArgDef;

// 配列

template<typename T>
class CNodeList {
	struct delete_object {
		void operator()(T *ptr){ delete ptr; }
	} ;

  public:
	CNodeList(const yy::location& l, T *node)
	{
		args.push_back(node);
	}
	~CNodeList()
	{
		std::for_each(args.begin(), args.end(), delete_object());
	}

	CNodeList<T> *Add(const yy::location& l, T *add)
	{
		args.push_back(add);
		return this;
	}

	template<typename Fn>
	void for_each(const Fn &func)
	{
		std::for_each(args.begin(), args.end(), func);
	}

	template<typename Fn>
	void for_each_rev(const Fn &func)
	{
		std::for_each(args.rbegin(), args.rend(), func);
	}

	void analyze(compiler *c)
	{
		std::for_each(args.begin(), args.end(), std::bind2nd(std::mem_fun(&T::analyze), c));
	}

	size_t size() const { return args.size(); }
	T *get(size_t idx) { return args[idx]; }
	T *operator[](size_t idx) { return args[idx]; }
	const T *get(size_t idx) const { return args[idx]; }
	const T *operator[](size_t idx) const { return args[idx]; }

  private:
	std::vector<T*> args;
} ;

typedef	CNodeList<CNode>		CArgs;

// ノードの命令
enum	{
	OP_NEG,
	OP_PLUS,
	OP_MINUS,
	OP_TIMES,
	OP_DIVIDE,
	OP_MOD,
	OP_EQ,
	OP_NE,
	OP_GT,
	OP_GE,
	OP_LT,
	OP_LE,
	OP_VALUE,
	OP_CONST,
	OP_RANDFUNC,
} ;

class CNode;
class CNodeValue {
  public:
	enum	{
		CONST,
		VALUE,
		TEMP,
	} ;

  public:
	CNodeValue(): type_(-1), value_(-1), c_(0)
	{
	}
	CNodeValue(int type, int value): type_(type), value_(value), c_(0)
	{
	}
	CNodeValue(compiler *c, int type, int value): type_(type), value_(value), c_(c)
	{
	}
	~CNodeValue()
	{
		if (type_ == TEMP) {
			ReleaseTempValue();
		}
	}

	// コピーコンストラクタ
	CNodeValue(const CNodeValue &a)
	{
		c_ = a.c_;
		type_ = a.type_;
		value_ = a.value_;
		if (type_ == TEMP) {
			UseTempValue();
		}
	}

	// 代入
	CNodeValue& operator=(const CNodeValue &a)
	{
		if (this == &a)
			return *this;

		if (type_ == TEMP) {
			ReleaseTempValue();
		}
		c_ = a.c_;
		type_ = a.type_;
		value_ = a.value_;
		if (type_ == TEMP) {
			UseTempValue();
		}
		return *this;
	}

	void ReleaseTempValue();
	void UseTempValue();

	int type() const { return type_; }
	int value() const;

	static CNodeValue MakeNodeValue(compiler *c, CNode *node);
	static CNodeValue MakeTempValue(compiler *c, int value);

  private:
	int type_;
	int value_;
	compiler *c_;
} ;

// ノード

class CNode {
  public:
	CNode(const yy::location& l, int op, CNode *left, CNode *right=0)
		: l_(l), op_(op), left_(left), right_(right), value_(0), string_(0)
	{
	}
	CNode(const yy::location& l, int op, int value)
		: l_(l), op_(op), left_(0), right_(0), value_(value), string_(0)
	{
	}
	CNode(const yy::location& l, int op, std::string *str)
		: l_(l), op_(op), left_(0), right_(0), value_(0), string_(str)
	{
	}
	CNode(const yy::location& l, int op, std::string *str, CNode *node)
		: l_(l), op_(op), left_(node), right_(0), value_(0), string_(str)
	{
	}
	virtual ~CNode()
	{
		delete left_;
		delete right_;
		delete string_;
	}

	virtual CNodeValue analyze(compiler *c, int ret = -1);

	const yy::location &location() const { return l_; }
	int op() const { return op_; }
	int value() const { return value_; }
	const std::string &string() const { return *string_; }
	const CNode *left() const { return left_; }
	const CNode *right() const { return right_; }

	static CNode *MakeNode(compiler &c, const yy::location& l, int op, CNode *left, CNode *right=0);

  protected:
	const yy::location l_;
	int op_;
	int value_;
	std::string *string_;
	CNode *left_;
	CNode *right_;
} ;

// 変数ノード

class CValueNode: public CNode {
  public:
	CValueNode(const yy::location& l, std::string *name, CNode *node=NULL)
		: CNode(l, OP_VALUE, name, node)
	{
	}
} ;

// 代入文用

class CAssign {
  public:
	CAssign(const yy::location& l, int op, CNode *value, CNode *expr)
		: l_(l), op_(op), value_(value), expr_(expr)
	{
	}
	~CAssign()
	{
		delete value_;
		delete expr_;
	}

	CNodeValue analyze(compiler *c);

  private:
	const yy::location l_;
	int op_;
	CNode *value_;
	CNode *expr_;
} ;

#endif