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