Exemplo n.º 1
0
    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;
    }
Exemplo n.º 2
0
    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);
        }
    }
Exemplo n.º 3
0
    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);
    }