/// <summary> /// Performs an assigment operation between a Class type and the typeExpression stored in this.rightOperand. /// The type to asign to the array must be promotable to an ClassType, and the only allowable operator is AssignmentOperator /// </summary> /// <param name="leftOperand">The left operand of the assignmet operator.</param> /// <returns>A type expression one all checks and promotions are tried to make the assignment right.</returns> public override object Exec(ClassType leftOperand, object arg) // the unique allowable operator { if (this.op == AssignmentOperator.Assign) { if (this.rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg) == null) { return(null); } if (!leftOperand.HasTypeVariables()) { return(leftOperand); } // * If the left expression of the assignment has type variables, // we must return the concrete type (not the abstract one) // * Then whe unify the concrete types FieldType fieldType = TypeExpression.As <FieldType>(this.rightOperand); if (fieldType != null) { this.rightOperand = fieldType.FieldTypeExpression; } if (leftOperand.Unify(this.rightOperand, this.unification, new List <Pair <TypeExpression, TypeExpression> >())) { leftOperand.ValidTypeExpression = false; return(leftOperand); } } ErrorManager.Instance.NotifyError(new OperationNotAllowedError(this.op.ToString(), leftOperand.FullName, rightOperand.FullName, this.location)); return(null); }
// * We simply check if the index is promotable to an Integer. #endregion #region ArrayType [] public override object Exec(ArrayType a, object arg) { if (this.index.AcceptOperation(PromotionOperation.Create(IntType.Instance, ArrayOperator.Indexer, this.methodAnalyzed, this.location), arg) != null) { return(a.ArrayTypeExpression); } return(null); }
/// <summary> /// Performs an assigment operation between a Interface type and the typeExpression stored in this.rightOperand. /// the result of the operation is the resulting operation of doing PromotionOperation the operation over the subclass attached to he inteface type. /// Only is factible do this operation if op is an AssigmentOperation. In other case it raises an error. /// </summary> /// <param name="leftOperand">A IntefaceType, the left operand of the assignment/param> /// <returns> The result of the operation is the resulting operation of doing The Assignment operation. ///</returns> public override object Exec(InterfaceType leftOperand, object arg) { if (this.op == AssignmentOperator.Assign) { return(rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg)); } return(ReportError(leftOperand)); }
/// <summary> /// It performs a an assigment operation with a StringType as left operand. /// </summary> /// <param name="leftOperand">A StringType as left operand</param> /// <returns>result the evaluation of the operator, in this case it can be =, and += operations, with these two types if they satisfies the condition embebed in the code.</returns> public override object Exec(StringType leftOperand, object arg) { if (op == AssignmentOperator.Assign || op == AssignmentOperator.PlusAssign) { return(rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg)); } // * se podría aquí hacer un base.ReportError()?; ErrorManager.Instance.NotifyError(new OperationNotAllowedError(leftOperand.FullName, rightOperand.FullName, this.location)); return(null); }
/// <summary> /// It performs a an assigment operation with a TypeVariable as left operand. /// </summary> /// <param name="leftOperand">leftOperand is Typevariable in the left par of the assignment</param> /// <returns>The result of the assignment if possible null and error if not.</returns> public override object Exec(TypeVariable leftOperand, object arg) { // * Bounded variable? if (leftOperand.Substitution != null && this.unification == SortOfUnification.Equivalent) { // * Check promotion to its substitution return(rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg)); } // * If the variable its not bounded, we add the parameter to the equivalence list if (leftOperand.addToMyEquivalenceClass(rightOperand, this.unification, new List <Pair <TypeExpression, TypeExpression> >())) { return(leftOperand); } // * If it has not been possible, error ErrorManager.Instance.NotifyError(new OperationNotAllowedError(this.op.ToString(), leftOperand.FullName, rightOperand.FullName, this.location)); return(null); }
public override object Exec(MethodType caller, object arg) { // * Quits if there's some error in the arguments if (this.arguments == null) { return(null); } // * An instance method cannot be call from a static method without using an object if ((!caller.MemberInfo.Modifiers.Contains(Modifier.Static)) && this.methodAnalyzed != null && this.methodAnalyzed.MemberInfo.Modifiers.Contains(Modifier.Static) && this.actualImplicitObject == null) { ErrorManager.Instance.NotifyError(new InstanceMethodCallFromStaticMethodError(caller.FullName, this.methodAnalyzed.FullName, this.location)); return(null); } // * Is Unification necessary? if (caller.MemberInfo.Class.HasTypeVariables() || caller.HasTypeVariables()) { // * We infer the return type return(MethodType.methodCall(this.actualImplicitObject, caller, this.arguments, this.methodAnalyzed, this.activeSortOfUnification, this.location)); } // h Otherwise... // Check the argument number if (this.arguments.GetLength(0) != caller.ParameterListCount) { ErrorManager.Instance.NotifyError(new ArgumentNumberError(caller.MemberInfo.MemberIdentifier, this.arguments.GetLength(0), this.location)); return(null); } // Check the argument type for (int i = 0; i < caller.ParameterListCount; i++) { this.arguments[i].AcceptOperation(PromotionOperation.Create(caller.getParam(i), this.methodAnalyzed, this.location), arg); } // * Returns the return type return(caller.Return); }
public override object Exec(UnionType from, object arg) { return(from.AcceptOperation(PromotionOperation.Create(this.to, AssignmentOperator.Assign, this.methodAnalyzed, this.location), arg)); }
public override object Exec(MethodType caller, object arg) { // * Quits if there's some error in the arguments if (this.arguments == null) { return(null); } // * An instance method cannot be call from a static method without using an object if ((!caller.MemberInfo.Modifiers.Contains(Modifier.Static)) && this.methodAnalyzed != null && this.methodAnalyzed.MemberInfo.Modifiers.Contains(Modifier.Static) && this.actualImplicitObject == null) { ErrorManager.Instance.NotifyError(new InstanceMethodCallFromStaticMethodError(caller.FullName, this.methodAnalyzed.FullName, this.location)); return(null); } // * Is Unification necessary? if (caller.MemberInfo.Class.HasTypeVariables() || caller.HasTypeVariables()) { return(MethodType.methodCall(this.actualImplicitObject, caller, this.arguments, this.methodAnalyzed, this.activeSortOfUnification, this.location)); } // h Otherwise... // Check the argument number if (this.arguments.GetLength(0) != caller.ParameterListCount) { ErrorManager.Instance.NotifyError(new ArgumentNumberError(caller.MemberInfo.MemberIdentifier, this.arguments.GetLength(0), this.location)); return(null); } int from = (this.methodAnalyzed != null && this.methodAnalyzed.Constraints != null) ? this.methodAnalyzed.Constraints.Count:0; // Check the argument type for (int i = 0; i < caller.ParameterListCount; i++) { this.arguments[i].AcceptOperation(PromotionOperation.Create(caller.getParam(i), this.methodAnalyzed, this.location), arg); } int to = (this.methodAnalyzed != null && this.methodAnalyzed.Constraints != null) ? this.methodAnalyzed.Constraints.Count : 0; if (to > from) { ConstraintList cl = new ConstraintList(); for (int i = from; i < to; i++) { cl.Add(this.methodAnalyzed.Constraints.Constraints[i]); } for (int i = to - 1; i >= from; i--) { this.methodAnalyzed.Constraints.Constraints.RemoveAt(i); } InvocationConstraint ic = null; foreach (var constraint in this.methodAnalyzed.Constraints.Constraints) { ic = constraint as InvocationConstraint; if (ic != null && ic.MethodName.Equals(caller.ToString())) { ic.Add(cl); break; } ic = null; } if (ic == null) { ic = new InvocationConstraint(caller.ToString()); ic.Add(cl); this.methodAnalyzed.Constraints.Add(ic); } } // * Returns the return type return(caller.Return); }
/// <summary> /// Performs an assigment operation between an boolean type and the typeExpression stored in this.rightOperand. /// The type to asign to the array must be promotable to an BoolType, and the only allowable operator is AssignmentOperator /// </summary> /// <param name="leftOperand">A BoolType to use as leftOperand in an assignment operation</param> /// <returns>The typeExpression resulting of have been doing the operation. Or an error if there is.</returns> public override object Exec(BoolType leftOperand, object arg) { return(this.op == AssignmentOperator.Assign // * if the operator is not assing raise and error, in other case, check if the second operand can be promotable to a BoolType ? rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg) : ReportError(leftOperand)); }
/// <summary> /// Performs an assigment operation between a IntType type and the typeExpression stored in this.rightOperand. /// the result of the operation is the resulting operation of pass a message to the right operand doing a PromotionOperation with the operation over the class IntType. /// Only is factible do this operation if op is an AssigmentOperation. In other case it raises an error. /// </summary> /// <param name="leftOperand">A IntType, the left operand of the assignment/param> /// <returns> The result of the operation is the resulting operation of doing The Assignment operation. ///</returns> public override object Exec(IntType leftOperand, object arg) { return(rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg)); }