Ejemplo n.º 1
0
        /// <summary>Read and eval all the lines in a file</summary>
        internal static void Do(string file, IScope scope)
        {
            StreamReader stream = null;
            try
            {
                List<string> lines = new List<string>();
                stream = new StreamReader(file);
                while (!stream.EndOfStream)
                    lines.Add(stream.ReadLine());

                LineConsumer consumer = new LineConsumer(lines);
                EvalLines.Do(consumer, scope);
                stream.Close();
            }
            catch (Loki3Exception e)
            {
                e.AddFileName(file);
                if (stream != null)
                    stream.Close();
                throw e;
            }
            catch (System.Exception e)
            {
                if (stream != null)
                    stream.Close();
                throw e;
            }
        }
Ejemplo n.º 2
0
        public void TestComplex()
        {
            try
            {
                IScope scope = new ScopeChain(GetBootstrapScope());

                // define complex math
                string[] lines = {
                    // complex [ 1 2 ] -> 1+2i
                    ":complex v= func1 [ ->x ->y ]",
                    "	{ :real x :imaginary y }",
                    ":complex @order 1",
                    // 5 i -> 5i
                    ":i v= .( ->y 1func",
                    "	{ :real 0 :imaginary y }",
                    ":i @order 1",
                    // addition
                    // todo: adjust when we have function overloading & default values
                    ":+c v= .( { :real ->x1 :imaginary ->y1 } 1func1 { :real ->x2 :imaginary ->y2 }",
                    "	{ :real ( x1 + x2 ) :imaginary ( y1 + y2 ) }",
                    ":+i v= .( ->x1 1func1 { :real ->x2 :imaginary ->y2 }",
                    "	{ :real ( x1 + x2 ) :imaginary y2 }",
                };
                LineConsumer requestor = new LineConsumer(lines);
                EvalLines.Do(requestor, scope);

                {
                    Value value = TestSupport.ToValue("complex [ 1 2 ]", scope);
                    Assert.AreEqual("{ :real 1 , :imaginary 2 }", value.ToString());
                }

                {
                    Value value = TestSupport.ToValue("4 i", scope);
                    Assert.AreEqual("{ :real 0 , :imaginary 4 }", value.ToString());
                }

                {
                    Value value = TestSupport.ToValue("1 +i 3 i", scope);
                    Assert.AreEqual("{ :real 1 , :imaginary 3 }", value.ToString());
                }

                {
                    Value value = TestSupport.ToValue("( 1 +i 3 i ) +c complex [ 4 6 ]", scope);
                    Assert.AreEqual("{ :real 5 , :imaginary 9 }", value.ToString());
                }
            }
            catch (Loki3Exception e)
            {
                Assert.Fail(e.ToString());
            }
        }
