コード例 #1
0
 StateDeclarationStatement ParseStateDeclaration(TokenRange toks)
 {
     toks = toks.Consume("state").RevSkipWhile(t => t.Value == ";");
     return(new StateDeclarationStatement {
         decl = ParseVarDeclaration(toks)
     });
 }
コード例 #2
0
        CodeBlock ParseCodeBlock(TokenRange toks)
        {
            List <Statement> statements = new List <Statement>();

            while (true)
            {
                Token delim = toks
                              .FirstOrDefault(
                    t => t.ParenDepth == toks.First().ParenDepth&&
                    t.BraceDepth == toks.First().BraceDepth&&
                    (t.Value == ";" || t.Value == "}")
                    );
                if (delim == null)
                {
                    break;
                }
                ParseStatement(range(toks.Begin, delim.Position + 1), statements);
                toks = range(delim.Position + 1, toks.End);
            }
            if (!toks.All(Whitespace))
            {
                throw new Error(toks.First(NonWhitespace).SourceLine, "Trailing unterminated statement in code block");
            }
            return(new CodeBlock {
                statements = statements.ToArray()
            });
        }
コード例 #3
0
        List <Declaration> ParseDescrCodeBlock(TokenRange toks)
        {
            List <Declaration> declarations = new List <Declaration>();

            while (true)
            {
                Token delim = toks.FirstOrDefault(t => t.Value == ";");
                if (delim == null)
                {
                    break;
                }

                int pos = delim.Position + 1;
                var potentialComment = range(pos, toks.End).SkipWhile(t => t.Value == "\t" || t.Value == " ");
                if (!potentialComment.IsEmpty && potentialComment.First().Value.StartsWith("//"))
                {
                    pos = potentialComment.First().Position + 1;
                }

                ParseDeclaration(range(toks.Begin, pos), declarations);

                toks = range(pos, toks.End);
            }
            if (!toks.All(Whitespace))
            {
                throw new Error(toks.First(NonWhitespace).SourceLine, "Trailing unterminated statement in code block");
            }
            return(declarations);
        }
コード例 #4
0
 ChooseStatement ParseChooseStatement(TokenRange toks)
 {
     return(new ChooseStatement
     {
         body = ParseCompoundStatement(toks.Consume("choose"))
     });
 }
コード例 #5
0
 Statement ParseTryStatement(TokenRange toks)
 {
     return(new TryStatement
     {
         tryBody = ParseCompoundStatement(toks.Consume("try")),
         catches = new List <TryStatement.Catch>()    // will be filled in later by ParseCatchStatement
     });
 }
コード例 #6
0
 ThrowStatement ParseThrowStatement(TokenRange toks)
 {
     toks = toks.Consume("throw").RevSkipWhile(t => t.Value == ";");
     return(new ThrowStatement
     {
         expression = str(NormalizeWhitespace(toks))
     });
 }
コード例 #7
0
        public TokenRange GetMatchingRangeIn(TokenRange range)
        {
            Func <Token, bool> pred;
            int dir;

            switch (Value)
            {
            case "(": pred = t => t.Value != ")" || t.ParenDepth != ParenDepth; dir = +1; break;

            case ")": pred = t => t.Value != "(" || t.ParenDepth != ParenDepth; dir = -1; break;

            case "{": pred = t => t.Value != "}" || t.BraceDepth != BraceDepth; dir = +1; break;

            case "}": pred = t => t.Value != "{" || t.BraceDepth != BraceDepth; dir = -1; break;

            case "<": return
                    (new TokenRange(range.GetAllTokens(),
                                    Position + 1,
                                    AngleBracketParser.NotInsideAngleBrackets(
                                        new TokenRange(range.GetAllTokens(), Position, range.End))
                                    .Skip(1) // skip the "<", which is considered "outside"
                                    .First() // get the ">", which is likewise "outside"
                                    .Position));

            case "[": return
                    (new TokenRange(range.GetAllTokens(),
                                    Position + 1,
                                    BracketParser.NotInsideBrackets(
                                        new TokenRange(range.GetAllTokens(), Position, range.End))
                                    .Skip(1) // skip the "[", which is considered "outside"
                                    .First() // get the "]", which is likewise "outside"
                                    .Position));

            default: throw new NotSupportedException("Can't match this token!");
            }
            TokenRange r;

            if (dir == -1)
            {
                r = new TokenRange(range.GetAllTokens(), range.Begin, Position)
                    .RevTakeWhile(pred);
                if (r.Begin == range.Begin)
                {
                    throw new Error(SourceLine, "Syntax error: Unmatched " + Value);
                }
            }
            else
            {
                r = new TokenRange(range.GetAllTokens(), Position + 1, range.End)
                    .TakeWhile(pred);
                if (r.End == range.End)
                {
                    throw new Error(SourceLine, "Syntax error: Unmatched " + Value);
                }
            }
            return(r);
        }
