Beispiel #1
0
        static IScope CreateScope()
        {
            ScopeChain scope = new ScopeChain();
            Conditional.Register(scope);

            scope.SetValue("[", new ValueDelimiter("]", DelimiterType.AsArray));
            scope.SetValue("'", new ValueDelimiter("'", DelimiterType.AsString));

            return scope;
        }
Beispiel #2
0
        static IScope CreateValueScope()
        {
            ScopeChain scope = new ScopeChain();
            Logic.Register(scope);

            scope.SetValue("[", new ValueDelimiter("]", DelimiterType.AsArray));
            scope.SetValue("`", new ValueDelimiter("`", DelimiterType.AsRaw));

            return scope;
        }
Beispiel #3
0
        static IScope CreateModuleScope()
        {
            ScopeChain scope = new ScopeChain();
            Module.Register(scope);
            Values.Register(scope);

            scope.SetValue("'", new ValueDelimiter("'", DelimiterType.AsString));
            scope.SetValue("{", new ValueDelimiter("}", DelimiterType.AsArray, new CreateMap()));

            return scope;
        }
Beispiel #4
0
        static IScope CreateStringScope()
        {
            ScopeChain scope = new ScopeChain();
            String.Register(scope);

            ValueDelimiter square = new ValueDelimiter("]", DelimiterType.AsArray);
            scope.SetValue("[", square);
            ValueDelimiter str = new ValueDelimiter("'", DelimiterType.AsString);
            scope.SetValue("'", str);
            ValueDelimiter curly = new ValueDelimiter("}", DelimiterType.AsArray, new CreateMap());
            scope.SetValue("{", curly);

            return scope;
        }
Beispiel #5
0
        public void TestBindFunction()
        {
            IScope scope = CreateValueScope();
            // a scope with a value for a
            IScope scopeA = new ScopeChain(scope);
            scopeA.SetValue("a", new ValueInt(3));

            // create a new function that returns a & is bound to a map where a=42
            TestSupport.ToValue("l3.setValue { :key :testBound :value ( l3.bindFunction { :function ( l3.createFunction { :post :x :body [ ' a ' ] } ) :map { :a 42 } } ) }", scope);
            // then eval it against a scope where a!=42
            Value value = TestSupport.ToValue("testBound 1", scopeA);
            Assert.AreEqual(42, value.AsInt);
            value = TestSupport.ToValue("a", scopeA);
            Assert.AreEqual(3, value.AsInt);
        }
