示例#1
0
        public void EvalTryParse(RCRunner runner, RCClosure closure, RCString right)
        {
            bool    fragment;
            RCValue val;
            RCBlock result = RCBlock.Empty;

            try
            {
                val    = DoParse(new RCLParser(RCSystem.Activator), right, false, out fragment);
                result = new RCBlock(result, "status", ":", new RCLong(0));
                result = new RCBlock(result, "fragment", ":", new RCBoolean(fragment));
                result = new RCBlock(result, "data", ":", val);
            }
            catch (Exception ex)
            {
                result = new RCBlock(result, "status", ":", new RCLong(1));
                result = new RCBlock(result, "fragment", ":", new RCBoolean(false));
                string  message     = ex.ToString();
                RCBlock report      = new RCBlock("", ":", new RCString(message + "\n"));
                int     escapeCount = RCTemplate.CalculateReportTemplateEscapeLevel(message);
                result = new RCBlock(result, "error", ":", new RCTemplate(report, escapeCount, true));
            }
            runner.Yield(closure, result);
        }
示例#2
0
        /*
         * protected Type InferType(string[] name, string original)
         * {
         * //Let's try to figure it out!
         * RCValue target = null;
         *
         * //Try the block under construction.
         * if (_block != null)
         * {
         * target = _block.Get(name);
         * }
         *
         * //Try to find it higher up the stack.
         * if (target == null)
         * {
         * RCBlock[] parents = _blocks.ToArray();
         * //When you ToArray the stack items come out in the same order
         * //you would have taken them off the stack.
         * for (int i = 0; i < parents.Length; ++i)
         * {
         * //There will be null blocks on the stack.
         * if (parents[i] != null)
         * {
         * target = parents[i].Get(name);
         * if (target != null) break;
         * }
         * }
         * }
         *
         * if (target == null)
         * {
         * throw new Exception("Unable to infer type for reference " + original + ".");
         * }
         * else return target.Yields;
         * }
         */

        protected RCVectorBase MakeVector(RCArray <RCToken> vector)
        {
            RCVectorBase result = null;

            if (vector[0].Text[0] == '~')
            {
                switch (vector[0].Text[1])
                {
                case 'x': return(RCByte.Empty);

                case 'b': return(RCBoolean.Empty);

                case 'l': return(RCLong.Empty);

                case 'd': return(RCDouble.Empty);

                case 'm': return(RCDecimal.Empty);

                case 's': return(RCString.Empty);

                case 'y': return(RCSymbol.Empty);

                case 't': return(RCTime.Empty);

                case 'n': return(RCIncr.Empty);

                default: throw new Exception("Unrecognized type code: " + vector[0].Text[1]);
                }
            }
            if (vector[0].Type == RCTokenType.Symbol)
            {
                RCArray <RCSymbolScalar> list = new RCArray <RCSymbolScalar> (vector.Count);
                for (int i = 0; i < vector.Count; ++i)
                {
                    list.Write(vector[i].ParseSymbol(_lexer));
                }
                result = new RCSymbol(list);
            }
            else if (vector[0].Type == RCTokenType.String)
            {
                RCArray <string> list = new RCArray <string> (vector.Count);
                for (int i = 0; i < vector.Count; ++i)
                {
                    list.Write(vector[i].ParseString(_lexer));
                }
                result = new RCString(list);
            }
            else if (vector[0].Type == RCTokenType.Boolean)
            {
                RCArray <bool> list = new RCArray <bool> (vector.Count);
                for (int i = 0; i < vector.Count; ++i)
                {
                    list.Write(vector[i].ParseBoolean(_lexer));
                }
                result = new RCBoolean(list);
            }
            else if (vector[0].Type == RCTokenType.Incr)
            {
                RCArray <RCIncrScalar> list = new RCArray <RCIncrScalar> (vector.Count);
                for (int i = 0; i < vector.Count; ++i)
                {
                    list.Write(vector[i].ParseIncr(_lexer));
                }
                result = new RCIncr(list);
            }
            else if (vector[0].Type == RCTokenType.Literal)
            {
                char type = vector[0].Text[1];
                switch (type)
                {
                case 'x':
                    RCArray <byte> list = new RCArray <byte> (vector.Count);
                    for (int i = 0; i < vector.Count; ++i)
                    {
                        list.Write(vector[i].ParseByte(_lexer));
                    }
                    result = new RCByte(list);
                    break;

                default: throw new Exception("Unknown type specifier:" + type);
                }
            }
            else if (vector[0].Type == RCTokenType.Time)
            {
                RCArray <RCTimeScalar> list = new RCArray <RCTimeScalar> (vector.Count);
                for (int i = 0; i < vector.Count; ++i)
                {
                    list.Write(vector[i].ParseTime(_lexer));
                }
                result = new RCTime(list);
            }
            else if (vector[0].Type == RCTokenType.Number)
            {
                // have a look at the last character in the last token
                // if there is a type specifier there we will use it to
                // create the appropriate type of vector.
                RCToken last = vector[vector.Count - 1];
                char    type = last.Text[last.Text.Length - 1];
                if (type == 'l')
                {
                    RCArray <long> list = new RCArray <long> (vector.Count);
                    for (int i = 0; i < vector.Count; ++i)
                    {
                        list.Write(vector[i].ParseLong(_lexer));
                    }
                    result = new RCLong(list);
                }
                if (type == 'd')
                {
                    RCArray <double> list = new RCArray <double> (vector.Count);
                    for (int i = 0; i < vector.Count; ++i)
                    {
                        list.Write(vector[i].ParseDouble(_lexer));
                    }
                    result = new RCDouble(list);
                }
                else if (type == 'm')
                {
                    RCArray <decimal> list = new RCArray <decimal> (vector.Count);
                    for (int i = 0; i < vector.Count; ++i)
                    {
                        list.Write(vector[i].ParseDecimal(_lexer));
                    }
                    result = new RCDecimal(list);
                }
                else // default to double
                {
                    if (vector[0].Text.IndexOf('.') > -1 || vector[0].Text == "NaN")
                    {
                        RCArray <double> list = new RCArray <double> (vector.Count);
                        for (int i = 0; i < vector.Count; ++i)
                        {
                            list.Write(vector[i].ParseDouble(_lexer));
                        }
                        result = new RCDouble(list);
                    }
                    else
                    {
                        RCArray <long> list = new RCArray <long> (vector.Count);
                        for (int i = 0; i < vector.Count; ++i)
                        {
                            list.Write(vector[i].ParseLong(_lexer));
                        }
                        result = new RCLong(list);
                    }
                }
            }
            return(result);
        }
