From 7caaaac4a0dace2cf9cea787d6c1d7cb282bc3cc Mon Sep 17 00:00:00 2001 From: CHatingPython Date: Mon, 1 Jun 2026 17:23:00 +0200 Subject: [PATCH] feat(furc): add compound statement This one: { [statement]... } --- compile_commands.json | 1 + furc/include/furc/ast/declaration.hpp | 3 +-- furc/include/furc/ast/fwd.hpp | 2 ++ furc/include/furc/ast/statement.hpp | 19 +++++++++++++++++++ furc/include/furc/ast/visitor.hpp | 1 + furc/include/furc/front/ir_generator.hpp | 1 + furc/src/ast.cpp | 12 ++++++++++++ furc/src/front/ir_generator.cpp | 6 ++++++ furc/src/front/parser.cpp | 6 ++++-- furc/src/main.cpp | 18 ++++++++++++++++-- 10 files changed, 63 insertions(+), 6 deletions(-) create mode 120000 compile_commands.json diff --git a/compile_commands.json b/compile_commands.json new file mode 120000 index 0000000..25eb4b2 --- /dev/null +++ b/compile_commands.json @@ -0,0 +1 @@ +build/compile_commands.json \ No newline at end of file diff --git a/furc/include/furc/ast/declaration.hpp b/furc/include/furc/ast/declaration.hpp index 09a1c67..5849faa 100644 --- a/furc/include/furc/ast/declaration.hpp +++ b/furc/include/furc/ast/declaration.hpp @@ -11,7 +11,6 @@ namespace ast { enum class declaration_node_t { FunctionDeclaration, FunctionDefinition, - Variable, }; class declaration_node : public statement_node { @@ -64,4 +63,4 @@ private: } // namespace ast } // namespace furc -#endif // FURC_AST_DECLARATION_HPP \ No newline at end of file +#endif // FURC_AST_DECLARATION_HPP diff --git a/furc/include/furc/ast/fwd.hpp b/furc/include/furc/ast/fwd.hpp index 30d767f..33fa45d 100644 --- a/furc/include/furc/ast/fwd.hpp +++ b/furc/include/furc/ast/fwd.hpp @@ -63,6 +63,8 @@ class return_statement_node; using return_statement_node_h = node_handle; class if_statement_node; using if_statement_node_h = node_handle; +class compound_statement_node; +using compound_statement_node_h = node_handle; } // namespace ast } // namespace furc diff --git a/furc/include/furc/ast/statement.hpp b/furc/include/furc/ast/statement.hpp index ebb09ab..5440c65 100644 --- a/furc/include/furc/ast/statement.hpp +++ b/furc/include/furc/ast/statement.hpp @@ -11,6 +11,7 @@ enum class statement_node_t { Declaration, Return, If, + Compound, }; class statement_node : public node { @@ -67,6 +68,24 @@ private: statement_node_h m_else; }; +class compound_statement_node : public statement_node { +public: + compound_statement_node(body_h&& body) + : m_body(std::move(body)) {} +public: + const body_h& body() const { return m_body; } +public: + statement_node_t statement_type() const override { return statement_node_t::Compound; } +public: + void accept(visitor& visitor) const override; + + std::ostream& print(std::ostream& os) const override; +protected: + bool equal(const node& rhs) const override; +private: + body_h m_body; +}; + } // namespace ast } // namespace furc diff --git a/furc/include/furc/ast/visitor.hpp b/furc/include/furc/ast/visitor.hpp index 67dbb0d..5599453 100644 --- a/furc/include/furc/ast/visitor.hpp +++ b/furc/include/furc/ast/visitor.hpp @@ -26,6 +26,7 @@ public: virtual void visit_function_definition_node(const function_definition_node&) {} virtual void visit_return_statement_node(const return_statement_node&) {} virtual void visit_if_statement_node(const if_statement_node&) {} + virtual void visit_compound_statement_node(const compound_statement_node&) {} virtual void visit_error(const node_handle& handle) {} }; diff --git a/furc/include/furc/front/ir_generator.hpp b/furc/include/furc/front/ir_generator.hpp index 4d741aa..5e96e72 100644 --- a/furc/include/furc/front/ir_generator.hpp +++ b/furc/include/furc/front/ir_generator.hpp @@ -23,6 +23,7 @@ public: void visit_function_definition_node(const ast::function_definition_node& funcDef) override; void visit_return_statement_node(const ast::return_statement_node& returnStmt) override; void visit_if_statement_node(const ast::if_statement_node& node) override; + void visit_compound_statement_node(const ast::compound_statement_node& node) override; void visit_string_literal_node(const ast::string_literal_node& node) override; void visit_integer_literal_node(const ast::integer_literal_node& node) override; void visit_var_read_expression_node(const ast::var_read_expression_node& node) override; diff --git a/furc/src/ast.cpp b/furc/src/ast.cpp index 631f4aa..931f6f3 100644 --- a/furc/src/ast.cpp +++ b/furc/src/ast.cpp @@ -204,6 +204,18 @@ bool if_statement_node::equal(const node& rhsNode) const { return statement_node::equal(rhs) && m_cond == rhs.m_cond && m_then == rhs.m_then && m_else == rhs.m_else; } +void compound_statement_node::accept(visitor& visitor) const { + visitor.visit_compound_statement_node(*this); +} + +std::ostream& compound_statement_node::print(std::ostream& os) const { + return os << m_body; +} + +bool compound_statement_node::equal(const node& rhs) const { + return statement_node::equal(rhs) && m_body == reinterpret_cast(rhs).m_body; +} + void program_node::accept(visitor& visitor) const { for (const auto& decl : m_declarations) { if (decl.has_error()) { diff --git a/furc/src/front/ir_generator.cpp b/furc/src/front/ir_generator.cpp index 5cd5d7e..50e03de 100644 --- a/furc/src/front/ir_generator.cpp +++ b/furc/src/front/ir_generator.cpp @@ -60,6 +60,12 @@ void ir_generator::visit_if_statement_node(const ast::if_statement_node& node) { push_block(); } +void ir_generator::visit_compound_statement_node(const ast::compound_statement_node& node) { + for (const auto& stmt : node.body()->statements) { + stmt->accept(*this); + } +} + void ir_generator::visit_string_literal_node(const ast::string_literal_node& node) { m_currentBlock->emplace(ir::operand::new_string(std::string(*node.value())), ir::operand::new_reg(m_registerCounter++)); diff --git a/furc/src/front/parser.cpp b/furc/src/front/parser.cpp index 278b06e..ae0591b 100644 --- a/furc/src/front/parser.cpp +++ b/furc/src/front/parser.cpp @@ -89,6 +89,7 @@ ast::declaration_node_h parser::parse_declaration() { ast::statement_node_h parser::parse_statement() { const auto& tok = peek_token(); if (tok.has_error()) return tok; + auto location = tok.location(); switch (tok->type) { case token_t::Keyword: { switch (tok->value.keyword) { @@ -121,20 +122,21 @@ ast::statement_node_h parser::parse_statement() { peek_token()->value.keyword == keyword_token::Else) { next_token(); - return ast::if_statement_node_h{ tok.location(), + return ast::if_statement_node_h{ location, m_arena, std::move(cond), std::move(then), std::move(parse_statement()) }; } - return ast::if_statement_node_h{ tok.location(), m_arena, std::move(cond), std::move(then) }; + return ast::if_statement_node_h{ location, m_arena, std::move(cond), std::move(then) }; } case keyword_token::None: case keyword_token::Func: default: break; } } + case token_t::Lbrace: return ast::compound_statement_node_h{ location, m_arena, parse_body() }; default: break; } diff --git a/furc/src/main.cpp b/furc/src/main.cpp index 3f5dfec..c755159 100644 --- a/furc/src/main.cpp +++ b/furc/src/main.cpp @@ -6,7 +6,21 @@ #include int main(void) { - furc::front::parser parser("", "func main() {\n if (1) return 7 + 6 * 10; else return 0;\n}"); + std::string programStr = R"( + func main() { + x = 5; + x -= 3; + if (x < 3) { + y = x * 2; + w = y; + } else { + y = x - 3; + } + w = x - y; + z = x + y; + } + )"; + furc::front::parser parser("", programStr); furc::front::ir_generator generator; auto program = parser.parse(); @@ -31,4 +45,4 @@ int main(void) { return 0; } -#endif // LIBFURC \ No newline at end of file +#endif // LIBFURC