From 97745ffbb0df15a13363b177a5e9134f36131a6e Mon Sep 17 00:00:00 2001 From: Sofia Date: Fri, 10 Apr 2026 17:39:38 +0300 Subject: [PATCH] Parse if-statements --- src/ast.cpp | 9 +++++++++ src/ast.h | 18 ++++++++++++++++++ src/codegen.cpp | 8 ++++++++ src/parsing.cpp | 22 ++++++++++++++++++++++ src/tokens.cpp | 10 ++++++++++ src/tokens.h | 2 ++ test.c | 6 ++++-- 7 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/ast.cpp b/src/ast.cpp index dd18fe1..2a3e88e 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -28,6 +28,15 @@ namespace AST { return out.str(); } + std::string IfStatement::formatted() { + std::stringstream out{ "if " }; + out << this->m_condition->formatted(); + out << "\n then " << this->m_then->formatted(); + if (this->m_else.has_value()) + out << "\n else " << (*this->m_else)->formatted(); + return out.str(); + } + std::string ReturnStatement::formatted() { std::stringstream out{ "" }; out << "return "; diff --git a/src/ast.h b/src/ast.h index 71eb8ff..9f53eaa 100644 --- a/src/ast.h +++ b/src/ast.h @@ -96,6 +96,24 @@ namespace AST { virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override; }; + class IfStatement : public Statement { + private: + std::unique_ptr m_condition; + std::unique_ptr m_then; + std::optional> m_else; + public: + IfStatement(std::unique_ptr condition, + std::unique_ptr then_statement, + std::optional> else_statement) + : m_condition{ std::move(condition) } + , m_then{ std::move(then_statement) } + , m_else{ std::move(else_statement) } { + } + virtual ~IfStatement() 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 6cf21d3..6af695c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -110,6 +110,14 @@ namespace AST { scope.values[this->m_name] = codegen::StackValue{ ptr, std::move(this->m_type) }; } + void IfStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) { + if (!builder.block) + return; + + // TODO + } + + void Function::codegen(codegen::Builder& builder, codegen::Scope& scope) { codegen::Scope inner_scope{ scope }; diff --git a/src/parsing.cpp b/src/parsing.cpp index d6126c8..07e6c07 100644 --- a/src/parsing.cpp +++ b/src/parsing.cpp @@ -148,6 +148,28 @@ namespace parsing { auto ret = new AST::ReturnStatement{ std::move(expression) }; return new std::unique_ptr{ ret }; } + else if (inner.peek().type == token::Type::IfKeyword) { + inner.next(); + inner.expect(token::Type::Symbol, "("); + auto expression = parse_expression(inner).unwrap(); + inner.expect(token::Type::Symbol, ")"); + + auto then_statement = parse_statement(inner).unwrap(); + std::optional> else_statement{}; + if (inner.peek().type == token::Type::ElseKeyword) { + inner.next(); + else_statement = parse_statement(inner).unwrap(); + } + + stream.m_position = inner.m_position; + + auto statement = new AST::IfStatement{ + std::move(expression), + std::move(then_statement), + std::move(else_statement) + }; + return new std::unique_ptr{ statement }; + } else if (auto init = parse_init_statement(inner); init.ok()) { stream.m_position = inner.m_position; return new std::unique_ptr{ init.unwrap() }; diff --git a/src/tokens.cpp b/src/tokens.cpp index 2a4ea46..257a578 100644 --- a/src/tokens.cpp +++ b/src/tokens.cpp @@ -26,6 +26,10 @@ namespace token { case token::Type::ReturnKeyword: return "Return"; + case token::Type::IfKeyword: + return "If"; + case token::Type::ElseKeyword: + return "Else"; case token::Type::Whitespace: return "Whitespace"; @@ -110,6 +114,12 @@ namespace token { if (content == "return") { type = token::Type::ReturnKeyword; } + else if (content == "if") { + type = token::Type::IfKeyword; + } + else if (content == "else") { + type = token::Type::ElseKeyword; + } tokens.push_back(token::Token{ type, content }); } else if (iswhitespace(c)) { diff --git a/src/tokens.h b/src/tokens.h index 9892bc5..f5bb092 100644 --- a/src/tokens.h +++ b/src/tokens.h @@ -12,6 +12,8 @@ namespace token { LiteralInt, ReturnKeyword, + IfKeyword, + ElseKeyword, Whitespace, diff --git a/test.c b/test.c index 9f182a7..5410f6e 100644 --- a/test.c +++ b/test.c @@ -1,5 +1,7 @@ -int fibonacci(int n, int b) { - return 0; +int fibonacci(int n) { + if (n < 2) + return 0; + return 1; } int main() {