예제 #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;
 }
예제 #2
0
        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);
        }