Пример #1
0
        /// <summary>
        /// Evaluates a token, possibly requesting the previous and next values.
        /// Returns a value.
        /// </summary>
        /// <param name="token">token representing a function or variable</param>
        /// <param name="scope">used to request functions, variables, and delimiters if there's no scope attached to the node</param>
        /// <param name="nodes">used to request previous and next nodes</param>
        internal static Value Do(DelimiterNode node, IScope scope, INodeRequestor nodes, ILineRequestor requestor)
        {
            if (node.Value != null)
            {	// node has already been evaluated
                return node.Value;
            }
            else if (node.Token != null)
            {	// function/variable or built-in
                Token token = node.Token;
                Value value = scope.GetValue(token);
                if (value is ValueFunction && nodes != null)
                {
                    ValueFunction function = value as ValueFunction;
                    // get previous & next nodes if needed
                    DelimiterNode previous = (function.ConsumesPrevious ? nodes.GetPrevious() : null);
                    DelimiterNode next = (function.ConsumesNext ? nodes.GetNext() : null);

                    scope.FunctionName = token.Value;

                    // evaluate
                    try
                    {
                        return function.Eval(previous, next, scope, scope, nodes, requestor);
                    }
                    catch (Loki3Exception e)
                    {	// this function is the correct context if there isn't already one there
                        if (!e.Errors.ContainsKey(Loki3Exception.keyFunction))
                            e.AddFunction(token.Value);
                        if (!e.Errors.ContainsKey(Loki3Exception.keyScope))
                            e.AddScope(scope);
                        throw e;
                    }
                }
                else if (value != null)
                {
                    return value;
                }
                else
                {
                    return EvalBuiltin.Do(token);
                }
            }
            else if (node.List != null)
            {	// delimited list of nodes
                Value value = null;
                DelimiterList list = node.List;
                IScope listScope = (list.Scope != null ? list.Scope : scope);
                DelimiterType type = list.Delimiter.DelimiterType;

                // get contents as a Value
                switch (type)
                {
                    case DelimiterType.AsString:
                        value = new ValueString(list.Original);
                        break;
                    case DelimiterType.AsValue:
                        value = EvalList.Do(list.Nodes, listScope);
                        break;
                    case DelimiterType.AsArray:
                        List<Value> values = new List<Value>(list.Nodes.Count);
                        foreach (DelimiterNode subnode in list.Nodes)
                        {	// note: 'nodes' is null so functions don't get evaled
                            Value subvalue = Do(subnode, listScope, null, requestor);
                            values.Add(subvalue);
                        }
                        value = new ValueArray(values);
                        break;
                    case DelimiterType.AsEvaledArray:
                        value = EvalList.DoEvaledArray(list.Nodes, listScope);
                        break;
                    case DelimiterType.AsRaw:
                        value = new ValueRaw(list, listScope);
                        break;
                    case DelimiterType.AsArrayOfRaw:
                        List<Value> rawvalues = new List<Value>(list.Nodes.Count);
                        foreach (DelimiterNode subnode in list.Nodes)
                            rawvalues.Add(new ValueRaw(subnode, listScope));
                        value = new ValueArray(rawvalues);
                        break;
                }

                // run contents through a function if specified
                ValueFunction function = list.Delimiter.Function;
                if (function == null)
                    return value;
                DelimiterNode next = new DelimiterNodeValue(value);
                return function.Eval(null, next, scope, scope, nodes, requestor);
            }
            return new ValueNil();
        }
Пример #2
0
            internal override Value Eval(Value arg, IScope scope)
            {
                Map map = arg.AsMap;
                List<Value> array = map["array"].AsArray;
                ValueFunction filter = map["filter?"] as ValueFunction;
                ValueFunction transform = map["transform"] as ValueFunction;
                if (filter == null && transform == null)
                    return map["array"];

                List<Value> newarray = new List<Value>(array.Count);
                bool bPre = ((filter != null && filter.ConsumesPrevious) || (transform != null && transform.ConsumesPrevious));
                int i = 0;
                foreach (Value val in array)
                {
                    DelimiterNode prev = (bPre ? new DelimiterNodeValue(new ValueInt(i)) : null);
                    DelimiterNode node = new DelimiterNodeValue(val);

                    // if we should use this value...
                    if (filter == null || filter.Eval(prev, node, scope, scope, null, null).AsBool)
                    {	// ...transform if appropriate
                        Value newval = (transform == null ? val : transform.Eval(prev, node, scope, scope, null, null));
                        newarray.Add(newval);
                    }
                    i++;
                }
                return new ValueArray(newarray);
            }
