Skip to content

Commit

Permalink
new 'call' and 'data'
Browse files Browse the repository at this point in the history
  • Loading branch information
TheNachoBIT committed Jul 15, 2023
1 parent e7d3a94 commit 050d67c
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 113 deletions.
141 changes: 90 additions & 51 deletions Language/AST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ llvm::Value* GetInst(AST::Expression* v, bool enable_phi = true)

if (r == nullptr) CodeGen::Error("r is nullptr");

if (dynamic_cast<AST::Number*>(v) || dynamic_cast<AST::Call*>(v)) return r;
if (dynamic_cast<AST::Number*>(v) || dynamic_cast<AST::Call*>(v) || dynamic_cast<AST::Data*>(v)) return r;

if (CodeGen::NamedPures.find(AST::CurrentIdentifier) != CodeGen::NamedPures.end())
if (CodeGen::NamedPures[AST::CurrentIdentifier] != nullptr) return CodeGen::NamedPures[AST::CurrentIdentifier];
Expand Down Expand Up @@ -1170,76 +1170,101 @@ llvm::Value* AST::GetElement::codegen()

llvm::Value* AST::NewArray::codegen()
{
if(target == nullptr) { CodeGen::Error("NewArray Target not found."); }

if(is_resizable)
if(!is_data)
{
auto TPtr = dynamic_cast<AST::Alloca*>(target.get());

auto TPtrType = dynamic_cast<AST::Array*>(TPtr->T.get());

auto final_array_type = std::make_unique<AST::Array>(std::move(TPtrType->childType), items.size());

std::string save_name = TPtr->VarName;

target = std::make_unique<AST::Alloca>(std::move(final_array_type), save_name);
}
if(target == nullptr) { CodeGen::Error("NewArray Target not found."); }

if(is_resizable)
{
auto TPtr = dynamic_cast<AST::Alloca*>(target.get());

auto TPtrType = dynamic_cast<AST::Array*>(TPtr->T.get());

auto final_array_type = std::make_unique<AST::Array>(std::move(TPtrType->childType), items.size());

std::string save_name = TPtr->VarName;

target = std::make_unique<AST::Alloca>(std::move(final_array_type), save_name);
}

llvm::Value* target_cg = GetInst(target.get());

if(target_cg == nullptr) {
std::cout << "TODO: Link Parser Error System with the CodeGen.\n";
CodeGen::Error("NewArray Target's leaf not found.");
}

llvm::ArrayType* target_type = dyn_cast<llvm::ArrayType>(target_cg->getType());

if(target_type == nullptr) {
std::cout << "TODO: Link Parser Error System with the CodeGen.\n";
CodeGen::Error("NewArray Target's Type is not an array.");
}

uint64_t num_elements = target_type->getNumElements();

if(num_elements < items.size())
{
std::cout << "TODO: Link Parser Error System with the CodeGen.\n";
CodeGen::Error("'new_array()' size is higher than the Array.");
}

llvm::Value* target_cg = GetInst(target.get());
int count;
for(auto const& i: items)
{
llvm::Value* i_cg = GetInst(i.get());

if(target_cg == nullptr) {
std::cout << "TODO: Link Parser Error System with the CodeGen.\n";
CodeGen::Error("NewArray Target's leaf not found.");
}
if(i_cg == nullptr)
{
CodeGen::Error("i_cg is nullptr.");
}

llvm::ArrayType* target_type = dyn_cast<llvm::ArrayType>(target_cg->getType());
if(i_cg->getType() != target_type->getArrayElementType())
{
std::cout << "TODO: Link Parser Error System with the CodeGen.\n";
CodeGen::Error("Item Type is not the same as Array Type.");
}

if(target_type == nullptr) {
std::cout << "TODO: Link Parser Error System with the CodeGen.\n";
CodeGen::Error("NewArray Target's Type is not an array.");
}
auto int_type = llvm::Type::getInt32Ty(*CodeGen::TheContext);
llvm::Value* indexList[2] = {llvm::ConstantInt::get(int_type, 0), llvm::ConstantInt::get(int_type, count)};

uint64_t num_elements = target_type->getNumElements();
auto load_inst = dyn_cast<llvm::LoadInst>(target_cg);

if(num_elements < items.size())
{
std::cout << "TODO: Link Parser Error System with the CodeGen.\n";
CodeGen::Error("'new_array()' size is higher than the Array.");
}
if(load_inst == nullptr)
{
CodeGen::Error("load_inst is nullptr.");
}

int count;
for(auto const& i: items)
{
llvm::Value* i_cg = GetInst(i.get());
llvm::Value* R = CodeGen::Builder->CreateGEP(target_type, load_inst->getPointerOperand(), llvm::ArrayRef<llvm::Value*>(indexList, 2), "getelement");
llvm::Value* S = CodeGen::Builder->CreateStore(i_cg, R, "arrayinit");

if(i_cg == nullptr)
{
CodeGen::Error("i_cg is nullptr.");
count++;
}

if(i_cg->getType() != target_type->getArrayElementType())
{
std::cout << "TODO: Link Parser Error System with the CodeGen.\n";
CodeGen::Error("Item Type is not the same as Array Type.");
}
return nullptr;
}

auto int_type = llvm::Type::getInt32Ty(*CodeGen::TheContext);
llvm::Value* indexList[2] = {llvm::ConstantInt::get(int_type, 0), llvm::ConstantInt::get(int_type, count)};
std::vector<llvm::Constant*> values;

auto load_inst = dyn_cast<llvm::LoadInst>(target_cg);
llvm::ArrayType* get_t;

if(load_inst == nullptr)
for(auto const& i: items)
{
auto c = GetInst(i.get());
if(!dyn_cast<llvm::Constant>(c))
{
CodeGen::Error("load_inst is nullptr.");
CodeGen::Error("One of the items is not constant");
}

llvm::Value* R = CodeGen::Builder->CreateGEP(target_type, load_inst->getPointerOperand(), llvm::ArrayRef<llvm::Value*>(indexList, 2), "getelement");
llvm::Value* S = CodeGen::Builder->CreateStore(i_cg, R, "arrayinit");
if(!get_t)
get_t = llvm::ArrayType::get(c->getType(), items.size());

count++;
values.push_back(dyn_cast<llvm::Constant>(c));
}

return nullptr;
if(!get_t) { CodeGen::Error("Constant Array Type not initialized."); }

return llvm::ConstantArray::get(get_t, values);
}

llvm::Value* AST::Exit::codegen()
Expand All @@ -1257,6 +1282,20 @@ llvm::Value* AST::IntCast::codegen()
return CodeGen::Builder->CreateIntCast(target_cg, convert_to_type->codegen(), !convert_to_type->is_unsigned);
}

