Exemple #1
0
		// General version in terms of CompileToDoubleOrNan.  
		// Should be overridden in CGNumberConst, CGTextConst, CGError, CGComposite ...
		/// <summary>
		/// Compile expression that is expected to evaluate to a proper (finite 
		/// and non-NaN) number; generate code to test whether it is actually a 
		/// proper number and then execute the code generated by ifProper, or 
		/// else execute the code generated by ifOther.
		/// </summary>
		/// <param name="ifProper">Generates code for the case where the expression 
		/// evaluates to a proper number; the generated code expects to find the value as
		/// an unwrapped proper float64 on the stack top.</param>
		/// <param name="ifOther"></param>
		public virtual void CompileToDoubleProper(Gen ifProper, Gen ifOther) {
			CompileToDoubleOrNan();
			ilg.Emit(OpCodes.Stloc, testDouble);
			ilg.Emit(OpCodes.Ldloc, testDouble);
			ilg.Emit(OpCodes.Call, isInfinityMethod);
			ilg.Emit(OpCodes.Brtrue, ifOther.GetLabel(ilg));
			ilg.Emit(OpCodes.Ldloc, testDouble);
			ilg.Emit(OpCodes.Call, isNaNMethod);
			ilg.Emit(OpCodes.Brtrue, ifOther.GetLabel(ilg));
			ilg.Emit(OpCodes.Ldloc, testDouble);
			ifProper.Generate(ilg);
			if (!ifOther.Generated) {
				Label endLabel = ilg.DefineLabel();
				ilg.Emit(OpCodes.Br, endLabel);
				ifOther.Generate(ilg);
				ilg.MarkLabel(endLabel);
			}
		}
Exemple #2
0
 // General version in terms of CompileToDoubleOrNan.
 // Should be overridden in CGNumberConst, CGTextConst, CGError, CGComposite ...
 /// <summary>
 /// Compile expression that is expected to evaluate to a proper (finite
 /// and non-NaN) number; generate code to test whether it is actually a
 /// proper number and then execute the code generated by ifProper, or
 /// else execute the code generated by ifOther.
 /// </summary>
 /// <param name="ifProper">Generates code for the case where the expression
 /// evaluates to a proper number; the generated code expects to find the value as
 /// an unwrapped proper float64 on the stack top.</param>
 /// <param name="ifOther"></param>
 public virtual void CompileToDoubleProper(Gen ifProper, Gen ifOther)
 {
     CompileToDoubleOrNan();
     ilg.Emit(OpCodes.Stloc, testDouble);
     ilg.Emit(OpCodes.Ldloc, testDouble);
     ilg.Emit(OpCodes.Call, isInfinityMethod);
     ilg.Emit(OpCodes.Brtrue, ifOther.GetLabel(ilg));
     ilg.Emit(OpCodes.Ldloc, testDouble);
     ilg.Emit(OpCodes.Call, isNaNMethod);
     ilg.Emit(OpCodes.Brtrue, ifOther.GetLabel(ilg));
     ilg.Emit(OpCodes.Ldloc, testDouble);
     ifProper.Generate(ilg);
     if (!ifOther.Generated)
     {
         Label endLabel = ilg.DefineLabel();
         ilg.Emit(OpCodes.Br, endLabel);
         ifOther.Generate(ilg);
         ilg.MarkLabel(endLabel);
     }
 }
Exemple #3
0
 /// <summary>
 /// Generate code to check the type of the stack top value, and leave it
 /// there if it is of the expected type t followed by success code; else
 /// jump to failure code.
 /// </summary>
 /// <param name="t">The expected type of the stack top value.</param>
 /// <param name="ifType">Generate success code -- the value is of the expected type.</param>
 /// <param name="ifOther">Generate failure code -- the value is not of the expected type.</param>
 protected void CheckType(Type t, Gen ifType, Gen ifOther)
 {
     ilg.Emit(OpCodes.Stloc, testValue);
     ilg.Emit(OpCodes.Ldloc, testValue);
     ilg.Emit(OpCodes.Isinst, t);
     ilg.Emit(OpCodes.Brfalse, ifOther.GetLabel(ilg));
     ilg.Emit(OpCodes.Ldloc, testValue);
     ifType.Generate(ilg);
     if (!ifOther.Generated)
     {
         Label endLabel = ilg.DefineLabel();
         ilg.Emit(OpCodes.Br, endLabel);
         ifOther.Generate(ilg);
         ilg.MarkLabel(endLabel);
     }
 }