Ejemplo n.º 3
0
            internal override Value Eval(Value arg, IScope scope)
            {
                Map map = arg.AsMap;

                Value collection = map["collection"];
                // todo: consolidate these bodies, one from an explicit param & one from the following lines
                Value valueBody = map.ContainsKey("body") ? map["body"] : map[ValueFunction.keyBody];

                IScope bodyScope = scope;
                if (valueBody is ValueRaw)
                {
                    IScope tempScope = (valueBody as ValueRaw).Scope;
                    if (tempScope != null)
                        bodyScope = tempScope;
                }

                // todo: abstract iteration to avoid these ifs
                Value result = ValueNil.Nil;
                if (collection is ValueString)
                {
                    string s = collection.AsString;
                    foreach (char c in s)
                    {
                        IScope local = new ScopeChain(bodyScope);
                        PatternAssign assign = new PatternAssign(map, local, true/*bCreate*/);
                        assign.Assign(new ValueString(c.ToString()));
                        result = EvalBody.Do(valueBody, local);
                        local.Exit();
                    }
                }
                else if (collection is ValueArray)
                {
                    List<Value> list = collection.AsArray;
                    foreach (Value v in list)
                    {
                        IScope local = new ScopeChain(bodyScope);
                        PatternAssign assign = new PatternAssign(map, local, true/*bCreate*/);
                        assign.Assign(v);
                        result = EvalBody.Do(valueBody, local);
                        local.Exit();
                    }
                }
                else if (collection is ValueMap)
                {
                    Dictionary<string, Value> dict = collection.AsMap.Raw;
                    foreach (string key in dict.Keys)
                    {
                        List<Value> list = new List<Value>();
                        list.Add(new ValueString(key));
                        list.Add(dict[key]);

                        IScope local = new ScopeChain(bodyScope);
                        PatternAssign assign = new PatternAssign(map, local, true/*bCreate*/);
                        assign.Assign(new ValueArray(list));
                        result = EvalBody.Do(valueBody, local);
                        local.Exit();
                    }
                }
                else if (collection is ValueLine)
                {
                    List<DelimiterList> list = collection.AsLine;

                    // if delimiter is specified, wrap each line w/ it
                    ValueDelimiter delim = scope.GetValue(new Token(map["delim"].AsString)) as ValueDelimiter;
                    if (delim != null)
                    {
                        List<DelimiterList> delimList = new List<DelimiterList>();
                        int indent = (list.Count > 0 ? list[0].Indent : 0);
                        foreach (DelimiterList line in list)
                        {
                            DelimiterList newLine = line;
                            // wrap lines & nested lines with proper delimiter, except for nested values that get evaled
                            if (line.Indent == indent || (delim.DelimiterType != DelimiterType.AsValue && line.Indent >= indent))
                            {
                                List<DelimiterNode> nodes = new List<DelimiterNode>();
                                string original = line.Original;
                                if (delim.DelimiterType == DelimiterType.AsString && line.Indent > indent)
                                {	// put the indentation back if portions of the body were indented
                                    original = "";
                                    for (int i = 0; i < line.Indent - indent; i++)
                                        original += "    ";
                                    original += line.Original;
                                }
                                nodes.Add(new DelimiterNodeList(new DelimiterList(delim, line.Nodes, line.Indent, "", original, line.Scope)));
                                newLine = new DelimiterList(delim, nodes, indent, "", original, line.Scope);
                            }
                            delimList.Add(newLine);
                        }
                        list = delimList;
                    }

                    // for each line, eval it then eval the body
                    ILineRequestor lines = new LineConsumer(list);
                    while (lines.HasCurrent())
                    {
                        IScope local = new ScopeChain(bodyScope);
                        Value value = EvalLines.DoOne(lines, local);
                        PatternAssign assign = new PatternAssign(map, local, true/*bCreate*/);
                        assign.Assign(value);
                        result = EvalBody.Do(valueBody, local);
                        local.Exit();
                    }
                }
                return result;
            }
Ejemplo n.º 4
0
        public void TestParamMetadata()
        {
            try
            {
                IScope scope = new ScopeChain(GetBootstrapScope());

                string[] lines = {
                    ":addUp v= func1 [ ( ->a : :int ) ( ->b d= 5 ) ]",
                    "	a + b",
                };
                LineConsumer requestor = new LineConsumer(lines);
                EvalLines.Do(requestor, scope);

                {	// pass expected parameters
                    Value value = TestSupport.ToValue("addUp [ 1 2 ]", scope);
                    Assert.AreEqual(3, value.AsInt);
                }

                {	// leave off 2nd, use default
                    Value value = TestSupport.ToValue("addUp [ 1 ]", scope);
                    Assert.AreEqual(6, value.AsInt);
                }

                // it throws if we pass wrong type
                bool bThrew = false;
                try
                {
                    TestSupport.ToValue("addUp [ true 1 ]", scope);
                }
                catch (Loki3Exception)
                {
                    bThrew = true;
                }
                Assert.IsTrue(bThrew);
            }
            catch (Loki3Exception e)
            {
                Assert.Fail(e.ToString());
            }
        }
