Exemple #1
0
 public abstract void VisitCaseLabel(Case p);
 public abstract void VisitCaseLabel(Case p);
 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();
     }
 }