Exemple #1
0
        /// <summary>
        /// If bCreate, always set value on current scope,
        /// else, change value on scope value exists on or throw exception if it doesn't exist
        /// </summary>
        /// <returns>true if it actually set a value</returns>
        internal static bool SetOnScope(IScope scope, string key, Value value, bool bCreate, bool bOverload, bool bInitOnly)
        {
            // figure out the scope to modify
            IScope where;
            if (bCreate)
            {
                where = scope;
            }
            else
            {
                where = scope.Exists(key);
                if (where == null)
                    throw new Loki3Exception().AddBadToken(new Token(key));
            }

            // if we're setting a function, it may be an overload
            if (bOverload && value.Type == ValueType.Function)
            {
                // first, if there's nothing there, see if key exists on an ancestor scope
                bool bFound = where.AsMap.ContainsKey(key);
                if (!bFound)
                {
                    IScope ancestor = scope.Exists(key);
                    if (ancestor != null)
                    {
                        Value existing = ancestor.AsMap[key];
                        if (existing.Type == ValueType.Function)
                        {	// copy function(s) to this scope so we can overload it
                            // and yet this definition only exists in this scope
                            Value copiedToThisScope = existing.Copy();
                            where.SetValue(key, copiedToThisScope);
                            bFound = true;
                        }
                    }
                }

                if (bFound)
                {
                    Value existing = where.AsMap[key];
                    ValueFunctionOverload overload = null;
                    if (existing.Type == ValueType.Function)
                    {	// change function value into an overload value
                        overload = existing as ValueFunctionOverload;
                        if (overload == null)
                        {
                            overload = new ValueFunctionOverload(existing as ValueFunction);
                            overload.Add(value as ValueFunction);
                            where.SetValue(key, overload);
                        }
                        else
                        {
                            overload.Add(value as ValueFunction);
                        }
                        return true;
                    }
                }
            }

            if (bInitOnly && where.AsMap.ContainsKey(key))
                return false;
            where.SetValue(key, value);
            return true;
        }
Exemple #2
0
            internal override Value Eval(Value arg, IScope scope)
            {
                Map map = arg.AsMap;

                // get parameter
                Value value = map["function"];
                if (value.IsNil)
                {
                    Value valueKey = map["key"];
                    if (!valueKey.IsNil)
                    {
                        string key = valueKey.AsString;
                        IScope container = scope.Exists(key);
                        if (container == null)
                            throw new Loki3Exception().AddMissingKey(map["key"]);
                        value = container.GetValue(new Token(key));
                    }
                }
                if (value.IsNil)
                    throw new Loki3Exception().AddMissingKey(new ValueString("function"));

                // fetch body of function
                ValueFunction function = value as ValueFunction;
                if (function == null)
                    throw new Loki3Exception().AddWrongType(ValueType.Function, value.Type);
                List<DelimiterList> body = function.GetBody(scope);
                if (body == null)
                    return ValueNil.Nil;

                // make an array
                List<Value> array = new List<Value>();
                foreach (DelimiterList line in body)
                {	// attach scope to the value, preferring the lines's scope
                    // & falling back to the function's scope if not present
                    IScope rawScope = (line.Scope != null ? line.Scope : scope);
                    array.Add(new ValueRaw(line, rawScope));
                }
                return new ValueArray(array);
            }
Exemple #3
0
        /// <summary>
        /// Start a read-eval-print loop at the console
        /// </summary>
        /// <param name="scope">scope for parse-eval</param>
        internal static void Do(IScope scope, string prompt)
        {
            prompt += " ";
            string s = "";
            do
            {
                Console.Write(prompt);

                // keep reading lines as long as they end with \
                List<string> lines = new List<string>();
                bool bMore = false;
                do
                {
                    s = Console.ReadLine();
                    bMore = (s.Length > 2 && s[s.Length - 1] == '\\' && s[s.Length - 2] == ' ');
                    if (bMore)
                        s = s.Substring(0, s.Length - 2);
                    lines.Add(s);
                } while (bMore);
                LineConsumer consumer = new LineConsumer(lines);

                // eval the line(s)
                try
                {
                    Value v = EvalLines.Do(consumer, scope);
                    Console.WriteLine(v.ToString());
                }
                catch (Loki3Exception error)
                {
                    // if we're at the root scope, remove it to avoid infinite
                    // recursion in Map.ToString
                    if (error.Errors.ContainsKey("l3.error.scope"))
                        if (error.Errors["l3.error.scope"].AsMap == scope.AsMap)
                            error.Errors.Raw.Remove("l3.error.scope");

                    if (scope.Exists("prettify") != null)
                    {
                        scope.SetValue("lastError", new ValueMap(error.Errors));
                        Value v = loki3.builtin.test.TestSupport.ToValue("prettify lastError", scope);
                        Console.WriteLine("LOKI3 ERROR:\n" + v.AsString);
                        if (error.Errors.ContainsKey(Loki3Exception.keyScope))
                        {
                            scope.SetValue("lastScope", error.Errors[Loki3Exception.keyScope]);
                            try
                            {
                                v = loki3.builtin.test.TestSupport.ToValue("dumpStack lastScope", scope);
                                Console.WriteLine("STACK:\n" + v.AsString);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("ERROR PRINTING STACK:\n" + e.ToString());
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine(error.ToString());
                    }
                }
                catch (Exception error)
                {
                    Console.WriteLine("INTERNAL ERROR: " + error.ToString());
                }
            } while (s != "");
        }