示例#3
0
        protected static RCString ExpandTemplate(StringBuilder builder,
                                                 RCTemplate template,
                                                 RCBlock right,
                                                 int I,
                                                 string parentIndent)
        {
            string indent = parentIndent;

            for (int i = 0; i < right.Count; ++i)
            {
                RCValue           child = right.Get(i);
                RCVector <string> text  = child as RCVector <string>;
                if (text == null)
                {
                    RCArray <string> strings     = new RCArray <string> (right.Count);
                    RCBlock          nestedBlock = (RCBlock)child;
                    for (int j = 0; j < nestedBlock.Count; ++j)
                    {
                        strings.Write(nestedBlock.GetString(j));
                    }
                    text = new RCString(strings);
                    // ExpandTemplate (builder, template, (RCBlock) child, I + i, indent);
                }
                // else
                {
                    bool somethingAdded = false;
                    for (int j = 0; j < text.Count; ++j)
                    {
                        string section = text[j];
                        int    start   = 0;
                        int    lineNum = 0;
                        for (int k = 0; k < section.Length; ++k)
                        {
                            if (section[k] == '\n')
                            {
                                string line;
                                if (i % 2 == 1)
                                {
                                    if (k > 0 && section.Length > 0 && section[k - 1] == '\r')
                                    {
                                        line = section.Substring(start, k - start - 1);
                                    }
                                    else
                                    {
                                        line = section.Substring(start, k - start);
                                    }
                                    // if (j > 0 || start > 0)
                                    // Using j and start here didn't work because sometimes empty strings
                                    // are added. Instead keep track of whether a line has been added.
                                    // We may need this variable to handle other cases as well, but
                                    // they haven't cropped yet.
                                    if (somethingAdded)
                                    {
                                        // Notice below in the section with w. If there is extra content
                                        // before the code section on the same line, it will have been
                                        // inserted/indented already.
                                        builder.Append(indent);
                                    }
                                    builder.Append(line);
                                    builder.Append("\n");
                                    somethingAdded = true;
                                }
                                else
                                {
                                    // In content sections after the first one,
                                    // skip newlines if they are the first thing in the section.
                                    line = section.Substring(start, k - start);
                                    if (I + i == 0)
                                    {
                                        builder.Append(line);
                                        builder.Append("\n");
                                    }
                                    else if (line != "")
                                    {
                                        if (builder[builder.Length - 1] == '\n')
                                        {
                                            if (start == 0 && (k < section.Length - 1 || i == right.Count - 1))
                                            {
                                                builder.Append(indent);
                                            }
                                            else if (k == section.Length - 1 && i < right.Count - 1)
                                            {
                                                builder.Append(indent);
                                            }
                                        }
                                        builder.Append(line);
                                        builder.Append("\n");
                                    }
                                    else if (k > 0 || (builder.Length > 0 && builder[builder.Length - 1] != '\n'))
                                    {
                                        builder.Append(line);
                                        builder.Append("\n");
                                    }
                                }
                                start = k + 1;
                                ++lineNum;
                            }
                        }
                        if (template.Multiline)
                        {
                            // If this is a code section, the lastPiece is just the last line of the
                            // template.
                            // There is no newline at the end.
                            // If this is a text section, the lastPiece is a prefix for the next code
                            // section.
                            string lastPiece = section.Substring(start, section.Length - start);
                            if (i % 2 == 1)
                            {
                                // Odd sections are always code sections.
                                // Code sections don't have a newline at the end.
                                if (j == 0)
                                {
                                    // This means there was a newline at the end of section.
                                    if (start > 0 && lastPiece != "")
                                    {
                                        builder.Append(indent);
                                    }
                                }
                                else if (j == text.Count - 1)
                                {
                                    indent = parentIndent;
                                }
                                builder.Append(lastPiece);
                            }
                            else
                            {
                                int w;
                                for (w = 0; w < lastPiece.Length; ++w)
                                {
                                    if (lastPiece[w] != ' ')
                                    {
                                        break;
                                    }
                                }
                                // indent only includes spaces before the first non-space character.
                                // The non-space part of the text is only inserted once.
                                // An edge case involves spaces inserted between code sections on the same
                                // line.
                                // \t not spoken here.
                                // while (builder.Length == 0 || builder[builder.Length - 1] == '\n')
                                {
                                    string end;
                                    if (builder.Length == 0 || builder[builder.Length - 1] == '\n')
                                    {
                                        indent = parentIndent + lastPiece.Substring(0, w);
                                        end    = lastPiece.Substring(w, lastPiece.Length - w);
                                    }
                                    else
                                    {
                                        end = lastPiece;
                                    }
                                    if (i < right.Count - 1)
                                    {
                                        if (section.Length > 0)
                                        {
                                            if (builder.Length == 0 || builder[builder.Length - 1] == '\n')
                                            {
                                                builder.Append(indent);
                                            }
                                        }
                                    }
                                    builder.Append(end);
                                }
                            }
                        }
                        else
                        {
                            // If there are no newlines in the template then just drop the whole thing
                            // in as is.
                            builder.Append(text[j]);
                        }
                    }
                }
            }
            // Go back and remove the final newline now.
            // Let the enclosing template decide how to finish off.
            if (template.Multiline)
            {
                if (builder.Length > 0 && builder[builder.Length - 1] != '\n')
                {
                    builder.Append("\n");
                }
            }
            return(new RCString(builder.ToString()));
        }
