From 85dbce112fddd7a9ff16aea82d8a6e28e1296b27 Mon Sep 17 00:00:00 2001 From: Sofia Date: Mon, 13 Apr 2026 01:08:34 +0300 Subject: [PATCH] Fill typechecking methods --- src/typechecker.cpp | 62 ++++++++++++++++++++++++++++++++++----------- src/types.h | 3 +-- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/typechecker.cpp b/src/typechecker.cpp index 3276c41..7262438 100644 --- a/src/typechecker.cpp +++ b/src/typechecker.cpp @@ -5,43 +5,75 @@ namespace AST { std::shared_ptr IntLiteralExpression::typecheck( - typecheck::State& state, - typecheck::Scope& scope, - std::optional> expected_ty + typecheck::State&, + typecheck::Scope&, + std::optional> ) { - throw CompileError("TODO", {}); + return std::shared_ptr{ + new types::FundamentalType{ types::FundamentalTypeKind::Int } + }; } std::shared_ptr StringLiteralExpression::typecheck( - typecheck::State& state, - typecheck::Scope& scope, - std::optional> expected_ty + typecheck::State&, + typecheck::Scope&, + std::optional> ) { - throw CompileError("TODO", {}); + auto char_ty = std::shared_ptr{ + new types::FundamentalType{ types::FundamentalTypeKind::Char } + }; + auto ptr_ty = new types::PointerType{ char_ty }; + return std::shared_ptr{ptr_ty}; } std::shared_ptr ValueReferenceExpression::typecheck( - typecheck::State& state, + typecheck::State&, typecheck::Scope& scope, - std::optional> expected_ty + std::optional> ) { - throw CompileError("TODO", {}); + return scope.symbols[this->m_name]; } std::shared_ptr BinaryOperationExpression::typecheck( typecheck::State& state, typecheck::Scope& scope, - std::optional> expected_ty + std::optional> ) { - throw CompileError("TODO", {}); + auto lhs_ty = this->m_lhs->typecheck(state, scope, {}); + auto rhs_ty = this->m_rhs->typecheck(state, scope, {}); + + // TODO actually check binop types properly + + return lhs_ty; } std::shared_ptr FunctionCallExpression::typecheck( typecheck::State& state, typecheck::Scope& scope, - std::optional> expected_ty + std::optional> ) { - throw CompileError("TODO", {}); + auto expr_ty = this->m_fn_expr->typecheck(state, scope, {}); + + // TODO make sure function_ty really is a function type + + auto fn_ty = dynamic_cast(expr_ty.get()); + + if (this->m_args.size() < fn_ty->m_param_tys.size()) { + state.errors.push_back(CompileError("too few arguments", this->m_meta)); + } + else if (this->m_args.size() > fn_ty->m_param_tys.size() && !fn_ty->m_vararg) { + state.errors.push_back(CompileError("too many arguments", this->m_meta)); + } + else { + for (int i = 0; i < static_cast(fn_ty->m_param_tys.size()); i++) { + 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 + } + } + + return fn_ty->m_ret_ty; } void ReturnStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) { diff --git a/src/types.h b/src/types.h index 640f057..8d2adeb 100644 --- a/src/types.h +++ b/src/types.h @@ -55,11 +55,10 @@ namespace types { class FunctionType : public Type { - private: + public: std::shared_ptr m_ret_ty; std::vector> m_param_tys; bool m_vararg; - public: FunctionType(std::shared_ptr ret_ty, std::vector> param_tys, bool vararg) : m_ret_ty{ std::move(ret_ty) }, m_param_tys{ std::move(param_tys) }, m_vararg{ vararg } { }