/// <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);
 }
Example #2
0
        // * 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));
 }
Example #8
0
        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));
 }