Beispiel #6
0
            internal override Value Eval(DelimiterNode prev, DelimiterNode next, IScope paramScope, IScope bodyScope, INodeRequestor nodes, ILineRequestor requestor)
            {
                // if we need prev or next params but they're not there, simply return the function
                if ((m_usePrevious || m_useNext) && prev == null && next == null)
                    return this;

                // scope we'll add prev/next/body params to
                ScopeChain localScope = new ScopeChain();

                if (m_usePrevious)
                {
                    if (prev == null)
                    {
                        if (m_useNext)
                            return new PartialFunctionIn(this, null, next);
                        throw new Loki3Exception().AddMissingValue(true/*bPrevious*/);
                    }

                    Value value1 = ComputeParam(Metadata[keyPreviousPattern], prev, paramScope, nodes, requestor);
                    Value match, leftover;
                    if (!PatternChecker.Do(value1, Metadata[keyPreviousPattern], false/*bShortPat*/, out match, out leftover))
                        throw new Loki3Exception().AddWrongPattern(Metadata[keyPreviousPattern], value1);

                    if (leftover != null)
                    {
                        if (m_useNext)
                            // currently can't do partials for infix
                            throw new Loki3Exception().AddWrongPattern(Metadata[keyPreviousPattern], value1);
                        // create a partial function that starts w/ match & still needs leftover
                        return new UserFunction(this, match, leftover, null);
                    }

                    Utility.AddToScope(m_pattern1, match, localScope);
                }
                if (m_useNext)
                {
                    if (next == null)
                    {
                        if (m_usePrevious)
                            return new PartialFunctionIn(this, prev, null);
                        throw new Loki3Exception().AddMissingValue(false/*bPrevious*/);
                    }

                    Value value2 = ComputeParam(Metadata[keyNextPattern], next, paramScope, nodes, requestor);
                    Value match, leftover;
                    if (!PatternChecker.Do(value2, Metadata[keyNextPattern], false/*bShortPat*/, out match, out leftover))
                        throw new Loki3Exception().AddWrongPattern(Metadata[keyNextPattern], value2);

                    // if we created a function that needs a body, add it if present
                    ValueFunction matchFunc = match as ValueFunction;
                    if (matchFunc != null && matchFunc.RequiresBody() && requestor != null)
                        match = EvalList.DoAddBody(matchFunc, bodyScope, requestor);

                    if (leftover != null)
                    {
                        if (m_usePrevious)
                            // currently can't do partials for infix
                            throw new Loki3Exception().AddWrongPattern(Metadata[keyNextPattern], value2);
                        // create a partial function that starts w/ match & still needs leftover
                        return new UserFunction(this, match, null, leftover);
                    }

                    Utility.AddToScope(m_pattern2, match, localScope);
                }

                // tack on body if requested
                if (Metadata.GetOptionalT<bool>("body?", false))
                {
                    bool foundBody = false;

                    // if there's a following node, use it
                    DelimiterNode possibleBody = nodes.GetNext();
                    if (possibleBody != null)
                    {
                        localScope.SetValue("body", UseNodeAsBody(possibleBody));
                        foundBody = true;
                    }

                    // if no body, use the following lines
                    if (!foundBody && requestor != null)
                    {
                        List<DelimiterList> body = EvalList.DoGetBody(bodyScope, requestor);
                        if (body.Count != 0)
                        {
                            localScope.SetValue("body", new ValueLine(body, bodyScope));
                            foundBody = true;
                        }
                    }

                    if (!foundBody)
                        // create a partial function that only needs a body
                        return new UserFunction(this, localScope);
                }

                // create a new scope and add passed in arguments...
                ScopeChain scope = (ShouldCreateScope ? new ScopeChain(bodyScope) : bodyScope as ScopeChain);
                scope.Function = this;
                if (m_fullPattern != null && m_passed != null)
                    Utility.AddToScope(m_fullPattern, m_passed, scope);
                // ...and the prev/next/body params we just extracted
                Utility.AddToScope(localScope, scope);
                if (m_passedScope != null)
                    Utility.AddToScope(m_passedScope, scope);

                // lazily parse
                EnsureParsed(bodyScope);

                // eval each line using current scope
                try
                {
                    Value retval = EvalBody.Do(m_parsedLines, scope);
                    scope.Exit();
                    return retval;
                }
                catch (PopStackException pop)
                {	// if we're supposed to pop back to here then return, else keep throwing up the stack
                    if (pop.ScopeName == scope.Name)
                        return pop.Return;
                    throw pop;
                }
                catch (Loki3Exception e)
                {	// if this scope catches exceptions, stop here
                    if (Loki3Exception.catchScopeName == scope.Name)
                    {
                        if (scope.Parent != null)
                            scope.Parent.SetValue(Loki3Exception.exceptionKey, new ValueMap(e.Errors));
                        return ValueNil.Nil;
                    }
                    throw e;
                }
            }
Beispiel #7
0
        static IScope CreateMathScope()
        {
            ScopeChain scope = new ScopeChain();
            Math.Register(scope);

            ValueDelimiter square = new ValueDelimiter("]", DelimiterType.AsArray);
            scope.SetValue("[", square);

            return scope;
        }
Beispiel #8
0
        static IScope CreateScope()
        {
            ScopeChain scope = new ScopeChain();
            MapFunctions.Register(scope);
            scope.SetValue("create-map", new CreateMap());

            scope.SetValue("[", new ValueDelimiter("]", DelimiterType.AsArray));
            scope.SetValue("{", new ValueDelimiter("}", DelimiterType.AsArray, new CreateMap()));
            return scope;
        }
Beispiel #9
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());
            }
        }
Beispiel #10
0
        static IScope CreateValueScope()
        {
            ScopeChain scope = new ScopeChain();
            Values.Register(scope);

            scope.SetValue("(", new ValueDelimiter(")", DelimiterType.AsValue));
            scope.SetValue("[", new ValueDelimiter("]", DelimiterType.AsArray));
            scope.SetValue("'", new ValueDelimiter("'", DelimiterType.AsString));
            scope.SetValue("{", new ValueDelimiter("}", DelimiterType.AsArray, new CreateMap()));
            scope.SetValue("`", new ValueDelimiter("`", DelimiterType.AsRaw));

            return scope;
        }