示例#4
0
 // Kicks off evaluation for a block.
 public static void DoEval(RCRunner runner, RCClosure closure, RCBlock block)
 {
     if (block.Count == 0)
     {
         DoYield(runner, closure, block);
     }
     else
     {
         RCBlock current = block.GetName(closure.Index);
         if (current.Evaluator.Invoke)
         {
             string op = ((RCString)current.Value)[0];
             RCSystem.Activator.Invoke(runner, closure, op, closure.Result);
         }
         else if (current.Evaluator.Template)
         {
             try
             {
                 RCString result = ExpandTemplate(new StringBuilder(),
                                                  (RCTemplate)current,
                                                  closure.Result,
                                                  0,
                                                  "");
                 runner.Yield(closure, result);
             }
             catch (Exception ex)
             {
                 RCException rcex = new RCException(closure,
                                                    ex,
                                                    RCErrors.Native,
                                                    "An exception was thrown by the template.");
                 runner.Finish(closure, rcex, (int)RCErrors.Native);
             }
         }
         else if (current.Evaluator.Pass)
         {
             DoYield(runner, closure, current.Value);
         }
         // This means that Value is an operator or a reference.
         else if (current.Value.ArgumentEval)
         {
             current.Value.Eval(runner,
                                new RCClosure(closure,
                                              closure.Bot,
                                              current.Value,
                                              closure.Left,
                                              closure.Result,
                                              0));
         }
         else if (current.Evaluator.Return)
         {
             DoYield(runner, closure, current.Value);
         }
         else
         {
             // I need something different to happen when we are at the top level already.
             // Or maybe I need to inject a wrapper closure when I do Rep this way?
             if ((closure.Index < block.Count - 1) || (closure.Parent != null))
             {
                 DoYield(runner, closure, current.Value);
             }
             else
             {
                 DoYield(runner, closure, current);
             }
         }
     }
 }
