Skip to content

Commit

Permalink
fix: Fixed import incorrect span, fixed errors in import not being ca…
Browse files Browse the repository at this point in the history
…tched
  • Loading branch information
alinalihassan committed Mar 10, 2022
1 parent 1f28be4 commit a0088a9
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 55 deletions.
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [ ] Fix symbols with same name but different function signatures (mangled and non-manged) overlapping, it should issue a warning and the newest one replace the old one
- [ ] Fix being able to call function without respective arguments, but throw error
- [x] Fix arguments not being usable (not stored in LLVM IR)
- [ ] Fix import error being catched by Utils function instead of module, which could show where import was stated

## Refactoring
- [ ] Replace SourceLocation by Span
Expand Down
111 changes: 60 additions & 51 deletions src/Backend/Codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,60 +53,69 @@ llvm::TargetMachine *Codegen::InitializeTargetMachine() {
return target->createTargetMachine(tripletString, "generic", "", opt, rm);
}

void Codegen::CompileModule(const std::string &filepath) {
void Codegen::CompileModule(Span span, const std::string &filepath) {
std::filesystem::path mainPath = filename;
// Read source
auto source = readFile(fmt::format("{}/{}", std::filesystem::absolute(mainPath).parent_path().c_str(), filepath));
// Lexer
auto lexer = std::make_unique<Lexer>(source, filepath.substr(filepath.find_last_of("/\\") + 1));
lexer->ScanAll();

// Parser
auto parser = std::make_unique<Parser>(lexer->getTokens());
parser->Parse();

// TODO: Delete it, memory leak, smart pointer made us lose the references to other modules
// Codegen
auto codegen = new Codegen(std::move(parser), filepath, isJIT, false);
codegen->Run();

// Optimize
codegen->Optimize(llvm::PassBuilder::OptimizationLevel::O3);

codegen->TheModule->setModuleIdentifier(filepath);

if (isJIT) {
// Link modules together
if (Linker::linkModules(*TheModule, std::move(codegen->TheModule)))
print(ERROR, "Error linking modules together");

// Add function to main module
Module::iterator it;
Module::iterator end = TheModule->end();
for (it = TheModule->begin(); it != end; ++it) {
auto name = std::string{(*it).getName()};
if (!Scope->lookup(name))
Scope->insertSymbol(name, (Value *) &(*it).getFunction(), (*it).getFunctionType());
}

Modules.push_back(codegen->getModule());
} else {
std::string obj_file = fmt::format("tmp{}", ObjectFiles.size());
codegen->WriteToObjectFile(obj_file);
ObjectFiles.push_back(fmt::format("{}.o", obj_file));

// Add function definitions
Module::iterator it;
Module::iterator end = codegen->TheModule->end();
for (it = codegen->TheModule->begin(); it != end; ++it) {
auto name = std::string{(*it).getName()};
auto new_func = Function::Create((*it).getFunctionType(),
Function::ExternalLinkage,
name,
*TheModule);

Scope->insertSymbol(name, new_func, new_func->getFunctionType());
try {
// Lexer
auto lexer = std::make_unique<Lexer>(source, filepath.substr(filepath.find_last_of("/\\") + 1));
lexer->ScanAll();

// Parser
auto parser = std::make_unique<Parser>(lexer->getTokens());
parser->Parse();

// TODO: Delete it, memory leak, smart pointer made us lose the references to other modules
// Codegen
auto codegen = new Codegen(std::move(parser), filepath, isJIT, false);
codegen->Run();

// Optimize
codegen->Optimize(llvm::PassBuilder::OptimizationLevel::O3);
codegen->TheModule->setModuleIdentifier(filepath);

if (isJIT) {
// Link modules together
if (Linker::linkModules(*TheModule, std::move(codegen->TheModule)))
throw CodegenError({},"Error linking modules together");

// Add function to main module
Module::iterator it;
Module::iterator end = TheModule->end();
for (it = TheModule->begin(); it != end; ++it) {
auto name = std::string{(*it).getName()};
if (!Scope->lookup(name))
Scope->insertSymbol(name, (Value *) &(*it).getFunction(), (*it).getFunctionType());
}

Modules.push_back(codegen->getModule());
} else {
std::string obj_file = fmt::format("tmp{}", ObjectFiles.size());
codegen->WriteToObjectFile(obj_file);
ObjectFiles.push_back(fmt::format("{}.o", obj_file));

// Add function definitions
Module::iterator it;
Module::iterator end = codegen->TheModule->end();
for (it = codegen->TheModule->begin(); it != end; ++it) {
auto name = std::string{(*it).getName()};
auto new_func = Function::Create((*it).getFunctionType(),
Function::ExternalLinkage,
name,
*TheModule);

Scope->insertSymbol(name, new_func, new_func->getFunctionType());
}
}
} catch (const LesmaError &err) {
if (err.getSpan() == Span{})
print(ERROR, err.what());
else
showInline(err.getSpan(), err.what(), fmt::format("{}/{}", std::filesystem::absolute(mainPath).parent_path().c_str(), filepath), true);

throw CodegenError(span, "Unable to import {} due to errors", filepath);
}
}

Expand Down Expand Up @@ -560,7 +569,7 @@ void Codegen::visit(ExpressionStatement *node) {

// TODO: Implement me
void Codegen::visit(Import *node) {
CompileModule(node->getFilePath());
CompileModule(node->getSpan(), node->getFilePath());
}

llvm::Value *Codegen::visit(FuncCall *node) {
Expand Down Expand Up @@ -796,7 +805,7 @@ std::string Codegen::getTypeMangledName(Span span, llvm::Type *type) {

// TODO: Change to support private/public and module system
std::string Codegen::getMangledName(Span span, std::string func_name, const std::vector<llvm::Type *> &paramTypes) {
std::string name = std::move(func_name);
std::string name = "_" + std::move(func_name);

for (auto param_type: paramTypes)
name += ":" + getTypeMangledName(span, param_type);
Expand Down
2 changes: 1 addition & 1 deletion src/Backend/Codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ namespace lesma {
protected:
llvm::TargetMachine *InitializeTargetMachine();
llvm::Function *InitializeTopLevel();
void CompileModule(const std::string &filepath);
void CompileModule(Span span, const std::string &filepath);

void visit(Statement *node) override;
void visit(Compound *node) override;
Expand Down
9 changes: 6 additions & 3 deletions src/Frontend/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,18 @@ Statement *Parser::ParseFunctionDeclaration() {
}

Statement *Parser::ParseImport() {
auto loc = Peek()->span;
Consume(TokenType::IMPORT);

auto token = Consume(TokenType::STRING);
auto filepath = token->lexeme.erase(0, 1).erase(token->lexeme.size() - 1);

if (AdvanceIfMatchAny<TokenType::AS>())
return new Import(Peek()->span, token->lexeme, Consume(TokenType::IDENTIFIER)->lexeme);
if (AdvanceIfMatchAny<TokenType::AS>()) {
auto alias = Consume(TokenType::IDENTIFIER);
return new Import({loc.Start, alias.getEnd()}, token->lexeme, alias->lexeme);
}

return new Import(Peek()->span, filepath, getBasename(token->lexeme));
return new Import({loc.Start, token.getEnd()}, filepath, getBasename(token->lexeme));
}

Compound *Parser::ParseCompound() {
Expand Down

0 comments on commit a0088a9

Please sign in to comment.