Move types to it's own file

This commit is contained in:
Sofia 2026-04-09 18:38:22 +03:00
parent ed51ee61ed
commit ea9bb1fcb9
9 changed files with 94 additions and 55 deletions

View File

@ -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

View File

@ -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";
}
}
} }

View File

@ -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
View 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

View File

@ -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();

View File

@ -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 {

View File

@ -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
View 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
View 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