Example #1
0
    public void visit(ExprNode_BinaryOp node)
    {
        if (node.Op == "&&" || node.Op == "||") {
            var endLabel = m_stmt.ILGenerator.DefineLabel();
            new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(int), node.Lexpr);
            m_stmt.ILGenerator.Emit(OpCodes.Dup);
            if (node.Op == "&&") m_stmt.ILGenerator.Emit(OpCodes.Brfalse, endLabel);
            else m_stmt.ILGenerator.Emit(OpCodes.Brtrue, endLabel);
            m_stmt.ILGenerator.Emit(OpCodes.Pop);
            new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(int), node.Rexpr);
            m_stmt.ILGenerator.MarkLabel(endLabel);
            m_currentType = typeof(int);
            return;
        }

        if (node.Op == "==" || node.Op == "!=") {
            new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(object), node.Lexpr);
            new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(object), node.Rexpr);
            m_stmt.ILGenerator.Emit(OpCodes.Call, typeof(object).GetMethod("Equals", new Type[] { typeof(object), typeof(object) }));
            if (node.Op == "!=") {
                m_stmt.ILGenerator.Emit(OpCodes.Ldc_I4_0);
                m_stmt.ILGenerator.Emit(OpCodes.Ceq);
            }
            m_currentType = typeof(int);
            return;
        }

        new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(double), node.Lexpr);
        new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(double), node.Rexpr);
        switch (node.Op) {
            case "+":
                m_stmt.ILGenerator.Emit(OpCodes.Add);
                m_currentType = typeof(double);
                break;
            case "-":
                m_stmt.ILGenerator.Emit(OpCodes.Sub);
                m_currentType = typeof(double);
                break;
            case "*":
                m_stmt.ILGenerator.Emit(OpCodes.Mul);
                m_currentType = typeof(double);
                break;
            case "/":
                m_stmt.ILGenerator.Emit(OpCodes.Div);
                m_currentType = typeof(double);
                break;
            case "%":
                m_stmt.ILGenerator.Emit(OpCodes.Rem);
                m_currentType = typeof(double);
                break;
            case "^":
                m_stmt.ILGenerator.Emit(OpCodes.Call, typeof(System.Math).GetMethod("Pow", new Type[] { typeof(double), typeof(double) }));
                m_currentType = typeof(double);
                break;
            case "<":
                m_stmt.ILGenerator.Emit(OpCodes.Clt);
                m_currentType = typeof(int);
                break;
            case "<=":
                m_stmt.ILGenerator.Emit(OpCodes.Cgt);
                m_stmt.ILGenerator.Emit(OpCodes.Ldc_I4_0);
                m_stmt.ILGenerator.Emit(OpCodes.Ceq);
                m_currentType = typeof(int);
                break;
            case ">":
                m_stmt.ILGenerator.Emit(OpCodes.Cgt);
                m_currentType = typeof(int);
                break;
            case ">=":
                m_stmt.ILGenerator.Emit(OpCodes.Clt);
                m_stmt.ILGenerator.Emit(OpCodes.Ldc_I4_0);
                m_stmt.ILGenerator.Emit(OpCodes.Ceq);
                m_currentType = typeof(int);
                break;
            default: Trace.Assert(false); break;
        }
    }
    public void visit(ExprNode_BinaryOp node)
    {
        if (node.Op == "&&" || node.Op == "||")
        {
            var endLabel = m_stmt.ILGenerator.DefineLabel();
            new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(int), node.Lexpr);
            m_stmt.ILGenerator.Emit(OpCodes.Dup);
            if (node.Op == "&&")
            {
                m_stmt.ILGenerator.Emit(OpCodes.Brfalse, endLabel);
            }
            else
            {
                m_stmt.ILGenerator.Emit(OpCodes.Brtrue, endLabel);
            }
            m_stmt.ILGenerator.Emit(OpCodes.Pop);
            new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(int), node.Rexpr);
            m_stmt.ILGenerator.MarkLabel(endLabel);
            m_currentType = typeof(int);
            return;
        }

        if (node.Op == "==" || node.Op == "!=")
        {
            new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(object), node.Lexpr);
            new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(object), node.Rexpr);
            m_stmt.ILGenerator.Emit(OpCodes.Call, typeof(object).GetMethod("Equals", new Type[] { typeof(object), typeof(object) }));
            if (node.Op == "!=")
            {
                m_stmt.ILGenerator.Emit(OpCodes.Ldc_I4_0);
                m_stmt.ILGenerator.Emit(OpCodes.Ceq);
            }
            m_currentType = typeof(int);
            return;
        }

        new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(double), node.Lexpr);
        new ExprNodeVisitor_CodeEmitor(m_stmt, typeof(double), node.Rexpr);
        switch (node.Op)
        {
        case "+":
            m_stmt.ILGenerator.Emit(OpCodes.Add);
            m_currentType = typeof(double);
            break;

        case "-":
            m_stmt.ILGenerator.Emit(OpCodes.Sub);
            m_currentType = typeof(double);
            break;

        case "*":
            m_stmt.ILGenerator.Emit(OpCodes.Mul);
            m_currentType = typeof(double);
            break;

        case "/":
            m_stmt.ILGenerator.Emit(OpCodes.Div);
            m_currentType = typeof(double);
            break;

        case "%":
            m_stmt.ILGenerator.Emit(OpCodes.Rem);
            m_currentType = typeof(double);
            break;

        case "^":
            m_stmt.ILGenerator.Emit(OpCodes.Call, typeof(System.Math).GetMethod("Pow", new Type[] { typeof(double), typeof(double) }));
            m_currentType = typeof(double);
            break;

        case "<":
            m_stmt.ILGenerator.Emit(OpCodes.Clt);
            m_currentType = typeof(int);
            break;

        case "<=":
            m_stmt.ILGenerator.Emit(OpCodes.Cgt);
            m_stmt.ILGenerator.Emit(OpCodes.Ldc_I4_0);
            m_stmt.ILGenerator.Emit(OpCodes.Ceq);
            m_currentType = typeof(int);
            break;

        case ">":
            m_stmt.ILGenerator.Emit(OpCodes.Cgt);
            m_currentType = typeof(int);
            break;

        case ">=":
            m_stmt.ILGenerator.Emit(OpCodes.Clt);
            m_stmt.ILGenerator.Emit(OpCodes.Ldc_I4_0);
            m_stmt.ILGenerator.Emit(OpCodes.Ceq);
            m_currentType = typeof(int);
            break;

        default: Trace.Assert(false); break;
        }
    }