Add scope

This commit is contained in:
Sofia 2026-04-09 15:53:01 +03:00
parent cf94296877
commit 1070aa6ed0
4 changed files with 35 additions and 20 deletions

View File

@ -16,19 +16,19 @@ namespace AST {
class Expression : public Node {
public:
virtual llvm::Value* codegen(codegen::Builder& builder) = 0;
virtual llvm::Value* codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
};
class Type {
public:
virtual ~Type() = default;
virtual std::string formatted() = 0;
virtual llvm::Type* codegen(codegen::Builder& builder) = 0;
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
};
class Statement : public Node {
public:
virtual void codegen(codegen::Builder& builder) = 0;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
};
class IntLiteralExpression : public Expression {
@ -38,7 +38,7 @@ namespace AST {
IntLiteralExpression(int value) : m_value{ value } {}
virtual ~IntLiteralExpression() override = default;
virtual std::string formatted() override;
virtual llvm::Value* codegen(codegen::Builder& builder) override;
virtual llvm::Value* codegen(codegen::Builder& builder, codegen::Scope& scope) override;
};
@ -49,7 +49,7 @@ namespace AST {
ReturnStatement(std::unique_ptr<Expression> expr) : m_expr{ std::move(expr) } {}
virtual ~ReturnStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder) override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
};
class InitializationStatement : public Statement {
@ -63,12 +63,12 @@ namespace AST {
}
virtual ~InitializationStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder) override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
};
class TopLevelStatement : public Node {
public:
virtual void codegen(codegen::Builder& builder) = 0;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
};
class Function : public TopLevelStatement {
@ -90,7 +90,7 @@ namespace AST {
}
virtual ~Function() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder) override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
};
enum class FundamentalTypeKind {
@ -104,7 +104,7 @@ namespace AST {
FundamentalType(FundamentalTypeKind kind) : m_ty{ kind } {}
virtual ~FundamentalType() override = default;
virtual std::string formatted() override;
virtual llvm::Type* codegen(codegen::Builder& builder) override;
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::Scope& scope) override;
};
}

View File

@ -7,38 +7,40 @@
#include <iostream>
namespace AST {
llvm::Value* IntLiteralExpression::codegen(codegen::Builder& builder) {
llvm::Value* IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
auto ty = builder.builder->getInt32Ty();
return llvm::ConstantInt::get(ty, this->m_value);
}
void ReturnStatement::codegen(codegen::Builder& builder) {
void ReturnStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) {
if (!builder.block)
return;
builder.builder->SetInsertPoint(builder.block.get());
auto value = this->m_expr->codegen(builder);
auto value = this->m_expr->codegen(builder, scope);
builder.builder->CreateRet(value);
}
void InitializationStatement::codegen(codegen::Builder& builder) {
void InitializationStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) {
if (!builder.block)
return;
builder.builder->SetInsertPoint(builder.block.get());
auto ty = this->m_type->codegen(builder);
auto ty = this->m_type->codegen(builder, scope);
auto ptr = builder.builder->CreateAlloca(ty);
if (this->m_expr.has_value()) {
auto value = this->m_expr->get()->codegen(builder);
auto value = this->m_expr->get()->codegen(builder, scope);
builder.builder->CreateStore(value, ptr, false);
}
}
void Function::codegen(codegen::Builder& builder) {
auto ret_ty = this->m_return_ty->codegen(builder);
void Function::codegen(codegen::Builder& builder, codegen::Scope& scope) {
codegen::Scope inner_scope{ scope };
auto ret_ty = this->m_return_ty->codegen(builder, inner_scope);
std::vector<llvm::Type*> params{};
@ -53,7 +55,7 @@ namespace AST {
builder.block = std::move(BB);
for (auto& statement : this->m_statements) {
statement->codegen(builder);
statement->codegen(builder, inner_scope);
}
llvm::verifyFunction(*function);
@ -62,7 +64,7 @@ namespace AST {
builder.block.release();
}
llvm::Type* FundamentalType::codegen(codegen::Builder& builder) {
llvm::Type* FundamentalType::codegen(codegen::Builder& builder, codegen::Scope& scope) {
switch (this->m_ty) {
case FundamentalTypeKind::Int:
return builder.builder->getInt32Ty();

View File

@ -4,6 +4,7 @@
#include <memory>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/IRBuilder.h>
#include <map>
namespace codegen {
struct Builder {
@ -12,6 +13,15 @@ namespace codegen {
std::unique_ptr<llvm::IRBuilder<>> builder;
std::unique_ptr<llvm::BasicBlock> block;
};
struct ScopeValue {
llvm::Value* value;
llvm::Type* ty;
};
struct Scope {
std::map<std::string, ScopeValue> values;
};
}
#endif

View File

@ -77,9 +77,11 @@ int main() {
{}
};
codegen::Scope scope{};
for (auto& tls : statements) {
std::cout << tls->formatted() << std::endl;
tls->codegen(builder);
tls->codegen(builder, scope);
}
llvm::InitializeAllTargetInfos();
@ -95,6 +97,7 @@ int main() {
llvm::TargetOptions opt;
auto TargetMachine = Target->createTargetMachine(TargetTriple, "generic", "", opt, llvm::Reloc::PIC_);
builder.mod->setDataLayout(TargetMachine->createDataLayout());
builder.mod->setTargetTriple(TargetMachine->getTargetTriple());
std::string ir_output;
llvm::raw_string_ostream dest{ ir_output };