예제 #1
0
        private Stmt ParseStmt()
        {
            Stmt result;

            if (index == tokens.Count)
            {
                throw new System.Exception("expected statement, got EOF");
            }

            // print
            if (tokens[index] == Tokens.Print)
            {
                MoveNext();
                Print print = new Print();
                print.Expr = ParseExpr();
                result     = print;
            }

            // printline
            else if (tokens[index] == Tokens.PrintLine)
            {
                MoveNext();
                PrintLine printLine = new PrintLine();
                printLine.Expr = ParseExpr();
                result         = printLine;
            }

            // clear
            else if (tokens[index] == Tokens.Clear)
            {
                Clear clearStmt = new Clear();
                MoveNext();

                clearStmt.Tag = "_Clear_";  // for debug

                result = clearStmt;
            }

            // var
            else if (tokens[index] == Tokens.Var)
            {
                MoveNext();

                DeclareVar declareVar = new DeclareVar();

                if (index < tokens.Count &&
                    tokens[index] is IdentifierToken)
                {
                    declareVar.Ident = ((IdentifierToken)tokens[index]).Name;
                }
                else
                {
                    throw new System.Exception("expected variable name after 'var'");
                }

                MoveNext();

                if (index == tokens.Count ||
                    tokens[index] != Tokens.Assignment)
                {
                    throw new System.Exception("expected = after 'var ident'");
                }

                MoveNext();

                declareVar.Expr = ParseExpr();
                result          = declareVar;
            }

            // readvar
            else if (tokens[index] == Tokens.ReadVar)
            {
                ReadVar  readVar = new ReadVar();
                Expr     expr;
                Variable var;

                MoveNext();

                Eat(Tokens.LeftCurlyBracket);

                while ((tokens[index] != Tokens.RightCurlyBracket) &&
                       (index < tokens.Count))
                {
                    var  = new Variable();
                    expr = ParseExpr();

                    Eat(Tokens.Colon);
                    var.Ident = ((IdentifierToken)tokens[index]).Name;
                    MoveNext();
                    readVar.Vars.Add(var, expr);

                    if (tokens[index] == Tokens.Comma)
                    {
                        MoveNext(); // Skip comma
                    }
                    else if (tokens[index] == Tokens.RightCurlyBracket)
                    {
                        break;
                    }
                    else
                    {
                        throw new System.Exception("unexpected character in arg list");
                    }
                }

                if (index == tokens.Count ||
                    tokens[index] != Tokens.RightCurlyBracket)
                {
                    throw new System.Exception("expect close curly bracket after open bracket/args");
                }

                result = readVar;

                // Skip RightCurlyBracket
                Eat(Tokens.RightCurlyBracket);
            }

            // for
            else if (tokens[index] == Tokens.For)
            {
                ForLoop forLoop = new ForLoop();
                MoveNext();

                if (index < tokens.Count &&
                    tokens[index] is IdentifierToken)
                {
                    forLoop.Ident = ((IdentifierToken)tokens[index]).Name;
                }
                else
                {
                    throw new System.Exception("expected identifier after 'for'");
                }

                MoveNext();

                if (index == tokens.Count ||
                    tokens[index] != Tokens.Assignment)
                {
                    throw new System.Exception("for missing '='");
                }
                MoveNext();

                forLoop.From = ParseExpr();

                if (index == tokens.Count ||
                    tokens[index] != Tokens.To)
                {
                    throw new System.Exception("expected 'to' after for");
                }
                MoveNext();

                forLoop.To = ParseExpr();

                // Body for loop
                forLoop.Body = ParseStmt();
                result       = forLoop;

                // end for
                if (index == tokens.Count ||
                    tokens[index] != Tokens.EndSequence)
                {
                    throw new System.Exception("unterminated 'end for' loop body");
                }
                MoveNext();
                if (!MaybeEat(Tokens.For))
                {
                    throw new System.Exception("unterminated 'for' body");
                }
            }

            // foreach
            else if (tokens[index] == Tokens.ForEach)
            {
                ForEachLoop forEachLoop = new ForEachLoop();
                MoveNext();

                if (index < tokens.Count &&
                    tokens[index] is IdentifierToken)
                {
                    forEachLoop.Ident = ((IdentifierToken)tokens[index]).Name;
                }
                else
                {
                    throw new System.Exception("expected identifier after 'for'");
                }

                MoveNext();

                if (index == tokens.Count ||
                    tokens[index] != Tokens.In)
                {
                    throw new System.Exception("foreach missing 'in '");
                }
                MoveNext();

                forEachLoop.Colec = ParseExpr();

                // Body for loop
                forEachLoop.Body = ParseStmt();
                result           = forEachLoop;

                // end for
                if (index == tokens.Count ||
                    tokens[index] != Tokens.EndSequence)
                {
                    throw new System.Exception("unterminated 'end foreach' loop body");
                }
                MoveNext();
                if (!MaybeEat(Tokens.ForEach))
                {
                    throw new System.Exception("unterminated 'for' body");
                }
            }

            // if
            else if (tokens[index] == Tokens.If)
            {
                IfStmt ifStmt = new IfStmt();
                MoveNext();

                ifStmt.TestExpr = ParseExpr();

                if (index == tokens.Count ||
                    tokens[index] != Tokens.Then)
                {
                    throw new System.Exception("expected 'then' after if");
                }
                MoveNext();

                ifStmt.BodyIf = ParseStmt();

                // Does else
                ifStmt.DoElse = MaybeEat(Tokens.Else);
                if (ifStmt.DoElse)
                {
                    ifStmt.BodyElse = ParseStmt();
                }

                result = ifStmt;

                if (index == tokens.Count ||
                    tokens[index] != Tokens.EndSequence)
                {
                    throw new System.Exception("unterminated 'end if' body");
                }
                MoveNext();
                if (!MaybeEat(Tokens.If))
                {
                    throw new System.Exception("unterminated 'if' body");
                }
            }

            // while
            else if (tokens[index] == Tokens.While)
            {
                WhileStmt whileStmt = new WhileStmt();
                MoveNext();

                whileStmt.TestExpr = ParseExpr();
                whileStmt.Body     = ParseStmt();

                result = whileStmt;

                if (index == tokens.Count ||
                    tokens[index] != Tokens.EndSequence)
                {
                    throw new System.Exception("unterminated 'end while' body");
                }
                MoveNext();
                if (!MaybeEat(Tokens.While))
                {
                    throw new System.Exception("unterminated 'while' body");
                }
            }

            // break
            else if (tokens[index] == Tokens.Break)
            {
                BreakStmt breakStmt = new BreakStmt();
                MoveNext();

                breakStmt.Tag = "_Break_";  // for debug

                result = breakStmt;
            }

            // assignment or funcionStmt
            else if (tokens[index] is IdentifierToken)
            {
                string ident = ((IdentifierToken)tokens[index]).Name;

                MoveNext();

                if (MaybeEat(Tokens.Assignment))
                {
                    Assign assign = new Assign();
                    assign.Ident = ident;
                    assign.Expr  = ParseExpr();
                    result       = assign;
                }
                else if (MaybeEat(Tokens.LeftBracket))
                {
                    FunctionStmt functionStmt = new FunctionStmt();
                    functionStmt.Function = ParseFunction(ident);
                    result = functionStmt;
                }
                else
                {
                    throw new System.Exception("expected assing or function call");
                }
            }

            else
            {
                throw new System.Exception("parse error at token " + index + ": " + tokens[index].Name);
            }

            if ((index < tokens.Count && tokens[index] == Tokens.Semi))
            {
                MoveNext();

                if ((index < tokens.Count && tokens[index] != Tokens.EndSequence) &&
                    tokens[index] != Tokens.Else)
                {
                    Sequence sequence = new Sequence();
                    sequence.First  = result;
                    sequence.Second = ParseStmt();
                    result          = sequence;
                }
            }

            return(result);
        }
