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