コード例 #8
0
        WaitStatement ParseWaitStatement(TokenRange toks)
        {
            WaitStatement ws = new WaitStatement();

            ws.FirstSourceLine = toks.First().SourceLine;
            if (toks.First().Value == "state")
            {
                ws.resultIsState = true;
                toks             = toks.Consume("state");
            }

            Token      name;
            TokenRange type, initializer;
            bool       constructorSyntax;

            ParseDeclaration(toks.RevSkipWhile(t => t.Value == ";"), out name, out type, out initializer, out constructorSyntax);

            ws.result = new VarDeclaration
            {
                name        = name.Value,
                type        = str(NormalizeWhitespace(type)),
                initializer = "",
                initializerConstructorSyntax = false
            };

            if (initializer == null)
            {
                throw new Error(ws.FirstSourceLine, "Wait statement must be a declaration");
            }

            var waitParams = initializer
                             .SkipWhile(Whitespace).Consume("Statement contains a wait, but is not a valid wait statement or a supported compound statement.",
                                                            t => {
                if (t.Value == "wait")
                {
                    return(true);
                }
                if (t.Value == "waitNext")
                {
                    ws.isWaitNext = true; return(true);
                }
                return(false);
            })
                             .SkipWhile(Whitespace).First().Assert("Expected (", t => t.Value == "(")
                             .GetMatchingRangeIn(initializer);

            if (!range(waitParams.End, initializer.End).Consume(")").All(Whitespace))
            {
                throw new Error(toks.First().SourceLine, "Statement contains a wait, but is not a valid wait statement or a supported compound statement.");
            }

            ws.futureExpression = str(NormalizeWhitespace(waitParams));
            return(ws);
        }
コード例 #9
0
        WhenStatement ParseWhenStatement(TokenRange toks)
        {
            var expr = toks.Consume("when")
                       .First(NonWhitespace)
                       .Assert("Expected (", t => t.Value == "(")
                       .GetMatchingRangeIn(toks);

            return(new WhenStatement {
                wait = ParseWaitStatement(expr),
                body = ParseCompoundStatement(range(expr.End + 1, toks.End))
            });
        }
コード例 #10
0
        Statement ParseIfStatement(TokenRange toks)
        {
            var expr = toks.Consume("if")
                       .First(NonWhitespace)
                       .Assert("Expected (", t => t.Value == "(")
                       .GetMatchingRangeIn(toks);

            return(new IfStatement {
                expression = str(NormalizeWhitespace(expr)),
                ifBody = ParseCompoundStatement(range(expr.End + 1, toks.End))
                         // elseBody will be filled in later if necessary by ParseElseStatement
            });
        }
コード例 #11
0
        WhileStatement ParseWhileStatement(TokenRange toks)
        {
            var expr = toks.Consume("while")
                       .First(NonWhitespace)
                       .Assert("Expected (", t => t.Value == "(")
                       .GetMatchingRangeIn(toks);

            return(new WhileStatement
            {
                expression = str(NormalizeWhitespace(expr)),
                body = ParseCompoundStatement(range(expr.End + 1, toks.End))
            });
        }
