Add typecheck-functions to AST

This commit is contained in:
Sofia 2026-04-13 00:35:14 +03:00
parent 5706a81098
commit e45f120f1c
4 changed files with 128 additions and 6 deletions

View File

@ -15,7 +15,15 @@ separate_arguments(LLVM_DEFINITIONS_LIST NATIVE_COMMAND ${LLVM_DEFINITIONS})
add_definitions(${LLVM_DEFINITIONS_LIST})
# Executable
add_executable(${PROJECT_NAME} src/main.cpp src/tokens.cpp src/parsing.cpp src/ast.cpp src/codegen.cpp src/types.cpp)
add_executable(${PROJECT_NAME}
src/main.cpp
src/tokens.cpp
src/parsing.cpp
src/ast.cpp
src/codegen.cpp
src/types.cpp
src/typechecker.cpp
)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Weffc++ -Wextra -Wpedantic -Werror)

View File

@ -1,14 +1,15 @@
#ifndef AST_H
#define AST_H
#include "codegen.h"
#include "types.h"
#include "tokens.h"
#include <string>
#include <vector>
#include <memory>
#include "codegen.h"
#include "types.h"
#include "tokens.h"
#include "typechecker.h"
namespace AST {
class Node {
public:
@ -23,12 +24,18 @@ namespace AST {
public:
Expression(token::Metadata meta) : Node{ meta } {}
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
virtual typecheck::TypecheckResult typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) = 0;
};
class Statement : public Node {
public:
Statement(token::Metadata meta) : Node{ meta } {}
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) = 0;
};
class IntLiteralExpression : public Expression {
@ -39,6 +46,11 @@ namespace AST {
virtual ~IntLiteralExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual typecheck::TypecheckResult typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) override;
};
class StringLiteralExpression : public Expression {
@ -49,6 +61,11 @@ namespace AST {
virtual ~StringLiteralExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual typecheck::TypecheckResult typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) override;
};
class ValueReferenceExpression : public Expression {
@ -59,6 +76,11 @@ namespace AST {
virtual ~ValueReferenceExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual typecheck::TypecheckResult typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) override;
};
class BinaryOperationExpression : public Expression {
@ -80,6 +102,11 @@ namespace AST {
virtual ~BinaryOperationExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual typecheck::TypecheckResult typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) override;
};
class FunctionCallExpression : public Expression {
@ -98,6 +125,11 @@ namespace AST {
virtual ~FunctionCallExpression() override = default;
virtual std::string formatted() override;
virtual codegen::StackValue codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual typecheck::TypecheckResult typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) override;
};
@ -111,6 +143,7 @@ namespace AST {
virtual ~ReturnStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};
class InitializationStatement : public Statement {
@ -132,6 +165,7 @@ namespace AST {
virtual ~InitializationStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};
class ExpressionStatement : public Statement {
@ -144,6 +178,7 @@ namespace AST {
virtual ~ExpressionStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};
class IfStatement : public Statement {
@ -164,12 +199,14 @@ namespace AST {
virtual ~IfStatement() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};
class TopLevelStatement : public Node {
public:
TopLevelStatement(token::Metadata meta) : Node{ meta } {}
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) = 0;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) = 0;
};
class Function : public TopLevelStatement {
@ -197,6 +234,7 @@ namespace AST {
virtual ~Function() override = default;
virtual std::string formatted() override;
virtual void codegen(codegen::Builder& builder, codegen::Scope& scope) override;
virtual void typecheck(typecheck::State& state, typecheck::Scope& scope) override;
};
}

66
src/typechecker.cpp Normal file
View File

@ -0,0 +1,66 @@
#include "typechecker.h"
#include "ast.h"
#include "errors.h"
namespace AST {
typecheck::TypecheckResult IntLiteralExpression::typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) {
throw CompileError("TODO", {});
}
typecheck::TypecheckResult StringLiteralExpression::typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) {
throw CompileError("TODO", {});
}
typecheck::TypecheckResult ValueReferenceExpression::typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) {
throw CompileError("TODO", {});
}
typecheck::TypecheckResult BinaryOperationExpression::typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) {
throw CompileError("TODO", {});
}
typecheck::TypecheckResult FunctionCallExpression::typecheck(
typecheck::State& state,
typecheck::Scope& scope,
std::optional<std::shared_ptr<types::Type>> expected_ty
) {
throw CompileError("TODO", {});
}
void ReturnStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) {
throw CompileError("TODO", {});
}
void InitializationStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) {
throw CompileError("TODO", {});
}
void ExpressionStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) {
throw CompileError("TODO", {});
}
void IfStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) {
throw CompileError("TODO", {});
}
void Function::typecheck(typecheck::State& state, typecheck::Scope& scope) {
throw CompileError("TODO", {});
}
}

View File

@ -4,14 +4,24 @@
#include <map>
#include "types.h"
#include "errors.h"
namespace typecheck {
enum class TypecheckResult {
/// @brief The types match perfectly (enough)
Suitable,
/// @brief The original type can be implicitly cast into the given type
Castable,
/// @brief The types are totally incompatible
Error,
};
struct Scope {
std::map<std::string, types::Type> symbols;
};
struct State {
std::vector<CompileError> errors;
};
}