Пример #3
0
            internal override Value Eval(Value arg, IScope scope)
            {
                Map map = arg.AsMap;
                List<Value> array = map["array"].AsArray;
                ValueFunction function = map["function"] as ValueFunction;

                Value last = array[array.Count - 1];
                for (int i = array.Count - 2; i >= 0; i--)
                {
                    Value val = array[i];
                    DelimiterNode node1 = new DelimiterNodeValue(last);
                    DelimiterNode node2 = new DelimiterNodeValue(val);
                    last = function.Eval(node2, node1, scope, scope, null, null);
                }
                return last;
            }
Пример #4
0
            internal override Value Eval(Value arg, IScope scope)
            {
                Map map = arg.AsMap;
                List<Value> array = map["array"].AsArray;
                ValueFunction function = map["function"] as ValueFunction;

                bool bFirst = true;
                Value last = null;
                foreach (Value val in array)
                {
                    if (bFirst)
                    {
                        last = val;
                        bFirst = false;
                    }
                    else
                    {
                        DelimiterNode node1 = new DelimiterNodeValue(last);
                        DelimiterNode node2 = new DelimiterNodeValue(val);
                        last = function.Eval(node1, node2, scope, scope, null, null);
                    }
                }
                return last;
            }
Пример #5
0
            internal override Value Eval(Value arg, IScope scope)
            {
                Map map = arg.AsMap;
                Map inputMap = map["map"].AsMap;
                bool bUseValue = map["value?"].AsBool;
                ValueFunction filter = map["filter?"] as ValueFunction;
                ValueFunction transform = map["transform"] as ValueFunction;
                if (filter == null && transform == null)
                    return map["map"];

                Dictionary<string, Value> dict = inputMap.Raw;
                Dictionary<string, Value> newdict = new Dictionary<string, Value>();
                if (dict == null)
                    return new ValueMap(new Map(newdict));

                bool bPre = ((filter != null && filter.ConsumesPrevious) || (transform != null && transform.ConsumesPrevious));
                foreach (string key in dict.Keys)
                {
                    DelimiterNode prev = (bPre ? new DelimiterNodeValue(new ValueString(key)) : null);
                    DelimiterNode next = new DelimiterNodeValue(dict[key]);

                    // if we should use this value...
                    if (filter == null || filter.Eval(prev, next, scope, scope, null, null).AsBool)
                    {	// ...transform if appropriate
                        if (bUseValue)
                        {
                            Value newval = (transform == null ? dict[key] : transform.Eval(prev, next, scope, scope, null, null));
                            newdict[key] = newval;
                        }
                        else
                        {
                            string newkey = (transform == null ? key : transform.Eval(prev, next, scope, scope, null, null).AsString);
                            newdict[newkey] = dict[key];
                        }
                    }
                }
                return new ValueMap(new Map(newdict));
            }
Пример #6
0
            internal override Value Eval(Value arg, IScope scope)
            {
                Map map = arg.AsMap;
                Map inputMap = map["map"].AsMap;
                bool bKeepValue = map["value?"].AsBool;
                ValueFunction filter = map["filter?"] as ValueFunction;
                ValueFunction transform = map["transform"] as ValueFunction;
                if (filter == null && transform == null)
                    return map["map"];

                Dictionary<string, Value> dict = inputMap.Raw;
                List<Value> newarray = new List<Value>();

                if (dict != null)
                {
                    bool bPre = (filter is ValueFunctionPre || transform is ValueFunctionPre);
                    foreach (string key in dict.Keys)
                    {
                        DelimiterNode prev = (bPre ? null : new DelimiterNodeValue(new ValueString(key)));
                        DelimiterNode toFilter = new DelimiterNodeValue(dict[key]);

                        // if we should use this value...
                        if (filter == null || filter.Eval(prev, toFilter, scope, scope, null, null).AsBool)
                        {	// get value or key & possibly transform
                            Value newval = (bKeepValue ? dict[key] : new ValueString(key));
                            if (transform != null)
                            {
                                DelimiterNode toTransform = new DelimiterNodeValue(newval);
                                newval = transform.Eval(prev, toTransform, scope, scope, null, null);
                            }
                            newarray.Add(newval);
                        }
                    }
                }
                return new ValueArray(newarray);
            }