private Stmt ParseStmt() { Stmt resultado; if (this.indice == this.tokens.Count) { throw new System.Exception("se esperaban sentencias, se llego al final del archivo"); } // <stmt> := print <expr> // <expr> := <string> // | <int> // | <arith_expr> // | <ident> if (this.tokens[this.indice].Equals("print")) { this.indice++; Print print = new Print(); print.Expr = this.ParseExpr(); resultado = print; } else if (this.tokens[this.indice].Equals("var")) { this.indice++; DeclareVar declareVar = new DeclareVar(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { declareVar.Ident = (string)this.tokens[this.indice]; } else { throw new System.Exception("Se esperaba nombre de variable despues de 'var'"); } this.indice++; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("se esperaba = despues de 'var ident'"); } this.indice++; declareVar.Expr = this.ParseExpr(); resultado = declareVar; } else if (this.tokens[this.indice].Equals("read_int")) { this.indice++; ReadInt readInt = new ReadInt(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { readInt.Ident = (string)this.tokens[this.indice++]; resultado = readInt; } else { throw new System.Exception("Se esperaba el nombre de la variable 'read_int'"); } } //******************* else if (this.tokens[this.indice].Equals("if")) { this.indice++; mcIf mcif = new mcIf(); Expr temp = ParseExpr(); if (this.tokens[this.indice] == Scanner.Eq || this.tokens[this.indice] == Scanner.Neq || this.tokens[this.indice] == Scanner.Gt || this.tokens[this.indice] == Scanner.Gte || this.tokens[this.indice] == Scanner.Lt || this.tokens[this.indice] == Scanner.Lte) { CompExpr compExpr = new CompExpr(); compExpr.Left = temp; object op = this.tokens[this.indice++]; if (op == Scanner.Eq) compExpr.Op = CompOp.Eq; else if (op == Scanner.Neq) compExpr.Op = CompOp.Neq; else if (op == Scanner.Gt) compExpr.Op = CompOp.Gt; else if (op == Scanner.Gte) compExpr.Op = CompOp.Gte; else if (op == Scanner.Lt) compExpr.Op = CompOp.Lt; else if (op == Scanner.Lte) compExpr.Op = CompOp.Lte; compExpr.Rigth = ParseExpr(); temp = compExpr; } mcif.compExpr = temp; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("then")) { throw new System.Exception("Se esperaba el identificador 'then' despues de 'if'"); } this.indice++; mcif.Then = ParseStmt(); if (this.tokens[this.indice].Equals("else")) { this.indice++; mcif.Else = ParseStmt(); } resultado = mcif; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("Sentencia if inconclusa"); } this.indice++; } else if (this.tokens[this.indice].Equals("while")) { this.indice++; WhileLoop whileLoop = new WhileLoop(); Expr temp = ParseExpr(); if (this.tokens[this.indice] == Scanner.Eq || this.tokens[this.indice] == Scanner.Neq || this.tokens[this.indice] == Scanner.Gt || this.tokens[this.indice] == Scanner.Gte || this.tokens[this.indice] == Scanner.Lt || this.tokens[this.indice] == Scanner.Lte) { CompExpr compExpr = new CompExpr(); compExpr.Left = temp; object op = this.tokens[this.indice++]; if (op == Scanner.Eq) compExpr.Op = CompOp.Eq; else if (op == Scanner.Neq) compExpr.Op = CompOp.Neq; else if (op == Scanner.Gt) compExpr.Op = CompOp.Gt; else if (op == Scanner.Gte) compExpr.Op = CompOp.Gte; else if (op == Scanner.Lt) compExpr.Op = CompOp.Lt; else if (op == Scanner.Lte) compExpr.Op = CompOp.Lte; compExpr.Rigth = ParseExpr(); temp = compExpr; } whileLoop.Cond = temp; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("do")) { throw new System.Exception("Se esperaba el identificador 'do' despues de 'while'"); } this.indice++; whileLoop.Body = ParseStmt(); resultado = whileLoop; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("sentencia while inconclusa"); } this.indice++; } //******************* else if (this.tokens[this.indice].Equals("for")) { this.indice++; ForLoop forLoop = new ForLoop(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { forLoop.Ident = (string)this.tokens[this.indice]; } else { throw new System.Exception("se esperaba un indentificador despues de 'for'"); } this.indice++; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("no se encontro en la sentencia for '='"); } this.indice++; forLoop.From = this.ParseExpr(); if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("to")) { throw new System.Exception("se epsaraba 'to' despues de for"); } this.indice++; forLoop.To = this.ParseExpr(); if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("do")) { throw new System.Exception("se esperaba 'do' despues de la expresion en el ciclo for"); } this.indice++; forLoop.Body = this.ParseStmt(); resultado = forLoop; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("setencia for inconclusa"); } this.indice++; } else if (this.tokens[this.indice] is string) { // assignment Assign assign = new Assign(); assign.Ident = (string)this.tokens[this.indice++]; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("se esperaba '='"); } this.indice++; assign.Expr = this.ParseExpr(); resultado = assign; } else { throw new System.Exception("Error en el token " + this.indice + ": " + this.tokens[this.indice]); } if (this.indice < this.tokens.Count && this.tokens[this.indice] == Scanner.PyC) { this.indice++; if (this.indice < this.tokens.Count && !this.tokens[this.indice].Equals("end") && !this.tokens[this.indice].Equals("else")) { Sequence sequence = new Sequence(); sequence.First = resultado; sequence.Second = this.ParseStmt(); resultado = sequence; } } return resultado; }
private void GenStmt(Stmt stmt) { if (stmt is Sequence) { Sequence seq = (Sequence)stmt; this.GenStmt(seq.First); this.GenStmt(seq.Second); } else if (stmt is DeclareVar) { // declare a local DeclareVar declare = (DeclareVar)stmt; this.symbolTable[declare.Ident] = this.il.DeclareLocal(this.TypeOfExpr(declare.Expr)); // set the initial value Assign assign = new Assign(); assign.Ident = declare.Ident; assign.Expr = declare.Expr; this.GenStmt(assign); } else if (stmt is Assign) { Assign assign = (Assign)stmt; this.GenExpr(assign.Expr, this.TypeOfExpr(assign.Expr)); this.Store(assign.Ident, this.TypeOfExpr(assign.Expr)); } else if (stmt is Print) { // the "print" statement is an alias for System.Console.WriteLine. // it uses the string case this.GenExpr(((Print)stmt).Expr, typeof(string)); this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); } else if (stmt is ReadInt) { this.il.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { }, null)); this.il.Emit(Emit.OpCodes.Call, typeof(int).GetMethod("Parse", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { typeof(string) }, null)); this.Store(((ReadInt)stmt).Ident, typeof(int)); } //******************* else if (stmt is mcIf) { mcIf mcif = (mcIf)stmt; //this.GenExpr(mcif.compExpr, typeof(int)); Emit.Label Else = this.il.DefineLabel(); Emit.Label Then = this.il.DefineLabel(); Emit.Label Salida = this.il.DefineLabel(); if (mcif.compExpr is CompExpr) { CompExpr compExpr = (CompExpr)mcif.compExpr; this.GenExpr(compExpr.Left, typeof(int)); this.GenExpr(compExpr.Rigth, typeof(int)); genCodComp(compExpr.Op, Then); } else { GenExpr(mcif.compExpr, typeof(string)); this.il.Emit(Emit.OpCodes.Ldc_I4, 0); this.il.Emit(Emit.OpCodes.Bne_Un, Then); } if (mcif.Else != null) { this.il.Emit(Emit.OpCodes.Br, Else); } else { this.il.Emit(Emit.OpCodes.Br, Salida); } this.il.MarkLabel(Then); GenStmt(mcif.Then); this.il.Emit(Emit.OpCodes.Br, Salida); this.il.MarkLabel(Else); if (mcif.Else != null) { GenStmt(mcif.Else); } this.il.MarkLabel(Salida); } else if (stmt is WhileLoop) { WhileLoop whileLoop = (WhileLoop)stmt; Emit.Label Body = this.il.DefineLabel(); Emit.Label Salida = this.il.DefineLabel(); Emit.Label Cond = this.il.DefineLabel(); this.il.MarkLabel(Cond); if (whileLoop.Cond is CompExpr) { CompExpr compExpr = (CompExpr)whileLoop.Cond; this.GenExpr(compExpr.Left, typeof(int)); this.GenExpr(compExpr.Rigth, typeof(int)); genCodComp(compExpr.Op, Body); } else { GenExpr(whileLoop.Cond, typeof(string)); this.il.Emit(Emit.OpCodes.Ldc_I4, 0); this.il.Emit(Emit.OpCodes.Bne_Un, Body); } this.il.Emit(Emit.OpCodes.Br, Salida); this.il.MarkLabel(Body); GenStmt(whileLoop.Body); this.il.Emit(Emit.OpCodes.Br, Cond); this.il.MarkLabel(Salida); } //******************* else if (stmt is ForLoop) { // example: // for x = 0 to 100 do // print "hello"; // end; // x = 0 ForLoop forLoop = (ForLoop)stmt; Assign assign = new Assign(); assign.Ident = forLoop.Ident; assign.Expr = forLoop.From; this.GenStmt(assign); // jump to the test Emit.Label test = this.il.DefineLabel(); this.il.Emit(Emit.OpCodes.Br, test); // statements in the body of the for loop Emit.Label body = this.il.DefineLabel(); this.il.MarkLabel(body); this.GenStmt(forLoop.Body); // to (increment the value of x) this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[forLoop.Ident]); this.il.Emit(Emit.OpCodes.Ldc_I4, 1); this.il.Emit(Emit.OpCodes.Add); this.Store(forLoop.Ident, typeof(int)); // **test** does x equal 100? (do the test) this.il.MarkLabel(test); this.il.Emit(Emit.OpCodes.Ldloc, this.symbolTable[forLoop.Ident]); this.GenExpr(forLoop.To, typeof(int)); this.il.Emit(Emit.OpCodes.Blt, body); } else { throw new System.Exception("imposible generar: " + stmt.GetType().Name); } }
private Stmt ParseStmt() { Stmt resultado; if (this.indice == this.tokens.Count) { throw new System.Exception("se esperaban sentencias, se llego al final del archivo"); } // <stmt> := print <expr> // <expr> := <string> // | <int> // | <arith_expr> // | <ident> if (this.tokens[this.indice].Equals("print")) { this.indice++; Print print = new Print(); print.Expr = this.ParseExpr(); resultado = print; } else if (this.tokens[this.indice].Equals("var")) { this.indice++; DeclareVar declareVar = new DeclareVar(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { declareVar.Ident = (string)this.tokens[this.indice]; } else { throw new System.Exception("Se esperaba nombre de variable despues de 'var'"); } this.indice++; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("se esperaba = despues de 'var ident'"); } this.indice++; declareVar.Expr = this.ParseExpr(); resultado = declareVar; } else if (this.tokens[this.indice].Equals("read_int")) { this.indice++; ReadInt readInt = new ReadInt(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { readInt.Ident = (string)this.tokens[this.indice++]; resultado = readInt; } else { throw new System.Exception("Se esperaba el nombre de la variable 'read_int'"); } } //******************* else if (this.tokens[this.indice].Equals("if")) { this.indice++; mcIf mcif = new mcIf(); Expr temp = ParseExpr(); if (this.tokens[this.indice] == Scanner.Eq || this.tokens[this.indice] == Scanner.Neq || this.tokens[this.indice] == Scanner.Gt || this.tokens[this.indice] == Scanner.Gte || this.tokens[this.indice] == Scanner.Lt || this.tokens[this.indice] == Scanner.Lte) { CompExpr compExpr = new CompExpr(); compExpr.Left = temp; object op = this.tokens[this.indice++]; if (op == Scanner.Eq) { compExpr.Op = CompOp.Eq; } else if (op == Scanner.Neq) { compExpr.Op = CompOp.Neq; } else if (op == Scanner.Gt) { compExpr.Op = CompOp.Gt; } else if (op == Scanner.Gte) { compExpr.Op = CompOp.Gte; } else if (op == Scanner.Lt) { compExpr.Op = CompOp.Lt; } else if (op == Scanner.Lte) { compExpr.Op = CompOp.Lte; } compExpr.Rigth = ParseExpr(); temp = compExpr; } mcif.compExpr = temp; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("then")) { throw new System.Exception("Se esperaba el identificador 'then' despues de 'if'"); } this.indice++; mcif.Then = ParseStmt(); if (this.tokens[this.indice].Equals("else")) { this.indice++; mcif.Else = ParseStmt(); } resultado = mcif; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("Sentencia if inconclusa"); } this.indice++; } else if (this.tokens[this.indice].Equals("while")) { this.indice++; WhileLoop whileLoop = new WhileLoop(); Expr temp = ParseExpr(); if (this.tokens[this.indice] == Scanner.Eq || this.tokens[this.indice] == Scanner.Neq || this.tokens[this.indice] == Scanner.Gt || this.tokens[this.indice] == Scanner.Gte || this.tokens[this.indice] == Scanner.Lt || this.tokens[this.indice] == Scanner.Lte) { CompExpr compExpr = new CompExpr(); compExpr.Left = temp; object op = this.tokens[this.indice++]; if (op == Scanner.Eq) { compExpr.Op = CompOp.Eq; } else if (op == Scanner.Neq) { compExpr.Op = CompOp.Neq; } else if (op == Scanner.Gt) { compExpr.Op = CompOp.Gt; } else if (op == Scanner.Gte) { compExpr.Op = CompOp.Gte; } else if (op == Scanner.Lt) { compExpr.Op = CompOp.Lt; } else if (op == Scanner.Lte) { compExpr.Op = CompOp.Lte; } compExpr.Rigth = ParseExpr(); temp = compExpr; } whileLoop.Cond = temp; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("do")) { throw new System.Exception("Se esperaba el identificador 'do' despues de 'while'"); } this.indice++; whileLoop.Body = ParseStmt(); resultado = whileLoop; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("sentencia while inconclusa"); } this.indice++; } //******************* else if (this.tokens[this.indice].Equals("for")) { this.indice++; ForLoop forLoop = new ForLoop(); if (this.indice < this.tokens.Count && this.tokens[this.indice] is string) { forLoop.Ident = (string)this.tokens[this.indice]; } else { throw new System.Exception("se esperaba un indentificador despues de 'for'"); } this.indice++; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("no se encontro en la sentencia for '='"); } this.indice++; forLoop.From = this.ParseExpr(); if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("to")) { throw new System.Exception("se epsaraba 'to' despues de for"); } this.indice++; forLoop.To = this.ParseExpr(); if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("do")) { throw new System.Exception("se esperaba 'do' despues de la expresion en el ciclo for"); } this.indice++; forLoop.Body = this.ParseStmt(); resultado = forLoop; if (this.indice == this.tokens.Count || !this.tokens[this.indice].Equals("end")) { throw new System.Exception("setencia for inconclusa"); } this.indice++; } else if (this.tokens[this.indice] is string) { // assignment Assign assign = new Assign(); assign.Ident = (string)this.tokens[this.indice++]; if (this.indice == this.tokens.Count || this.tokens[this.indice] != Scanner.Igual) { throw new System.Exception("se esperaba '='"); } this.indice++; assign.Expr = this.ParseExpr(); resultado = assign; } else { throw new System.Exception("Error en el token " + this.indice + ": " + this.tokens[this.indice]); } if (this.indice < this.tokens.Count && this.tokens[this.indice] == Scanner.PyC) { this.indice++; if (this.indice < this.tokens.Count && !this.tokens[this.indice].Equals("end") && !this.tokens[this.indice].Equals("else")) { Sequence sequence = new Sequence(); sequence.First = resultado; sequence.Second = this.ParseStmt(); resultado = sequence; } } return(resultado); }