Skip to content

Commit

Permalink
fix: Function call based on parameters
Browse files Browse the repository at this point in the history
Functions can now have the same name with different parameters, and the compiler will make the right call based on the parameters supplied.
  • Loading branch information
alinalihassan committed Mar 10, 2022
1 parent 91f5ddb commit b304917
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 10 deletions.
24 changes: 15 additions & 9 deletions src/Backend/Codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,6 @@ void Codegen::visit(FuncDecl *node) {
BasicBlock *BB = BasicBlock::Create(*TheContext, "entry", F);
Builder->SetInsertPoint(BB);


for (auto &param: F->args()) {
param.setName(node->getParameters()[param.getArgNo()].first);

Expand Down Expand Up @@ -419,7 +418,7 @@ void Codegen::visit(FuncDecl *node) {

// Insert Function to Symbol Table
Scope = Scope->getParent();
Scope->insertSymbol(node->getName(), F, F->getFunctionType());
Scope->insertSymbol(name, F, F->getFunctionType());

// Reset Insert Point to Top Level
Builder->SetInsertPoint(&TopLevelFunc->back());
Expand Down Expand Up @@ -565,16 +564,23 @@ void Codegen::visit(Import *node) {
}

llvm::Value *Codegen::visit(FuncCall *node) {
if (Scope->lookup(node->getName()) == nullptr)
std::vector<llvm::Value *> params;
std::vector<llvm::Type *> paramTypes;
for (auto arg: node->getArguments()) {
params.push_back(visit(arg));
paramTypes.push_back(params.back()->getType());
}

auto name = getMangledName(node->getSpan(), node->getName(), paramTypes);
auto symbol = Scope->lookup(name);
// Get function without name mangling in case of extern C functions
symbol = symbol == nullptr ? Scope->lookup(node->getName()) : symbol;

if (symbol == nullptr)
throw CodegenError(node->getSpan(), "Function {} not in current scope.", node->getName());

auto symbol = Scope->lookup(node->getName());
if (!static_cast<llvm::FunctionType *>(symbol->getType()))
throw CodegenError(node->getSpan(), "Symbol {} not of FunctionType.", node->getName());

std::vector<llvm::Value *> params;
for (auto arg: node->getArguments())
params.push_back(visit(arg));
throw CodegenError(node->getSpan(), "Symbol {} is not a function.", node->getName());

auto *func = static_cast<Function *>(symbol->getValue());
return Builder->CreateCall(func, params, func->getReturnType()->isVoidTy() ? "" : "tmp");
Expand Down
9 changes: 9 additions & 0 deletions std/time.les
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ret=101
def extern usleep(x: int)

def sleep(x: float)
let y: float = x * 1000000
usleep(y as int)

def sleep(x: int)
usleep(x * 1000000)
File renamed without changes.
File renamed without changes.
10 changes: 10 additions & 0 deletions tests/lesma/function_mangling.les
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ret=101
def extern exit(x: int)

def sleep(x: float) -> int
return 50

def sleep(x: int) -> int
return 51

exit(sleep(1.0) + sleep(1))
2 changes: 1 addition & 1 deletion tests/lesma/import.les
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ret=101
import "functioncall.les"
import "function_call.les"

def extern exit(x: int)

Expand Down
File renamed without changes.

0 comments on commit b304917

Please sign in to comment.