Ejemplo n.º 5
0
        public void TestNested()
        {
            try
            {
                IScope scope = new ScopeChain(GetBootstrapScope());

                string[] lines = {
                    ":result v= 0",
                    "if flag1?",
                    "	if flag2?",
                    "		:result = 1",
                    "	else",
                    "		:result = 2",
                    "else",
                    "	if flag3?",
                    "		:result = 3",
                    "	else",
                    "		:result = 4",
                };

                {	// nested if block is run
                    scope.SetValue("flag1?", ValueBool.True);
                    scope.SetValue("flag2?", ValueBool.True);
                    LineConsumer requestor = new LineConsumer(lines);
                    EvalLines.Do(requestor, scope);
                    Assert.AreEqual(1, scope.GetValue(new Token("result")).AsInt);
                }

                {	// nested else is run
                    scope.SetValue("flag1?", ValueBool.True);
                    scope.SetValue("flag2?", ValueBool.False);
                    LineConsumer requestor = new LineConsumer(lines);
                    EvalLines.Do(requestor, scope);
                    Assert.AreEqual(2, scope.GetValue(new Token("result")).AsInt);
                }

                {	// top level else block is run, nested if
                    scope.SetValue("flag1?", ValueBool.False);
                    scope.SetValue("flag3?", ValueBool.True);
                    LineConsumer requestor = new LineConsumer(lines);
                    EvalLines.Do(requestor, scope);
                    Assert.AreEqual(3, scope.GetValue(new Token("result")).AsInt);
                }

                {	// top level else block is run, nested else
                    scope.SetValue("flag1?", ValueBool.False);
                    scope.SetValue("flag3?", ValueBool.False);
                    LineConsumer requestor = new LineConsumer(lines);
                    EvalLines.Do(requestor, scope);
                    Assert.AreEqual(4, scope.GetValue(new Token("result")).AsInt);
                }
            }
            catch (Loki3Exception e)
            {
                Assert.Fail(e.ToString());
            }
        }
Ejemplo n.º 6
0
        public void TestLoop()
        {
            try
            {
                IScope scope = new ScopeChain(GetBootstrapScope());

                {	// l3.loop
                    string[] lines = {
                        ":total v= 0",
                        ":i v= 0",
                        "l3.loop .{ :check .` i !=? 5",
                        "	:i = i + 1",
                        "	:total = total + i",
                    };
                    LineConsumer requestor = new LineConsumer(lines);
                    Value result = EvalLines.Do(requestor, scope);
                    Assert.AreEqual(15, result.AsInt);
                }
            }
            catch (Loki3Exception e)
            {
                Assert.Fail(e.ToString());
            }
        }
Ejemplo n.º 7
0
        public void TestGetFunctionBody()
        {
            IScope scope = CreateValueScope();

            {	// built-in function doesn't have a body
                Value value = TestSupport.ToValue("l3.getFunctionBody { :key :l3.getFunctionBody }", scope);
                Assert.IsTrue(value.IsNil);
            }

            {	// get user defined function body
                string[] lines = {
                    "l3.setValue { :key :v= :value ( l3.createFunction { :pre ->key :post ->value :order 5 :body [ ` l3.setValue { :key key :value value :level 1 :create? true } ` ] } ) }",
                    ":myFunc v= l3.createFunction { :post ->a }",
                    "	some code",
                    "	more code",
                };
                LineConsumer requestor = new LineConsumer(lines);
                EvalLines.Do(requestor, scope);

                Value value = TestSupport.ToValue("l3.getFunctionBody { :key :myFunc }", scope);
                Assert.AreEqual(2, value.Count);

                value = TestSupport.ToValue("l3.getFunctionBody { :function ( myFunc ) }", scope);
                Assert.AreEqual(2, value.Count);
            }
        }
Ejemplo n.º 8
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 != "");
        }