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 {
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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
|
||||||
@ -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 };
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user