Type* IndexExpression::GetType() { Type *containerType = Container->GetType(); if (typeid(*containerType) == typeid(ArrayType)) { ArrayType *arrayType = dynamic_cast<ArrayType *>(containerType); return arrayType->GetElementType(); } else if (typeid(*containerType) == typeid(PointerType)) { PointerType *pointerType = dynamic_cast<PointerType *>(containerType); return pointerType->GetUnderlyingType(); } else { abort(); } }
void TypeDeduction::Visit(UnaryExpression* node) { Type *targetType; node->GetOperand()->Accept(this); Type *operandType = node->GetOperand()->GetTag<Type>("Type"); assert(operandType != NULL); switch (node->GetAction()) { case Expression::Plus: case Expression::Minus: case Expression::Not: //TODO: Check the type targetType = operandType; break; case Expression::Reference: if (node->GetOperand()->GetLValue() == NULL) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Only l-value can be get its address taken."); } targetType = new PointerType(operandType); break; case Expression::Dereference: { PointerType *pointerType = dynamic_cast<PointerType *>(operandType); if (pointerType == NULL) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Dereferencing requires a pointer type, but %s is provided.", operandType->ToString().c_str()); } targetType = pointerType->GetUnderlyingType(); break; } default: abort(); } node->SetTag<Type>("Type", targetType); }
bool ArrayType::CanImplicitlyConvertTo(Type* other) { if (this->Equals(other)) { return true; } else { PointerType *pointerType = dynamic_cast<PointerType *>(other); if (pointerType == NULL) { return false; } if (pointerType->GetUnderlyingType()->CanImplicitlyConvertTo(_elementType)) { return true; } return false; } }