Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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));
            }
        }