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}) 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 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_features(${PROJECT_NAME} PRIVATE cxx_std_20)
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Weffc++ -Wextra -Wpedantic -Werror) target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Weffc++ -Wextra -Wpedantic -Werror)

View File

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