示例#1
0
        // WriteType Unification

        #region Unify
        /// <summary>
        /// This method unifies two type expressions (this and te)
        /// </summary>
        /// <param name="te">The expression to be unfied with this</param>
        /// <param name="unification">Indicates if the kind of unification (equivalent, incremental or override).</param>
        /// <param name="previouslyUnified">To detect infinite loops. The previously unified pairs of type expressions.</param>
        /// <returns>If the unification was successful</returns>
        public override bool Unify(TypeExpression te, SortOfUnification unification, IList <Pair <TypeExpression, TypeExpression> > previouslyUnified)
        {
            // * Infinite recursion detection
            Pair <TypeExpression, TypeExpression> pair = new Pair <TypeExpression, TypeExpression>(this, te);

            if (previouslyUnified.Contains(pair))
            {
                return(true);
            }
            previouslyUnified.Add(pair);

            bool      success = false;
            ArrayType at      = te as ArrayType;

            if (at != null)
            {
                success = this.arrayType.Unify(at.arrayType, unification, previouslyUnified);
            }
            else if (te is TypeVariable)
            {
                TypeVariable typeVariable = (TypeVariable)te;
                if (unification != SortOfUnification.Incremental)
                {
                    // * Incremental is commutative
                    success = typeVariable.Unify(this, unification, previouslyUnified);
                }
                else   // * Array(var) should unify to Var=Array(int)
                {
                    if (typeVariable.Substitution != null)
                    {
                        success = this.Unify(typeVariable.Substitution, unification, previouslyUnified);
                    }
                    else
                    {
                        success = false;
                    }
                }
            }
            else if (te is UnionType)
            {
                success = te.Unify(this, unification, previouslyUnified);
            }
            // * Clears the type expression cache
            this.ValidTypeExpression = false;
            te.ValidTypeExpression   = false;
            return(success);
        }
