Add typecheck-functions to AST
This commit is contained in:
parent
5706a81098
commit
e45f120f1c
@ -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)
|
||||||
|
|
||||||
|
|||||||
46
src/ast.h
46
src/ast.h
@ -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
66
src/typechecker.cpp
Normal 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", {});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user