#pragma once #include #include #include #include namespace cps { class ExprAST { public: virtual ~ExprAST() = default; }; class NumberExprAST : public ExprAST { int64_t Val; public: NumberExprAST(int64_t Val) : Val(Val) {} int64_t getVal() const { return Val; } }; class VariableExprAST : public ExprAST { std::string Name; public: VariableExprAST(const std::string &Name) : Name(Name) {} const std::string &getName() const { return Name; } }; class ArrayAccessExprAST : public ExprAST { std::string Name; std::vector> Indices; int Line; public: ArrayAccessExprAST(const std::string &Name, std::vector> Indices, int Line) : Name(Name), Indices(std::move(Indices)), Line(Line) {} const std::string &getName() const { return Name; } const std::vector> &getIndices() const { return Indices; } int getLine() const { return Line; } }; class BinaryExprAST : public ExprAST { int Op; std::unique_ptr LHS, RHS; int Line; public: BinaryExprAST(int Op, std::unique_ptr LHS, std::unique_ptr RHS, int Line) : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)), Line(Line) {} int getOp() const { return Op; } ExprAST *getLHS() const { return LHS.get(); } ExprAST *getRHS() const { return RHS.get(); } int getLine() const { return Line; } }; class StmtAST { public: virtual ~StmtAST() = default; }; class DeclareStmtAST : public StmtAST { std::string Name; public: DeclareStmtAST(const std::string &Name) : Name(Name) {} const std::string &getName() const { return Name; } }; class ArrayDeclareStmtAST : public StmtAST { std::string Name; std::vector, std::unique_ptr>> Bounds; std::string Type; public: ArrayDeclareStmtAST(const std::string &Name, std::vector, std::unique_ptr>> Bounds, const std::string &Type) : Name(Name), Bounds(std::move(Bounds)), Type(Type) {} const std::string &getName() const { return Name; } const std::vector, std::unique_ptr>> &getBounds() const { return Bounds; } const std::string &getType() const { return Type; } }; class AssignStmtAST : public StmtAST { std::string Name; std::unique_ptr Expr; public: AssignStmtAST(const std::string &Name, std::unique_ptr Expr) : Name(Name), Expr(std::move(Expr)) {} const std::string &getName() const { return Name; } ExprAST *getExpr() const { return Expr.get(); } }; class ArrayAssignStmtAST : public StmtAST { std::string Name; std::vector> Indices; std::unique_ptr Expr; int Line; public: ArrayAssignStmtAST(const std::string &Name, std::vector> Indices, std::unique_ptr Expr, int Line) : Name(Name), Indices(std::move(Indices)), Expr(std::move(Expr)), Line(Line) {} const std::string &getName() const { return Name; } const std::vector> &getIndices() const { return Indices; } ExprAST *getExpr() const { return Expr.get(); } int getLine() const { return Line; } }; class InputStmtAST : public StmtAST { std::string Name; public: InputStmtAST(const std::string &Name) : Name(Name) {} const std::string &getName() const { return Name; } }; class OutputStmtAST : public StmtAST { std::unique_ptr Expr; public: OutputStmtAST(std::unique_ptr Expr) : Expr(std::move(Expr)) {} ExprAST *getExpr() const { return Expr.get(); } }; class IfStmtAST : public StmtAST { std::unique_ptr Cond; std::vector> ThenStmts; std::vector> ElseStmts; public: IfStmtAST(std::unique_ptr Cond, std::vector> ThenStmts, std::vector> ElseStmts) : Cond(std::move(Cond)), ThenStmts(std::move(ThenStmts)), ElseStmts(std::move(ElseStmts)) {} ExprAST *getCond() const { return Cond.get(); } const std::vector> &getThenStmts() const { return ThenStmts; } const std::vector> &getElseStmts() const { return ElseStmts; } }; class WhileStmtAST : public StmtAST { std::unique_ptr Cond; std::vector> Body; public: WhileStmtAST(std::unique_ptr Cond, std::vector> Body) : Cond(std::move(Cond)), Body(std::move(Body)) {} ExprAST *getCond() const { return Cond.get(); } const std::vector> &getBody() const { return Body; } }; class RepeatStmtAST : public StmtAST { std::vector> Body; std::unique_ptr Cond; public: RepeatStmtAST(std::vector> Body, std::unique_ptr Cond) : Body(std::move(Body)), Cond(std::move(Cond)) {} ExprAST *getCond() const { return Cond.get(); } const std::vector> &getBody() const { return Body; } }; class ForStmtAST : public StmtAST { std::string VarName; std::unique_ptr Start; std::unique_ptr End; std::unique_ptr Step; std::vector> Body; public: ForStmtAST(const std::string &VarName, std::unique_ptr Start, std::unique_ptr End, std::unique_ptr Step, std::vector> Body) : VarName(VarName), Start(std::move(Start)), End(std::move(End)), Step(std::move(Step)), Body(std::move(Body)) {} const std::string &getVarName() const { return VarName; } ExprAST *getStart() const { return Start.get(); } ExprAST *getEnd() const { return End.get(); } ExprAST *getStep() const { return Step.get(); } const std::vector> &getBody() const { return Body; } }; } // namespace cps