示例#5
0
 public void EvalEval(RCRunner runner, RCClosure closure, RCBlock left, RCString right)
 {
     runner.Yield(closure, right);
 }
示例#6
0
        public RCLArgv(params string[] argv)
        {
            Exit      = false;
            Batch     = false;
            NoKeys    = false;
            NoResult  = false;
            Version   = false;
            FullStack = false;
            Program   = "";
            Action    = "";
            Output    = "full";
            Show      = new string[] { "*" };
            Hide      = new string[] { };
            RCBlock       custom    = RCBlock.Empty;
            List <string> arguments = new List <string> ();

            for (int i = 0; i < argv.Length; ++i)
            {
                string[] kv = argv[i].Split('=');
                if (kv.Length == 1)
                {
                    if (kv[0].StartsWith("--"))
                    {
                        string option = kv[0].Substring(2);
                        if (option.Equals("exit"))
                        {
                            Exit = true;
                        }
                        else if (option.Equals("batch"))
                        {
                            Batch = true;
                        }
                        else if (option.Equals("nokeys"))
                        {
                            NoKeys = true;
                        }
                        else if (option.Equals("noread"))
                        {
                            NoRead = true;
                        }
                        else if (option.Equals("noresult"))
                        {
                            NoResult = true;
                        }
                        else if (option.Equals("fullstack"))
                        {
                            FullStack = true;
                        }
                        else if (option.Equals("version"))
                        {
                            // This option forces the version to display no matter what.
                            // Useful when you need to check the version number from a test.
                            Version = true;
                        }
                        else
                        {
                            custom = new RCBlock(custom, option, ":", RCBoolean.True);
                        }
                    }
                    else if (kv[0].StartsWith("-"))
                    {
                        for (int j = 1; j < kv[0].Length; ++j)
                        {
                            char c;
                            switch (c = kv[0][j])
                            {
                            case 'x':
                                Exit = true;
                                break;

                            case 'b':
                                Batch = true;
                                break;

                            case 'k':
                                NoKeys = true;
                                break;

                            case 'r':
                                NoRead = true;
                                break;

                            case 'v':
                                Version = true;
                                break;

                            default:
                                Usage("Unknown option '" + kv[0][j] + "'");
                                break;
                            }
                        }
                    }
                    else
                    {
                        // do position.
                        arguments.Add(kv[0]);
                    }
                }
                else
                {
                    // do named arguments.
                    if (kv[0].StartsWith("--"))
                    {
                        string option = kv[0].Substring(2);
                        if (option.Equals("program"))
                        {
                            Program = kv[1];
                        }
                        else if (option.Equals("action"))
                        {
                            Action = kv[1];
                        }
                        else if (option.Equals("output"))
                        {
                            Output = kv[1];
                        }
                        else if (option.Equals("show"))
                        {
                            Show = kv[1].Split(',');
                        }
                        else if (option.Equals("hide"))
                        {
                            Hide = kv[1].Split(',');
                        }
                        else
                        {
                            custom = new RCBlock(custom, option, ":", new RCString(kv[1]));
                        }
                    }
                    else
                    {
                        Usage("Named options start with --");
                    }
                }
            }
            Arguments  = new RCString(arguments.ToArray());
            Options    = RCBlock.Empty;
            Options    = new RCBlock(Options, "program", ":", new RCString(Program));
            Options    = new RCBlock(Options, "action", ":", new RCString(Action));
            Options    = new RCBlock(Options, "output", ":", new RCString(Output));
            Options    = new RCBlock(Options, "show", ":", new RCString(Show));
            Options    = new RCBlock(Options, "hide", ":", new RCString(Hide));
            Options    = new RCBlock(Options, "batch", ":", new RCBoolean(Batch));
            Options    = new RCBlock(Options, "nokeys", ":", new RCBoolean(NoKeys));
            Options    = new RCBlock(Options, "noread", ":", new RCBoolean(NoRead));
            Options    = new RCBlock(Options, "noresult", ":", new RCBoolean(NoResult));
            Options    = new RCBlock(Options, "exit", ":", new RCBoolean(Exit));
            Options    = new RCBlock(Options, "version", ":", new RCBoolean(Version));
            Options    = new RCBlock(Options, "fullstack", ":", new RCBoolean(FullStack));
            OutputEnum = (RCOutput)Enum.Parse(typeof(RCOutput), Output, true);
            for (int i = 0; i < custom.Count; ++i)
            {
                RCBlock name = custom.GetName(i);
                Options = new RCBlock(Options, name.Name, ":", name.Value);
            }
        }
