// // Helper routine for parsing a code entity from a token stream. // // This terminology is mostly legacy from an older implementation of Epoch. // An entity is really just a branch/flow-control construct such as a loop // or an if/else statement. Typically there is an expression which controls // execution and an associated code block. // internal static bool ParseEntity(ParseSession parser, LexicalScope parentscope, int starttoken, out int consumedtokens) { consumedtokens = starttoken; int totaltokens = starttoken; if (parser.CheckToken(totaltokens, "if")) { if (!parser.CheckToken(totaltokens + 1, "(")) { return(false); } totaltokens += 2; var expr = Expression.Parse(parser, totaltokens, out totaltokens); if (expr == null) { throw new SyntaxError("if() statement must be supplied with a valid Boolean-typed expression", parser.ReversePeekToken()); } while (parser.CheckToken(totaltokens, ")")) { ++totaltokens; } if (!parser.CheckToken(totaltokens, "{")) { throw new SyntaxError("if() statement must be followed by a code block surrounded in braces { }", parser.PeekToken(totaltokens)); } ++totaltokens; LexicalScope.Parse(parser, parentscope, totaltokens, out totaltokens); while (parser.CheckToken(totaltokens, "elseif")) { totaltokens += 2; var condexpr = Expression.Parse(parser, totaltokens, out totaltokens); if (condexpr == null) { throw new SyntaxError("elseif() statement must be supplied with a valid Boolean-typed expression", parser.ReversePeekToken()); } while (parser.CheckToken(totaltokens, ")")) { ++totaltokens; } if (!parser.CheckToken(totaltokens, "{")) { throw new SyntaxError("elseif() statement must be followed by a code block surrounded in braces { }", parser.PeekToken(totaltokens)); } ++totaltokens; LexicalScope.Parse(parser, parentscope, totaltokens, out totaltokens); } if (parser.CheckToken(totaltokens, "else")) { ++totaltokens; if (!parser.CheckToken(totaltokens, "{")) { throw new SyntaxError("else statement must be followed by a code block surrounded in braces { }", parser.PeekToken(totaltokens)); } ++totaltokens; LexicalScope.Parse(parser, parentscope, totaltokens, out totaltokens); } consumedtokens = totaltokens; return(true); } else if (parser.CheckToken(totaltokens, "while")) { if (!parser.CheckToken(totaltokens + 1, "(")) { throw new SyntaxError("while() statement must be supplied with a valid Boolean-typed expression", parser.ReversePeekToken()); } totaltokens += 2; while (parser.CheckToken(totaltokens, ")")) { ++totaltokens; } var expr = Expression.Parse(parser, totaltokens, out totaltokens); ++totaltokens; if (!parser.CheckToken(totaltokens, "{")) { throw new SyntaxError("while() statement must be followed by a code block surrounded in braces { }", parser.PeekToken(totaltokens)); } ++totaltokens; LexicalScope.Parse(parser, parentscope, totaltokens, out totaltokens); consumedtokens = totaltokens; return(true); } return(false); }