コード例 #12
0
        Statement ParseForStatement(TokenRange toks)
        {
            var head =
                toks.Consume("for")
                .First(NonWhitespace)
                .Assert("Expected (", t => t.Value == "(")
                .GetMatchingRangeIn(toks);

            Token[] delim =
                head.Where(
                    t => t.ParenDepth == head.First().ParenDepth&&
                    t.BraceDepth == head.First().BraceDepth&&
                    t.Value == ";"
                    ).ToArray();
            if (delim.Length == 2)
            {
                var init = range(head.Begin, delim[0].Position);
                var cond = range(delim[0].Position + 1, delim[1].Position);
                var next = range(delim[1].Position + 1, head.End);
                var body = range(head.End + 1, toks.End);

                return(new ForStatement
                {
                    initExpression = str(NormalizeWhitespace(init)),
                    condExpression = str(NormalizeWhitespace(cond)),
                    nextExpression = str(NormalizeWhitespace(next)),
                    body = ParseCompoundStatement(body)
                });
            }

            delim =
                head.Where(
                    t => t.ParenDepth == head.First().ParenDepth&&
                    t.BraceDepth == head.First().BraceDepth&&
                    t.Value == ":"
                    ).ToArray();
            if (delim.Length != 1)
            {
                throw new Error(head.First().SourceLine, "for statement must be 3-arg style or c++11 2-arg style");
            }

            return(new RangeForStatement
            {
                // The container over which to iterate
                rangeExpression = str(NormalizeWhitespace(range(delim[0].Position + 1, head.End).SkipWhile(Whitespace))),
                // Type and name of the variable assigned in each iteration
                rangeDecl = str(NormalizeWhitespace(range(head.Begin, delim[0].Position - 1).SkipWhile(Whitespace))),
                // The body of the for loop
                body = ParseCompoundStatement(range(head.End + 1, toks.End))
            });
        }
コード例 #13
0
        void ParseDescrHeading(Descr descr, TokenRange toks)
        {
            toks.First(NonWhitespace).Assert("non-struct DESCR!", t => t.Value == "struct");
            toks = toks.SkipWhile(Whitespace).Skip(1).SkipWhile(Whitespace);

            var colon = toks.FirstOrDefault(t => t.Value == ":");

            if (colon != null)
            {
                descr.superClassList = str(range(colon.Position + 1, toks.End)).Trim();
                toks = range(toks.Begin, colon.Position);
            }
            descr.name = str(toks).Trim();
        }
コード例 #14
0
        void ParseElseStatement(TokenRange toks, Statement prevStatement)
        {
            var ifStatement = prevStatement as IfStatement;

            while (ifStatement != null && ifStatement.elseBody != null)
            {
                ifStatement = ifStatement.elseBody as IfStatement;
            }
            if (ifStatement == null)
            {
                throw new Error(toks.First().SourceLine, "else without matching if");
            }
            ifStatement.elseBody = ParseCompoundStatement(toks.Consume("else"));
        }
コード例 #15
0
        void ParseDeclaration(TokenRange toks, List <Declaration> declarations)
        {
            Declaration dec = new Declaration();

            Token delim        = toks.First(t => t.Value == ";");
            var   nameRange    = range(toks.Begin, delim.Position).RevSkipWhile(Whitespace).RevTakeWhile(NonWhitespace);
            var   typeRange    = range(toks.Begin, nameRange.Begin);
            var   commentRange = range(delim.Position + 1, toks.End);

            dec.name    = str(nameRange).Trim();
            dec.type    = str(typeRange).Trim();
            dec.comment = str(commentRange).Trim().TrimStart('/');

            declarations.Add(dec);
        }
コード例 #16
0
        void ParseTestCaseHeading(Actor actor, TokenRange toks)
        {
            actor.isStatic = true;

            // The parameter(s) to the TEST_CASE macro are opaque to the actor compiler
            TokenRange paramRange = toks.Last(NonWhitespace)
                                    .Assert("Unexpected tokens after test case parameter list.",
                                            t => t.Value == ")" && t.ParenDepth == toks.First().ParenDepth)
                                    .GetMatchingRangeIn(toks);

            actor.testCaseParameters = str(paramRange);

            actor.name       = "flowTestCase" + toks.First().SourceLine;
            actor.parameters = new VarDeclaration[] { };
            actor.returnType = "Void";
        }
コード例 #17
0
        IEnumerable <TokenRange> SplitParameterList(TokenRange toks, string delimiter)
        {
            if (toks.Begin == toks.End)
            {
                yield break;
            }
            while (true)
            {
                Token comma = AngleBracketParser.NotInsideAngleBrackets(toks)
                              .FirstOrDefault(t => t.Value == delimiter && t.ParenDepth == toks.First().ParenDepth);
                if (comma == null)
                {
                    break;
                }
                yield return(range(toks.Begin, comma.Position));

                toks = range(comma.Position + 1, toks.End);
            }
            yield return(toks);
        }
コード例 #18
0
        Statement ParseCompoundStatement(TokenRange toks)
        {
            var first = toks.First(NonWhitespace);

            if (first.Value == "{")
            {
                var inBraces = first.GetMatchingRangeIn(toks);
                if (!range(inBraces.End, toks.End).Consume("}").All(Whitespace))
                {
                    throw new Error(inBraces.Last().SourceLine, "Unexpected tokens after compound statement");
                }
                return(ParseCodeBlock(inBraces));
            }
            else
            {
                List <Statement> statements = new List <Statement>();
                ParseStatement(toks.Skip(1), statements);
                return(statements[0]);
            }
        }
