void MemberCallExpressionAST::typeCheck(TypeChecker& checker) { mAccessExpression->typeCheck(checker); if (auto varRef = std::dynamic_pointer_cast<VariableReferenceExpressionAST>(mAccessExpression)) { auto varSymbol = std::dynamic_pointer_cast<VariableSymbol>(mSymbolTable->find(varRef->name())); auto varRefType = checker.findType(varSymbol->variableType()); std::string objName = varRefType->name(); if (!checker.objectExists(objName)) { checker.typeError(varRefType->name() + " is not an object type."); } auto classSymbol = std::dynamic_pointer_cast<ClassSymbol>(Helpers::findSymbolInNamespace(mSymbolTable, objName)); mMemberCallExpression->setCallTable(classSymbol->symbolTable()); mMemberCallExpression->generateSymbols(checker.binder(), mSymbolTable); mMemberCallExpression->typeCheck(checker); } else { auto varRefType = mAccessExpression->expressionType(checker); std::string objName = varRefType->name(); if (!checker.objectExists(objName)) { checker.typeError(varRefType->name() + " is not an object type."); } auto classSymbol = std::dynamic_pointer_cast<ClassSymbol>(Helpers::findSymbolInNamespace(mSymbolTable, objName)); mMemberCallExpression->setCallTable(classSymbol->symbolTable()); mMemberCallExpression->generateSymbols(checker.binder(), mSymbolTable); mMemberCallExpression->typeCheck(checker); } }
void BinaryOpExpressionAST::typeCheck(TypeChecker& checker) { mRightHandSide->typeCheck(checker); mLeftHandSide->typeCheck(checker); auto lhsType = mLeftHandSide->expressionType(checker); auto rhsType = mRightHandSide->expressionType(checker); if (lhsType->name() != "Auto") { checker.assertSameType( *lhsType, *rhsType, asString()); } else { //Infer the type auto lhsVarDec = std::dynamic_pointer_cast<VariableDeclarationExpressionAST>(mLeftHandSide); if (lhsVarDec != nullptr) { if (lhsType->name() == "Auto" && *rhsType == NullReferenceType()) { checker.typeError("Implicitly type of a null variable is not allowed."); } mLeftHandSide = std::make_shared<VariableDeclarationExpressionAST>( rhsType->name(), lhsVarDec->name(), lhsVarDec->isFunctionParameter()); //Update the symbol mSymbolTable->remove(lhsVarDec->name()); mLeftHandSide->generateSymbols(checker.binder(), mSymbolTable); } else { //Should never happen checker.typeError("Auto type is only allowed in variable declaration."); } } }