/** * @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); }
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); }
/** * @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 ???/// } } }
/** * @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); }