Exemple #4
0
 /// <summary>
 /// Compiles an expression as a condition, that can be true (if non-zero) or
 /// false (if zero) or other (if +/-infinity or NaN).  If possible, avoids
 /// computing and pushing a value and then testing it, instead performing
 /// comparisons directly on arguments, or even statically.  This implementation
 /// is a general version in terms of CompileToDoubleProper.  Should be overridden
 /// in CGNumberConst, CGTextConst, CGError, CGIf, CGComparison, ...
 /// </summary>
 /// <param name="ifTrue">Generates code for the true branch</param>
 /// <param name="ifFalse">Generates code for the false branch</param>
 /// <param name="ifOther">Generates code for the other (neither true nor
 /// false) branch</param>
 public virtual void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther)
 {
     CompileToDoubleProper(
         new Gen(delegate {
         ilg.Emit(OpCodes.Ldc_R8, 0.0);
         ilg.Emit(OpCodes.Beq, ifFalse.GetLabel(ilg));
         ifTrue.Generate(ilg);
         if (!ifFalse.Generated)
         {
             Label endLabel = ilg.DefineLabel();
             ilg.Emit(OpCodes.Br, endLabel);
             ifFalse.Generate(ilg);
             ilg.MarkLabel(endLabel);
         }
     }),
         ifOther);
 }
Exemple #5
0
		// This override combines the ordering predicate and the conditional jump
		public override void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther) {
			es[0].CompileToDoubleProper(
									    new Gen(delegate {
													es[1].CompileToDoubleProper(
																			    new Gen(delegate {
																							GenDoubleFalseJump(ifFalse.GetLabel(ilg));
																							ifTrue.Generate(ilg);
																							if (!ifFalse.Generated) {
																								Label endLabel = ilg.DefineLabel();
																								ilg.Emit(OpCodes.Br, endLabel);
																								ifFalse.Generate(ilg);
																								ilg.MarkLabel(endLabel);
																							}
																						}),
																				new Gen(delegate {
																							ilg.Emit(OpCodes.Pop);
																							ifOther.Generate(ilg);
																						}));
												}),
										ifOther);
		}
Exemple #6
0
 // This override combines the ordering predicate and the conditional jump
 public override void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther)
 {
     es[0].CompileToDoubleProper(
         new Gen(delegate {
         es[1].CompileToDoubleProper(
             new Gen(delegate {
             GenDoubleFalseJump(ifFalse.GetLabel(ilg));
             ifTrue.Generate(ilg);
             if (!ifFalse.Generated)
             {
                 Label endLabel = ilg.DefineLabel();
                 ilg.Emit(OpCodes.Br, endLabel);
                 ifFalse.Generate(ilg);
                 ilg.MarkLabel(endLabel);
             }
         }),
             new Gen(delegate {
             ilg.Emit(OpCodes.Pop);
             ifOther.Generate(ilg);
         }));
     }),
         ifOther);
 }
Exemple #7
0
		/// <summary>
		/// Generate code to check the type of the stack top value, and leave it 
		/// there if it is of the expected type t followed by success code; else
		/// jump to failure code.
		/// </summary>
		/// <param name="t">The expected type of the stack top value.</param>
		/// <param name="ifType">Generate success code -- the value is of the expected type.</param>
		/// <param name="ifOther">Generate failure code -- the value is not of the expected type.</param>
		protected void CheckType(Type t, Gen ifType, Gen ifOther) {
			ilg.Emit(OpCodes.Stloc, testValue);
			ilg.Emit(OpCodes.Ldloc, testValue);
			ilg.Emit(OpCodes.Isinst, t);
			ilg.Emit(OpCodes.Brfalse, ifOther.GetLabel(ilg));
			ilg.Emit(OpCodes.Ldloc, testValue);
			ifType.Generate(ilg);
			if (!ifOther.Generated) {
				Label endLabel = ilg.DefineLabel();
				ilg.Emit(OpCodes.Br, endLabel);
				ifOther.Generate(ilg);
				ilg.MarkLabel(endLabel);
			}
		}
Exemple #8
0
		/// <summary>
		/// Compiles an expression as a condition, that can be true (if non-zero) or 
		/// false (if zero) or other (if +/-infinity or NaN).  If possible, avoids 
		/// computing and pushing a value and then testing it, instead performing 
		/// comparisons directly on arguments, or even statically.  This implementation 
		/// is a general version in terms of CompileToDoubleProper.  Should be overridden 
		/// in CGNumberConst, CGTextConst, CGError, CGIf, CGComparison, ...
		/// </summary>
		/// <param name="ifTrue">Generates code for the true branch</param>
		/// <param name="ifFalse">Generates code for the false branch</param>
		/// <param name="ifOther">Generates code for the other (neither true nor 
		/// false) branch</param>
		public virtual void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther) {
			CompileToDoubleProper(
								  new Gen(delegate {
											  ilg.Emit(OpCodes.Ldc_R8, 0.0);
											  ilg.Emit(OpCodes.Beq, ifFalse.GetLabel(ilg));
											  ifTrue.Generate(ilg);
											  if (!ifFalse.Generated) {
												  Label endLabel = ilg.DefineLabel();
												  ilg.Emit(OpCodes.Br, endLabel);
												  ifFalse.Generate(ilg);
												  ilg.MarkLabel(endLabel);
											  }
										  }),
								  ifOther);
		}