#ifndef __DRAGON_LISP_AST_H__ #define __DRAGON_LISP_AST_H__ #include #include #include "types.h" #include "token.h" #include "context.h" namespace DragonLisp { enum ASTType { T_ArrayRefAST, T_IdentifierAST, T_FuncDefAST, T_FuncCallAST, T_IfAST, T_LoopAST, T_UnaryAST, T_BinaryAST, T_ListAST, T_VarOpAST, T_LValOpAST, }; /// BaseAST - Base class for all AST nodes. class BaseAST { public: virtual ~BaseAST() = default; virtual ASTType getType() const = 0; }; class ExprAST : public BaseAST { public: virtual std::shared_ptr eval(Context* parent) = 0; }; class LValueAST : public ExprAST { public: virtual std::shared_ptr set(Context* parent, std::shared_ptr value) = 0; }; class ArrayRefAST : public LValueAST { private: std::string name; std::shared_ptr index; public: ArrayRefAST(std::string name, std::shared_ptr index) : name(std::move(name)), index(std::move(index)) {} ASTType getType() const override final { return T_ArrayRefAST; } std::shared_ptr eval(Context* parent) override final; std::shared_ptr set(Context* parent, std::shared_ptr value) override final; }; class IdentifierAST : public LValueAST { private: std::string name; public: explicit IdentifierAST(std::string name) : name(std::move(name)) {} ASTType getType() const override final { return T_IdentifierAST; } std::shared_ptr eval(Context* parent) override final; std::shared_ptr set(Context* parent, std::shared_ptr value) override final; }; class FuncDefAST : public BaseAST { private: std::string name; std::vector args; std::vector> body; public: FuncDefAST(std::string name, std::vector args, std::vector> body) : name(std::move(name)), args(std::move(args)), body(std::move(body)) {} std::shared_ptr eval(Context* parent, std::vector> arg); inline ASTType getType() const override final { return T_FuncDefAST; } }; class FuncCallAST : public ExprAST { private: std::string name; std::vector> args; public: FuncCallAST(std::string name, std::vector> args); std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_FuncCallAST; } }; class IfAST : public ExprAST { private: std::shared_ptr cond; std::shared_ptr then; std::shared_ptr els; public: IfAST(std::unique_ptr cond, std::unique_ptr then, std::unique_ptr els); std::shared_ptr eval(Context* parent) override final { throw std::runtime_error("You should use IfAST::getResult() instead of IfAST::eval()"); } std::shared_ptr getResult(Context* parent); inline ASTType getType() const override final { return T_IfAST; } }; class LoopAST : public ExprAST { private: std::string loopVar; std::shared_ptr start; std::shared_ptr end; std::shared_ptr body; public: LoopAST(std::string loopVar, std::unique_ptr start, std::unique_ptr end, std::unique_ptr body); std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_LoopAST; } }; class UnaryAST : public ExprAST { private: std::shared_ptr expr; Token op; public: UnaryAST(std::unique_ptr expr, Token op); std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_UnaryAST; } }; class BinaryAST : public ExprAST { private: std::shared_ptr lhs; std::shared_ptr rhs; Token op; public: BinaryAST(std::unique_ptr lhs, std::unique_ptr rhs, Token op); std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_BinaryAST; } }; class ListAST : public ExprAST { private: std::vector> exprs; Token op; public: ListAST(std::vector> exprs, Token op); std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_ListAST; } }; class VarOpAST : public ExprAST { private: std::string name; std::shared_ptr expr; Token op; public: VarOpAST(std::string name, std::unique_ptr expr, Token op); std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_VarOpAST; } }; class LValOpAST : public ExprAST { private: std::shared_ptr lval; std::shared_ptr expr; Token op; public: LValOpAST(std::unique_ptr lval, std::unique_ptr expr, Token op); std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_LValOpAST; } }; } #endif // __DRAGON_LISP_AST_H__