コード例 #19
0
        void ParseCatchStatement(TokenRange toks, Statement prevStatement)
        {
            var tryStatement = prevStatement as TryStatement;

            if (tryStatement == null)
            {
                throw new Error(toks.First().SourceLine, "catch without matching try");
            }
            var expr = toks.Consume("catch")
                       .First(NonWhitespace)
                       .Assert("Expected (", t => t.Value == "(")
                       .GetMatchingRangeIn(toks);

            tryStatement.catches.Add(
                new TryStatement.Catch
            {
                expression      = str(NormalizeWhitespace(expr)),
                body            = ParseCompoundStatement(range(expr.End + 1, toks.End)),
                FirstSourceLine = expr.First().SourceLine
            });
        }
コード例 #20
0
        void ParseActorHeading(Actor actor, TokenRange toks)
        {
            var template = toks.First(NonWhitespace);

            if (template.Value == "template")
            {
                var templateParams = range(template.Position + 1, toks.End)
                                     .First(NonWhitespace)
                                     .Assert("Invalid template declaration", t => t.Value == "<")
                                     .GetMatchingRangeIn(toks);

                actor.templateFormals = SplitParameterList(templateParams, ",")
                                        .Select(p => ParseVarDeclaration(p)) //< SOMEDAY: ?
                                        .ToArray();

                toks = range(templateParams.End + 1, toks.End);
            }
            var attribute = toks.First(NonWhitespace);

            while (attribute.Value == "[")
            {
                var attributeContents = attribute.GetMatchingRangeIn(toks);

                var asArray = attributeContents.ToArray();
                if (asArray.Length < 2 || asArray[0].Value != "[" || asArray[asArray.Length - 1].Value != "]")
                {
                    throw new Error(actor.SourceLine, "Invalid attribute: Expected [[...]]");
                }
                actor.attributes.Add("[" + str(NormalizeWhitespace(attributeContents)) + "]");
                toks = range(attributeContents.End + 1, toks.End);

                attribute = toks.First(NonWhitespace);
            }

            var staticKeyword = toks.First(NonWhitespace);

            if (staticKeyword.Value == "static")
            {
                actor.isStatic = true;
                toks           = range(staticKeyword.Position + 1, toks.End);
            }

            var uncancellableKeyword = toks.First(NonWhitespace);

            if (uncancellableKeyword.Value == "UNCANCELLABLE")
            {
                actor.SetUncancellable();
                toks = range(uncancellableKeyword.Position + 1, toks.End);
            }

            // Find the parameter list
            TokenRange paramRange = toks.Last(NonWhitespace)
                                    .Assert("Unexpected tokens after actor parameter list.",
                                            t => t.Value == ")" && t.ParenDepth == toks.First().ParenDepth)
                                    .GetMatchingRangeIn(toks);

            actor.parameters = SplitParameterList(paramRange, ",")
                               .Select(p => ParseVarDeclaration(p))
                               .ToArray();

            var name = range(toks.Begin, paramRange.Begin - 1).Last(NonWhitespace);

            actor.name = name.Value;

            // SOMEDAY: refactor?
            var returnType = range(toks.First().Position + 1, name.Position).SkipWhile(Whitespace);
            var retToken   = returnType.First();

            if (retToken.Value == "Future")
            {
                var ofType = returnType.Skip(1).First(NonWhitespace).Assert("Expected <", tok => tok.Value == "<").GetMatchingRangeIn(returnType);
                actor.returnType = str(NormalizeWhitespace(ofType));
                toks             = range(ofType.End + 1, returnType.End);
            }
            else if (retToken.Value == "void" /* && !returnType.Skip(1).Any(NonWhitespace)*/)
            {
                actor.returnType = null;
                toks             = returnType.Skip(1);
            }
            else
            {
                throw new Error(actor.SourceLine, "Actor apparently does not return Future<T>");
            }

            toks = toks.SkipWhile(Whitespace);
            if (!toks.IsEmpty)
            {
                if (toks.Last().Value == "::")
                {
                    actor.nameSpace = str(range(toks.Begin, toks.End - 1));
                }
                else
                {
                    Console.WriteLine("Tokens: '{0}' {1} '{2}'", str(toks), toks.Count(), toks.Last().Value);
                    throw new Error(actor.SourceLine, "Unrecognized tokens preceding parameter list in actor declaration");
                }
            }
            if (errorMessagePolicy.ActorsNoDiscardByDefault() && !actor.attributes.Contains("[[flow_allow_discard]]"))
            {
                if (actor.IsCancellable())
                {
                    actor.attributes.Add("[[nodiscard]]");
                }
            }
            HashSet <string> knownFlowAttributes = new HashSet <string>();

            knownFlowAttributes.Add("[[flow_allow_discard]]");
            foreach (var flowAttribute in actor.attributes.Where(a => a.StartsWith("[[flow_")))
            {
                if (!knownFlowAttributes.Contains(flowAttribute))
                {
                    throw new Error(actor.SourceLine, "Unknown flow attribute {0}", flowAttribute);
                }
            }
            actor.attributes = actor.attributes.Where(a => !a.StartsWith("[[flow_")).ToList();
        }
