From 8dc0a6bf129b4e14c47fb3f8fcc8e965d8c0f5d7 Mon Sep 17 00:00:00 2001 From: Sofia Date: Fri, 10 Apr 2026 18:30:29 +0300 Subject: [PATCH] Parse function calls --- src/ast.cpp | 15 +++++++++++++++ src/ast.h | 13 +++++++++++++ src/codegen.cpp | 4 ++++ src/parsing.cpp | 35 ++++++++++++++++++++++++++++++++++- test.c | 2 +- 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/ast.cpp b/src/ast.cpp index 5cd00a3..194a02d 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -21,6 +21,21 @@ namespace AST { return out.str(); } + std::string FunctionCallExpression::formatted() { + std::stringstream out{ "" }; + out << this->m_fn_expr->formatted() << "("; + + int counter = 0; + for (auto& arg : this->m_args) { + if (counter++ > 0) + out << ", "; + out << arg->formatted(); + } + + out << ")"; + return out.str(); + } + std::string ExpressionStatement::formatted() { std::stringstream out{ "" }; out << this->m_expr->formatted(); diff --git a/src/ast.h b/src/ast.h index 9f53eaa..81e7a48 100644 --- a/src/ast.h +++ b/src/ast.h @@ -59,6 +59,19 @@ namespace AST { virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; }; + class FunctionCallExpression : public Expression { + private: + std::unique_ptr m_fn_expr; + std::vector> m_args; + public: + FunctionCallExpression(std::unique_ptr fn_expr, std::vector> args) + : m_fn_expr{ std::move(fn_expr) }, m_args{ std::move(args) } { + } + virtual ~FunctionCallExpression() override = default; + virtual std::string formatted() override; + virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override; + }; + class ReturnStatement : public Statement { private: diff --git a/src/codegen.cpp b/src/codegen.cpp index 2ed29ee..e1381ab 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -76,6 +76,10 @@ namespace AST { } } + codegen::StackValue FunctionCallExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { + // TODO + } + void ReturnStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) { if (!builder.block) return; diff --git a/src/parsing.cpp b/src/parsing.cpp index 07e6c07..c43f7ce 100644 --- a/src/parsing.cpp +++ b/src/parsing.cpp @@ -4,6 +4,8 @@ namespace parsing { namespace { + Result, std::string> parse_expression(token::TokenStream& stream); + Result, std::string> parse_type(token::TokenStream& stream) { token::TokenStream inner{ stream }; try { @@ -19,7 +21,7 @@ namespace parsing { } } - Result, std::string> parse_primary_expression(token::TokenStream& stream) { + Result, std::string> parse_plain_expression(token::TokenStream& stream) { token::TokenStream inner{ stream }; try { auto token = inner.next(); @@ -44,6 +46,37 @@ namespace parsing { } } + Result, std::string> parse_primary_expression(token::TokenStream& stream) { + token::TokenStream inner{ stream }; + try { + auto plain_expr = parse_plain_expression(inner); + while (inner.peek().content == "(") { + inner.next(); + + std::vector> args{}; + + int counter = 0; + while (inner.peek().content != ")") { + if (counter++ > 0) + inner.expect(token::Type::Symbol, ","); + args.push_back(parse_expression(inner).unwrap()); + } + + inner.expect(token::Type::Symbol, ")"); + + auto fn_call = new AST::FunctionCallExpression{ std::move(plain_expr.unwrap()), std::move(args) }; + plain_expr = new std::unique_ptr{ fn_call }; + } + + + stream.m_position = inner.m_position; + return plain_expr; + } + catch (std::runtime_error error) { + return new std::string{ error.what() }; + } + } + Result parse_binop(token::TokenStream& stream) { token::TokenStream inner{ stream }; try { diff --git a/test.c b/test.c index 5410f6e..df13984 100644 --- a/test.c +++ b/test.c @@ -1,7 +1,7 @@ int fibonacci(int n) { if (n < 2) return 0; - return 1; + return fibonacci(n - 1); } int main() {