diff --git a/furc/include/furc/front/ast.hpp b/furc/include/furc/front/ast.hpp index 0f7c6fa..9d4ea32 100644 --- a/furc/include/furc/front/ast.hpp +++ b/furc/include/furc/front/ast.hpp @@ -8,6 +8,50 @@ namespace furc { +struct comp_stmt_node; +struct if_stmt_node; +struct while_stmt_node; +struct return_stmt_node; +struct var_decl_node; +struct func_decl_node; +struct var_read_expr_node; +struct func_call_expr_node; +struct group_expr_node; +struct binary_op_expr_node; +struct unary_op_expr_node; +struct if_expr_node; +struct int_lit_node; +struct char_lit_node; + +struct ast_visitor { + ast_visitor() = default; + virtual ~ast_visitor() = default; + + ast_visitor(ast_visitor&&) noexcept = default; + ast_visitor& operator=(ast_visitor&&) noexcept = default; + + ast_visitor(const ast_visitor&) = default; + ast_visitor& operator=(const ast_visitor&) = default; + + virtual void visit_comp_stmt_node(const comp_stmt_node& node) {} + virtual void visit_if_stmt_node(const if_stmt_node& node) {} + virtual void visit_while_stmt_node(const while_stmt_node& node) {} + virtual void visit_return_stmt_node(const return_stmt_node& node) {} + + virtual void visit_var_decl_node(const var_decl_node& node) {} + virtual void visit_func_decl_node(const func_decl_node& node) {} + + virtual void visit_var_read_expr_node(const var_read_expr_node& node) {} + virtual void visit_func_call_expr_node(const func_call_expr_node& node) {} + virtual void visit_group_expr_node(const group_expr_node& node) {} + virtual void visit_binary_op_expr_node(const binary_op_expr_node& node) {} + virtual void visit_unary_op_expr_node(const unary_op_expr_node& node) {} + virtual void visit_if_expr_node(const if_expr_node& node) {} + + virtual void visit_int_lit_node(const int_lit_node& node) {} + virtual void visit_char_lit_node(const char_lit_node& node) {} +}; + struct ast_type { enum type_e { Void = 0, @@ -41,6 +85,8 @@ public: ast_node& operator=(const ast_node&) = delete; public: virtual category_e category() const = 0; + + virtual void accept(ast_visitor& visitor) const = 0; }; using ast_node_cat = ast_node::category_e; @@ -65,6 +111,8 @@ public: struct comp_stmt_node final : public stmt_node { stmt_type_e stmt_type() const override { return Compound; } + void accept(ast_visitor& visitor) const override { visitor.visit_comp_stmt_node(*this); } + std::vector stmts; }; @@ -73,6 +121,8 @@ class expr_node; struct if_stmt_node final : public stmt_node { stmt_type_e stmt_type() const override { return If; } + void accept(ast_visitor& visitor) const override { visitor.visit_if_stmt_node(*this); } + expr_node* cond = nullptr; stmt_node* thenBranch = nullptr; stmt_node* elseBranch = nullptr; @@ -81,6 +131,8 @@ struct if_stmt_node final : public stmt_node { struct while_stmt_node final : public stmt_node { stmt_type_e stmt_type() const override { return While; } + void accept(ast_visitor& visitor) const override { visitor.visit_while_stmt_node(*this); } + expr_node* cond = nullptr; stmt_node* body = nullptr; }; @@ -88,6 +140,8 @@ struct while_stmt_node final : public stmt_node { struct return_stmt_node final : public stmt_node { stmt_type_e stmt_type() const override { return Return; } + void accept(ast_visitor& visitor) const override { visitor.visit_return_stmt_node(*this); } + expr_node* value = nullptr; }; @@ -108,6 +162,8 @@ public: struct var_decl_node final : public decl_node { decl_type_e decl_type() const override { return Variable; } + void accept(ast_visitor& visitor) const override { visitor.visit_var_decl_node(*this); } + std::string name; ast_type type; expr_node* init = nullptr; @@ -116,6 +172,8 @@ struct var_decl_node final : public decl_node { struct func_decl_node final : public decl_node { decl_type_e decl_type() const override { return Function; } + void accept(ast_visitor& visitor) const override { visitor.visit_func_decl_node(*this); } + struct def_s { comp_stmt_node body; std::vector preConds; @@ -151,6 +209,8 @@ public: struct var_read_expr_node final : public expr_node { expr_type_e expr_type() const override { return VarRead; } + void accept(ast_visitor& visitor) const override { visitor.visit_var_read_expr_node(*this); } + std::string name; var_read_expr_node(std::string&& name) @@ -160,6 +220,8 @@ struct var_read_expr_node final : public expr_node { struct func_call_expr_node final : public expr_node { expr_type_e expr_type() const override { return FunctionCall; } + void accept(ast_visitor& visitor) const override { visitor.visit_func_call_expr_node(*this); } + expr_node* lhs = nullptr; std::vector args; }; @@ -167,6 +229,8 @@ struct func_call_expr_node final : public expr_node { struct group_expr_node final : public expr_node { expr_type_e expr_type() const override { return Group; } + void accept(ast_visitor& visitor) const override { visitor.visit_group_expr_node(*this); } + expr_node* inner = nullptr; }; @@ -196,6 +260,8 @@ struct binary_op_expr_node final : public expr_node { expr_type_e expr_type() const override { return BinaryOp; } + void accept(ast_visitor& visitor) const override { visitor.visit_binary_op_expr_node(*this); } + expr_node* lhs = nullptr; expr_node* rhs = nullptr; binary_op_type type = Add; @@ -219,6 +285,8 @@ struct unary_op_expr_node final : public expr_node { expr_type_e expr_type() const override { return UnaryOp; } + void accept(ast_visitor& visitor) const override { visitor.visit_unary_op_expr_node(*this); } + expr_node* lhs = nullptr; unary_op_type type = Positive; }; @@ -226,6 +294,8 @@ struct unary_op_expr_node final : public expr_node { struct if_expr_node final : public expr_node { expr_type_e expr_type() const override { return If; } + void accept(ast_visitor& visitor) const override { visitor.visit_if_expr_node(*this); } + expr_node* cond = nullptr; expr_node* thenExpr = nullptr; expr_node* elseExpr = nullptr; @@ -251,6 +321,8 @@ struct int_lit_node final : public lit_node { lit_type_e lit_type() const override { return Integer; } + void accept(ast_visitor& visitor) const override { visitor.visit_int_lit_node(*this); } + std::uint64_t value; }; @@ -260,6 +332,8 @@ struct char_lit_node final : public lit_node { lit_type_e lit_type() const override { return Char; } + void accept(ast_visitor& visitor) const override { visitor.visit_char_lit_node(*this); } + char value; };