示例#1
0
文件: Parser.cs 项目: RoboLOGO/IDE
 Stmt ParseStmt(bool in_dec = false)
 {
     Sequence result = new Sequence();
     Stmt stmt = new Nop();
     bool breaked = false;
     if (Index == Tokens.Count)
     {     // Already got EOF?
         throw new RPExeption(20, App.Current.TryFindResource("x_nexpend").ToString(), Line, Column);
     }
     while (Index < Tokens.Count && !breaked)
     {
         switch (Config.In(Tokens[Index]).Name)
         {
             case "Forward":
                 Index++;
                 var stmtForward = new Forward();
                 stmtForward.Expression = ParseExpr();
                 stmt = stmtForward;
                 break;
             case "Backward":
                 Index++;
                 var stmtBackward = new Backward();
                 stmtBackward.Expression = ParseExpr();
                 stmt = stmtBackward;
                 break;
             case "Right":
                 Index++;
                 var stmtRight = new Right();
                 stmtRight.Expression = ParseExpr();
                 stmt = stmtRight;
                 break;
             case "Left":
                 Index++;
                 var stmtLeft = new Left();
                 stmtLeft.Expression = ParseExpr();
                 stmt = stmtLeft;
                 break;
             case "PenUp":
                 Index++;
                 stmt = new PenUp();
                 break;
             case "PenDown":
                 Index++;
                 stmt = new PenDown();
                 break;
             case "Home":
                 Index++;
                 stmt = new Home();
                 break;
             case "Clear":
                 Index++;
                 stmt = new Clear();
                 break;
             case "DeclareFunction":
                 if (in_dec)
                 {        // Are we already declarating a function?
                     throw new RPExeption(21, App.Current.TryFindResource("x_cdfif").ToString(), Line, Column);
                 }
                 var stmtDeclareFunction = new DeclareFunction();
                 // Read function name
                 Index++;
                 if (Index < Tokens.Count && Tokens[Index].isStr)
                 {
                     stmtDeclareFunction.Identity = (string)Tokens[Index];
                 }
                 else
                 {
                     throw new RPExeption(22, App.Current.TryFindResource("x_expfn").ToString(), Line, Column);
                 }
                 // Read parameters if any
                 Index++;
                 while (Index + 1 < Tokens.Count && Tokens[Index].Equals(Scanner.ValueOf) && Tokens[Index + 1].isStr)
                 {
                     stmtDeclareFunction.Parameters.Add((string)Tokens[Index + 1]);
                     Index += 2;
                 }
                 if (Index == Tokens.Count)
                 {
                     throw new RPExeption(23, App.Current.TryFindResource("x_expfb").ToString(), Line, Column);
                 }
                 // Add function to the functions list
                 FuncDef.Add(stmtDeclareFunction.Identity, stmtDeclareFunction);
                 // Parse body
                 stmtDeclareFunction.Body = ParseStmt(true);
                 // End of function
                 if (Index == Tokens.Count || Tokens[Index].isStr && Config.Primitives.ContainsKey((string)Tokens[Index]) && Config.Primitives[(string)Tokens[Index]] == "End")
                 {
                     throw new RPExeption(24, App.Current.TryFindResource("x_expendttd").ToString(), Line, Column);
                 }
                 Index++;
                 stmt = stmtDeclareFunction;
                 break;
             case "Output":
                 Index++;
                 var stmtOutput = new Output();
                 stmtOutput.Expression = ParseExpr();
                 stmt = stmtOutput;
                 break;
             case "Stop":
                 Index++;
                 stmt = new Stop();
                 break;
             case "IfElse":
                 var stmtIfElse = new IfElse();
                 // Parse the condition
                 Index++;
                 stmtIfElse.Condition = ParseExpr();
                 // Parse the true branch
                 if (Index == Tokens.Count || !Tokens[Index].Equals(Scanner.BodyStart))
                 {
                     throw new RPExeption(25, App.Current.TryFindResource("x_expzbb").ToString(), Line, Column);
                 }
                 Index++;
                 stmtIfElse.True = ParseStmt(in_dec);
                 if (Index == Tokens.Count || !Tokens[Index].Equals(Scanner.BodyEnd))
                 {
                     throw new RPExeption(26, App.Current.TryFindResource("x_expzab").ToString(), Line, Column);
                 }
                 // Parse the false branch if any
                 Index++;
                 if (Index < Tokens.Count && Tokens[Index].Equals(Scanner.BodyStart))
                 {
                     Index++;
                     stmtIfElse.False = ParseStmt(in_dec);
                     if (Index == Tokens.Count || !Tokens[Index].Contains.Equals(Scanner.BodyEnd))
                     {
                         throw new RPExeption(26, App.Current.TryFindResource("x_expzab").ToString(), Line, Column);
                     }
                     Index++;
                 }
                 else
                 {
                     stmtIfElse.False = new Nop();
                 }
                 stmt = stmtIfElse;
                 break;
             case "Loop":
                 var stmtLoop = new Loop();
                 // Parse expression
                 Index++;
                 stmtLoop.Repeat = ParseExpr();
                 // Parse the body
                 if (Index == Tokens.Count || !Tokens[Index].Equals(Scanner.BodyStart))
                 {
                     throw new RPExeption(25, App.Current.TryFindResource("x_expzbb").ToString(), Line, Column);
                 }
                 Index++;
                 stmtLoop.Body = ParseStmt(in_dec);
                 if (Index == Tokens.Count || !Tokens[Index].Equals(Scanner.BodyEnd))
                 {
                     throw new RPExeption(26, App.Current.TryFindResource("x_expzab").ToString(), Line, Column);
                 }
                 Index++;
                 stmt = stmtLoop;
                 break;
             case "While":
                 var stmtWhile = new While();
                 Index++;
                 if (Index == Tokens.Count || !Tokens[Index].Equals(Scanner.BodyStart))
                 {
                     throw new RPExeption(30, App.Current.TryFindResource("x_expzbtce").ToString(), Line, Column);
                 }
                 Index++;
                 stmtWhile.Condition = ParseExpr();
                 if (Index == Tokens.Count || !Tokens[Index].Equals(Scanner.BodyEnd))
                 {
                     throw new RPExeption(31, App.Current.TryFindResource("x_expzatce").ToString(), Line, Column);
                 }
                 Index++;
                 // Parse the body
                 if (Index == Tokens.Count || !Tokens[Index].Equals(Scanner.BodyStart))
                 {
                     throw new RPExeption(25, App.Current.TryFindResource("x_expzbb").ToString(), Line, Column);
                 }
                 Index++;
                 stmtWhile.Body = ParseStmt(in_dec);
                 if (Index == Tokens.Count || !Tokens[Index].Equals(Scanner.BodyEnd))
                 {
                     throw new RPExeption(26, App.Current.TryFindResource("x_expzab").ToString(), Line, Column);
                 }
                 Index++;
                 stmt = stmtWhile;
                 break;
             case "Forever":
                 var stmtForever = new Forever();
                 Index++;
                 // Parse the body
                 if (Index == Tokens.Count || !Tokens[Index].Equals(Scanner.BodyStart))
                 {
                     throw new RPExeption(25, App.Current.TryFindResource("x_expzbb").ToString(), Line, Column);
                 }
                 Index++;
                 stmtForever.Body = ParseStmt(in_dec);
                 if (Index == Tokens.Count || !Tokens[Index].Equals(Scanner.BodyEnd))
                 {
                     throw new RPExeption(26, App.Current.TryFindResource("x_expzab").ToString(), Line, Column);
                 }
                 Index++;
                 stmt = stmtForever;
                 break;
             case "Print":
                 Index++;
                 var stmtPrint = new Print();
                 stmtPrint.Text = ParseExpr();
                 stmt = stmtPrint;
                 break;
             case "DeclareVariable":
                 var stmtDeclareVariable = new DeclareVariable();
                 Index += 2;
                 if (Index < Tokens.Count && Tokens[Index - 1].Equals(Scanner.AsIs))
                 {
                     stmtDeclareVariable.Identity = (string)Tokens[Index];
                 }
                 else
                 {
                     throw new RPExeption(27, App.Current.TryFindResource("x_expvarname").ToString(), Line, Column);
                 }
                 // Do the math
                 Index++;
                 stmtDeclareVariable.Expression = ParseExpr();
                 stmt = stmtDeclareVariable;
                 break;
             default:
                 if (Tokens[Index].isStr)
                 {
                     if (Tokens[Index].Equals("language"))
                     {
                         Index++;
                         Config.Load();
                         Index++;
                         continue;
                     }
                     else if (Tokens[Index].Equals(Scanner.BodyEnd))
                     {
                         breaked = true;
                         continue;
                     }
                     else if (Tokens[Index].Equals(Config.Primitives["End"]))
                     {
                         if (!in_dec)
                             throw new RPExeption(23, App.Current.TryFindResource("x_expfb").ToString(), Line, Column);
                         else breaked = true;
                         continue;
                     }
                     else if (!FuncDef.ContainsKey((string)Tokens[Index]))
                     {
                         throw new RPExeption(28, App.Current.TryFindResource("x_unknid").ToString() + (string)Tokens[Index] + "'", Line, Column);
                     }
                     else
                     {
                         var stmtCallFunction = new CallFunction();
                         stmtCallFunction.Identity = (string)Tokens[Index];
                         var P = FuncDef[(string)Tokens[Index]].Parameters.Count;
                         int i = 0;
                         Index++;
                         while (Index < Tokens.Count && i < P)
                         {
                             stmtCallFunction.Parameters.Add(ParseExpr());
                             i++;
                         }
                         if (Index == Tokens.Count && i < P)
                         {
                             throw new RPExeption(29, App.Current.TryFindResource("x_fparnm").ToString(), Line, Column);
                         }
                         stmt = stmtCallFunction;
                     }
                 }
                 else
                 {
                     throw new RPExeption(99, App.Current.TryFindResource("x_unkncomm").ToString(), Line, Column);
                 }
                 break;
         }
         result.Statements.Add(stmt);
     }
     return result;
 }