예제 #2
0
파일: CodeRun.cs 프로젝트: afumfer/KNote
        private void RunStmt(Stmt stmt)
        {
            if (flagBreak)
            {
                return;
            }

            //Application.DoEvents();

            #region Sequence

            if (stmt is Sequence)
            {
                Sequence seq = (Sequence)stmt;
                RunStmt(seq.First);
                RunStmt(seq.Second);
            }

            #endregion

            #region DeclareVar

            else if (stmt is DeclareVar)
            {
                // declare
                DeclareVar declare = (DeclareVar)stmt;

                CodeDeclareSymbol(declare);

                //TODO: (Z) Sustituir lo anterior por esto cuando se
                //       arregle el código de asignación + declaración.
                //Assign assign = new Assign();
                //assign.Ident = declare.Ident;
                //assign.Expr = declare.Expr;
                //RunStmt(assign);
            }

            #endregion

            #region Assign

            else if (stmt is Assign)
            {
                Assign assign = (Assign)stmt;
                CodeStoreSymbol(assign);
            }

            #endregion

            #region Print / PrintLine / Clear

            else if (stmt is Print)
            {
                Print print = (Print)stmt;
                CodeExecutePrint(print);
            }

            else if (stmt is PrintLine)
            {
                PrintLine printLine = (PrintLine)stmt;
                CodeExecutePrintLine(printLine);
            }

            else if (stmt is Clear)
            {
                CodeExecuteClear();
            }

            #endregion

            #region FunctionStmt

            else if (stmt is FunctionStmt)
            {
                FunctionStmt fun = (FunctionStmt)stmt;
                CodeExecuteFunction(fun.Function);
            }

            #endregion

            #region ReadVar

            else if (stmt is ReadVar)
            {
                ReadVar            read = (ReadVar)stmt;
                ReadVarItem        readVarItem;
                Assign             assign;
                List <ReadVarItem> readVarItmes = new List <ReadVarItem>();

                foreach (var pair in read.Vars)
                {
                    readVarItem          = new ReadVarItem();
                    readVarItem.VarIdent = pair.Key.Ident;
                    readVarItem.VarValue = CodeReadSymbol(pair.Key);
                    readVarItem.Label    = GenExpr(pair.Value);
                    readVarItmes.Add(readVarItem);
                }

                if (CodeExecuteReadVars(readVarItmes))
                {
                    foreach (ReadVarItem vi in readVarItmes)
                    {
                        assign = new Assign();
                        //assign.Ident = vi.Var.Ident;
                        assign.Ident = vi.VarIdent;
                        assign.Expr  = ValueToExpr(vi.VarValue.GetType(), vi.VarNewValueText);
                        RunStmt(assign);
                    }
                }
            }

            #endregion

            #region BreakStmt

            else if (stmt is BreakStmt)
            {
                flagBreak = true;
                return;
            }

            #endregion

            #region  FoorLoop

            else if (stmt is ForLoop)
            {
                // example:
                // for x = 0 to 100
                //   print "hello";
                // end for;

                ForLoop forLoop = (ForLoop)stmt;

                IntVal numFrom = new IntVal();
                IntVal numTo   = new IntVal();

                Assign assignFrom = new Assign();
                assignFrom.Ident = forLoop.Ident;

                assignFrom.Expr = forLoop.From;
                RunStmt(assignFrom);

                numFrom.Value = Convert.ToInt32(GenExpr(forLoop.From));
                numTo.Value   = Convert.ToInt32(GenExpr(forLoop.To));

                while (numFrom.Value <= numTo.Value)
                {
                    if (flagBreak)
                    {
                        break;
                    }
                    RunStmt(forLoop.Body);
                    numFrom.Value++;
                    assignFrom.Expr = numFrom;
                    RunStmt(assignFrom);
                }
                if (flagBreak)
                {
                    flagBreak = false;
                }
            }

            #endregion

            #region FoorEachLoop

            else if (stmt is ForEachLoop)
            {
                // example:
                // foreach x in myColec
                //   print "hello";
                //   print x.MyProp;
                // end foreach;

                ForEachLoop forEachLoop = (ForEachLoop)stmt;

                object colec = GenExpr(forEachLoop.Colec);

                foreach (object o in (IEnumerable <object>)colec)
                {
                    if (flagBreak)
                    {
                        break;
                    }

                    // TODO: Pending susutiruir CodeSpecialStoreObject by CodeStoreSymbol
                    //       In the future, CodeStoreSymbol should store the variable
                    //       if it had not previously been declared.
                    CodeSpecialStoreObject(forEachLoop.Ident, o);
                    // CodeStoreSymbol(forEachLoop.Ident, o);

                    RunStmt(forEachLoop.Body);
                }
                if (flagBreak)
                {
                    flagBreak = false;
                }
            }

            #endregion

            #region IfStmt

            else if (stmt is IfStmt)
            {
                // example:
                // if a == 10 then
                //   print "hello";
                // else
                //   print "bye";
                // end if;

                IfStmt ifStmt = (IfStmt)stmt;
                IntVal ifExp  = new IntVal();

                ifExp.Value = Convert.ToInt32(GenExpr(ifStmt.TestExpr));

                if (ifExp.Value != 0)
                {
                    RunStmt(ifStmt.BodyIf);
                }
                else
                {
                    if (ifStmt.DoElse)
                    {
                        RunStmt(ifStmt.BodyElse);
                    }
                }
            }

            #endregion

            #region WhileStmt

            else if (stmt is WhileStmt)
            {
                // example:
                // while a <= 10
                //   print "hello";
                //   a = a + 1;
                // end while;

                WhileStmt whileStmt = (WhileStmt)stmt;
                IntVal    whileExp  = new IntVal();

                while (true)
                {
                    if (flagBreak)
                    {
                        break;
                    }
                    whileExp.Value = Convert.ToInt32(GenExpr(whileStmt.TestExpr));
                    if (whileExp.Value == 0)
                    {
                        break;
                    }
                    RunStmt(whileStmt.Body);
                }
                if (flagBreak)
                {
                    flagBreak = false;
                }
            }

            #endregion

            else
            {
                throw new System.Exception("don't know how to gen a " + stmt.GetType().Name);
            }
        }