Compare commits

..

3 Commits

Author SHA1 Message Date
d3d487159a Use static allocator 2026-04-27 23:11:35 +03:00
8530e1162d Pass allocator in codegen 2026-04-27 23:07:54 +03:00
bf87aa8c08 Add static allocator 2026-04-27 23:04:12 +03:00
6 changed files with 202 additions and 58 deletions

View File

@ -25,6 +25,7 @@ add_executable(${PROJECT_NAME}
src/typechecker.cpp
src/binops.cpp
src/casting.cpp
src/stack_allocator.cpp
)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Weffc++ -Wextra -Wpedantic -Werror)

View File

@ -10,6 +10,7 @@
#include "binops.h"
#include "tokens.h"
#include "typechecker.h"
#include "stack_allocator.h"
namespace AST {
class Node {
@ -24,7 +25,8 @@ namespace AST {
class Expression : public Node {
public:
Expression(token::Metadata meta) : Node{ meta } {}
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) = 0;
virtual void codegen_alloca(codegen::StackAllocator& allocator) = 0;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) = 0;
virtual void typecheck_preprocess(typecheck::Scope& scope) = 0;
virtual typecheck::ExpressionType typecheck(
@ -37,7 +39,8 @@ namespace AST {
class Statement : public Node {
public:
Statement(token::Metadata meta) : Node{ meta } {}
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) = 0;
virtual void codegen_alloca(codegen::StackAllocator& allocator) = 0;
virtual void typecheck_preprocess(typecheck::Scope& scope) = 0;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) = 0;
};
@ -57,7 +60,8 @@ namespace AST {
}
virtual ~IntLiteralExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -75,7 +79,8 @@ namespace AST {
StringLiteralExpression(token::Metadata meta, std::string value) : Expression{ meta }, m_value{ value } {}
virtual ~StringLiteralExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -93,7 +98,8 @@ namespace AST {
ValueReferenceExpression(token::Metadata meta, std::string name) : Expression{ meta }, m_name{ name } {}
virtual ~ValueReferenceExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -122,7 +128,8 @@ namespace AST {
}
virtual ~BinaryOperationExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -148,7 +155,8 @@ namespace AST {
}
virtual ~FunctionCallExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -174,7 +182,8 @@ namespace AST {
}
virtual ~CastExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -197,7 +206,8 @@ namespace AST {
}
virtual ~RefExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -220,7 +230,8 @@ namespace AST {
}
virtual ~DerefExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -246,7 +257,8 @@ namespace AST {
}
virtual ~IndexAccessExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -272,7 +284,8 @@ namespace AST {
}
virtual ~FieldAccessExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -298,7 +311,8 @@ namespace AST {
}
virtual ~ListInitializerExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual std::shared_ptr<types::Type> get_codegen_type(codegen::Scope& scope) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual typecheck::ExpressionType typecheck(
@ -318,7 +332,8 @@ namespace AST {
}
virtual ~ReturnStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};
@ -341,7 +356,8 @@ namespace AST {
}
virtual ~InitializationStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};
@ -355,7 +371,8 @@ namespace AST {
}
virtual ~ExpressionStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};
@ -377,7 +394,8 @@ namespace AST {
}
virtual ~IfStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) override;
virtual void codegen_alloca(codegen::StackAllocator& allocator) override;
virtual void typecheck_preprocess(typecheck::Scope& scope) override;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};

View File

