#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_LoopForeverAST, T_LoopForAST, T_LoopDoTimesAST, T_UnaryAST, T_BinaryAST, T_ListAST, T_VarOpAST, T_LValOpAST, T_ReturnAST, T_LiteralAST, }; /// 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; } inline const std::string& getName() const { return this->name; } }; class FuncCallAST : public ExprAST { private: std::string name; std::vector> args; public: FuncCallAST(std::string name, std::vector> args) : name(std::move(name)), args(std::move(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::shared_ptr cond, std::shared_ptr then, std::shared_ptr els) : cond(std::move(cond)), then(std::move(then)), els(std::move(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 {}; class LoopForeverAST : public LoopAST { private: std::vector> body; public: explicit LoopForeverAST(std::vector> body) : body(std::move(body)) {} std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_LoopForeverAST; } }; class LoopForAST : public LoopAST { private: std::string name; std::shared_ptr start; std::shared_ptr end; std::vector> body; public: LoopForAST(std::string name, std::shared_ptr start, std::shared_ptr end, std::vector> body) : name(std::move(name)), start(std::move(start)), end(std::move(end)), body(std::move(body)) {} std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_LoopForAST; } }; class LoopDoTimesAST : public LoopAST { private: std::string name; std::shared_ptr times; std::vector> body; public: LoopDoTimesAST(std::string name, std::shared_ptr times, std::vector> body) : name(std::move(name)), times(std::move(times)), body(std::move(body)) {} std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_LoopDoTimesAST; } }; class UnaryAST : public ExprAST { private: std::shared_ptr expr; Token op; public: UnaryAST(std::shared_ptr expr, Token op) : expr(std::move(expr)), op(std::move(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::shared_ptr lhs, std::shared_ptr rhs, Token op) : lhs(std::move(lhs)), rhs(std::move(rhs)), op(std::move(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) : exprs(std::move(exprs)), op(std::move(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::shared_ptr expr, Token op) : name(std::move(name)), expr(std::move(expr)), op(std::move(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::shared_ptr lval, std::shared_ptr expr, Token op) : lval(std::move(lval)), expr(std::move(expr)), op(std::move(op)) {} std::shared_ptr eval(Context* parent) override final; inline ASTType getType() const override final { return T_LValOpAST; } }; class ReturnAST : public ExprAST { private: std::shared_ptr expr; std::string name; public: explicit ReturnAST(std::shared_ptr expr) : expr(std::move(expr)), name() {} ReturnAST(std::shared_ptr expr, std::string name) : expr(std::move(expr)), name(std::move(name)) {} std::shared_ptr eval(Context* parent) override final; std::string getName() const { return name; } inline ASTType getType() const override final { return T_ReturnAST; } }; class LiteralAST : public ExprAST { private: std::shared_ptr val; public: explicit LiteralAST(bool val) : val(std::make_shared(val)) {} explicit LiteralAST(std::int64_t val) : val(std::make_shared(val)) {} explicit LiteralAST(double val) : val(std::make_shared(val)) {} explicit LiteralAST(std::string val) : val(std::make_shared(std::move(val))) {} inline ASTType getType() const override final { return T_LiteralAST; } std::shared_ptr eval(Context* parent) override final { return val->copy(); } }; } #endif // __DRAGON_LISP_AST_H__