void MemberAccessAST::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 memberName = getMemberName(); std::string objName = varRefType->name(); if (std::dynamic_pointer_cast<ArrayType>(varRefType)) { objName = "Array"; } if (!checker.objectExists(objName)) { checker.typeError(varRefType->name() + " is not an object type."); } auto& object = checker.getObject(objName); if (!object.fieldExists(memberName)) { checker.typeError("There exists no field '" + memberName + "' in the type '" + varRefType->name() + "'."); } if (auto arrayMember = std::dynamic_pointer_cast<ArrayAccessAST>(mMemberExpression)) { arrayMember->accessExpression()->typeCheck(checker); } } }
void SetFieldValueAST::typeCheck(TypeChecker& checker) { mObjectRefExpression->typeCheck(checker); std::shared_ptr<Type> objRefType; if (auto varRef = std::dynamic_pointer_cast<VariableReferenceExpressionAST>(mObjectRefExpression)) { auto varSymbol = std::dynamic_pointer_cast<VariableSymbol>(mSymbolTable->find(varRef->name())); objRefType = checker.findType(varSymbol->variableType()); } else if (auto arrayRef = std::dynamic_pointer_cast<ArrayAccessAST>(mObjectRefExpression)) { objRefType = arrayRef->expressionType(checker); } else { checker.typeError("Not implemented"); } auto memberName = getMemberName(); std::string objName = objRefType->name(); if (!checker.objectExists(objName)) { checker.typeError(objRefType->name() + " is not an object type."); } auto& object = checker.getObject(objName); if (!object.fieldExists(memberName)) { checker.typeError("There exists no field '" + memberName + "' in the type '" + objRefType->name() + "'."); } mRightHandSide->typeCheck(checker); //Check rhs std::shared_ptr<Type> fieldType; if (std::dynamic_pointer_cast<ArrayAccessAST>(mMemberExpression)) { fieldType = std::dynamic_pointer_cast<ArrayType>(object.getField(memberName).type())->elementType(); } else { fieldType = object.getField(memberName).type(); } checker.assertSameType( *fieldType, *mRightHandSide->expressionType(checker), asString()); }