コード例 #1
0
        /// <summary>
        /// Resolves the given element in this scope.
        /// </summary>
        /// <param name="elem">The element.</param>
        /// <param name="isFirst">Is the element the first one in the list.</param>
        /// <returns>Resolved value or null</returns>
        public object ResolveInScopes(object elem, bool isFirst)
        {
            object result;

            // try to access the cached function value (speed optimization)
            LispVariant elemAsVariant = elem as LispVariant;

            if (elemAsVariant != null && elemAsVariant.CachedFunction != null)
            {
                return(elemAsVariant.CachedFunction);
            }

            var       name = elem.ToString();
            LispScope foundClosureScope;

            // first try to resolve in this scope
            if (TryGetValue(name, out result))
            {
                UpdateFunctionCache(elemAsVariant, result, isFirst);
            }
            // then try to resolve in global scope
            else if (GlobalScope != null &&
                     GlobalScope.TryGetValue(name, out result))
            {
                UpdateFunctionCache(elemAsVariant, result, isFirst);
            }
            // then try to resolve in closure chain scope(s)
            else if (IsInClosureChain(name, out foundClosureScope, out result))
            {
                UpdateFunctionCache(elemAsVariant, result, isFirst);
            }
            // then try to resolve in scope of loaded modules
            else if (LispEnvironment.IsInModules(name, GlobalScope))
            {
                result = LispEnvironment.GetFunctionInModules(name, GlobalScope);
            }
            else
            {
                // activate this code if symbols must be resolved in parameter evaluation --> (println blub)
                //if (elemAsVariant != null && elemAsVariant.IsSymbol && name != "fuellib")
                //{
                //    throw new LispException($"Could not resolve symbol {name}");
                //}
                result = elem;
            }

            return(result);
        }