view boost-spirit/Compiler-boost-spirit/node.h @ 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
line wrap: on
line source

#ifndef __NODE_H__
#define	__NODE_H__

#include <iostream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>

class compiler;

// ノード

// 変数、関数の型
enum VALUE_TYPE {
	TYPE_INTEGER,
	TYPE_STRING,
	TYPE_VOID,
	TYPE_REF = 0x80,
	TYPE_INTEGER_REF = TYPE_INTEGER | TYPE_REF,
	TYPE_STRING_REF = TYPE_STRING | TYPE_REF,
} ;

// ノードの命令
enum OPCODE {
	OP_NEG,
	OP_ADD,
	OP_SUB,
	OP_MUL,
	OP_DIV,
	OP_MOD,
	OP_AND,
	OP_OR,
	OP_LSHIFT,
	OP_RSHIFT,
	OP_LOGAND,
	OP_LOGOR,
	OP_EQ,
	OP_NE,
	OP_GT,
	OP_GE,
	OP_LT,
	OP_LE,
	OP_ASSIGN,
	OP_ADD_ASSIGN,
	OP_SUB_ASSIGN,
	OP_MUL_ASSIGN,
	OP_DIV_ASSIGN,
	OP_MOD_ASSIGN,
	OP_AND_ASSIGN,
	OP_OR_ASSIGN,
	OP_LSHIFT_ASSIGN,
	OP_RSHIFT_ASSIGN,
	OP_NUMBER,
	OP_IDENTIFIER,
	OP_STRING,
	OP_FUNCTION,
	OP_ARRAY,
} ;

// ノード

class cnode;
class cnode_list;
typedef	boost::shared_ptr<cnode> cnode_t;
typedef	boost::shared_ptr<cnode_list> cnode_list_t;

class cnode {
  public:
	cnode(int op, const cnode_t &left, const cnode_t &right)
		: op_(op), left_(left), right_(right), number_(0)
	{
	}
	cnode(int op, const cnode_t &left)
		: op_(op), left_(left), number_(0)
	{
	}
	cnode(int op, int number)
		: op_(op), number_(number)
	{
	}
	cnode(int op, const std::string &str)
		: op_(op), number_(0), string_(str)
	{
	}
	cnode(int op, const char *b, const char *e)
		: op_(op), string_(b, e)
	{
	}
	virtual ~cnode()
	{
	}

	int op() const { return op_; }
	int number() const { return number_; }
	const std::string &string() const { return string_; }
	cnode_t left() const { return left_; }
	cnode_t right() const { return right_; }

	virtual int push(compiler *c) const;
	virtual int pop(compiler *c) const;

	void assign(compiler *c) const;
	int call(compiler *c, const std::string &name, const std::vector<cnode_t> *args) const;

	static cnode_t make_node(int op, int number)
	{
		return cnode_t(new cnode(op, number));
	}

	static cnode_t make_node(int op, const std::string &str);
	static cnode_t make_node(int op, cnode_t left);
	static cnode_t make_node(int op, cnode_t left, cnode_t right);
	static cnode_t make_node(int op, cnode_t left, cnode_list_t right);

  protected:
	int op_;
	int number_;
	std::string string_;
	cnode_t left_;
	cnode_t right_;
} ;

// 変数ノード

class cvalue_node: public cnode {
  public:
	cvalue_node(const std::string &name)
		: cnode(OP_IDENTIFIER, name)
	{
	}

	int push(compiler *c) const;
	int pop(compiler *c) const;
} ;

// ノードリスト

class cnode_list {
  public:
	cnode_list(cnode_t node)
	{
		args_.push_back(node);
	}

	cnode_list *add(cnode_t add)
	{
		args_.push_back(add);
		return this;
	}

	size_t size() const { return args_.size(); }
	cnode_t get(size_t index) const { return args_[index]; }

  public:
	std::vector<cnode_t> args_;
} ;

// 関数のノード

class cfunction_node: public cnode {
  public:
	cfunction_node(int op, const cnode_t &node, const cnode_list_t &list)
		: cnode(op, node), node_list_(list)
	{
	}

	virtual int push(compiler *c) const;
	virtual int pop(compiler *c) const;

  private:
	cnode_list_t node_list_;
} ;

// ステートメント

enum STATE_TYPE {
	NOP_STATE,
	ASSIGN_STATE,
	CALL_STATE,
	CASE_STATE,
	DEFAULT_STATE,
	BREAK_STATE,
	RETURN_STATE,
	IF_STATE,
	FOR_STATE,
	WHILE_STATE,
	SWITCH_STATE,
	BLOCK_STATE,
} ;

class cblock;
typedef	boost::shared_ptr<cblock> cblock_t;

class cstatement;
typedef	boost::shared_ptr<cstatement> cstatement_t;

// 文
class cstatement {
  public:
	virtual void add(cstatement_t statement)
	{
		std::cerr << "内部エラー:add(statement)が呼ばれました" << std::endl;
	}

	virtual void add(cnode_t node)
	{
		std::cerr << "内部エラー:add(node)が呼ばれました" << std::endl;
	}

	virtual void add(int index, cstatement_t statement)
	{
		std::cerr << "内部エラー:add(index, statement)が呼ばれました" << std::endl;
	}

	virtual void add(int index, cnode_t node)
	{
		std::cerr << "内部エラー:add(index, node)が呼ばれました" << std::endl;
	}

