From 7397183c3427d75edb42a7bac9f9dca122b6e416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Wed, 18 Jun 2025 17:44:43 +0900 Subject: [PATCH] Build function call --- src/ModuleBuilder.cpp | 37 +++++++++++++++++++++++++++---------- src/ModuleBuilder.h | 3 +++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/ModuleBuilder.cpp b/src/ModuleBuilder.cpp index 3a80e16..9f26312 100644 --- a/src/ModuleBuilder.cpp +++ b/src/ModuleBuilder.cpp @@ -38,13 +38,14 @@ void ModuleBuilder::buildStatement(shared_ptr statement) { buildExpression(dynamic_pointer_cast(statement)); return; default: - exit(1); + failed("Unexpected statement"); } } void ModuleBuilder::buildFunctionDeclaration(shared_ptr statement) { llvm::FunctionType *funType = llvm::FunctionType::get(typeForValueType(statement->getReturnValueType()), false); llvm::Function *fun = llvm::Function::Create(funType, llvm::GlobalValue::InternalLinkage, statement->getName(), module.get()); + funMap[statement->getName()] = fun; llvm::BasicBlock *block = llvm::BasicBlock::Create(*context, statement->getName(), fun); builder->SetInsertPoint(block); buildStatement(statement->getStatementBlock()); @@ -90,8 +91,10 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr expression return valueForIfElse(dynamic_pointer_cast(expression)); case ExpressionKind::VAR: return valueForVar(dynamic_pointer_cast(expression)); + case ExpressionKind::CALL: + return valueForCall(dynamic_pointer_cast(expression)); default: - exit(1); + failed("Unexpected expression"); } } @@ -120,8 +123,10 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr expressi return valueForBinaryInteger(expression); case ValueType::REAL32: return valueForBinaryReal(expression); + case ValueType::NONE: + return valueForBinaryInteger(expression); default: - exit(1); + failed("Unexpected operation"); } } @@ -135,7 +140,7 @@ llvm::Value *ModuleBuilder::valueForBinaryBool(shared_ptr expr case ExpressionBinary::Operation::NOT_EQUAL: return builder->CreateICmpNE(leftValue, rightValue); default: - exit(1); + failed("Undefined operation for boolean operands"); } } @@ -203,7 +208,6 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expressi shared_ptr conditionExpression = expression->getCondition(); llvm::Function *fun = builder->GetInsertBlock()->getParent(); - //llvm::Value *conditionValue = valueForBinary(conditionExpression); llvm::Value *conditionValue = valueForExpression(conditionExpression); llvm::BasicBlock *thenBlock = llvm::BasicBlock::Create(*context, "thenBlock", fun); @@ -217,14 +221,11 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expressi builder->SetInsertPoint(thenBlock); llvm::Value *thenValue = valueForExpression(expression->getThenBlock()->getStatementExpression()->getExpression()); buildStatement(expression->getThenBlock()); - //llvm::Value *thenValue = llvm::ConstantInt::get(typeSInt32, 11, true); - //buildStatement(expression->getThenBlock()); builder->CreateBr(mergeBlock); thenBlock = builder->GetInsertBlock(); // Else fun->insert(fun->end(), elseBlock); - //llvm::Value *elseValue = llvm::ConstantInt::get(typeSInt32, 22, true); builder->SetInsertPoint(elseBlock); llvm::Value *elseValue = nullptr; if (expression->getElseBlock() != nullptr) { @@ -243,18 +244,29 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expressi if (elseValue != nullptr) phi->addIncoming(elseValue, elseBlock); - //return llvm::ConstantInt::get(int32Type, 42, true); return phi; } llvm::Value *ModuleBuilder::valueForVar(shared_ptr expression) { llvm::AllocaInst *alloca = allocaMap[expression->getName()]; if (alloca == nullptr) - exit(1); + failed("Variable " + expression->getName() + " not defined"); return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName()); } +llvm::Value *ModuleBuilder::valueForCall(shared_ptr expression) { + llvm::Function *fun = funMap[expression->getName()]; + failed("Function " + expression->getName() + " not defined"); + llvm::FunctionType *funType = fun->getFunctionType(); + vector argValues; + for (shared_ptr &argumentExpression : expression->getArgumentExpressions()) { + llvm::Value *argValue = valueForExpression(argumentExpression); + argValues.push_back(argValue); + } + builder->CreateCall(funType, fun, llvm::ArrayRef(argValues)); +} + llvm::Type *ModuleBuilder::typeForValueType(ValueType valueType) { switch (valueType) { case ValueType::NONE: @@ -267,3 +279,8 @@ llvm::Type *ModuleBuilder::typeForValueType(ValueType valueType) { return typeReal32; } } + +void ModuleBuilder::failed(string message) { + cerr << "Building module " << moduleName << " failed: " << message << endl; + exit(1); +} diff --git a/src/ModuleBuilder.h b/src/ModuleBuilder.h index df35902..d711088 100644 --- a/src/ModuleBuilder.h +++ b/src/ModuleBuilder.h @@ -30,6 +30,7 @@ private: vector> statements; map allocaMap; + map funMap; void buildStatement(shared_ptr statement); void buildFunctionDeclaration(shared_ptr statement); @@ -47,8 +48,10 @@ private: llvm::Value *valueForBinaryReal(shared_ptr expression); llvm::Value *valueForIfElse(shared_ptr expression); llvm::Value *valueForVar(shared_ptr expression); + llvm::Value *valueForCall(shared_ptr expression); llvm::Type *typeForValueType(ValueType valueType); + void failed(string message); public: ModuleBuilder(string moduleName, string sourceFileName, vector> statements);