view WindowsOnly/WinScript2/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 <string>
#include <vector>
#include <map>
#include <algorithm>
#include "location.hh"
#include "vm.h"

class compiler;
class CNode;
class CValueNode;
class CDecl;
class CArgDef;
class CStatement;

// 配列

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

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

	CNodeList<T> *Add(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);
	}

	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;
typedef	CNodeList<CValueNode>	CValueList;
typedef	CNodeList<CArgDef>		CArgList;
typedef	CNodeList<CDecl>		CDeclList;
typedef	CNodeList<CStatement>	CStateList;

// 変数、関数の型
enum	{
	TYPE_INTEGER,
	TYPE_STRING,
	TYPE_INTEGER_REF,
	TYPE_STRING_REF,
	TYPE_VOID,
} ;

// 変数型に対応した参照型を得る
inline int TypeToRef(int type)
{
	return type + TYPE_INTEGER_REF - TYPE_INTEGER;
}

// ノードの命令
enum	{
	OP_NEG,
	OP_PLUS,
	OP_MINUS,
	OP_TIMES,
	OP_DIVIDE,
	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_VALUE,
	OP_CONST,
	OP_STRING,
	OP_FUNCTION,
} ;

// ノード

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 int push(compiler *c) const;
	virtual int pop(compiler *c) const;

	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)
	{
	}

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

// 関数ノード

class CFunctionNode: public CNode {
  public:
	CFunctionNode(const yy::location& l, std::string *name, CArgs *args)
		: CNode(l, OP_FUNCTION, name), args_(args)
	{
	}
	~CFunctionNode()
	{
		delete args_;
	}

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

  private:
	CArgs *args_;
} ;

// 代入文用

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_;
	}

	void analyze(compiler *c);

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

// 引数定義

class CArgDef {
  public:
	CArgDef(const yy::location& l, int type, const std::string *name)
		: l_(l), type_(type), name_(name)
	{
	}
	~CArgDef()
	{
		delete name_;
	}

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

  private:
	const yy::location l_;
	int type_;
	const std::string *name_;
} ;

// 変数定義

class CDecl {
  public:
	CDecl(int type, CValueList *list)
		: type_(type), list_(list)
	{
	}
	~CDecl()
	{
		delete list_;
	}

	void analyze(compiler *c);

  private:
	int type_;
	CValueList *list_;
} ;

// '{' '}' による文のまとまり

class CStateBlock {
  public:
	CStateBlock(CDeclList *decls, CStateList *states)
		: decls_(decls), states_(states)
	{
	}
	~CStateBlock()
	{
		delete decls_;
		delete states_;
	}

	void analyze(compiler *c);

  private:
	CDeclList *decls_;
	CStateList *states_;
} ;

// case文の処理

struct case_action_param {
	compiler *comp_;
	int &default_label;
	case_action_param(compiler *comp, int &label): comp_(comp), default_label(label)
	{
	}
} ;

// 文

class CStatement {
  public:
	enum	{
		NOP,
		ASSIGN,
		FUNCTION,
		IF,
		FOR,
		WHILE,
		SWITCH,
		CASE,
		DEFAULT,
		BREAK,
		RETURN,
		BLOCK,
	} ;

  public:
	CStatement(const yy::location& l, int code)
		: l_(l), code_(code)
	{
	}
	virtual ~CStatement()
	{
	}

	virtual void analyze(compiler *c) = 0;
	virtual void case_analyze(case_action_param *param)
	{
	}

  protected:
	const yy::location l_;
	int code_;
} ;

// nop文

class CNopStatement: public CStatement {
  public:
	CNopStatement(const yy::location& l)
		: CStatement(l, NOP)
	{
	}
	virtual void analyze(compiler *c);
} ;

// 代入文

class CAssignStatement: public CStatement {
  public:
	CAssignStatement(const yy::location& l, CAssign *assign)
		: CStatement(l, ASSIGN), assign_(assign)
	{
	}
	~CAssignStatement()
	{
		delete assign_;
	}

	virtual void analyze(compiler *c);

