Allow typechecker to perform implicit casts
This commit is contained in:
parent
1555c12bbd
commit
ee0e30934a
@ -10,10 +10,15 @@ namespace {
|
|||||||
Castable,
|
Castable,
|
||||||
};
|
};
|
||||||
|
|
||||||
Result<TypecheckRes, std::string> check_type(std::shared_ptr<types::Type> checked, std::shared_ptr<types::Type> target) {
|
Result<TypecheckRes, std::string> check_type(typecheck::State& state, std::shared_ptr<types::Type> checked, std::shared_ptr<types::Type> target) {
|
||||||
|
auto potential_cast = types::find_cast(state.casts, checked, target);
|
||||||
|
|
||||||
if (types::types_equal(checked, target)) {
|
if (types::types_equal(checked, target)) {
|
||||||
return TypecheckRes::Ok;
|
return TypecheckRes::Ok;
|
||||||
}
|
}
|
||||||
|
else if (potential_cast.has_value() && potential_cast->allow_implicit) {
|
||||||
|
return TypecheckRes::Castable;
|
||||||
|
}
|
||||||
|
|
||||||
return std::string{ "Types " + checked->formatted() + " and " + target->formatted() + " incompatible" };
|
return std::string{ "Types " + checked->formatted() + " and " + target->formatted() + " incompatible" };
|
||||||
}
|
}
|
||||||
@ -156,7 +161,7 @@ namespace AST {
|
|||||||
auto expected_param_ty = fn_ty->m_param_tys[i];
|
auto expected_param_ty = fn_ty->m_param_tys[i];
|
||||||
auto param_ty = this->m_args[i]->typecheck(state, scope, expected_param_ty);
|
auto param_ty = this->m_args[i]->typecheck(state, scope, expected_param_ty);
|
||||||
|
|
||||||
auto check_res = check_type(param_ty, expected_param_ty);
|
auto check_res = check_type(state, param_ty, expected_param_ty);
|
||||||
this->m_args[i] = handle_res(std::move(this->m_args[i]), check_res, state);
|
this->m_args[i] = handle_res(std::move(this->m_args[i]), check_res, state);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -190,7 +195,7 @@ namespace AST {
|
|||||||
void ReturnStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) {
|
void ReturnStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) {
|
||||||
auto res_ty = this->m_expr->typecheck(state, scope, scope.return_ty);
|
auto res_ty = this->m_expr->typecheck(state, scope, scope.return_ty);
|
||||||
if (scope.return_ty) {
|
if (scope.return_ty) {
|
||||||
auto check_res = check_type(res_ty, *scope.return_ty);
|
auto check_res = check_type(state, res_ty, *scope.return_ty);
|
||||||
this->m_expr = handle_res(std::move(this->m_expr), check_res, state);
|
this->m_expr = handle_res(std::move(this->m_expr), check_res, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,7 +216,7 @@ namespace AST {
|
|||||||
new types::FundamentalType{ types::FundamentalTypeKind::Bool } };
|
new types::FundamentalType{ types::FundamentalTypeKind::Bool } };
|
||||||
auto expr_ty = this->m_condition->typecheck(state, scope, bool_ty);
|
auto expr_ty = this->m_condition->typecheck(state, scope, bool_ty);
|
||||||
|
|
||||||
auto check_res = check_type(expr_ty, bool_ty);
|
auto check_res = check_type(state, expr_ty, bool_ty);
|
||||||
this->m_condition = handle_res(std::move(this->m_condition), check_res, state);
|
this->m_condition = handle_res(std::move(this->m_condition), check_res, state);
|
||||||
|
|
||||||
this->m_then->typecheck(state, scope);
|
this->m_then->typecheck(state, scope);
|
||||||
|
|||||||
@ -76,7 +76,7 @@ namespace types {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Type::is_signed() {
|
bool Type::is_signed() {
|
||||||
false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<llvm::Value*, std::shared_ptr<Type>> FundamentalType::load(codegen::Builder&, llvm::Value* ptr) {
|
std::pair<llvm::Value*, std::shared_ptr<Type>> FundamentalType::load(codegen::Builder&, llvm::Value* ptr) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user