* Statement.cs (class if): reimplemented Emit based on fall_false.
* Equality.cs: added code generation for != and emit jumping code
only in the case we are at a global expression not statement.
* CodeGenerator.cs (fall_true, fall_false): Check if convertion to
boolean needed. Made emit_to_boolean internal. Added need_convert_to_boolean.
svn path=/trunk/mcs/; revision=25649
+2004-04-17 Cesar Lopez Nataren <cesar@ciencias.unam.mx>
+
+ * Statement.cs (class if): reimplemented Emit based on fall_false.
+ * Equality.cs: added code generation for != and emit jumping code
+ only in the case we are at a global expression not statement.
+ * CodeGenerator.cs (fall_true, fall_false): Check if convertion to
+ boolean needed. Made emit_to_boolean internal. Added need_convert_to_boolean.
+
2004-04-14 Cesar Lopez Nataren <cesar@ciencias.unam.mx>
* expression.cs (Binary.Emit): treat boolean operator
// Author:
// Cesar Lopez Nataren (cesar@ciencias.unam.mx)
//
-// (C) 2003, Cesar Lopez Nataren
+// (C) 2003, 2004 Cesar Lopez Nataren
//
using System;
}
} else {
ast.Emit (ec);
- emit_to_boolean (ig, 0);
+ if (need_convert_to_boolean (ast))
+ emit_to_boolean (ast, ig, 0);
ig.Emit (OpCodes.Brfalse, lbl);
}
}
}
} else {
ast.Emit (ec);
- emit_to_boolean (ig, 0);
+ if (need_convert_to_boolean (ast))
+ emit_to_boolean (ast, ig, 0);
ig.Emit (OpCodes.Brtrue, lbl);
}
}
- public static void emit_to_boolean (ILGenerator ig, int i)
+ internal static void emit_to_boolean (AST ast, ILGenerator ig, int i)
{
ig.Emit (OpCodes.Ldc_I4, i);
ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToBoolean",
- new Type [] { typeof (object), typeof (Boolean)}));
+ new Type [] { typeof (object), typeof (Boolean)}));
+ }
+
+ internal static bool need_convert_to_boolean (AST ast)
+ {
+ if (ast == null)
+ return false;
+
+ if (ast is Expression) {
+ Expression exp = ast as Expression;
+ int n = exp.exprs.Count - 1;
+ AST tmp = (AST) exp.exprs [n];
+ if (tmp is Equality || tmp is Relational || tmp is BooleanLiteral)
+ return false;
+ else
+ return true;
+ } else
+ return false;
}
}
}
// Author:
// Cesar Lopez Nataren (cesar@ciencias.unam.mx)
//
-// (C) 2003, Cesar Lopez Nataren
+// (C) 2003, 2004 Cesar Lopez Nataren
//
using System;
if (right != null)
right.Emit (ec);
- if (current_op == JSToken.Equal) {
+ if (current_op == JSToken.Equal || current_op == JSToken.NotEqual) {
ig.Emit (OpCodes.Call, typeof (Equality).GetMethod ("EvaluateEquality"));
- Label t = ig.DefineLabel ();
- Label f = ig.DefineLabel ();
- ig.Emit (OpCodes.Brtrue_S, t);
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Br_S, f);
- ig.MarkLabel (t);
- ig.Emit (OpCodes.Ldc_I4_1);
- ig.MarkLabel (f);
- }
- if (no_effect)
- ig.Emit (OpCodes.Pop);
+ if (no_effect) {
+ Label t_lbl = ig.DefineLabel ();
+ Label f_lbl = ig.DefineLabel ();
+
+ if (current_op == JSToken.Equal)
+ ig.Emit (OpCodes.Brtrue_S, t_lbl);
+ else if (current_op == JSToken.NotEqual)
+ ig.Emit (OpCodes.Brfalse_S, t_lbl);
+
+ ig.Emit (OpCodes.Ldc_I4_0);
+ ig.Emit (OpCodes.Br_S, f_lbl);
+ ig.MarkLabel (t_lbl);
+ ig.Emit (OpCodes.Ldc_I4_1);
+ ig.MarkLabel (f_lbl);
+ ig.Emit (OpCodes.Pop);
+ }
+ }
}
}
}
// Author:
// Cesar Octavio Lopez Nataren
//
-// (C) 2003, Cesar Octavio Lopez Nataren, <cesar@ciencias.unam.mx>
+// (C) 2003, 2004 Cesar Octavio Lopez Nataren, <cesar@ciencias.unam.mx>
//
using System;
internal override void Emit (EmitContext ec)
{
ILGenerator ig = ec.ig;
- Label a, b;
-
- a = ig.DefineLabel ();
- b = ig.DefineLabel ();
-
- if (cond != null)
- cond.Emit (ec);
-
- Expression e = cond as Expression;
- AST tmp = (AST) e.exprs [e.exprs.Count - 1];
-
- if (tmp is Relational)
- //ig.Emit (OpCodes.Bge, a);
- ig.Emit (OpCodes.Brfalse, a);
- else {
- Console.WriteLine ("cond is not relational");
- ig.Emit (OpCodes.Ldc_I4_1);
- ig.Emit (OpCodes.Call,
- typeof (Convert).GetMethod ("ToBoolean",
- new Type [] { typeof (object), typeof (Boolean)}));
- ig.Emit (OpCodes.Brfalse, a);
- }
-
+ Label true_lbl = ig.DefineLabel ();
+ Label merge_lbl = ig.DefineLabel ();
+ CodeGenerator.fall_false (ec, cond, true_lbl);
if (true_stm != null)
- true_stm.Emit (ec);
-
- ig.Emit (OpCodes.Br, b);
- ig.MarkLabel (a);
-
+ true_stm.Emit (ec);
+ ig.Emit (OpCodes.Br, merge_lbl);
+ ig.MarkLabel (true_lbl);
if (false_stm != null)
- false_stm.Emit (ec);
-
- ig.MarkLabel (b);
+ false_stm.Emit (ec);
+ ig.MarkLabel (merge_lbl);
}
- }
+ }
internal class Continue : AST {