From 4d307d0eb9cbecdc04768841a8a4a0db964a65b3 Mon Sep 17 00:00:00 2001 From: Sofia Date: Thu, 9 Apr 2026 16:31:47 +0300 Subject: [PATCH] Add expression statements --- src/ast.cpp | 7 +++++++ src/ast.h | 12 ++++++++++++ src/codegen.cpp | 8 ++++++++ src/parsing.cpp | 13 ++++++++++--- test.c | 1 + 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/ast.cpp b/src/ast.cpp index d5e0e5f..64e179e 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -3,6 +3,13 @@ #include namespace AST { + std::string ExpressionStatement::formatted() { + std::stringstream out{ "" }; + out << this->m_expr->formatted(); + out << ";"; + return out.str(); + } + std::string ReturnStatement::formatted() { std::stringstream out{ "" }; out << "return "; diff --git a/src/ast.h b/src/ast.h index d12ce83..e32a6c8 100644 --- a/src/ast.h +++ b/src/ast.h @@ -76,6 +76,18 @@ namespace AST { virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override; }; + class ExpressionStatement : public Statement { + private: + std::unique_ptr m_expr; + public: + ExpressionStatement(std::unique_ptr expr) + : m_expr{ std::move(expr) } { + } + virtual ~ExpressionStatement() override = default; + virtual std::string formatted() override; + virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override; + }; + class TopLevelStatement : public Node { public: virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0; diff --git a/src/codegen.cpp b/src/codegen.cpp index a0e0bc8..f213dbc 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -32,6 +32,14 @@ namespace AST { builder.builder->CreateRet(value); } + void ExpressionStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) { + if (!builder.block) + return; + + builder.builder->SetInsertPoint(builder.block); + this->m_expr->codegen(builder, scope); + } + void InitializationStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) { if (!builder.block) return; diff --git a/src/parsing.cpp b/src/parsing.cpp index 6b19d07..c20a4eb 100644 --- a/src/parsing.cpp +++ b/src/parsing.cpp @@ -58,7 +58,8 @@ namespace parsing { inner.expect(token::Type::Symbol, ";"); stream.m_position = inner.m_position; - return &std::make_unique(std::move(ty), name.content, std::move(expr)); + auto init = new AST::InitializationStatement{ std::move(ty), name.content, std::move(expr) }; + return new std::unique_ptr{ init }; } catch (std::runtime_error error) { return new std::string{ error.what() }; @@ -79,10 +80,16 @@ namespace parsing { return new std::unique_ptr{ ret }; } else if (inner.peek().type == token::Type::Ident) { - auto init = parse_init_statement(inner); - if (init.ok()) { + if (auto init = parse_init_statement(inner); init.ok()) { + stream.m_position = inner.m_position; return new std::unique_ptr{ init.unwrap() }; } + else if (auto expr = parse_expression(inner); expr.ok()) { + stream.m_position = inner.m_position; + stream.expect(token::Type::Symbol, ";"); + auto expr_statement = new AST::ExpressionStatement{ expr.unwrap() }; + return new std::unique_ptr{ expr_statement }; + } else { throw std::runtime_error("Expected initialization statement"); } diff --git a/test.c b/test.c index 3dc2205..4e45ea1 100644 --- a/test.c +++ b/test.c @@ -1,4 +1,5 @@ int main() { int a = 5; + a; return a; } \ No newline at end of file