コード例 #21
0
        void ParseStatement(TokenRange toks, List <Statement> statements)
        {
            toks = toks.SkipWhile(Whitespace);

            Action <Statement> Add = stmt =>
            {
                stmt.FirstSourceLine = toks.First().SourceLine;
                statements.Add(stmt);
            };

            switch (toks.First().Value)
            {
            case "loop": Add(ParseLoopStatement(toks)); break;

            case "while": Add(ParseWhileStatement(toks)); break;

            case "for": Add(ParseForStatement(toks)); break;

            case "break": Add(new BreakStatement()); break;

            case "continue": Add(new ContinueStatement()); break;

            case "return": Add(ParseReturnStatement(toks)); break;

            case "{": Add(ParseCompoundStatement(toks)); break;

            case "if": Add(ParseIfStatement(toks)); break;

            case "else": ParseElseStatement(toks, statements[statements.Count - 1]); break;

            case "choose": Add(ParseChooseStatement(toks)); break;

            case "when": Add(ParseWhenStatement(toks)); break;

            case "try": Add(ParseTryStatement(toks)); break;

            case "catch": ParseCatchStatement(toks, statements[statements.Count - 1]); break;

            case "throw": Add(ParseThrowStatement(toks)); break;

            default:
                if (IllegalKeywords.Contains(toks.First().Value))
                {
                    throw new Error(toks.First().SourceLine, "Statement '{0}' not supported in actors.", toks.First().Value);
                }
                if (toks.Any(t => t.Value == "wait" || t.Value == "waitNext"))
                {
                    Add(ParseWaitStatement(toks));
                }
                else if (toks.First().Value == "state")
                {
                    Add(ParseStateDeclaration(toks));
                }
                else if (toks.First().Value == "switch" && toks.Any(t => t.Value == "return"))
                {
                    throw new Error(toks.First().SourceLine, "Unsupported compound statement containing return.");
                }
                else if (toks.RevSkipWhile(t => t.Value == ";").Any(NonWhitespace))
                {
                    Add(new PlainOldCodeStatement
                    {
                        code = str(NormalizeWhitespace(toks.RevSkipWhile(t => t.Value == ";"))) + ";"
                    });
                }
                break;
            }
            ;
        }
