StateDeclarationStatement ParseStateDeclaration(TokenRange toks) { toks = toks.Consume("state").RevSkipWhile(t => t.Value == ";"); return(new StateDeclarationStatement { decl = ParseVarDeclaration(toks) }); }
ChooseStatement ParseChooseStatement(TokenRange toks) { return(new ChooseStatement { body = ParseCompoundStatement(toks.Consume("choose")) }); }
Statement ParseTryStatement(TokenRange toks) { return(new TryStatement { tryBody = ParseCompoundStatement(toks.Consume("try")), catches = new List <TryStatement.Catch>() // will be filled in later by ParseCatchStatement }); }
ThrowStatement ParseThrowStatement(TokenRange toks) { toks = toks.Consume("throw").RevSkipWhile(t => t.Value == ";"); return(new ThrowStatement { expression = str(NormalizeWhitespace(toks)) }); }
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); }
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)) }); }
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 }); }
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)) }); }
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)) }); }
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")); }
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 }); }
LoopStatement ParseLoopStatement(TokenRange toks) { return(new LoopStatement { body = ParseCompoundStatement(toks.Consume("loop")) }); }