Add a function to test if types are equal
This commit is contained in:
parent
8ec4e538f5
commit
a901806dfb
@ -3,6 +3,10 @@
|
|||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace AST {
|
namespace AST {
|
||||||
std::shared_ptr<types::Type> IntLiteralExpression::typecheck(
|
std::shared_ptr<types::Type> IntLiteralExpression::typecheck(
|
||||||
typecheck::State&,
|
typecheck::State&,
|
||||||
@ -109,6 +113,8 @@ namespace AST {
|
|||||||
auto bool_ty_ptr = new types::FundamentalType{ types::FundamentalTypeKind::Bool };
|
auto bool_ty_ptr = new types::FundamentalType{ types::FundamentalTypeKind::Bool };
|
||||||
this->m_condition->typecheck(state, scope, std::shared_ptr<types::Type>{ bool_ty_ptr });
|
this->m_condition->typecheck(state, scope, std::shared_ptr<types::Type>{ bool_ty_ptr });
|
||||||
|
|
||||||
|
// TODO check that condition really is a boolean
|
||||||
|
|
||||||
this->m_then->typecheck(state, scope);
|
this->m_then->typecheck(state, scope);
|
||||||
if (this->m_else) {
|
if (this->m_else) {
|
||||||
(*this->m_else)->typecheck(state, scope);
|
(*this->m_else)->typecheck(state, scope);
|
||||||
|
|||||||
@ -165,4 +165,44 @@ namespace types {
|
|||||||
this->m_inner
|
this->m_inner
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool types_equal(std::shared_ptr<types::Type> type1, std::shared_ptr<types::Type> type2) {
|
||||||
|
if (type1->m_kind != type2->m_kind)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (type1->m_kind == TypeKind::Fundamental) {
|
||||||
|
auto ty1 = dynamic_cast<FundamentalType*>(type1.get());
|
||||||
|
auto ty2 = dynamic_cast<FundamentalType*>(type2.get());
|
||||||
|
return ty1->m_ty == ty2->m_ty;
|
||||||
|
}
|
||||||
|
else if (type1->m_kind == TypeKind::Function) {
|
||||||
|
auto ty1 = dynamic_cast<FunctionType*>(type1.get());
|
||||||
|
auto ty2 = dynamic_cast<FunctionType*>(type2.get());
|
||||||
|
|
||||||
|
if (!types_equal(ty1->m_ret_ty, ty2->m_ret_ty))
|
||||||
|
return false;
|
||||||
|
if (ty1->m_vararg != ty2->m_vararg)
|
||||||
|
return false;
|
||||||
|
if (ty1->m_param_tys.size() != ty2->m_param_tys.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < static_cast<int>(ty1->m_param_tys.size()); i++) {
|
||||||
|
auto param1 = ty1->m_param_tys[i];
|
||||||
|
auto param2 = ty2->m_param_tys[i];
|
||||||
|
if (!types_equal(param1, param2))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (type1->m_kind == TypeKind::Pointer) {
|
||||||
|
auto ty1 = dynamic_cast<PointerType*>(type1.get());
|
||||||
|
auto ty2 = dynamic_cast<PointerType*>(type2.get());
|
||||||
|
|
||||||
|
return types_equal(ty1->m_inner, ty2->m_inner);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -47,9 +47,8 @@ namespace types {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class FundamentalType : public Type {
|
class FundamentalType : public Type {
|
||||||
private:
|
|
||||||
FundamentalTypeKind m_ty;
|
|
||||||
public:
|
public:
|
||||||
|
FundamentalTypeKind m_ty;
|
||||||
FundamentalType(FundamentalTypeKind kind) : Type(TypeKind::Fundamental), m_ty{ kind } {}
|
FundamentalType(FundamentalTypeKind kind) : Type(TypeKind::Fundamental), m_ty{ kind } {}
|
||||||
virtual ~FundamentalType() override = default;
|
virtual ~FundamentalType() override = default;
|
||||||
virtual std::string formatted() override;
|
virtual std::string formatted() override;
|
||||||
@ -83,9 +82,8 @@ namespace types {
|
|||||||
|
|
||||||
|
|
||||||
class PointerType : public Type {
|
class PointerType : public Type {
|
||||||
private:
|
|
||||||
std::shared_ptr<Type> m_inner;
|
|
||||||
public:
|
public:
|
||||||
|
std::shared_ptr<Type> m_inner;
|
||||||
PointerType(std::shared_ptr<Type> inner)
|
PointerType(std::shared_ptr<Type> inner)
|
||||||
: Type(TypeKind::Pointer), m_inner{ std::move(inner) } {
|
: Type(TypeKind::Pointer), m_inner{ std::move(inner) } {
|
||||||
}
|
}
|
||||||
@ -94,6 +92,8 @@ namespace types {
|
|||||||
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
||||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
|
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool types_equal(std::shared_ptr<types::Type> type1, std::shared_ptr<types::Type> type2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user