Ejemplo n.º 1
0
        /// <summary>
        /// Look up the given identifier in the given sequence, walking the type chain
        /// until we either find it, or fail.
        /// </summary>
        /// <param name="sequence">Sequence (object) to look in.</param>
        /// <param name="identifier">Identifier to look for.</param>
        /// <param name="context">Context.</param>
        public static Value Resolve(Value sequence, string identifier, TAC.Context context, out ValMap valueFoundIn)
        {
            var includeMapType = true;

            valueFoundIn = null;
            int loopsLeft = 1000;                       // (max __isa chain depth)

            while (sequence != null)
            {
                if (sequence is ValTemp || sequence is ValVar)
                {
                    sequence = sequence.Val(context);
                }
                if (sequence is ValMap)
                {
                    // If the map contains this identifier, return its value.
                    Value result = null;
                    var   idVal  = TempValString.Get(identifier);
                    bool  found  = ((ValMap)sequence).map.TryGetValue(idVal, out result);
                    TempValString.Release(idVal);
                    if (found)
                    {
                        valueFoundIn = (ValMap)sequence;
                        return(result);
                    }

                    // Otherwise, if we have an __isa, try that next.
                    if (loopsLeft < 0)
                    {
                        return(null);                                           // (unless we've hit the loop limit)
                    }
                    if (!((ValMap)sequence).map.TryGetValue(ValString.magicIsA, out sequence))
                    {
                        // ...and if we don't have an __isa, try the generic map type if allowed
                        if (!includeMapType)
                        {
                            throw new KeyException(identifier);
                        }
                        sequence       = context.vm.mapType ?? Intrinsics.MapType();
                        includeMapType = false;
                    }
                }
                else if (sequence is ValList)
                {
                    sequence       = context.vm.listType ?? Intrinsics.ListType();
                    includeMapType = false;
                }
                else if (sequence is ValString)
                {
                    sequence       = context.vm.stringType ?? Intrinsics.StringType();
                    includeMapType = false;
                }
                else if (sequence is ValNumber)
                {
                    sequence       = context.vm.numberType ?? Intrinsics.NumberType();
                    includeMapType = false;
                }
                else if (sequence is ValFunction)
                {
                    sequence       = context.vm.functionType ?? Intrinsics.FunctionType();
                    includeMapType = false;
                }
                else
                {
                    throw new TypeException("Type Error (while attempting to look up " + identifier + ")");
                }
                loopsLeft--;
            }
            return(null);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Look up the given identifier in the given sequence, walking the type chain
        /// until we either find it, or fail.
        /// </summary>
        /// <param name="sequence">Sequence (object) to look in.</param>
        /// <param name="identifier">Identifier to look for.</param>
        /// <param name="context">Context.</param>
        public static Value Resolve(Value sequence, string identifier, Context context, out ValMap valueFoundIn)
        {
            var includeMapType = true;

            valueFoundIn = null;
            int loopsLeft = 1000;                       // (max __isa chain depth)

            while (sequence != null)
            {
                int seqTypeInt = sequence.GetBaseMiniscriptType();

                //if (sequence is ValTemp || sequence is ValVar)
                if (seqTypeInt == MiniscriptTypeInts.ValTempTypeInt || seqTypeInt == MiniscriptTypeInts.ValVarTypeInt)
                {
                    sequence   = sequence.Val(context, false);
                    seqTypeInt = sequence == null ? -1 : sequence.GetBaseMiniscriptType();
                }
                //if (sequence is ValMap) {
                if (seqTypeInt == MiniscriptTypeInts.ValMapTypeInt)
                {
                    // If the map contains this identifier, return its value.
                    ValMap seqMap = sequence as ValMap;
                    Value  result = null;
                    var    idVal  = ValString.Create(identifier);
                    bool   found  = seqMap.TryGetValue(idVal, out result);
                    idVal.Unref();
                    if (found)
                    {
                        valueFoundIn = seqMap;
                        return(result);
                    }

                    // Otherwise, if we have an __isa, try that next.
                    if (loopsLeft < 0)
                    {
                        return(null);        // (unless we've hit the loop limit)
                    }
                    if (!seqMap.TryGetValue(ValString.magicIsA, out sequence))
                    {
                        // ...and if we don't have an __isa, try the generic map type if allowed
                        if (!includeMapType)
                        {
                            throw new KeyException(identifier);
                        }
                        sequence       = context.vm.mapType ?? Intrinsics.MapType();
                        includeMapType = false;
                    }
                    //} else if (sequence is ValList) {
                }
                else if (seqTypeInt == MiniscriptTypeInts.ValListTypeInt)
                {
                    sequence       = context.vm.listType ?? Intrinsics.ListType();
                    includeMapType = false;
                    //} else if (sequence is ValString) {
                }
                else if (seqTypeInt == MiniscriptTypeInts.ValStringTypeInt)
                {
                    sequence       = context.vm.stringType ?? Intrinsics.StringType();
                    includeMapType = false;
                    //} else if (sequence is ValNumber) {
                }
                else if (seqTypeInt == MiniscriptTypeInts.ValNumberTypeInt)
                {
                    sequence       = context.vm.numberType ?? Intrinsics.NumberType();
                    includeMapType = false;
                    //} else if (sequence is ValFunction) {
                }
                else if (seqTypeInt == MiniscriptTypeInts.ValFunctionTypeInt)
                {
                    sequence       = context.vm.functionType ?? Intrinsics.FunctionType();
                    includeMapType = false;
                }
                else if (seqTypeInt == MiniscriptTypeInts.ValCustomTypeInt)
                {
                    ValCustom custom = sequence as ValCustom;
                    if (custom.Resolve(identifier, out Value result))
                    {
                        //valueFoundIn
                        return(result);
                    }
                    return(null);
                }
                else
                {
                    throw new TypeException("Type Error (while attempting to look up " + identifier + ")");
                }
                loopsLeft--;
            }
            return(null);
        }