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; }