	virtual void analyze(compiler *c) const = 0;

	virtual void case_analyze(compiler *c, int *default_label)
	{
	}

	static cstatement_t make_statement(int state);
	static cstatement_t make_statement(int state, cnode_t node);
	static cstatement_t make_statement(int state, cblock_t block);
} ;

// nop文
class cnop_statement: public cstatement {
  public:
	void analyze(compiler *c) const;
} ;

// 代入文
class cassign_statement: public cstatement {
  public:
	cassign_statement(cnode_t node)
		: node_(node)
	{
	}

	void analyze(compiler *c) const;

  private:
	cnode_t node_;
} ;

// 関数呼び出し文
class ccall_statement: public cstatement {
  public:
	ccall_statement(cnode_t node)
		: node_(node)
	{
	}

	void analyze(compiler *c) const;

  private:
	cnode_t node_;
} ;

// case文
class ccase_statement: public cstatement {
  public:
	ccase_statement(cnode_t node)
		: node_(node)
	{
	}

	void analyze(compiler *c) const;
	void case_analyze(compiler *c, int *default_label);

  private:
	cnode_t node_;
	int label_;
} ;

// default文
class cdefault_statement: public cstatement {
  public:
	void analyze(compiler *c) const;
	void case_analyze(compiler *c, int *default_label);

  private:
	int label_;
} ;

// break文
class cbreak_statement: public cstatement {
  public:
	void analyze(compiler *c) const;
} ;

// return文
class creturn_statement: public cstatement {
  public:
	void add(cnode_t node)
	{
		node_ = node;
	}

	void analyze(compiler *c) const;

  private:
	cnode_t node_;
} ;

// if文
class cif_statement: public cstatement {
  public:
	cif_statement()
	{
	}

	void add(cnode_t node)
	{
		node_ = node;
	}

	void add(int index, cstatement_t statement)
	{
		statement_[index] = statement;
	}

	void analyze(compiler *c) const;

  private:
	cnode_t node_;
	cstatement_t statement_[2];
} ;

// for文
class cfor_statement: public cstatement {
  public:
	void add(cstatement_t statement)
	{
		statement_ = statement;
	}

	void add(int index, cnode_t node)
	{
		node_[index] = node;
	}

	void analyze(compiler *c) const;

  private:
	cstatement_t statement_;
	cnode_t node_[3];
} ;

// while文
class cwhile_statement: public cstatement {
  public:
	void add(cstatement_t statement)
	{
		statement_ = statement;
	}

	void add(cnode_t node)
	{
		node_ = node;
	}

	void analyze(compiler *c) const;

  private:
	cnode_t node_;
	cstatement_t statement_;
} ;

// switch文
class cswitch_statement: public cstatement {
  public:
	cswitch_statement(cnode_t node)
		: node_(node)
	{
	}

	void add(cstatement_t statement)
	{
		statement_.push_back(statement);
	}

	void analyze(compiler *c) const;

  private:
	cnode_t node_;
	std::vector<cstatement_t> statement_;
} ;

// block文
class cblock_statement: public cstatement {
  public:
	cblock_statement(cblock_t block)
		: block_(block)
	{
	}

	void analyze(compiler *c) const;

  private:
	cblock_t block_;
} ;

// 宣言

class cdeclaration: public cstatement {
  public:
	cdeclaration(int type)
		:type_(type), is_func_(false)
	{
	}

	cdeclaration(int type, const std::string &name)
		:type_(type), name_(name), is_func_(true)
	{
	}

	void add(cnode_t node)
	{
		node_.push_back(node);
	}

	void add(int type)
	{
		arg_.push_back(type);
	}

	void analyze(compiler *c) const;

  private:
	int type_;					// 型
	bool is_func_;				// 関数か変数か
	std::vector<cnode_t> node_;	// 変数
	std::string name_;			// 関数名
	std::vector<int> arg_;		// 関数の引数
} ;

typedef	boost::shared_ptr<cdeclaration> cdeclaration_t;

// 文ブロック

class cblock {
  public:
	void add(const cdeclaration_t &decl)
	{
		decl_.push_back(decl);
	}
	void add(const cstatement_t &state)
	{
		state_.push_back(state);
	}

	void analyze(compiler *c) const;

  private:
	std::vector<cdeclaration_t> decl_;
	std::vector<cstatement_t> state_;
} ;

// 関数の引数

class cargdef {
  public:
	cargdef()
		: type_(0)
	{
	}

	cargdef(int type)
		: type_(type)
	{
	}

	void set_ref()
	{
		type_ |= TYPE_REF;
	}

	void set_name(const std::string &name)
	{
		name_ = name;
	}

	int type() const { return type_; }
	const std::string &name() const { return name_; }

  private:
	int type_;
	std::string name_;
} ;

// 関数

class cfunction {
  public:
	cfunction(int type, const std::string &name)
		:type_(type), name_(name)
	{
	}

	void add(cargdef arg)
	{
		args_.push_back(arg);
	}

	void add(cblock_t block)
	{
		block_ = block;
	}

	void analyze(compiler *c) const;

  private:
	int type_;
	std::string name_;
	std::vector<cargdef> args_;
	cblock_t block_;
} ;

typedef	boost::shared_ptr<cfunction> cfunction_t;

#endif