示例#7
0
        public static void DoFormat(RCTemplate template,
                                    StringBuilder builder,
                                    RCFormat args,
                                    RCColmap
                                    colmap,
                                    int level)
        {
            // templates need to follow the same indenting rules as everyone else please.
            builder.Append("[");
            builder.Append('?', template.EscapeCount);
            // Use AppendLine not args.Newline, because the newline is signficant
            //  and needs to be there no matter what.  Otherwise when we parse it again
            ++level;
            if (template.Multiline)
            {
                builder.Append("\n");
                for (int tab = args.Fragment ? 1 : 0; tab < level; ++tab)
                {
                    builder.Append(args.Indent);
                }
            }
            for (int i = 0; i < template.Count - 1; ++i)
            {
                RCValue  child = template.Get(i);
                RCString str   = child as RCString;
                if (str != null && i % 2 == 0)
                {
                    for (int j = 0; j < str.Count; ++j)
                    {
                        // Now go through str one char at a time to find the newlines.
                        int start = 0, end = 0;
                        for (; end < str[j].Length; ++end)
                        {
                            if (str[j][end] == '\n')
                            {
                                string line = str[j].Substring(start, end - start);
                                builder.Append(line);
                                builder.Append("\n");
                                if (i < template.Count - 2 || end < str[j].Length - 1)
                                {
                                    for (int tab = args.Fragment ? 1 : 0; tab < level; ++tab)
                                    {
                                        builder.Append(args.Indent);
                                    }
                                }
                                start = end + 1;
                            }
                            else if (end == str[j].Length - 1)
                            {
                                builder.Append(str[j].Substring(start, 1 + end - start));
                            }
                        }
                    }
                }
                else
                {
                    if (template.Multiline)
                    {
                        // for (int tab = 0; tab < level; ++tab)
                        // {
                        //  builder.Append (args.Indent);
                        // }

                        /*
                         * int k = builder.Length - 1;
                         * while (k >= 0)
                         * {
                         * if (builder[k] == '\n')
                         * {
                         *  for (int tab = 0; tab < level; ++tab)
                         *  {
                         *    builder.Append (args.Indent);
                         *  }
                         *  break;
                         * }
                         * else if (builder[k] != ' ')
                         * {
                         *  break;
                         * }
                         * --k;
                         * }
                         */
                    }
                    builder.Append("[");
                    builder.Append('!', template.EscapeCount);
                    builder.Append(' ');
                    child.Format(builder, RCFormat.Default, colmap, level);
                    builder.Append(' ');
                    builder.Append('!', template.EscapeCount);
                    builder.Append("]");
                }
            }
            --level;
            if (template.Multiline)
            {
                for (int tab = args.Fragment ? 1 : 0; tab < level; ++tab)
                {
                    builder.Append(args.Indent);
                }
            }
            builder.Append('?', template.EscapeCount);
            builder.Append("]");
        }
示例#8
0
 public void EvalFail(RCRunner runner, RCClosure closure, RCString right)
 {
     runner.Finish(closure,
                   new RCException(closure, RCErrors.Custom, right[0]),
                   (int)RCErrors.Custom);
 }