Ejemplo n.º 1
0
 /// <summary>Transform a node into something we can use as a body</summary>
 internal static Value UseNodeAsBody(DelimiterNode bodyNode)
 {
     if (bodyNode.List.Delimiter.DelimiterType == DelimiterType.AsArray)
     {
         List<DelimiterList> body = new List<DelimiterList>();
         List<DelimiterNode> originalList = bodyNode.List.Nodes;
         foreach (DelimiterNode node in originalList)
         {
             IScope scope = node.List.Scope;
             DelimiterList dList = new DelimiterList(ValueDelimiter.Line, node.List.Nodes, 0, "", node.ToString(), scope);
             body.Add(dList);
         }
         return new ValueLine(body, bodyNode.List.Scope);
     }
     else
     {
         IScope scope = bodyNode.List.Scope;
         DelimiterList dList = new DelimiterList(ValueDelimiter.Line, bodyNode.List.Nodes, 0, "", bodyNode.ToString(), scope);
         List<DelimiterList> body = new List<DelimiterList>();
         body.Add(dList);
         return new ValueLine(body, scope);
     }
 }
Ejemplo n.º 2
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.º 3
0
 internal DelimiterNodeList(DelimiterList tree)
 {
     m_list = tree;
 }
Ejemplo n.º 4
0
        // simply search for end and stuff everything in the middle into a single token
        private static bool ParseString(int indent, string[] strs, int iStart,
			ValueDelimiter thisDelim, List<DelimiterNode> nodes,
			out int iEnd, out DelimiterList result)
        {
            iEnd = -1;
            bool bExtra = false;
            for (int i = iStart; i < strs.Length; i++)
            {
                string s = strs[i];
                if (s == thisDelim.End)
                {
                    iEnd = i;
                    break;
                }
                else if (s.Substring(s.Length - 1, 1) == thisDelim.End)
                {
                    iEnd = i + 1;
                    bExtra = true;
                    break;
                }
            }

            // no specified end delim means take the remainder of the line
            if (thisDelim.End == "")
                iEnd = strs.Length;

            // if we found end, wrap entire string in a single node
            if (iEnd != -1)
            {
                string subStr = GetSubStr(iStart, iEnd, strs);
                if (bExtra)
                {
                    subStr = subStr.Substring(0, subStr.Length - 1);
                    --iEnd;
                }
                Token token = new Token(subStr);
                DelimiterNode node = new DelimiterNodeToken(token);
                nodes.Add(node);
                result = new DelimiterList(thisDelim, nodes, indent, strs[iStart - 1], subStr, null);
                return true;
            }
            result = null;
            return false;
        }
Ejemplo n.º 5
0
        // handle as individual tokens and nested lists
        private static bool ParseMisc(int indent, string original, string[] strs, int iStart, ValueDelimiter thisDelim,
			IParseLineDelimiters delims, ILineRequestor requestor, List<DelimiterNode> nodes,
			out int iEnd, out DelimiterList result)
        {
            result = null;
            iEnd = strs.Length;

            for (int i = iStart; i < strs.Length; i++)
            {
                string s = strs[i];

                // is this the end of current set of delimited tokens?
                if (s == thisDelim.End)
                {	// end delimiter
                    iEnd = i;
                    string subStr = GetSubStr(iStart, iEnd, strs);
                    result = new DelimiterList(thisDelim, nodes, indent, strs[iStart - 1], subStr, null);
                    return true;
                }
                // TODO: rework this so I don't need to check for : (e.g. for :}, when creating a delim)
                if (s.Substring(s.Length - 1, 1) == thisDelim.End && (s[0] != ':' || s.Length > 2))
                {	// end delimiter is part of final token
                    iEnd = i + 1;
                    string without = s.Substring(0, s.Length - 1);

                    Token token = new Token(without);
                    DelimiterNode node = new DelimiterNodeToken(token);
                    nodes.Add(node);

                    strs[i] = without;
                    string subStr = GetSubStr(iStart, iEnd, strs);
                    result = new DelimiterList(thisDelim, nodes, indent, strs[iStart - 1], subStr, null);
                    strs[i] = s;
                    --iEnd;
                    return true;
                }

                // is it a stand alone starting delimiter?
                bool bAnyToken = false;
                ValueDelimiter subDelim = (delims == null ? null : delims.GetDelim(s, out bAnyToken));
                string[] strsToUse = strs;
                bool bExtra = true;
                if (subDelim == null && !bAnyToken)
                {	// whole thing wasn't a delimiter, function, etc., how about the 1st char?
                    string s1 = s.Substring(0, 1);
                    subDelim = (delims == null ? null : delims.GetDelim(s1, out bAnyToken));
                    if (subDelim != null)
                    {	// copy across array, but break iStart into delim & remainder
                        bExtra = false;
                        strsToUse = new string[strs.Length + 1];
                        for (int j = 0; j < i; j++)
                            strsToUse[j] = strs[j];
                        strsToUse[i] = s1;
                        strsToUse[i + 1] = s.Substring(1);
                        for (int j = i + 1; j < strs.Length; j++)
                            strsToUse[j + 1] = strs[j];
                    }
                }
                if (subDelim != null)
                {	// start delimiter
                    int end;
                    DelimiterList sublist = Do(0, original, strsToUse, i + 1, subDelim, delims, requestor, out end);
                    if (sublist != null)
                    {
                        DelimiterNodeList node = new DelimiterNodeList(sublist);
                        nodes.Add(node);
                    }
                    // skip past the sublist
                    i = (bExtra ? end : end - 1);
                }
                else
                {	// stand alone token
                    Token token = new Token(s);
                    DelimiterNode node = new DelimiterNodeToken(token);
                    nodes.Add(node);
                }
            }
            return false;
        }
Ejemplo n.º 6
0
        // ignore everything up to the end delimiter
        private static bool ParseComment(string[] strs, int iStart, ValueDelimiter thisDelim,
			out int iEnd, out DelimiterList result)
        {
            result = null;
            for (int i = iStart; i < strs.Length; i++)
            {
                if (strs[i] == thisDelim.End)
                {
                    iEnd = i;
                    return true;
                }
            }
            iEnd = strs.Length;
            return false;
        }