Typecheck parameter types
This commit is contained in:
parent
a901806dfb
commit
185f25d412
@ -2,9 +2,41 @@
|
|||||||
#include "typechecker.h"
|
#include "typechecker.h"
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
|
#include "result.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
enum class TypecheckRes {
|
||||||
|
Ok,
|
||||||
|
Castable,
|
||||||
|
};
|
||||||
|
|
||||||
|
Result<TypecheckRes, std::string> check_type(std::shared_ptr<types::Type> checked, std::shared_ptr<types::Type> target) {
|
||||||
|
if (types::types_equal(checked, target)) {
|
||||||
|
return TypecheckRes::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string{ "Types " + checked->formatted() + " and " + target->formatted() + " incompatible" };
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AST::Expression> handle_res(
|
||||||
|
std::unique_ptr<AST::Expression> expr,
|
||||||
|
Result<TypecheckRes, std::string> res,
|
||||||
|
typecheck::State& state) {
|
||||||
|
if (res.ok()) {
|
||||||
|
auto result = res.unwrap();
|
||||||
|
if (result == TypecheckRes::Ok) {
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
state.errors.push_back(CompileError("Casting not yet implemented", expr->m_meta));
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
state.errors.push_back(CompileError(res.unwrap_err(), expr->m_meta));
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace AST {
|
namespace AST {
|
||||||
@ -35,15 +67,14 @@ namespace AST {
|
|||||||
typecheck::Scope& scope,
|
typecheck::Scope& scope,
|
||||||
std::optional<std::shared_ptr<types::Type>>
|
std::optional<std::shared_ptr<types::Type>>
|
||||||
) {
|
) {
|
||||||
if (scope.symbols.contains(this->m_name)) {
|
if (scope.symbols.find(this->m_name) != scope.symbols.end()) {
|
||||||
return scope.symbols[this->m_name];
|
return scope.symbols[this->m_name];
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
state.errors.push_back(CompileError("Value " + this->m_name + " not defined", this->m_meta));
|
state.errors.push_back(CompileError("Value " + this->m_name + " not defined", this->m_meta));
|
||||||
return std::shared_ptr<types::Type>{
|
return std::shared_ptr<types::Type>{
|
||||||
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
new types::FundamentalType{ types::FundamentalTypeKind::Void }
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<types::Type> BinaryOperationExpression::typecheck(
|
std::shared_ptr<types::Type> BinaryOperationExpression::typecheck(
|
||||||
@ -86,7 +117,8 @@ 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);
|
||||||
|
|
||||||
// TODO make sure types actually match
|
auto check_res = check_type(param_ty, expected_param_ty);
|
||||||
|
this->m_args[i] = handle_res(std::move(this->m_args[i]), check_res, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user