mirror of
https://github.com/PashaBibko/LX.git
synced 2026-04-04 01:49:05 +00:00
VarDec and VarAssign now work
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
func main()
|
func main()
|
||||||
{
|
{
|
||||||
result = 3
|
int result
|
||||||
|
result = 4
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user