Add scope
This commit is contained in:
parent
cf94296877
commit
1070aa6ed0
18
src/ast.h
18
src/ast.h
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
@ -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 };
|
||||
|
||||
Loading…
Reference in New Issue
Block a user