void TypeDeduction::Visit(ConditionalExpression* node) { std::map<Expression *, Expression *> *condBranches = node->GetConditionalBranches(); for (std::map<Expression *, Expression *>::iterator it = condBranches->begin(); it != condBranches->end(); ++it) { Expression *condition = it->first; Expression *condExpr = it->second; condition->Accept(this); condExpr->Accept(this); Type *conditionType = condition->GetTag<Type>("Type"); if (!conditionType->CanImplicitlyConvertTo(new BooleanType())) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Boolean expression expected."); } } node->GetDefaultBranch()->Accept(this); Type *defType = node->GetDefaultBranch()->GetTag<Type>("Type"); for (std::map<Expression *, Expression *>::iterator it = condBranches->begin(); it != condBranches->end(); ++it) { Expression *condition = it->first; Expression *condExpr = it->second; Type *exprType = condExpr->GetTag<Type>("Type"); if (!defType->Equals(exprType)) { node->SetTag<Type>("Type", new VoidType()); return; } } node->SetTag<Type>("Type", defType); }
void TypeDeduction::Visit(AssignExpression* node) { Expression *source = node->GetSource(); Expression *target = node->GetTarget(); source->Accept(this); target->Accept(this); Expression *lvalue = target->GetLValue(); if (lvalue == NULL) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Assignment target is not an l-value."); } if (lvalue->GetTag<Type>("Type") == NULL) { lvalue->Accept(this); } Type *sourceType = source->GetTag<Type>("Type"); Type *targetType = lvalue->GetTag<Type>("Type"); if (!sourceType->CanImplicitlyConvertTo(targetType)) { if (sourceType->CanExplicitlyConvertTo(targetType)) { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Cannot assign %s to %s, an explicit conversion is required.", sourceType->ToString().c_str(), targetType->ToString().c_str()); } else { CompilationContext::GetInstance()->ReportError(node->SourceLocation, false, "Cannot assign %s to %s.", sourceType->ToString().c_str(), targetType->ToString().c_str()); } } else { if (!sourceType->Equals(targetType)) { ConvertExpression *castExpr = new ConvertExpression(targetType, source); node->SetSource(castExpr); castExpr->SetTag<Type>("Type", targetType); } node->SetTag<Type>("Type", targetType); } }