public override object Exec(UnionType firstOperand, object arg) { // * If all the types in typeset generate a constraint, we simply generate one constraint using the whole union type if (firstOperand.IsFreshVariable() && methodAnalyzed != null) { // * A constraint is added to the method analyzed RelationalConstraint constraint = new RelationalConstraint(firstOperand, secondOperand, relationalOperator, location); methodAnalyzed.AddConstraint(constraint); return(constraint.ReturnType); } bool oneCorrectType = false; foreach (TypeExpression type in firstOperand.TypeSet) { TypeExpression ret = (TypeExpression)type.AcceptOperation(new RelationalOperation(secondOperand, relationalOperator, methodAnalyzed, !firstOperand.IsDynamic && showErrorMessage, location), arg); if (ret == null && !firstOperand.IsDynamic) { return(null); } if (ret != null) { oneCorrectType = true; } } // * If there has been some errors, they have not been shown because the type is dynamic, we show it if (showErrorMessage && firstOperand.IsDynamic && !oneCorrectType) { ErrorManager.Instance.NotifyError(new NoTypeAcceptsOperation(firstOperand.FullName, relationalOperator.ToString(), secondOperand.FullName, location)); } return(BoolType.Instance); }
public override object Exec(TypeVariable operand, object arg) { if (operand.Substitution != null) { DynVarOptions.Instance.AssignDynamism(operand.Substitution, operand.IsDynamic); return(operand.Substitution.AcceptOperation(this, arg)); } if (methodAnalyzed != null) { // * A constraint is added to the method analyzed ArithmeticConstraint constraint = new ArithmeticConstraint(operand, unaryOperator, location); methodAnalyzed.AddConstraint(constraint); return(constraint.ReturnType); } return(ReportError(operand)); }
public override object Exec(TypeVariable d, object arg) { if (d.Substitution != null) { DynVarOptions.Instance.AssignDynamism(d.Substitution, d.IsDynamic); return(d.Substitution.AcceptOperation(this, arg)); } if (methodAnalyzed != null) { // * A attribute access constraint is added to the method analyzed DotConstraint constraint = new DotConstraint(d, this.memberName, this.location); methodAnalyzed.AddConstraint(constraint); return(constraint.ReturnType); } ErrorManager.Instance.NotifyError(new OperationNotAllowedError(".", d.FullName, this.location)); return(null); }
/// <summary> /// If there are Substitution in the first operand, it return the result of aplying the operation using the substitution /// as first operand. It is not the case, a constraint is added and if showErrorMessages is true an error is raise. /// </summary> /// <param name="firstOperand">A TypeVariable</param> /// <sumary>The type expression resulting of applying the operand and second operator. /// If somethis is worng and showMessages is true an error is raise.</sumary> public override object Exec(TypeVariable firstOperand, object arg) { if (firstOperand.Substitution != null) { DynVarOptions.Instance.AssignDynamism(firstOperand.Substitution, firstOperand.IsDynamic); return(firstOperand.Substitution.AcceptOperation(this, arg)); } if (methodAnalyzed != null) { // * A constraint is added to the method analyzed ArithmeticConstraint constraint = new ArithmeticConstraint(firstOperand, secondOperand, binaryOperator, location); methodAnalyzed.AddConstraint(constraint); return(constraint.ReturnType); } if (showErrorMessage) { ErrorManager.Instance.NotifyError(new OperationNotAllowedError(binaryOperator.ToString(), firstOperand.FullName, secondOperand.FullName, location)); } return(null); }
/// <summary> /// The first Operand is a Double so the second must be promotable to a DoubleType so the whole operation must have sense. /// Implements a double dispatch pattern. /// </summary> /// <param name="firstOperand">A double type to perform a binary arithmetica operation with. The second operate have to be promotable /// to Double, cause is the grater integral value.</param> /// <returns>A TypeExpression if the operation makes sense, otherwise if showMessages is true, an error is raised</returns> public override object Exec(DoubleType firstOperand, object arg) { if ((int)this.secondOperand.AcceptOperation(new PromotionLevelOperation(firstOperand), arg) != -1) { if (secondOperand is TypeVariable) { if (methodAnalyzed != null && ((TypeVariable)secondOperand).Substitution == null) { // * A constraint is added to the method analyzed ArithmeticConstraint constraint = new ArithmeticConstraint(firstOperand, secondOperand, binaryOperator, location); methodAnalyzed.AddConstraint(constraint); return(constraint.ReturnType); } } return(DoubleType.Instance); } if (this.binaryOperator.Equals(ArithmeticOperator.Plus) && (bool)this.secondOperand.AcceptOperation(new EquivalentOperation(StringType.Instance), arg)) { return(StringType.Instance); } // We rely in arithmetic conmutativiness to perform a cross recursion. Could it be dangerous? return(secondOperand.AcceptOperation(ArithmeticalOperation.Create(firstOperand, this.binaryOperator, this.methodAnalyzed, this.showErrorMessage, this.location), arg)); }