llvm::Value* AST::Data::codegen()
{
initializer->is_data = true;
auto init = initializer->codegen();

llvm::Constant* init_c = dyn_cast<llvm::Constant>(init);

if(!init_c) { CodeGen::Error("Data Initializer is not Constant.\n"); }

auto globalVariable = new llvm::GlobalVariable(*CodeGen::TheModule, init->getType(), false, llvm::GlobalVariable::ExternalLinkage, init_c, "");

return globalVariable;
}

llvm::Function* AST::Prototype::codegen()
{
std::vector<llvm::Type*> llvmArgs;
Expand Down
15 changes: 15 additions & 0 deletions Language/AST.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ struct AST

bool is_initialized_by_call = false;

bool is_explicit = false;

bool is_data = false;

llvm::Value* codegenOnlyLoad();

llvm::Value* CurrentInstruction();
Expand Down Expand Up @@ -335,6 +339,17 @@ struct AST
llvm::Value* codegen() override;
};

struct Data : public Expression
{
std::unique_ptr<Expression> initializer;

Data(std::unique_ptr<Expression> initializer) : initializer(std::move(initializer)) {}

int get_length();

llvm::Value* codegen() override;
};

struct Prototype
{
std::unique_ptr<AST::Type> PType;
Expand Down
55 changes: 51 additions & 4 deletions Language/IncludeCInternals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct IncludeCInternals
AST::FunctionProtos["i8_to_string"] = std::move(P);
}

static void say_i8_number()
static void say_i8()
{
std::vector<std::unique_ptr<AST::Variable>> ArgNames;

Expand All @@ -57,10 +57,27 @@ struct IncludeCInternals
)
);

auto P = std::make_unique<AST::Prototype>(std::make_unique<AST::i32>(), "say_i8_number", std::move(ArgNames), "i32");
auto P = std::make_unique<AST::Prototype>(std::make_unique<AST::i32>(), "say_i8", std::move(ArgNames), "i32");

P->codegen();
AST::FunctionProtos["say_i8_number"] = std::move(P);
AST::FunctionProtos["say_i8"] = std::move(P);
}

static void say_i32()
{
std::vector<std::unique_ptr<AST::Variable>> ArgNames;

ArgNames.push_back(
std::make_unique<AST::Variable>(
std::make_unique<AST::i32>(),
"number"
)
);

auto P = std::make_unique<AST::Prototype>(std::make_unique<AST::i32>(), "say_i32", std::move(ArgNames), "i32");

P->codegen();
AST::FunctionProtos["say_i32"] = std::move(P);
}

static void input()
Expand All @@ -87,12 +104,42 @@ struct IncludeCInternals
AST::FunctionProtos["input"] = std::move(P);
}

static void random_between()
{
std::vector<std::unique_ptr<AST::Variable>> ArgNames;

ArgNames.push_back(
std::make_unique<AST::Variable>(
std::make_unique<AST::i32>(),
"min"
)
);

ArgNames.push_back(
std::make_unique<AST::Variable>(
std::make_unique<AST::i32>(),
"max"
)
);

auto P = std::make_unique<AST::Prototype>(std::make_unique<AST::i32>(), "random_between", std::move(ArgNames), "i32");

P->codegen();
AST::FunctionProtos["random_between"] = std::move(P);
}

static void start()
{
// Say.c
say();
i8_to_string();
say_i8_number();
//i32_to_string();
say_i8();
say_i32();
input();

// Random.c
random_between();
}
};

Expand Down
8 changes: 8 additions & 0 deletions Language/Lexer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ enum Token
Exit = -30,

IntCast = -31,

Call = -32,

Data = -33,
};

struct Lexer
Expand Down Expand Up @@ -300,6 +304,10 @@ struct Lexer
else if (IsIdentifier("exit")) return Token::Exit;

else if (IsIdentifier("int_cast")) return Token::IntCast;

else if (IsIdentifier("call")) return Token::Call;

else if (IsIdentifier("data")) return Token::Data;
return Token::Identifier;
}

Expand Down
Loading

0 comments on commit 050d67c

Please sign in to comment.