+
+ if(assign.oper->token[0]!='=')
+ return visit(assign, true);
+ else if(assign.left->type!=assign.right->type)
+ {
+ BasicTypeDeclaration *basic_left = dynamic_cast<BasicTypeDeclaration *>(assign.left->type);
+ BasicTypeDeclaration *basic_right = dynamic_cast<BasicTypeDeclaration *>(assign.right->type);
+ if(!basic_left || !basic_right)
+ return;
+
+ Compatibility compat = get_compatibility(*basic_left, *basic_right);
+ if(compat==RIGHT_CONVERTIBLE)
+ convert_to(assign.right, *basic_left);
+ else if(compat!=SAME_TYPE)
+ return;
+ }
+
+ resolve(assign, assign.left->type, true);
+}
+
+void ExpressionResolver::visit(TernaryExpression &ternary)
+{
+ TraversingVisitor::visit(ternary);
+
+ BasicTypeDeclaration *basic_cond = dynamic_cast<BasicTypeDeclaration *>(ternary.condition->type);
+ if(!basic_cond || basic_cond->kind!=BasicTypeDeclaration::BOOL)
+ return;
+
+ TypeDeclaration *type = 0;
+ if(ternary.true_expr->type==ternary.false_expr->type)
+ type = ternary.true_expr->type;
+ else
+ {
+ BasicTypeDeclaration *basic_true = dynamic_cast<BasicTypeDeclaration *>(ternary.true_expr->type);
+ BasicTypeDeclaration *basic_false = dynamic_cast<BasicTypeDeclaration *>(ternary.false_expr->type);
+ Compatibility compat = get_compatibility(*basic_true, *basic_false);
+ if(compat==NOT_COMPATIBLE)
+ return;
+
+ type = (compat==LEFT_CONVERTIBLE ? basic_true : basic_false);
+
+ if(compat==LEFT_CONVERTIBLE)
+ convert_to(ternary.true_expr, *basic_false);
+ else if(compat==RIGHT_CONVERTIBLE)
+ convert_to(ternary.false_expr, *basic_true);
+ }
+
+ resolve(ternary, type, false);