diff --git a/IR-Generator/inc/Parser.h b/IR-Generator/inc/Parser.h index 18487ec..6c44c82 100644 --- a/IR-Generator/inc/Parser.h +++ b/IR-Generator/inc/Parser.h @@ -3,7 +3,7 @@ // Lexer foward declares fstream components so we can use them here // #include -#include +#include #include // Foward declares STD stuff that is passed around // @@ -11,7 +11,11 @@ namespace std::filesystem { class path; } // Foward declares all items of the llvm lib that we need // // Done to avoid including LLVM.h to shorten compile times // -namespace llvm { class Value; } +namespace llvm +{ + class Value; + class AllocaInst; +} // Foward declares the wrapper around the LLVM objects we need to pass around // namespace LX { struct InfoLLVM; } @@ -103,14 +107,14 @@ namespace LX {} // Gets a variable from the scope by it's name // - bool DoesVarExist(const std::string& name); + llvm::AllocaInst* GetVar(const std::string& name); // Creates a variable of the given name // - void CreateVar(const std::string& name); + llvm::AllocaInst* CreateVar(const std::string& name, InfoLLVM& LLVM); private: // Holds all the variables in the scope (excluding ones owned by the children // - std::unordered_set m_LocalVariables; + std::unordered_map m_LocalVariables; // Holds a section of the scope, for example the variables created in a while loop // std::unique_ptr m_Child; diff --git a/Parser/src/AST-LLVM.cpp b/Parser/src/AST-LLVM.cpp index fea25b5..e5d1525 100644 --- a/Parser/src/AST-LLVM.cpp +++ b/Parser/src/AST-LLVM.cpp @@ -77,15 +77,17 @@ namespace LX::AST llvm::Value* VariableDeclaration::GenIR(InfoLLVM& LLVM) { // Creates the variable within the scope // - LLVM.scope->CreateVar(m_Name); - - // Creates the declaration within the IR // - return LLVM.builder.CreateAlloca(LLVM.builder.getInt32Ty(), nullptr, m_Name); + return LLVM.scope->CreateVar(m_Name, LLVM); } llvm::Value* VariableAssignment::GenIR(InfoLLVM& LLVM) { - return nullptr; + // Gets the variable from the current scope // + llvm::AllocaInst* asignee = LLVM.scope->GetVar(m_Name); + ThrowIf(asignee == nullptr); + + // Creates the assignment // + return LLVM.builder.CreateStore(m_Value->GenIR(LLVM), asignee); } llvm::Value* VariableAccess::GenIR(InfoLLVM& LLVM) diff --git a/Parser/src/Scope.cpp b/Parser/src/Scope.cpp index 42cdbf4..4c9789a 100644 --- a/Parser/src/Scope.cpp +++ b/Parser/src/Scope.cpp @@ -1,10 +1,11 @@ #include #include +#include namespace LX { - bool Scope::DoesVarExist(const std::string& name) + llvm::AllocaInst* Scope::GetVar(const std::string& name) { // Stores a pointer to the current scope // Scope* current = this; @@ -13,7 +14,7 @@ namespace LX { // Checks if the variable exists in the current scope // bool exists = current->m_LocalVariables.contains(name); - if (exists) { return true; } + if (exists) { return m_LocalVariables[name]; } // Travels to the next scope // current = current->m_Child.get(); @@ -21,15 +22,16 @@ namespace LX } while (current != nullptr); // If it gets here it means it couldnt find the variable so it doesnt exist in the current context // - return false; + return nullptr; } - void Scope::CreateVar(const std::string& name) + llvm::AllocaInst* Scope::CreateVar(const std::string& name, InfoLLVM& LLVM) { // Checks variable of the same name doesn't exist // - ThrowIf(DoesVarExist(name)); + ThrowIf(GetVar(name) != nullptr); // Else inserts it into the local set // - m_LocalVariables.insert(name); + m_LocalVariables[name] = LLVM.builder.CreateAlloca(LLVM.builder.getInt32Ty(), nullptr, name); + return m_LocalVariables[name]; } } diff --git a/example/main.lx b/example/main.lx index 5f87439..bf8aa63 100644 --- a/example/main.lx +++ b/example/main.lx @@ -1,4 +1,5 @@ func main() { - result = 3 + int result + result = 4 }