Ejemplo n.º 1
0
        /// <summary>
        /// Look up a value in this dictionary, walking the __isa chain to find
        /// it in a parent object if necessary; return both the value found an
        /// (via the output parameter) the map it was found in.
        /// </summary>
        /// <param name="key">key to search for</param>
        /// <returns>value associated with that key, or null if not found</returns>
        public Value Lookup(Value key, out ValMap valueFoundIn)
        {
            if (key == null)
            {
                key = ValNull.instance;
            }
            Value  result = null;
            ValMap obj    = this;

            while (obj != null)
            {
                if (obj.TryGetValue(key, out result))
                {
                    valueFoundIn = obj;
                    return(result);
                }
                Value parent;
                if (!obj.TryGetValue(ValString.magicIsA, out parent))
                {
                    break;
                }
                obj = parent as ValMap;
            }
            valueFoundIn = null;
            return(null);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Get the value of a local variable ONLY -- does not check any other
        /// scopes, nor check for special built-in identifiers like "globals".
        /// Used mainly by host apps to easily look up an argument to an
        /// intrinsic function call by the parameter name.
        /// </summary>
        public Value GetLocal(string identifier, Value defaultValue = null)
        {
            Value result;

            if (variables != null && variables.TryGetValue(identifier, out result))
            {
                return(result);
            }
            return(defaultValue);
        }
Ejemplo n.º 3
0
            /// <summary>
            /// Get the value of a variable available in this context (including
            /// locals, globals, and intrinsics).  Raise an exception if no such
            /// identifier can be found.
            /// </summary>
            /// <param name="identifier">name of identifier to look up</param>
            /// <returns>value of that identifier</returns>
            public Value GetVar(string identifier)
            {
                // check for special built-in identifiers 'locals' and 'globals'
                if (identifier == "locals")
                {
                    if (variables == null)
                    {
                        variables = new ValMap();
                    }
                    return(variables);
                }
                if (identifier == "globals")
                {
                    if (root.variables == null)
                    {
                        root.variables = new ValMap();
                    }
                    return(root.variables);
                }

                // check for a local variable
                Value result;

                if (variables != null && variables.TryGetValue(identifier, out result))
                {
                    return(result);
                }

                // OK, we don't have a local variable with that name.
                // Check higher scopes.
                Context c = parent;

                while (c != null)
                {
                    if (c.variables != null && c.variables.ContainsKey(identifier))
                    {
                        return(c.variables[identifier]);
                    }
                    c = c.parent;
                }

                // Finally, check intrinsics.
                Intrinsic intrinsic = Intrinsic.GetByName(identifier);

                if (intrinsic != null)
                {
                    return(intrinsic.GetFunc());
                }

                // No luck there either?  Undefined identifier.
                throw new UndefinedIdentifierException(identifier);
            }
Ejemplo n.º 4
0
        /// <summary>
        /// Get the value of a variable available in this context (including
        /// locals, globals, and intrinsics).  Raise an exception if no such
        /// identifier can be found.
        /// </summary>
        /// <param name="identifier">name of identifier to look up</param>
        /// <returns>value of that identifier</returns>
        public Value GetVar(string identifier)
        {
            // check for special built-in identifiers 'locals' and 'globals'
            if (identifier == "locals")
            {
                if (variables == null)
                {
                    variables = ValMap.Create();
                }
                return(variables);
            }
            if (identifier == "globals")
            {
                if (root.variables == null)
                {
                    root.variables = ValMap.Create();
                }
                return(root.variables);
            }
            if (identifier == "outer")
            {
                // return module variables, if we have them; else globals
                if (outerVars != null)
                {
                    return(outerVars);
                }
                if (root.variables == null)
                {
                    root.variables = ValMap.Create();
                }
                return(root.variables);
            }

            // check for a local variable
            Value result;

            if (variables != null && variables.TryGetValue(identifier, out result))
            {
                return(result);
            }

            // check for a module variable
            if (outerVars != null && outerVars.TryGetValue(identifier, out result))
            {
                return(result);
            }

            // OK, we don't have a local or module variable with that name.
            // Check the global scope (if that's not us already).
            if (parent != null)
            {
                Context globals = root;
                if (globals.variables != null && globals.variables.ContainsKey(identifier))
                {
                    return(globals.variables[identifier]);
                }
            }

            // Finally, check intrinsics.
            Intrinsic intrinsic = Intrinsic.GetByName(identifier);

            if (intrinsic != null)
            {
                return(intrinsic.GetFunc());
            }

            // No luck there either?  Undefined identifier.
            throw new UndefinedIdentifierException(identifier);
        }
Ejemplo n.º 5
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);
        }