VarDec and VarAssign now work

This commit is contained in:
Pasha Bibko
2025-04-28 20:43:41 +01:00
parent 3ec6cc0c6e
commit cbc179411a
4 changed files with 26 additions and 17 deletions

View File

@@ -3,7 +3,7 @@
// Lexer foward declares fstream components so we can use them here // // Lexer foward declares fstream components so we can use them here //
#include <Lexer.h> #include <Lexer.h>
#include <unordered_set> #include <unordered_map>
#include <memory> #include <memory>
// Foward declares STD stuff that is passed around // // 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 // // Foward declares all items of the llvm lib that we need //
// Done to avoid including LLVM.h to shorten compile times // // 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 // // Foward declares the wrapper around the LLVM objects we need to pass around //
namespace LX { struct InfoLLVM; } namespace LX { struct InfoLLVM; }
@@ -103,14 +107,14 @@ namespace LX
{} {}
// Gets a variable from the scope by it's name // // 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 // // Creates a variable of the given name //
void CreateVar(const std::string& name); llvm::AllocaInst* CreateVar(const std::string& name, InfoLLVM& LLVM);
private: private:
// Holds all the variables in the scope (excluding ones owned by the children // // Holds all the variables in the scope (excluding ones owned by the children //
std::unordered_set<std::string> m_LocalVariables; std::unordered_map<std::string, llvm::AllocaInst*> m_LocalVariables;
// Holds a section of the scope, for example the variables created in a while loop // // Holds a section of the scope, for example the variables created in a while loop //
std::unique_ptr<Scope> m_Child; std::unique_ptr<Scope> m_Child;

View File

@@ -77,15 +77,17 @@ namespace LX::AST
llvm::Value* VariableDeclaration::GenIR(InfoLLVM& LLVM) llvm::Value* VariableDeclaration::GenIR(InfoLLVM& LLVM)
{ {
// Creates the variable within the scope // // Creates the variable within the scope //
LLVM.scope->CreateVar(m_Name); return LLVM.scope->CreateVar(m_Name, LLVM);
// Creates the declaration within the IR //
return LLVM.builder.CreateAlloca(LLVM.builder.getInt32Ty(), nullptr, m_Name);
} }
llvm::Value* VariableAssignment::GenIR(InfoLLVM& 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<Scope::VariableDoesntExist>(asignee == nullptr);
// Creates the assignment //
return LLVM.builder.CreateStore(m_Value->GenIR(LLVM), asignee);
} }
llvm::Value* VariableAccess::GenIR(InfoLLVM& LLVM) llvm::Value* VariableAccess::GenIR(InfoLLVM& LLVM)

View File

@@ -1,10 +1,11 @@
#include <Parser.h> #include <Parser.h>
#include <Util.h> #include <Util.h>
#include <AST.h>
namespace LX namespace LX
{ {
bool Scope::DoesVarExist(const std::string& name) llvm::AllocaInst* Scope::GetVar(const std::string& name)
{ {
// Stores a pointer to the current scope // // Stores a pointer to the current scope //
Scope* current = this; Scope* current = this;
@@ -13,7 +14,7 @@ namespace LX
{ {
// Checks if the variable exists in the current scope // // Checks if the variable exists in the current scope //
bool exists = current->m_LocalVariables.contains(name); bool exists = current->m_LocalVariables.contains(name);
if (exists) { return true; } if (exists) { return m_LocalVariables[name]; }
// Travels to the next scope // // Travels to the next scope //
current = current->m_Child.get(); current = current->m_Child.get();
@@ -21,15 +22,16 @@ namespace LX
} while (current != nullptr); } while (current != nullptr);
// If it gets here it means it couldnt find the variable so it doesnt exist in the current context // // 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 // // Checks variable of the same name doesn't exist //
ThrowIf<Scope::VariableAlreadyExists>(DoesVarExist(name)); ThrowIf<Scope::VariableAlreadyExists>(GetVar(name) != nullptr);
// Else inserts it into the local set // // 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];
} }
} }

View File

@@ -1,4 +1,5 @@
func main() func main()
{ {
result = 3 int result
result = 4
} }