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 { class Expression : public Node {
public: public:
virtual llvm::Value* codegen(codegen::Builder& builder) = 0; virtual llvm::Value* codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
}; };
class Type { class Type {
public: public:
virtual ~Type() = default; virtual ~Type() = default;
virtual std::string formatted() = 0; 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 { class Statement : public Node {
public: public:
virtual void codegen(codegen::Builder& builder) = 0; virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
}; };
class IntLiteralExpression : public Expression { class IntLiteralExpression : public Expression {
@ -38,7 +38,7 @@ namespace AST {
IntLiteralExpression(int value) : m_value{ value } {} IntLiteralExpression(int value) : m_value{ value } {}
virtual ~IntLiteralExpression() override = default; virtual ~IntLiteralExpression() override = default;
virtual std::string formatted() override; 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) } {} ReturnStatement(std::unique_ptr<Expression> expr) : m_expr{ std::move(expr) } {}
virtual ~ReturnStatement() override = default; virtual ~ReturnStatement() override = default;
virtual std::string formatted() override; 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 { class InitializationStatement : public Statement {
@ -63,12 +63,12 @@ namespace AST {
} }
virtual ~InitializationStatement() override = default; virtual ~InitializationStatement() override = default;
virtual std::string formatted() override; 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 { class TopLevelStatement : public Node {
public: public:
virtual void codegen(codegen::Builder& builder) = 0; virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
}; };
class Function : public TopLevelStatement { class Function : public TopLevelStatement {
@ -90,7 +90,7 @@ namespace AST {
} }
virtual ~Function() override = default; virtual ~Function() override = default;
virtual std::string formatted() override; 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 { enum class FundamentalTypeKind {
@ -104,7 +104,7 @@ namespace AST {
FundamentalType(FundamentalTypeKind kind) : m_ty{ kind } {} FundamentalType(FundamentalTypeKind kind) : m_ty{ kind } {}
virtual ~FundamentalType() override = default; virtual ~FundamentalType() override = default;
virtual std::string formatted() override; 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> #include <iostream>
namespace AST { namespace AST {
llvm::Value* IntLiteralExpression::codegen(codegen::Builder& builder) { llvm::Value* IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
auto ty = builder.builder->getInt32Ty(); auto ty = builder.builder->getInt32Ty();
return llvm::ConstantInt::get(ty, this->m_value); 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) if (!builder.block)
return; return;
builder.builder->SetInsertPoint(builder.block.get()); 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); builder.builder->CreateRet(value);
} }
void InitializationStatement::codegen(codegen::Builder& builder) { void InitializationStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) {
if (!builder.block) if (!builder.block)
return; return;
builder.builder->SetInsertPoint(builder.block.get()); 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); auto ptr = builder.builder->CreateAlloca(ty);
if (this->m_expr.has_value()) { 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); builder.builder->CreateStore(value, ptr, false);
} }
} }
void Function::codegen(codegen::Builder& builder) { void Function::codegen(codegen::Builder& builder, codegen::Scope& scope) {
auto ret_ty = this->m_return_ty->codegen(builder); codegen::Scope inner_scope{ scope };
auto ret_ty = this->m_return_ty->codegen(builder, inner_scope);
std::vector<llvm::Type*> params{}; std::vector<llvm::Type*> params{};
@ -53,7 +55,7 @@ namespace AST {
builder.block = std::move(BB); builder.block = std::move(BB);
for (auto& statement : this->m_statements) { for (auto& statement : this->m_statements) {
statement->codegen(builder); statement->codegen(builder, inner_scope);
} }
llvm::verifyFunction(*function); llvm::verifyFunction(*function);
@ -62,7 +64,7 @@ namespace AST {
builder.block.release(); builder.block.release();
} }
llvm::Type* FundamentalType::codegen(codegen::Builder& builder) { llvm::Type* FundamentalType::codegen(codegen::Builder& builder, codegen::Scope& scope) {
switch (this->m_ty) { switch (this->m_ty) {
case FundamentalTypeKind::Int: case FundamentalTypeKind::Int:
return builder.builder->getInt32Ty(); return builder.builder->getInt32Ty();

View File

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

View File

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