#pragma once #include #include #include "string_utils.hpp" #include "base.hpp" template using ptr = std::unique_ptr; struct Assign : Stmt { ptr target; ptr value; Assign(ptr t, ptr v) : target(std::move(t)), value(std::move(v)) {} std::string dump(int indent = 0) const override { std::ostringstream oss; oss << indent_str(indent) << "Assign\n"; oss << target->dump(indent + 1) << "\n"; oss << value->dump(indent + 1); return oss.str(); } }; struct ExprStmt : Stmt { ptr expr; ExprStmt(ptr e) : expr(std::move(e)) {} std::string dump(int indent = 0) const override { std::ostringstream oss; oss << indent_str(indent) << "ExprStmt\n"; oss << expr->dump(indent + 1); return oss.str(); } }; struct Return : Stmt { ptr value; Return(ptr v) : value(std::move(v)) {} std::string dump(int indent = 0) const override { std::ostringstream oss; oss << indent_str(indent) << "Return\n"; if (value) { oss << value->dump(indent + 1); } return oss.str(); } }; struct Pass : Stmt { std::string dump(int indent = 0) const override { return indent_str(indent) + "Pass"; } }; // #todo elif struct If : Stmt { ptr condition; std::vector> then_body; std::vector> else_body; If(ptr cond, std::vector> then_b, std::vector> else_b) : condition(std::move(cond)), then_body(std::move(then_b)), else_body(std::move(else_b)) {} std::string dump(int indent = 0) const override { std::ostringstream oss; oss << indent_str(indent) << "If\n"; oss << condition->dump(indent + 1); for (const auto &stmt : then_body) { oss << "\n" << stmt->dump(indent + 1); } if (!else_body.empty()) { oss << "\n" << indent_str(indent + 1) << "Else"; for (const auto &stmt : else_body) { oss << "\n" << stmt->dump(indent + 1); } } return oss.str(); } }; struct For : Stmt { std::string target; ptr iter; std::vector> body; For(std::string t, ptr i, std::vector> b) : target(t), iter(std::move(i)), body(std::move(b)) {} std::string dump(int indent = 0) const override { std::ostringstream oss; oss << indent_str(indent) << "For(" << target << ")\n"; oss << iter->dump(indent + 1); for (const auto &stmt : body) { oss << "\n" << stmt->dump(indent + 1); } return oss.str(); } }; struct FunctionDef : Stmt { std::string name; std::vector params; std::vector> body; FunctionDef(std::string n, std::vector p, std::vector> b) : name(n), params(std::move(p)), body(std::move(b)) {} std::string dump(int indent = 0) const override { std::ostringstream oss; oss << indent_str(indent) << "FunctionDef(" << name << ")"; for (const auto ¶m : params) { oss << "\n" << indent_str(indent + 1) << "Param(" << param << ")"; } for (const auto &stmt : body) { oss << "\n" << stmt->dump(indent + 1); } return oss.str(); } }; struct ClassDef : Stmt { std::string name; std::vector> body; ClassDef(std::string n, std::vector> b) : name(n), body(std::move(b)) {} std::string dump(int indent = 0) const override { std::ostringstream oss; oss << indent_str(indent) << "ClassDef(" << name << ")"; for (const auto &stmt : body) { oss << "\n" << stmt->dump(indent + 1); } return oss.str(); } }; struct Module : Node { std::vector> body; Module(std::vector> b) : body(std::move(b)) {} std::string dump(int indent = 0) const override { std::ostringstream oss; oss << "Module"; for (const auto &stmt : body) { oss << "\n" << stmt->dump(indent + 1); } return oss.str(); } }; struct While : Stmt { ptr condition; std::vector> body; While(ptr cond, std::vector> b) : condition(std::move(cond)), body(std::move(b)) {} std::string dump(int indent = 0) const override { std::ostringstream oss; oss << indent_str(indent) << "While\n"; oss << condition->dump(indent + 1); for (const auto &stmt : body) { oss << "\n" << stmt->dump(indent + 1); } return oss.str(); } };