diff --git a/Parser/src/GenIR.cpp b/Parser/src/GenIR.cpp index ae8d646..aa64117 100644 --- a/Parser/src/GenIR.cpp +++ b/Parser/src/GenIR.cpp @@ -1,63 +1,62 @@ #include +#include #include namespace LX { + static constexpr bool IsValidTopLevelNode(AST::Node::NodeType type) + { + return true; + } + + static void GenerateFunctionIR(FunctionDefinition& funcAST, llvm::LLVMContext& context, llvm::Module& module, llvm::IRBuilder<>& builder) + { + // Creates the functions signature and return type // + + llvm::FunctionType* retType = llvm::FunctionType::get(llvm::Type::getInt32Ty(context), false); // <- Defaults to int currently + llvm::Function* func = llvm::Function::Create(retType, llvm::Function::ExternalLinkage, "main", module); // Defaults to main currently + llvm::BasicBlock* entry = llvm::BasicBlock::Create(context, "entry", func); + builder.SetInsertPoint(entry); + + // Generates the IR within the function // + + for (auto& node : funcAST.body) + { + ThrowIf(IsValidTopLevelNode(node->m_Type) == false); // <- TODO: replace with actual error type + node->GenIR(context, module, builder); + } + + // Adds a terminator if there is none // + + if (entry->getTerminator() == nullptr) + { + builder.CreateRet(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), 0, true)); + } + + // Verifies the function works // + + ThrowIf(llvm::verifyFunction(*func), &llvm::errs()); // <- Make error type + } + void GenerateIR(FileAST& ast) { - // Generates stuff // + // Creates the LLVM variables needed for generating IR that are shared between functions // llvm::LLVMContext context; llvm::IRBuilder<> builder(context); - + llvm::Module module("add_ints", context); + + // Loops over AST to generate IR // + + for (auto& func : ast.functions) { - std::unique_ptr module = std::make_unique("add_ints", context); + GenerateFunctionIR(func, context, module, builder); + } - // Defines main function // + // Outputs the IR to the console // - llvm::FunctionType* funcType = llvm::FunctionType::get(llvm::Type::getInt32Ty(context), false); - llvm::Function* mainFunc = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, "main", module.get()); - llvm::BasicBlock* entry = llvm::BasicBlock::Create(context, "entry", mainFunc); - builder.SetInsertPoint(entry); - - // Loops over AST to generate IR // - - for (auto& node : ast.functions[0].body) - { - switch (node->m_Type) - { - case AST::Node::RETURN_STATEMENT: - { - node->GenIR(context, *module, builder); - break; - } - - default: - { - break; - } - } - } - - if (entry->getTerminator() == nullptr) - { - builder.CreateRet(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), 0, true)); - } - - // Verification of the IR // - - if (llvm::verifyFunction(*mainFunc, &llvm::errs()) || llvm::verifyModule(*module, &llvm::errs())) - { - std::cerr << "Error: IR generation failed" << std::endl; - return; - } - - // Outputs the IR to the console // - - module->print(llvm::outs(), nullptr); - - } // <- Crashes here + module.print(llvm::outs(), nullptr); std::cout << "Finished generating IR" << std::endl; } diff --git a/build-test/Log.txt b/build-test/Log.txt index e69de29..983c5e3 100644 --- a/build-test/Log.txt +++ b/build-test/Log.txt @@ -0,0 +1,17 @@ + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Started lexing file +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +Token::FUNCTION +Token::IDENTIFIER: main +Unknown: 3 +Token::NUMBER_LITERAL: 3 +Token::ADD +Token::NUMBER_LITERAL: 56 + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Started parsing tokens +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +AST length: 1 diff --git a/build-test/main.lx b/build-test/main.lx index fd50a1a..c555ba4 100644 --- a/build-test/main.lx +++ b/build-test/main.lx @@ -1,2 +1,2 @@ func main - return 3 + 4 + return 3 + 56