  private:
	CAssign *assign_;
} ;

// 関数呼び出し

class CFunctionStatement: public CStatement {
  public:
	CFunctionStatement(const yy::location& l, std::string *name, CArgs *args)
		: CStatement(l, FUNCTION), node_(l, name, args)
	{
	}
	~CFunctionStatement()
	{
	}

	virtual void analyze(compiler *c);

  private:
	CFunctionNode node_;
} ;

// if文

class CIfStatement: public CStatement {
  public:
	CIfStatement(const yy::location& l, CNode *expr, CStatement *then_statement, CStatement *else_statement=NULL)
		: CStatement(l, IF), expr_(expr), then_statement_(then_statement), else_statement_(else_statement)
	{
	}
	~CIfStatement()
	{
		delete expr_;
		delete then_statement_;
		delete else_statement_;
	}

	virtual void analyze(compiler *c);

  private:
	CNode *expr_;
	CStatement *then_statement_;
	CStatement *else_statement_;
} ;

// while文

class CForStatement: public CStatement {
  public:
	CForStatement(const yy::location& l, CAssign *init, CNode *expr, CAssign *next, CStatement *statement)
		: CStatement(l, FOR), init_(init), expr_(expr), next_(next), statement_(statement)
	{
	}
	~CForStatement()
	{
		delete init_;
		delete expr_;
		delete next_;
		delete statement_;
	}

	virtual void analyze(compiler *c);

  private:
	CAssign *init_;
	CNode *expr_;
	CAssign *next_;
	CStatement *statement_;
} ;

// while文

class CWhileStatement: public CStatement {
  public:
	CWhileStatement(const yy::location& l, CNode *expr, CStatement *statement)
		: CStatement(l, WHILE), expr_(expr), statement_(statement)
	{
	}
	~CWhileStatement()
	{
		delete expr_;
		delete statement_;
	}

	virtual void analyze(compiler *c);

  private:
	CNode *expr_;
	CStatement *statement_;
} ;

// switch文

class CSwitchStatement: public CStatement {
  public:
	CSwitchStatement(const yy::location& l, CNode *expr, CStateList *list)
		: CStatement(l, SWITCH), expr_(expr), list_(list)
	{
	}
	~CSwitchStatement()
	{
		delete expr_;
		delete list_;
	}

	virtual void analyze(compiler *c);

  private:
	CNode *expr_;
	CStateList *list_;
} ;

// case文

class CCaseStatement: public CStatement {
  public:
	CCaseStatement(const yy::location& l, CNode *expr)
		: CStatement(l, CASE), expr_(expr)
	{
	}
	~CCaseStatement()
	{
		delete expr_;
	}

	virtual void analyze(compiler *c);
	virtual void case_analyze(case_action_param *param);

  private:
	CNode *expr_;
	int label_;
} ;

// default文

class CDefaultStatement: public CStatement {
  public:
	CDefaultStatement(const yy::location& l)
		: CStatement(l, DEFAULT)
	{
	}

	virtual void analyze(compiler *c);
	virtual void case_analyze(case_action_param *param);

  private:
	int label_;
} ;

// break文

class CBreakStatement: public CStatement {
  public:
	CBreakStatement(const yy::location& l)
		: CStatement(l, BREAK)
	{
	}

	virtual void analyze(compiler *c);
} ;

// return文

class CReturnStatement: public CStatement {
  public:
	CReturnStatement(const yy::location& l, CNode *expr)
		: CStatement(l, RETURN), expr_(expr)
	{
	}
	~CReturnStatement()
	{
		delete expr_;
	}

	virtual void analyze(compiler *c);

  private:
	CNode *expr_;
} ;

// ブロック文

class CBlockStatement: public CStatement {
  public:
	CBlockStatement(const yy::location& l, CStateBlock *block)
		: CStatement(l, BLOCK), block_(block)
	{
	}
	~CBlockStatement()
	{
		delete block_;
	}

	virtual void analyze(compiler *c);

  private:
	CStateBlock *block_;
} ;

#endif