Move types to it's own file
This commit is contained in:
parent
ed51ee61ed
commit
ea9bb1fcb9
@ -15,7 +15,7 @@ separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
|
|||||||
add_definitions(${LLVM_DEFINITIONS_LIST})
|
add_definitions(${LLVM_DEFINITIONS_LIST})
|
||||||
|
|
||||||
# Executable
|
# Executable
|
||||||
add_executable(${PROJECT_NAME} src/main.cpp src/tokens.cpp src/parsing.cpp src/ast.cpp src/codegen.cpp)
|
add_executable(${PROJECT_NAME} src/main.cpp src/tokens.cpp src/parsing.cpp src/ast.cpp src/codegen.cpp src/types.cpp)
|
||||||
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
|
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
|
||||||
|
|
||||||
# Find the libraries that correspond to the LLVM components
|
# Find the libraries that correspond to the LLVM components
|
||||||
|
|||||||
10
src/ast.cpp
10
src/ast.cpp
@ -81,14 +81,4 @@ namespace AST {
|
|||||||
out << "}";
|
out << "}";
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FundamentalType::formatted() {
|
|
||||||
switch (this->m_ty) {
|
|
||||||
case FundamentalTypeKind::Int:
|
|
||||||
return "Int";
|
|
||||||
default:
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
34
src/ast.h
34
src/ast.h
@ -2,6 +2,7 @@
|
|||||||
#define AST_H
|
#define AST_H
|
||||||
|
|
||||||
#include "codegen.h"
|
#include "codegen.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -27,13 +28,6 @@ namespace AST {
|
|||||||
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
|
virtual codegen::StackValue 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, codegen::Scope& scope) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Statement : public Node {
|
class Statement : public Node {
|
||||||
public:
|
public:
|
||||||
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
|
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
|
||||||
@ -86,11 +80,11 @@ namespace AST {
|
|||||||
|
|
||||||
class InitializationStatement : public Statement {
|
class InitializationStatement : public Statement {
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Type> m_type;
|
std::unique_ptr<types::Type> m_type;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::optional<std::unique_ptr<Expression>> m_expr;
|
std::optional<std::unique_ptr<Expression>> m_expr;
|
||||||
public:
|
public:
|
||||||
InitializationStatement(std::unique_ptr<Type> ty, std::string name, std::optional<std::unique_ptr<Expression>> expr)
|
InitializationStatement(std::unique_ptr<types::Type> ty, std::string name, std::optional<std::unique_ptr<Expression>> expr)
|
||||||
: m_type{ std::move(ty) }, m_name{ name }, m_expr{ std::move(expr) } {
|
: m_type{ std::move(ty) }, m_name{ name }, m_expr{ std::move(expr) } {
|
||||||
}
|
}
|
||||||
virtual ~InitializationStatement() override = default;
|
virtual ~InitializationStatement() override = default;
|
||||||
@ -117,14 +111,14 @@ namespace AST {
|
|||||||
|
|
||||||
class Function : public TopLevelStatement {
|
class Function : public TopLevelStatement {
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Type> m_return_ty;
|
std::unique_ptr<types::Type> m_return_ty;
|
||||||
std::vector<std::pair<std::string, std::unique_ptr<Type>>> m_params;
|
std::vector<std::pair<std::string, std::unique_ptr<types::Type>>> m_params;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::vector<std::unique_ptr<Statement>> m_statements;
|
std::vector<std::unique_ptr<Statement>> m_statements;
|
||||||
public:
|
public:
|
||||||
Function(
|
Function(
|
||||||
std::unique_ptr<Type> return_ty,
|
std::unique_ptr<types::Type> return_ty,
|
||||||
std::vector<std::pair<std::string, std::unique_ptr<Type>>> params,
|
std::vector<std::pair<std::string, std::unique_ptr<types::Type>>> params,
|
||||||
std::string name,
|
std::string name,
|
||||||
std::vector<std::unique_ptr<Statement>> statements)
|
std::vector<std::unique_ptr<Statement>> statements)
|
||||||
: m_return_ty{ std::move(return_ty) }
|
: m_return_ty{ std::move(return_ty) }
|
||||||
@ -136,20 +130,6 @@ namespace AST {
|
|||||||
virtual std::string formatted() override;
|
virtual std::string formatted() override;
|
||||||
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
|
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class FundamentalTypeKind {
|
|
||||||
Int,
|
|
||||||
};
|
|
||||||
|
|
||||||
class FundamentalType : public Type {
|
|
||||||
private:
|
|
||||||
FundamentalTypeKind m_ty;
|
|
||||||
public:
|
|
||||||
FundamentalType(FundamentalTypeKind kind) : m_ty{ kind } {}
|
|
||||||
virtual ~FundamentalType() override = default;
|
|
||||||
virtual std::string formatted() override;
|
|
||||||
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::Scope& scope) override;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
16
src/builder.h
Normal file
16
src/builder.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef BUILDER_H
|
||||||
|
#define BUILDER_H
|
||||||
|
|
||||||
|
#include <llvm/IR/LLVMContext.h>
|
||||||
|
#include <llvm/IR/IRBuilder.h>
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
struct Builder {
|
||||||
|
std::unique_ptr<llvm::LLVMContext> context;
|
||||||
|
std::unique_ptr<llvm::Module> mod;
|
||||||
|
std::unique_ptr<llvm::IRBuilder<>> builder;
|
||||||
|
llvm::BasicBlock* block;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,5 +1,6 @@
|
|||||||
#include "codegen.h"
|
#include "codegen.h"
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
#include <llvm/IR/Module.h>
|
#include <llvm/IR/Module.h>
|
||||||
#include <llvm/IR/Verifier.h>
|
#include <llvm/IR/Verifier.h>
|
||||||
@ -15,7 +16,13 @@ namespace codegen {
|
|||||||
namespace AST {
|
namespace AST {
|
||||||
codegen::StackValue IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
codegen::StackValue IntLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||||
auto ty = builder.builder->getInt32Ty();
|
auto ty = builder.builder->getInt32Ty();
|
||||||
return codegen::StackValue{ llvm::ConstantInt::get(ty, this->m_value), ty };
|
|
||||||
|
auto stack_type = new types::FundamentalType{ types::FundamentalTypeKind::Int };
|
||||||
|
|
||||||
|
return codegen::StackValue{
|
||||||
|
llvm::ConstantInt::get(ty, this->m_value),
|
||||||
|
std::unique_ptr<types::Type>{stack_type}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
codegen::StackValue ValueReferenceExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
codegen::StackValue ValueReferenceExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||||
@ -26,7 +33,7 @@ namespace AST {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return codegen::StackValue{
|
return codegen::StackValue{
|
||||||
builder.builder->CreateLoad(value->second.ty, value->second.value),
|
builder.builder->CreateLoad(value->second.ty->codegen(builder), value->second.value),
|
||||||
value->second.ty
|
value->second.ty
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -78,20 +85,20 @@ namespace AST {
|
|||||||
|
|
||||||
builder.builder->SetInsertPoint(builder.block);
|
builder.builder->SetInsertPoint(builder.block);
|
||||||
|
|
||||||
auto ty = this->m_type->codegen(builder, scope);
|
auto ty = this->m_type->codegen(builder);
|
||||||
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, scope);
|
auto value = this->m_expr->get()->codegen(builder, scope);
|
||||||
builder.builder->CreateStore(value.value, ptr, false);
|
builder.builder->CreateStore(value.value, ptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.values[this->m_name] = codegen::StackValue{ ptr, ty };
|
scope.values[this->m_name] = codegen::StackValue{ ptr, std::move(this->m_type) };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Function::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
void Function::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
||||||
codegen::Scope inner_scope{ scope };
|
codegen::Scope inner_scope{ scope };
|
||||||
|
|
||||||
auto ret_ty = this->m_return_ty->codegen(builder, inner_scope);
|
auto ret_ty = this->m_return_ty->codegen(builder);
|
||||||
std::vector<llvm::Type*> params{};
|
std::vector<llvm::Type*> params{};
|
||||||
|
|
||||||
|
|
||||||
@ -113,8 +120,10 @@ namespace AST {
|
|||||||
|
|
||||||
builder.block = nullptr;
|
builder.block = nullptr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
llvm::Type* FundamentalType::codegen(codegen::Builder& builder, codegen::Scope& scope) {
|
namespace types {
|
||||||
|
llvm::Type* FundamentalType::codegen(codegen::Builder& builder) {
|
||||||
switch (this->m_ty) {
|
switch (this->m_ty) {
|
||||||
case FundamentalTypeKind::Int:
|
case FundamentalTypeKind::Int:
|
||||||
return builder.builder->getInt32Ty();
|
return builder.builder->getInt32Ty();
|
||||||
|
|||||||
@ -6,17 +6,13 @@
|
|||||||
#include <llvm/IR/IRBuilder.h>
|
#include <llvm/IR/IRBuilder.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace codegen {
|
#include "builder.h"
|
||||||
struct Builder {
|
#include "types.h"
|
||||||
std::unique_ptr<llvm::LLVMContext> context;
|
|
||||||
std::unique_ptr<llvm::Module> mod;
|
|
||||||
std::unique_ptr<llvm::IRBuilder<>> builder;
|
|
||||||
llvm::BasicBlock* block;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
struct StackValue {
|
struct StackValue {
|
||||||
llvm::Value* value;
|
llvm::Value* value;
|
||||||
llvm::Type* ty;
|
std::shared_ptr<types::Type> ty;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Scope {
|
struct Scope {
|
||||||
|
|||||||
@ -1,17 +1,18 @@
|
|||||||
|
#include "types.h"
|
||||||
#include "parsing.h"
|
#include "parsing.h"
|
||||||
|
|
||||||
|
|
||||||
namespace parsing {
|
namespace parsing {
|
||||||
namespace {
|
namespace {
|
||||||
Result<std::unique_ptr<AST::Type>, std::string> parse_type(token::TokenStream& stream) {
|
Result<std::unique_ptr<types::Type>, std::string> parse_type(token::TokenStream& stream) {
|
||||||
token::TokenStream inner{ stream };
|
token::TokenStream inner{ stream };
|
||||||
try {
|
try {
|
||||||
auto token = inner.expect(token::Type::Ident);
|
auto token = inner.expect(token::Type::Ident);
|
||||||
|
|
||||||
stream.m_position = inner.m_position;
|
stream.m_position = inner.m_position;
|
||||||
|
|
||||||
auto ty = new AST::FundamentalType{ AST::FundamentalTypeKind::Int };
|
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Int };
|
||||||
return new std::unique_ptr<AST::Type>{ ty };
|
return new std::unique_ptr<types::Type>{ ty };
|
||||||
}
|
}
|
||||||
catch (std::runtime_error error) {
|
catch (std::runtime_error error) {
|
||||||
return new std::string{ error.what() };
|
return new std::string{ error.what() };
|
||||||
|
|||||||
15
src/types.cpp
Normal file
15
src/types.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace types {
|
||||||
|
std::string FundamentalType::formatted() {
|
||||||
|
switch (this->m_ty) {
|
||||||
|
case FundamentalTypeKind::Int:
|
||||||
|
return "Int";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/types.h
Normal file
32
src/types.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef TYPES_H
|
||||||
|
#define TYPES_H
|
||||||
|
|
||||||
|
#include "builder.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace types {
|
||||||
|
enum FundamentalTypeKind {
|
||||||
|
Int,
|
||||||
|
};
|
||||||
|
|
||||||
|
class Type {
|
||||||
|
public:
|
||||||
|
virtual ~Type() = default;
|
||||||
|
virtual std::string formatted() = 0;
|
||||||
|
virtual llvm::Type* codegen(codegen::Builder& builder) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FundamentalType : public Type {
|
||||||
|
private:
|
||||||
|
FundamentalTypeKind m_ty;
|
||||||
|
public:
|
||||||
|
FundamentalType(FundamentalTypeKind kind) : m_ty{ kind } {}
|
||||||
|
virtual ~FundamentalType() override = default;
|
||||||
|
virtual std::string formatted() override;
|
||||||
|
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user