예제 #1
0
        /**
         * @brief Add new variable to the dictionary.
         */
        public bool AddEntry(TokenDeclVar var)
        {
            if (isFrozen)
            {
                throw new Exception("var dict is frozen");
            }

            // Make sure we have a sub-dictionary based on the bare name (ie, no signature)
            Dictionary <ArgTypes, TDVEntry> typedic;

            if (!master.TryGetValue(var.name.val, out typedic))
            {
                typedic = new Dictionary <ArgTypes, TDVEntry>();
                master.Add(var.name.val, typedic);
            }

            // See if there is an entry in the sub-dictionary that matches the argument signature.
            // Note that fields have null argument lists.
            // Methods always have a non-null argument list, even if only 0 entries long.
            ArgTypes types;

            types.argTypes = (var.argDecl == null) ? null : KeyTypesToStringTypes(var.argDecl.types);
            if (typedic.ContainsKey(types))
            {
                return(false);
            }

            // It is unique, add to its name-specific sub-dictionary.
            TDVEntry entry;

            entry.count = ++count;
            entry.var   = var;
            typedic.Add(types, entry);
            return(true);
        }
예제 #2
0
        public TokenDeclVar[] FindCallables(string name, TokenType[] argTypes)
        {
            argTypes = KeyTypesToStringTypes(argTypes);
            TokenDeclVar var = FindExact(name, argTypes);

            if (var != null)
            {
                return new TokenDeclVar[] { var }
            }
            ;

            Dictionary <ArgTypes, TDVEntry> typedic;

            if (!master.TryGetValue(name, out typedic))
            {
                return(null);
            }

            found.Clear();
            foreach (KeyValuePair <ArgTypes, TDVEntry> kvp in typedic)
            {
                if ((kvp.Value.count <= this.count) && kvp.Key.CanBeCalledBy(argTypes))
                {
                    found.Add(kvp.Value.var);
                }
            }
            return((found.Count > 0) ? found.ToArray() : null);
        }
예제 #3
0
        /**
         * @brief build dictionary of internal functions from an interface.
         * @param iface = interface with function definitions
         * @param inclSig = true: catalog by name with arg sig, eg, llSay(integer,string)
         *                 false: catalog by simple name only, eg, state_entry
         * @returns dictionary of function definition tokens
         */
        public InternalFuncDict(Type iface, bool inclSig)
            : base(false)
        {
            /*
             * Loop through list of all methods declared in the interface.
             */
            System.Reflection.MethodInfo[] ifaceMethods = iface.GetMethods();
            foreach (System.Reflection.MethodInfo ifaceMethod in ifaceMethods)
            {
                string key = ifaceMethod.Name;

                /*
                 * Only do ones that begin with lower-case letters...
                 * as any others can't be referenced by scripts
                 */
                if ((key[0] < 'a') || (key[0] > 'z'))
                {
                    continue;
                }

                try {
                    /*
                     * Create a corresponding TokenDeclVar struct.
                     */
                    System.Reflection.ParameterInfo[] parameters = ifaceMethod.GetParameters();
                    TokenArgDecl argDecl = new TokenArgDecl(null);
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        System.Reflection.ParameterInfo param = parameters[i];
                        TokenType type = TokenType.FromSysType(null, param.ParameterType);
                        TokenName name = new TokenName(null, param.Name);
                        argDecl.AddArg(type, name);
                    }
                    TokenDeclVar declFunc = new TokenDeclVar(null, null, null);
                    declFunc.name    = new TokenName(null, key);
                    declFunc.retType = TokenType.FromSysType(null, ifaceMethod.ReturnType);
                    declFunc.argDecl = argDecl;

                    /*
                     * Add the TokenDeclVar struct to the dictionary.
                     */
                    this.AddEntry(declFunc);
                } catch (Exception except) {
                    string msg = except.ToString();
                    int    i   = msg.IndexOf("\n");
                    if (i > 0)
                    {
                        msg = msg.Substring(0, i);
                    }
                    Console.WriteLine("InternalFuncDict*: {0}:     {1}", key, msg);

                    ///??? IGNORE ANY THAT FAIL - LIKE UNRECOGNIZED TYPE ???///
                }
            }
        }
예제 #4
0
        /**
         * @brief Find exact matching function/variable
         * @param name = name of function to look for
         * @param argTypes = argument types the function was declared with
         *                   null to look for a variable
         * @returns null: no matching function/variable found
         *          else: the matching function/variable
         */
        public TokenDeclVar FindExact(string name, TokenType[] argTypes)
        {
            // Look for list of stuff that matches the given name.
            Dictionary <ArgTypes, TDVEntry> typedic;

            if (!master.TryGetValue(name, out typedic))
            {
                return(null);
            }

            // Loop through all fields/methods declared by that name, regardless of arg signature.
            foreach (TDVEntry entry in typedic.Values)
            {
                if (entry.count > this.count)
                {
                    continue;
                }
                TokenDeclVar var = entry.var;

                // Get argument types of declaration.
                //   fields are always null
                //   methods are always non-null, though may be zero-length
                TokenType[] declArgs = (var.argDecl == null) ? null : var.argDecl.types;

                // Convert any key args to string args.
                declArgs = KeyTypesToStringTypes(declArgs);

                // If both are null, they are signature-less (ie, both are fields), and so match.
                if ((declArgs == null) && (argTypes == null))
                {
                    return(var);
                }

                // If calling a delegate, it is a match, regardless of delegate arg types.
                // If it turns out the arg types do not match, the compiler will give an error
                // trying to cast the arguments to the delegate arg types.
                // We don't allow overloading same field name with different delegate types.
                if ((declArgs == null) && (argTypes != null))
                {
                    TokenType fieldType = var.type;
                    if (fieldType is TokenTypeSDTypeDelegate)
                    {
                        return(var);
                    }
                }

                // If not both null, no match, keep looking.
                if ((declArgs == null) || (argTypes == null))
                {
                    continue;
                }

                // Both not null, match argument types to make sure we have correct overload.
                int i = declArgs.Length;
                if (i != argTypes.Length)
                {
                    continue;
                }
                while (--i >= 0)
                {
                    string da = declArgs[i].ToString();
                    string ga = argTypes[i].ToString();
                    if (da == "key")
                    {
                        da = "string";
                    }
                    if (ga == "key")
                    {
                        ga = "string";
                    }
                    if (da != ga)
                    {
                        break;
                    }
                }
                if (i < 0)
                {
                    return(var);
                }
            }

            // No match.
            return(null);
        }