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); }
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; } ; }