コード例 #22
0
        IEnumerable <Token> NormalizeWhitespace(IEnumerable <Token> tokens)
        {
            bool inWhitespace = false;
            bool leading      = true;

            foreach (var tok in tokens)
            {
                if (!tok.IsWhitespace)
                {
                    if (inWhitespace && !leading)
                    {
                        yield return new Token {
                                   Value = " "
                        }
                    }
                    ;
                    inWhitespace = false;
                    yield return(tok);

                    leading = false;
                }
                else
                {
                    inWhitespace = true;
                }
            }
        }

        void ParseDeclaration(TokenRange tokens,
                              out Token name,
                              out TokenRange type,
                              out TokenRange initializer,
                              out bool constructorSyntax)
        {
            initializer = null;
            TokenRange beforeInitializer = tokens;

            constructorSyntax = false;

            Token equals = AngleBracketParser.NotInsideAngleBrackets(tokens)
                           .FirstOrDefault(t => t.Value == "=" && t.ParenDepth == tokens.First().ParenDepth);

            if (equals != null)
            {
                // type name = initializer;
                beforeInitializer = range(tokens.Begin, equals.Position);
                initializer       = range(equals.Position + 1, tokens.End);
            }
            else
            {
                Token paren = AngleBracketParser.NotInsideAngleBrackets(tokens)
                              .FirstOrDefault(t => t.Value == "(");
                if (paren != null)
                {
                    // type name(initializer);
                    constructorSyntax = true;
                    beforeInitializer = range(tokens.Begin, paren.Position);
                    initializer       =
                        range(paren.Position + 1, tokens.End)
                        .TakeWhile(t => t.ParenDepth > paren.ParenDepth);
                }
            }
            name = beforeInitializer.Last(NonWhitespace);
            if (beforeInitializer.Begin == name.Position)
            {
                throw new Error(beforeInitializer.First().SourceLine, "Declaration has no type.");
            }
            type = range(beforeInitializer.Begin, name.Position);
        }

        VarDeclaration ParseVarDeclaration(TokenRange tokens)
        {
            Token      name;
            TokenRange type, initializer;
            bool       constructorSyntax;

            ParseDeclaration(tokens, out name, out type, out initializer, out constructorSyntax);
            return(new VarDeclaration
            {
                name = name.Value,
                type = str(NormalizeWhitespace(type)),
                initializer = initializer == null ? "" : str(NormalizeWhitespace(initializer)),
                initializerConstructorSyntax = constructorSyntax
            });
        }
コード例 #23
0
        void ParseActorHeading(Actor actor, TokenRange toks)
        {
            var template = toks.First(NonWhitespace);

            if (template.Value == "template")
            {
                var templateParams = range(template.Position + 1, toks.End)
                                     .First(NonWhitespace)
                                     .Assert("Invalid template declaration", t => t.Value == "<")
                                     .GetMatchingRangeIn(toks);

                actor.templateFormals = SplitParameterList(templateParams, ",")
                                        .Select(p => ParseVarDeclaration(p)) //< SOMEDAY: ?
                                        .ToArray();

                toks = range(templateParams.End + 1, toks.End);
            }

            var staticKeyword = toks.First(NonWhitespace);

            if (staticKeyword.Value == "static")
            {
                actor.isStatic = true;
                toks           = range(staticKeyword.Position + 1, toks.End);
            }

            var uncancellableKeyword = toks.First(NonWhitespace);

            if (uncancellableKeyword.Value == "UNCANCELLABLE")
            {
                actor.isUncancellable = true;
                toks = range(uncancellableKeyword.Position + 1, toks.End);
            }

            // Find the parameter list
            TokenRange paramRange = toks.Last(NonWhitespace)
                                    .Assert("Unexpected tokens after actor parameter list.",
                                            t => t.Value == ")" && t.ParenDepth == toks.First().ParenDepth)
                                    .GetMatchingRangeIn(toks);

            actor.parameters = SplitParameterList(paramRange, ",")
                               .Select(p => ParseVarDeclaration(p))
                               .ToArray();

            var name = range(toks.Begin, paramRange.Begin - 1).Last(NonWhitespace);

            actor.name = name.Value;

            // SOMEDAY: refactor?
            var returnType = range(toks.First().Position + 1, name.Position).SkipWhile(Whitespace);
            var retToken   = returnType.First();

            if (retToken.Value == "Future")
            {
                var ofType = returnType.Skip(1).First(NonWhitespace).Assert("Expected <", tok => tok.Value == "<").GetMatchingRangeIn(returnType);
                actor.returnType = str(NormalizeWhitespace(ofType));
                toks             = range(ofType.End + 1, returnType.End);
            }
            else if (retToken.Value == "void" /* && !returnType.Skip(1).Any(NonWhitespace)*/)
            {
                actor.returnType = null;
                toks             = returnType.Skip(1);
            }
            else
            {
                throw new Error(actor.SourceLine, "Actor apparently does not return Future<T>");
            }

            toks = toks.SkipWhile(Whitespace);
            if (!toks.IsEmpty)
            {
                if (toks.Last().Value == "::")
                {
                    actor.nameSpace = str(range(toks.Begin, toks.End - 1));
                }
                else
                {
                    Console.WriteLine("Tokens: '{0}' {1} '{2}'", str(toks), toks.Count(), toks.Last().Value);
                    throw new Error(actor.SourceLine, "Unrecognized tokens preceding parameter list in actor declaration");
                }
            }
        }
コード例 #24
0
 LoopStatement ParseLoopStatement(TokenRange toks)
 {
     return(new LoopStatement {
         body = ParseCompoundStatement(toks.Consume("loop"))
     });
 }