示例#2
0
        // WriteType Promotion

        #region PromotionLevel()

        /// <summary>
        /// Returns a value thdat indicates a promotion level.
        /// </summary>
        /// <param name="type">WriteType to promotion.</param>
        /// <returns>Returns a promotion value.</returns>
        //public override int PromotionLevel(TypeExpression type) {
        //    int aux, less = -1;

        //    // * The same type
        //    if (this == type)
        //        return 0;
        //    // * Equivalent types
        //    if ((bool)this.AcceptOperation(new EquivalentOperation(type)))
        //        return 0;

        //    // * Field type and bounded type variable
        //    FieldType fieldType = TypeExpression.As<FieldType>(type);
        //    if (fieldType != null)
        //        return this.PromotionLevel(fieldType.FieldTypeExpression);

        //    // * WriteType variable
        //    TypeVariable typeVariable = type as TypeVariable;
        //    if (typeVariable != null) {
        //        if (typeVariable.Substitution != null)
        //            // * If the variable is bounded, the promotion is the one of its substitution
        //            return this.PromotionLevel(typeVariable.EquivalenceClass.Substitution);
        //        // * A free variable is complete promotion
        //        return 0;
        //    }

        //    // * Inheritance
        //    if (this.BaseClass == null)
        //        // * Object only promotes to object
        //        return -1;
        //    if ((bool)this.baseClass.AcceptOperation(new EquivalentOperation(type)))
        //        return 1;
        //    else {
        //        aux = this.baseClass.PromotionLevel(type);
        //        if (aux != -1)
        //            return aux + 1;
        //    }

        //    // * Interfaces
        //    if (this.interfaceList.Count != 0) {
        //        for (int i = 0; i < this.interfaceList.Count; i++) {
        //            if ((bool)this.interfaceList[i].AcceptOperation( new EquivalentOperation(type))) {
        //                if ((less > 1) || (less == -1))
        //                    less = 1;
        //            }
        //            else {
        //                aux = this.interfaceList[i].PromotionLevel(type);
        //                if (aux != -1) {
        //                    if ((less > (aux + 1)) || (less == -1))
        //                        less = aux + 1;
        //                }
        //            }
        //        }
        //    }
        //    if (less != -1)
        //        return less;

        //    // * Union type
        //    UnionType unionType = TypeExpression.As<UnionType>(type);
        //    if (unionType != null)
        //        return unionType.SuperType(this);

        //    // * No promotion
        //    return -1;
        //}

        #endregion

        // WriteType Unification

        #region Unify
        /// <summary>
        /// This method unifies two type expressions (this and te)
        /// </summary>
        /// <param name="te">The expression to be unfied with this</param>
        /// <param name="unification">Indicates if the kind of unification (equivalent, incremental or override).</param>
        /// <param name="previouslyUnified">To detect infinite loops. The previously unified pairs of type expressions.</param>
        /// <returns>If the unification was successful</returns>
        public override bool Unify(TypeExpression te, SortOfUnification unification, IList <Pair <TypeExpression, TypeExpression> > previouslyUnified)
        {
            // * Infinite recursion detection
            Pair <TypeExpression, TypeExpression> pair = new Pair <TypeExpression, TypeExpression>(this, te);

            if (previouslyUnified.Contains(pair))
            {
                return(true);
            }
            previouslyUnified.Add(pair);

            ClassType ct      = te as ClassType;
            bool      success = true;

            // * Class WriteType
            if (ct != null)
            {
                // * Inheritance is taken into account
                if ((int)ct.AcceptOperation(new PromotionLevelOperation(this), null) == -1)
                {
                    return(false);
                }
                // * Walk upward in the tree till find the correct class
                while (!(bool)ct.AcceptOperation(new EquivalentOperation(this), null))
                {
                    ct = ct.baseClass;
                }
                // * Now we unify the fields
                foreach (string key in this.Fields.Keys)
                {
                    FieldType thisField = (FieldType)this.Fields[key].Type,
                                teField = (FieldType)ct.Fields[key].Type;
                    if (thisField.FieldTypeExpression is ClassTypeProxy || teField.FieldTypeExpression is ClassTypeProxy)
                    {
                        success = thisField.FieldTypeExpression.FullName.Equals(teField.FieldTypeExpression.FullName);
                    }
                    else if (!(thisField.Unify(teField, unification, previouslyUnified)))
                    {
                        success = false;
                    }
                    if (!success)
                    {
                        break;
                    }
                }
                if (success && this.baseClass != null)
                {
                    // * The same with the base class
                    this.baseClass.Unify(ct.baseClass, unification, previouslyUnified);
                }
                // * If one of the classes is a concrete type, so it is the other
                if (success)
                {
                    this.ConcreteType = ct.ConcreteType = this.ConcreteType || ct.ConcreteType;
                }
            }
            // * WriteType variable
            else if (te is TypeVariable)
            {
                TypeVariable typeVariable = (TypeVariable)te;
                if (unification != SortOfUnification.Incremental)
                {
                    // * Incremental is commutative
                    success = typeVariable.Unify(this, unification, previouslyUnified);
                }
                // * Incremental unification (not commutative)
                else if (typeVariable.Substitution != null)
                {
                    // * Class(var) should unify to Var=Class(int)
                    success = this.Unify(typeVariable.Substitution, unification, previouslyUnified);
                }
                else
                {
                    success = false;
                }
            }
            // * Union WriteType
            else if (te is UnionType)
            {
                success = te.Unify(this, unification, previouslyUnified);
            }
            // * Class WriteType Proxy
            else if (te is ClassTypeProxy)
            {
                success = this.Unify(((ClassTypeProxy)te).RealType, unification, previouslyUnified);
            }
            else if (te is FieldType)
            {
                success = this.Unify(((FieldType)te).FieldTypeExpression, unification, previouslyUnified);
            }
            else
            {
                success = false;
            }
            // * Clears the type expression cache
            this.ValidTypeExpression = false;
            te.ValidTypeExpression   = false;
            return(success);
        }