Пример #1
0
        Statement tstmt()
        {
            int        l = next.line;
            int        c = next.col;
            Statement  s, s1, s2;
            Expression e;

            if (t == TokenKind.OpeningCurlyBrace)
            {
                return(block());
            }
            else if (t == TokenKind.If)
            {
                move(); e = expr(); if (t == TokenKind.Then)
                {
                    move();
                }
                s = stmt();
                if (t == TokenKind.Else)
                {
                    move();
                    return(new If(e, s, stmt(), l, c));
                }
                return(new If(e, s, l, c));
            }
            else if (t == TokenKind.While)
            {
                move(); e = expr(); if (t == TokenKind.Do)
                {
                    move();
                }
                return(new While(e, stmt(), l, c));
            }
            else if (t == TokenKind.Do)
            {
                move();
                s = stmt();
                match(Token.Until, Error.ExpectedUntil);
                return(new Do(s, expr(), l, c));
            }
            else if (t == TokenKind.For)
            {
                // "For" is very weird in GM. Any legal statement including control flow and blocks can be used in for.
                // example of legal "for" statements:
                // for (i = 0 i<3; {case 3:exit};;;)func();
                move();
                match(Token.OpeningParenthesis);
                s1 = stmt();
                //match(Token.Semicolon); // Taken care of by stmt();
                e = expr();
                match(Token.Semicolon);
                s2 = stmt();
                match(Token.ClosingParenthesis);
                return(new For(s1, e, s2, stmt(), l, c));
            }
            else if (t == TokenKind.Break)
            {
                move();
                return(new Break(l, c));
            }
            else if (t == TokenKind.Continue)
            {
                move();
                return(new Continue(l, c));
            }
            else if (t == TokenKind.Exit)
            {
                move();
                return(new Exit(l, c));
            }
            else if (t == TokenKind.Return)
            {
                move();
                return(new Return(expr(), l, c));
            }
            else if (t == TokenKind.Repeat)
            {
                move();
                return(new Repeat(expr(), stmt(), l, c));
            }
            else if (t == TokenKind.Var)
            {
                move();
                List <string> strs = new List <string>();
                while (t == TokenKind.Identifier)
                {
                    if (peek().t == TokenKind.OpeningParenthesis)
                    {
                        break;
                    }
                    if (Context.IsBuiltIn(next.lexeme))
                    {
                        error(Error.BuiltinVariable);
                    }
                    strs.Add(next.lexeme);
                    move();
                    if (t == TokenKind.Comma)
                    {
                        move();
                    }
                }
                return(new Var(strs.ToArray(), l, c));
            }
            else if (t == TokenKind.Globalvar)
            {
                move();
                List <string> strs = new List <string>();
                while (t == TokenKind.Identifier)
                {
                    if (peek().t == TokenKind.OpeningParenthesis)
                    {
                        break;
                    }
                    if (Context.IsBuiltIn(next.lexeme))
                    {
                        error(Error.BuiltinVariable);
                    }
                    strs.Add(next.lexeme);
                    move();
                    if (t == TokenKind.Comma)
                    {
                        move();
                    }
                }
                return(new Globalvar(strs.ToArray(), l, c));
            }
            else if (t == TokenKind.With)
            {
                move();
                e = expr();
                if (t == TokenKind.Do)
                {
                    move();
                }
                return(new With(e, stmt(), l, c));
            }
            else if (t == TokenKind.Default)
            {
                move();
                match(Token.Colon);
                return(new Default(l, c));
            }
            else if (t == TokenKind.Case)
            {
                move();
                Case @case = new Case(expr(), l, c); // @ since case is a keyword
                match(Token.Colon);
                return(@case);
            }
            else if (t == TokenKind.Switch)
            {
                move();
                e = expr();
                match(Token.OpeningCurlyBrace);
                List <Statement> lst = new List <Statement>();
                while (t != TokenKind.ClosingCurlyBrace && t != TokenKind.Eof)
                {
                    lst.Add(stmt());
                    while (t == TokenKind.Semicolon)
                    {
                        move();
                    }
                }
                match(Token.ClosingCurlyBrace);
                return(new Switch(e, lst.ToArray(), l, c));
            }
            else if (t == TokenKind.Identifier)
            {
                if (peek().t == TokenKind.OpeningParenthesis)
                {
                    string str = next.lexeme;
                    if (!Context.Resources.FunctionExists(str))
                    {
                        error(Error.UnknownFunction, str);
                    }
                    move(); move();
                    List <Expression> exprs = new List <Expression>();
                    if (t != TokenKind.ClosingParenthesis && t != TokenKind.Eof)
                    {
                        exprs.Add(expr());
                    }
                    while (t == TokenKind.Comma)
                    {
                        move();
                        exprs.Add(expr());
                    }
                    match(Token.ClosingParenthesis);
                    IFunction f = Context.Resources.GetFunction(str);
                    if ((f.Argc != -1 && exprs.Count != f.Argc) || exprs.Count > 16)
                    {
                        error(Error.WrongArgumentNumber);
                    }
                    return(new CallStatement(f, exprs.ToArray(), l, c));
                }
                else
                {
                    return(assign());
                }
            }
            else
            {
                return(assign());
            }
        }