@ -20,7 +20,7 @@ namespace AST {
return this->m_ty;
}
codegen::StackValue IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
codegen::StackValue IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator&) {
auto ty = this->m_ty->codegen(builder, scope.structs);
return codegen::StackValue{
@ -38,7 +38,7 @@ namespace AST {
return std::shared_ptr<types::Type> {stack_type};
}
codegen::StackValue StringLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
codegen::StackValue StringLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator&) {
auto stack_type = new types::ArrayType{
std::make_shared<types::FundamentalType>(true, types::FundamentalTypeKind::Char),
static_cast<uint32_t>(this->m_value.size()) + 1,
@ -78,7 +78,7 @@ namespace AST {
}
}
codegen::StackValue ValueReferenceExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
codegen::StackValue ValueReferenceExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator&) {
auto value = scope.values.find(this->m_name);
if (value != scope.values.end()) {
if (scope.is_lvalue) {
@ -121,10 +121,10 @@ namespace AST {
}
}
codegen::StackValue BinaryOperationExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
codegen::StackValue BinaryOperationExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
auto lvalued = scope.with_lvalue();
auto lhs = this->m_lhs->codegen(builder, this->m_binop == types::BinOp::Assignment ? lvalued : scope);
auto rhs = this->m_rhs->codegen(builder, scope);
auto lhs = this->m_lhs->codegen(builder, this->m_binop == types::BinOp::Assignment ? lvalued : scope, allocator);
auto rhs = this->m_rhs->codegen(builder, scope, allocator);
try {
switch (this->m_binop) {
case types::BinOp::Assignment:
@ -155,12 +155,12 @@ namespace AST {
return *fn_ty->return_type();
}
codegen::StackValue FunctionCallExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
codegen::StackValue FunctionCallExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
std::vector<llvm::Value*> args{};
for (auto& arg : this->m_args) {
args.push_back(arg->codegen(builder, scope).value);
args.push_back(arg->codegen(builder, scope, allocator).value);
}
auto function = this->m_fn_expr->codegen(builder, scope);
auto function = this->m_fn_expr->codegen(builder, scope, allocator);
auto value = builder.builder->CreateCall(llvm::dyn_cast<llvm::FunctionType>(function.ty->codegen(builder, scope.structs)), function.value, args, "call");
return codegen::StackValue{
@ -173,12 +173,12 @@ namespace AST {
return this->m_ty;
}
codegen::StackValue CastExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
codegen::StackValue CastExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
auto expr_ty = this->m_expr->get_codegen_type(scope);
if (expr_ty->m_kind == types::TypeKind::Array
&& this->m_ty->m_kind == types::TypeKind::Pointer) {
auto lvalued = scope.with_lvalue();
auto expr = this->m_expr->codegen(builder, lvalued);
auto expr = this->m_expr->codegen(builder, lvalued, allocator);
auto cast = types::find_cast(scope.casts, expr.ty, this->m_ty);
if (cast) {
return codegen::StackValue{
@ -191,7 +191,7 @@ namespace AST {
}
}
else {
auto expr = this->m_expr->codegen(builder, scope);
auto expr = this->m_expr->codegen(builder, scope, allocator);
auto cast = types::find_cast(scope.casts, expr.ty, this->m_ty);
if (cast) {
return codegen::StackValue{
@ -209,9 +209,9 @@ namespace AST {
};
}
codegen::StackValue RefExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
codegen::StackValue RefExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
auto with_lvalue = scope.with_lvalue();
return this->m_expr->codegen(builder, with_lvalue);
return this->m_expr->codegen(builder, with_lvalue, allocator);
}
std::shared_ptr<types::Type> DerefExpression::get_codegen_type(codegen::Scope& scope) {
@ -225,8 +225,8 @@ namespace AST {
}
}
codegen::StackValue DerefExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
auto value = this->m_expr->codegen(builder, scope);
codegen::StackValue DerefExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
auto value = this->m_expr->codegen(builder, scope, allocator);
if (value.ty->m_kind == types::TypeKind::Pointer) {
auto loaded = value.ty->load(builder, value.value, scope.structs);
return codegen::StackValue{
@ -255,16 +255,16 @@ namespace AST {
}
codegen::StackValue IndexAccessExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
codegen::StackValue IndexAccessExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
auto intended_ty = this->m_expr->get_codegen_type(scope);
codegen::StackValue value;
if (intended_ty->m_kind != types::TypeKind::Pointer) {
auto lvalued = scope.with_lvalue();
value = this->m_expr->codegen(builder, lvalued);
value = this->m_expr->codegen(builder, lvalued, allocator);
}
else {
value = this->m_expr->codegen(builder, scope);
value = this->m_expr->codegen(builder, scope, allocator);
}
std::cout << intended_ty->formatted() << std::endl;
@ -339,9 +339,9 @@ namespace AST {
}
}
codegen::StackValue FieldAccessExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
codegen::StackValue FieldAccessExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
auto lvalued = scope.with_lvalue();
auto struct_ptr = this->m_expr->codegen(builder, lvalued);
auto struct_ptr = this->m_expr->codegen(builder, lvalued, allocator);
if (struct_ptr.ty->m_kind == types::TypeKind::Pointer) {
auto ptr_ty = dynamic_cast<types::PointerType*>(struct_ptr.ty.get());
if (ptr_ty->m_inner->m_kind == types::TypeKind::Struct) {
@ -392,8 +392,8 @@ namespace AST {
return this->m_ty;
}
codegen::StackValue ListInitializerExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
auto value_ptr = builder.builder->CreateAlloca(this->m_ty->codegen(builder, scope.structs));
codegen::StackValue ListInitializerExpression::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
auto value_ptr = allocator.pop_alloca(this->m_ty);
if (this->m_ty->m_kind == types::TypeKind::Array) {
auto array_ty = dynamic_cast<types::ArrayType*>(this->m_ty.get());
@ -404,7 +404,7 @@ namespace AST {
indices.push_back(llvm::ConstantInt::get(builder.builder->getInt32Ty(), counter++));
auto gep = builder.builder->CreateGEP(
array_ty->m_inner->codegen(builder, scope.structs), value_ptr, indices, "GEP");
builder.builder->CreateStore(expr->codegen(builder, scope).value, gep);
builder.builder->CreateStore(expr->codegen(builder, scope, allocator).value, gep);
}
auto ptr_ty = std::shared_ptr<types::Type>{
@ -428,7 +428,7 @@ namespace AST {
struct_ty->codegen(builder, scope.structs), value_ptr, i, "struct_gep"
);
builder.builder->CreateStore(
this->m_expressions[i]->codegen(builder, scope).value, gep);
this->m_expressions[i]->codegen(builder, scope, allocator).value, gep);
}
auto ptr_ty = std::shared_ptr<types::Type>{
@ -450,35 +450,34 @@ namespace AST {
}
void ReturnStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) {
void ReturnStatement::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
if (!builder.block)
return;
builder.builder->SetInsertPoint(builder.block);
auto value = this->m_expr->codegen(builder, scope);
auto value = this->m_expr->codegen(builder, scope, allocator);
builder.builder->CreateRet(value.value);
}
void ExpressionStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) {
void ExpressionStatement::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
if (!builder.block)
return;
builder.builder->SetInsertPoint(builder.block);
this->m_expr->codegen(builder, scope);
this->m_expr->codegen(builder, scope, allocator);
}
void InitializationStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) {
void InitializationStatement::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
if (!builder.block)
return;
builder.builder->SetInsertPoint(builder.block);
if (this->m_type->m_kind == types::TypeKind::Array) {
auto raw_llvm_ty = this->m_type->codegen(builder, scope.structs);
auto ptr = builder.builder->CreateAlloca(raw_llvm_ty);
auto ptr = allocator.pop_alloca(this->m_type);
if (this->m_expr.has_value()) {
auto value = this->m_expr->get()->codegen(builder, scope);
auto value = this->m_expr->get()->codegen(builder, scope, allocator);
builder.builder->CreateStore(value.value, ptr, false);
}
@ -486,10 +485,9 @@ namespace AST {
return;
}
auto ty = this->m_type->codegen(builder, scope.structs);
auto ptr = builder.builder->CreateAlloca(ty);
auto ptr = allocator.pop_alloca(this->m_type);
if (this->m_expr.has_value()) {
auto value = this->m_expr->get()->codegen(builder, scope);
auto value = this->m_expr->get()->codegen(builder, scope, allocator);
builder.builder->CreateStore(value.value, ptr, false);
}
@ -500,13 +498,13 @@ namespace AST {
scope.values[this->m_name] = codegen::StackValue{ ptr, ptr_ty };
}
void IfStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) {
void IfStatement::codegen(codegen::Builder& builder, codegen::Scope& scope, codegen::StackAllocator& allocator) {
if (!builder.block)
return;
builder.builder->SetInsertPoint(builder.block);
auto condition = this->m_condition->codegen(builder, scope);
auto condition = this->m_condition->codegen(builder, scope, allocator);
auto function = builder.block->getParent();
auto then_block = llvm::BasicBlock::Create(*builder.context, "then", function);
@ -521,13 +519,13 @@ namespace AST {
builder.block = then_block;
builder.builder->SetInsertPoint(then_block);
this->m_then->codegen(builder, scope);
this->m_then->codegen(builder, scope, allocator);
builder.builder->CreateBr(after_block);
if (else_block.has_value()) {
builder.block = *else_block;
builder.builder->SetInsertPoint(*else_block);
this->m_else->get()->codegen(builder, scope);
this->m_else->get()->codegen(builder, scope, allocator);
builder.builder->CreateBr(after_block);
}
@ -597,8 +595,15 @@ namespace AST {
}
}
codegen::StackAllocator allocator{ builder, scope.structs };
builder.builder->SetInsertPoint(BB);
for (auto& statement : *this->m_statements) {
statement->codegen(builder, inner_scope);
statement->codegen_alloca(allocator);
}
for (auto& statement : *this->m_statements) {
statement->codegen(builder, inner_scope, allocator);
}
}

92
src/stack_allocator.cpp Normal file
View File

@ -0,0 +1,92 @@
#include "stack_allocator.h"
#include "ast.h"
namespace codegen {
void StackAllocator::push_alloca(std::shared_ptr<types::Type> ty, std::string name) {
auto type = ty->codegen(this->m_builder, this->m_structs);
auto value = this->m_builder.builder->CreateAlloca(type, nullptr, name);
this->m_stack_ptrs.push_back(std::pair<llvm::Value*, std::shared_ptr<types::Type>>{ value, ty });
}
llvm::Value* StackAllocator::pop_alloca(std::shared_ptr<types::Type> ty) {
assert(this->m_stack_ptrs.size() > 0);
auto first = this->m_stack_ptrs[0];
assert(types::types_equal(first.second, ty));
this->m_stack_ptrs.erase(this->m_stack_ptrs.begin());
return first.first;
}
}
namespace AST {
void IntLiteralExpression::codegen_alloca(codegen::StackAllocator&) {
}
void StringLiteralExpression::codegen_alloca(codegen::StackAllocator&) {
}
void ValueReferenceExpression::codegen_alloca(codegen::StackAllocator&) {
}
void BinaryOperationExpression::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_lhs->codegen_alloca(allocator);
this->m_rhs->codegen_alloca(allocator);
}
void FunctionCallExpression::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_fn_expr->codegen_alloca(allocator);
for (auto& arg : this->m_args) {
arg->codegen_alloca(allocator);
}
}
void CastExpression::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_expr->codegen_alloca(allocator);
}
void RefExpression::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_expr->codegen_alloca(allocator);
}
void DerefExpression::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_expr->codegen_alloca(allocator);
}
void IndexAccessExpression::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_expr->codegen_alloca(allocator);
}
void FieldAccessExpression::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_expr->codegen_alloca(allocator);
}
void ListInitializerExpression::codegen_alloca(codegen::StackAllocator& allocator) {
allocator.push_alloca(this->m_ty, "list");
for (auto& expr : this->m_expressions) {
expr->codegen_alloca(allocator);
}
}
void ReturnStatement::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_expr->codegen_alloca(allocator);
}
void InitializationStatement::codegen_alloca(codegen::StackAllocator& allocator) {
allocator.push_alloca(this->m_type, this->m_name);
if (this->m_expr) {
(*this->m_expr)->codegen_alloca(allocator);
}
}
void ExpressionStatement::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_expr->codegen_alloca(allocator);
}
void IfStatement::codegen_alloca(codegen::StackAllocator& allocator) {
this->m_condition->codegen_alloca(allocator);
this->m_then->codegen_alloca(allocator);
if (this->m_else) {
(*this->m_else)->codegen_alloca(allocator);
}
}
}

28
src/stack_allocator.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef ALLOCATOR_H
#define ALLOCATOR_H
#include <vector>
#include <llvm/IR/IRBuilder.h>
#include "types.h"
#include "builder.h"
namespace codegen {
class StackAllocator {
private:
std::vector<std::pair<llvm::Value*, std::shared_ptr<types::Type>>> m_stack_ptrs;
codegen::Builder& m_builder;
codegen::TypeMap& m_structs;
public:
StackAllocator(codegen::Builder& builder, codegen::TypeMap& structs)
: m_stack_ptrs{}
, m_builder{ builder }
, m_structs{ structs } {
}
void push_alloca(std::shared_ptr<types::Type> ty, std::string name);
llvm::Value* pop_alloca(std::shared_ptr<types::Type> ty);
};
}
#endif

0
tokei Normal file
View File