diff --git a/src/typechecker.cpp b/src/typechecker.cpp index 913be10..46130c8 100644 --- a/src/typechecker.cpp +++ b/src/typechecker.cpp @@ -2,9 +2,41 @@ #include "typechecker.h" #include "ast.h" #include "errors.h" +#include "result.h" namespace { + enum class TypecheckRes { + Ok, + Castable, + }; + Result check_type(std::shared_ptr checked, std::shared_ptr target) { + if (types::types_equal(checked, target)) { + return TypecheckRes::Ok; + } + + return std::string{ "Types " + checked->formatted() + " and " + target->formatted() + " incompatible" }; + } + + std::unique_ptr handle_res( + std::unique_ptr expr, + Result 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 { @@ -35,15 +67,14 @@ namespace AST { typecheck::Scope& scope, std::optional> ) { - if (scope.symbols.contains(this->m_name)) { + if (scope.symbols.find(this->m_name) != scope.symbols.end()) { return scope.symbols[this->m_name]; } - else { - state.errors.push_back(CompileError("Value " + this->m_name + " not defined", this->m_meta)); - return std::shared_ptr{ - new types::FundamentalType{ types::FundamentalTypeKind::Void } - }; - } + + state.errors.push_back(CompileError("Value " + this->m_name + " not defined", this->m_meta)); + return std::shared_ptr{ + new types::FundamentalType{ types::FundamentalTypeKind::Void } + }; } std::shared_ptr BinaryOperationExpression::typecheck( @@ -86,7 +117,8 @@ namespace AST { auto expected_param_ty = fn_ty->m_param_tys[i]; 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); } }