public Expression Parse(Parser parser, Token token, out bool trailingSemicolon) { trailingSemicolon = false; parser.Take(TokenType.LeftParen); BlockExpression initializer = null; if (!parser.Match(TokenType.Semicolon)) { var initializerExpr = parser.ParseStatement(false); if (initializerExpr is IStatementExpression && !(initializerExpr is VarExpression)) throw new MondCompilerException(token, CompilerError.BadForLoopInitializer); initializer = new BlockExpression(new List<Expression>() { initializerExpr }); } parser.Take(TokenType.Semicolon); Expression condition = null; if (!parser.Match(TokenType.Semicolon)) condition = parser.ParseExpression(); parser.Take(TokenType.Semicolon); BlockExpression increment = null; if (!parser.Match(TokenType.RightParen)) { var statements = new List<Expression>(); do { statements.Add(parser.ParseExpression()); if (!parser.Match(TokenType.Comma)) break; parser.Take(TokenType.Comma); } while (true); increment = new BlockExpression(statements); } parser.Take(TokenType.RightParen); var block = new ScopeExpression(parser.ParseBlock()); return new ForExpression(token, initializer, condition, increment, block); }
public Expression Parse(Parser parser, Token token, out bool trailingSemicolon) { trailingSemicolon = false; parser.Take(TokenType.LeftParen); var condition = parser.ParseExpession(); parser.Take(TokenType.RightParen); var block = new ScopeExpression(parser.ParseBlock()); return new WhileExpression(token, condition, block); }
public Expression Parse(Parser parser, Token token, out bool trailingSemicolon) { trailingSemicolon = false; parser.Take(TokenType.LeftParen); Expression initializer = null; if (!parser.Match(TokenType.Semicolon)) initializer = parser.ParseStatement(false); if (initializer is IBlockStatementExpression) throw new MondCompilerException(token.FileName, token.Line, "For loop initializer can not be block statement"); parser.Take(TokenType.Semicolon); Expression condition = null; if (!parser.Match(TokenType.Semicolon)) condition = parser.ParseExpession(); parser.Take(TokenType.Semicolon); BlockExpression increment = null; if (!parser.Match(TokenType.RightParen)) { var statements = new List<Expression>(); do { statements.Add(parser.ParseStatement(false)); if (!parser.Match(TokenType.Comma)) break; parser.Take(TokenType.Comma); } while (true); increment = new BlockExpression(token, statements); } parser.Take(TokenType.RightParen); var block = new ScopeExpression(parser.ParseBlock()); return new ForExpression(token, initializer, condition, increment, block); }
public Expression Parse(Parser parser, Token token, out bool trailingSemicolon) { trailingSemicolon = false; var first = true; var branches = new List<IfExpression.Branch>(); IfExpression.Branch elseBranch = null; do { var isDefaultBlock = !first && !parser.MatchAndTake(TokenType.If); first = false; Expression condition = null; if (!isDefaultBlock) { parser.Take(TokenType.LeftParen); condition = parser.ParseExpession(); parser.Take(TokenType.RightParen); } var block = new ScopeExpression(parser.ParseBlock()); var branch = new IfExpression.Branch(condition, block); if (isDefaultBlock) elseBranch = branch; else branches.Add(branch); if (isDefaultBlock) break; } while (parser.MatchAndTake(TokenType.Else)); return new IfExpression(token, branches, elseBranch); }
public static void ParseFunction( Parser parser, Token token, bool isStatement, out bool trailingSemicolon, out string name, out List<string> arguments, out string otherArgs, out bool isOperator, out ScopeExpression body) { trailingSemicolon = false; name = null; arguments = new List<string>(); otherArgs = null; isOperator = false; // only statements can be named if (isStatement) { if (parser.MatchAndTake(TokenType.LeftParen)) { var operatorToken = parser.Take(TokenType.UserDefinedOperator); parser.Take(TokenType.RightParen); isOperator = true; name = operatorToken.Contents; } else { name = parser.Take(TokenType.Identifier).Contents; } } // parse argument list parser.Take(TokenType.LeftParen); if (!parser.Match(TokenType.RightParen)) { while (true) { if (parser.MatchAndTake(TokenType.Ellipsis)) { otherArgs = parser.Take(TokenType.Identifier).Contents; break; } var identifier = parser.Take(TokenType.Identifier); arguments.Add(identifier.Contents); if (parser.Match(TokenType.RightParen)) break; parser.Take(TokenType.Comma); } } parser.Take(TokenType.RightParen); if (isOperator) { if (arguments.Count != 1 && arguments.Count != 2) throw new MondCompilerException(token, CompilerError.IncorrectOperatorArity, arguments.Count); if (otherArgs != null) throw new MondCompilerException(token, CompilerError.EllipsisInOperator); } // parse body if (parser.MatchAndTake(TokenType.Pointy)) { body = new ScopeExpression(new List<Expression> { new ReturnExpression(parser.Peek(), parser.ParseExpression()) }); trailingSemicolon = true; } else { body = new ScopeExpression(parser.ParseBlock(false)); } }