Esempio n. 1
0
		public override void CompileToDoubleProper(Gen ifProper, Gen ifOther) {
			CompileCondition(
							 new Gen(delegate {
										 ilg.Emit(OpCodes.Ldc_R8, 1.0);
										 ifProper.Generate(ilg);
									 }),
							 new Gen(delegate {
										 ilg.Emit(OpCodes.Ldc_R8, 0.0);
										 ifProper.Generate(ilg);
									 }),
							 ifOther);
		}
Esempio n. 2
0
 public override void CompileToDoubleProper(Gen ifProper, Gen ifOther)
 {
     CompileCondition(
         new Gen(delegate {
         ilg.Emit(OpCodes.Ldc_R8, 1.0);
         ifProper.Generate(ilg);
     }),
         new Gen(delegate {
         ilg.Emit(OpCodes.Ldc_R8, 0.0);
         ifProper.Generate(ilg);
     }),
         ifOther);
 }
Esempio n. 3
0
 public override void CompileToDoubleOrNan()
 {
     if (ef == null)
     {
         ilg.Emit(OpCodes.Ldc_R8, errorValue.ErrorNan);
     }
     else
     {
         // sestoft: This is maybe correct
         Gen ifOther = GenLoadErrorNan(ErrorValue.argTypeError);
         if (ef.ResType == typeof(System.Double))
         {
             // If argument evaluation is successful, call external function
             // and continue with ifDouble; otherwise continue with ifOther
             Gen success = new Gen(delegate { ef.EmitCall(ilg); });
             CompileArgumentsAndApply(es, success, ifOther);
         }
         else if (numeric.Contains(ef.ResType))
         {
             // If argument evaluation is successful, call external function, convert
             // to float64
             Gen success =
                 new Gen(delegate {
                 ef.EmitCall(ilg);
                 ilg.Emit(OpCodes.Conv_R8);
             });
             CompileArgumentsAndApply(es, success, ifOther);
         }
         else                 // Result type cannot be converted to a float64
         {
             ifOther.Generate(ilg);
         }
     }
 }
Esempio n. 4
0
        public override void CompileToDoubleOrNan()
        {
            Gen success =
                new Gen(delegate {
                ilg.Emit(OpCodes.Call, functionInfo.methodInfo);
                if (functionInfo.signature.retType != Typ.Number)
                {
                    UnwrapToDoubleOrNan();
                }
            });

            if (Arity < 0)               // Variable arity
            {
                CompileToValueArray(es.Length, 0, es);
                success.Generate(ilg);
            }
            else if (es.Length != Arity)
            {
                LoadErrorNan(ErrorValue.argCountError);
            }
            else
            {
                // TODO: ifOther should probably load error from testValue instead?
                Gen ifOther = GenLoadErrorNan(ErrorValue.argTypeError);
                CompileArgumentsAndApply(es, success, ifOther);
            }
        }
Esempio n. 5
0
		public override void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther) {
			for (int i = es.Length - 1; i >= 0; i--) {
				// These declarations are needed to capture rvalues rather than lvalues:
				CGExpr ei = es[i];
				Gen localIfFalse = ifFalse;
				ifFalse = new Gen(delegate { ei.CompileCondition(ifTrue, localIfFalse, ifOther); });
			}
			ifFalse.Generate(ilg);
		}
Esempio n. 6
0
 protected void UnwrapToString(Gen ifString, Gen ifError)
 {
     CheckType(TextValue.type,
               new Gen(delegate {
         ilg.Emit(OpCodes.Ldfld, TextValue.valueField);
         ifString.Generate(ilg);
     }),
               ifError);
 }
Esempio n. 7
0
		// Special case for the argumentless and always-proper 
		// functions RAND and NOW, often used in conditions
		public override void CompileToDoubleProper(Gen ifProper, Gen ifOther) {
			if (es.Length == 0 && (functionInfo.name == "RAND" || functionInfo.name == "NOW")) {
				ilg.Emit(OpCodes.Call, functionInfo.methodInfo);
				ifProper.Generate(ilg);
			}
			else {
				base.CompileToDoubleProper(ifProper, ifOther);
			}
		}
Esempio n. 8
0
		public override void CompileToDoubleProper(Gen ifProper, Gen ifOther) {
			if (double.IsInfinity(number.value) || double.IsNaN(number.value)) {
				ilg.Emit(OpCodes.Ldc_R8, number.value);
				ilg.Emit(OpCodes.Stloc, testDouble);
				ifOther.Generate(ilg);
			}
			else {
				ilg.Emit(OpCodes.Ldc_R8, number.value);
				ifProper.Generate(ilg);
			}
		}
Esempio n. 9
0
 public override void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther)
 {
     for (int i = es.Length - 1; i >= 0; i--)
     {
         // These declarations are needed to capture rvalues rather than lvalues:
         CGExpr ei           = es[i];
         Gen    localIfFalse = ifFalse;
         ifFalse = new Gen(delegate { ei.CompileCondition(ifTrue, localIfFalse, ifOther); });
     }
     ifFalse.Generate(ilg);
 }
Esempio n. 10
0
 // Special case for the argumentless and always-proper
 // functions RAND and NOW, often used in conditions
 public override void CompileToDoubleProper(Gen ifProper, Gen ifOther)
 {
     if (es.Length == 0 && (functionInfo.name == "RAND" || functionInfo.name == "NOW"))
     {
         ilg.Emit(OpCodes.Call, functionInfo.methodInfo);
         ifProper.Generate(ilg);
     }
     else
     {
         base.CompileToDoubleProper(ifProper, ifOther);
     }
 }
Esempio n. 11
0
		// This handles compilation of IF(IF(e00,e01,e02), e1, e2) and such
		public override void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther) {
			if (es.Length != 3) {
				SetArgCountErrorNan();
				ifOther.Generate(ilg);
			}
			else {
				es[0].CompileCondition(
									   new Gen(delegate { es[1].CompileCondition(ifTrue, ifFalse, ifOther); }),
									   new Gen(delegate { es[2].CompileCondition(ifTrue, ifFalse, ifOther); }),
									   ifOther);
			}
		}
Esempio n. 12
0
		public override void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther) {
			if (Double.IsInfinity(number.value) || Double.IsNaN(number.value)) {
				ilg.Emit(OpCodes.Ldc_R8, number.value);
				ilg.Emit(OpCodes.Stloc, testDouble);
				ifOther.Generate(ilg);
			}
			else if (number.value != 0) {
				ifTrue.Generate(ilg);
			}
			else {
				ifFalse.Generate(ilg);
			}
		}
Esempio n. 13
0
 public override void CompileToDoubleProper(Gen ifProper, Gen ifOther)
 {
     if (double.IsInfinity(number.value) || double.IsNaN(number.value))
     {
         ilg.Emit(OpCodes.Ldc_R8, number.value);
         ilg.Emit(OpCodes.Stloc, testDouble);
         ifOther.Generate(ilg);
     }
     else
     {
         ilg.Emit(OpCodes.Ldc_R8, number.value);
         ifProper.Generate(ilg);
     }
 }
Esempio n. 14
0
		public override void CompileToDoubleProper(Gen ifProper, Gen ifOther) {
			if (es.Length != Arity) {
				SetArgCountErrorNan();
				ifOther.Generate(ilg);
			}
			else {
				es[0].CompileToDoubleProper(
										    new Gen(delegate {
														ilg.Emit(OpCodes.Neg);
														ifProper.Generate(ilg);
													}),
											ifOther);
			}
		}
Esempio n. 15
0
 // This handles compilation of IF(IF(e00,e01,e02), e1, e2) and such
 public override void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther)
 {
     if (es.Length != 3)
     {
         SetArgCountErrorNan();
         ifOther.Generate(ilg);
     }
     else
     {
         es[0].CompileCondition(
             new Gen(delegate { es[1].CompileCondition(ifTrue, ifFalse, ifOther); }),
             new Gen(delegate { es[2].CompileCondition(ifTrue, ifFalse, ifOther); }),
             ifOther);
     }
 }
Esempio n. 16
0
		// A comparison evaluates to a proper double only if both operands do
		public override void CompileToDoubleProper(Gen ifProper, Gen ifOther) {
			es[0].CompileToDoubleProper(
									    new Gen(delegate {
													es[1].CompileToDoubleProper(
																			    new Gen(delegate {
																							GenCompareDouble();
																							ilg.Emit(OpCodes.Conv_R8);
																							ifProper.Generate(ilg);
																						}),
																				new Gen(delegate {
																							ilg.Emit(OpCodes.Pop);
																							ifOther.Generate(ilg);
																						}));
												}),
										ifOther);
		}
Esempio n. 17
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);
     }
 }
Esempio n. 18
0
 public override void CompileToDoubleProper(Gen ifProper, Gen ifOther)
 {
     if (es.Length != Arity)
     {
         SetArgCountErrorNan();
         ifOther.Generate(ilg);
     }
     else
     {
         es[0].CompileToDoubleProper(
             new Gen(delegate {
             ilg.Emit(OpCodes.Neg);
             ifProper.Generate(ilg);
         }),
             ifOther);
     }
 }
Esempio n. 19
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);
 }
Esempio n. 20
0
 // A comparison evaluates to a proper double only if both operands do
 public override void CompileToDoubleProper(Gen ifProper, Gen ifOther)
 {
     es[0].CompileToDoubleProper(
         new Gen(delegate {
         es[1].CompileToDoubleProper(
             new Gen(delegate {
             GenCompareDouble();
             ilg.Emit(OpCodes.Conv_R8);
             ifProper.Generate(ilg);
         }),
             new Gen(delegate {
             ilg.Emit(OpCodes.Pop);
             ifOther.Generate(ilg);
         }));
     }),
         ifOther);
 }
Esempio n. 21
0
 public override void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther)
 {
     if (Double.IsInfinity(number.value) || Double.IsNaN(number.value))
     {
         ilg.Emit(OpCodes.Ldc_R8, number.value);
         ilg.Emit(OpCodes.Stloc, testDouble);
         ifOther.Generate(ilg);
     }
     else if (number.value != 0)
     {
         ifTrue.Generate(ilg);
     }
     else
     {
         ifFalse.Generate(ilg);
     }
 }
Esempio n. 22
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);
			}
		}
Esempio n. 23
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);
     }
 }
Esempio n. 24
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);
		}
Esempio n. 25
0
		public override void CompileToDoubleOrNan() {
			Gen success =
				new Gen(delegate {
							ilg.Emit(OpCodes.Call, functionInfo.methodInfo);
							if (functionInfo.signature.retType != Typ.Number) {
								UnwrapToDoubleOrNan();
							}
						});
			if (Arity < 0) { // Variable arity 
				CompileToValueArray(es.Length, 0, es);
				success.Generate(ilg);
			}
			else if (es.Length != Arity) {
				LoadErrorNan(ErrorValue.argCountError);
			}
			else {
				// TODO: ifOther should probably load error from testValue instead?
				Gen ifOther = GenLoadErrorNan(ErrorValue.argTypeError);
				CompileArgumentsAndApply(es, success, ifOther);
			}
		}
Esempio n. 26
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);
 }
Esempio n. 27
0
		protected void UnwrapToString(Gen ifString, Gen ifError) {
			CheckType(TextValue.type,
					  new Gen(delegate {
								  ilg.Emit(OpCodes.Ldfld, TextValue.valueField);
								  ifString.Generate(ilg);
							  }),
					  ifError);
		}
Esempio n. 28
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);
			}
		}
Esempio n. 29
0
        // Generate code to evaluate all argument expressions, including the receiver es[1]
        // if the method is an instance method, and convert their values to .NET types.

        private void CompileArgumentsAndApply(CGExpr[] es, Gen ifSuccess, Gen ifOther)
        {
            int argCount = es.Length;

            // The error continuations must pop the arguments computed so far.
            Gen[] errorCont = new Gen[argCount];
            if (argCount > 0)
            {
                errorCont[0] = ifOther;
            }
            for (int i = 1; i < argCount; i++)
            {
                int ii = i;                 // Capture lvalue -- do NOT inline!
                errorCont[ii] = new Gen(delegate {
                    ilg.Emit(OpCodes.Pop);
                    errorCont[ii - 1].Generate(ilg);
                });
            }
            // Generate code, backwards, to evaluate argument expressions and
            // convert to the .NET method's argument types
            for (int i = argCount - 1; i >= 0; i--)
            {
                // These local vars capture rvalue rather than lvalue -- do NOT inline them!
                CGExpr ei           = es[i];
                Gen    localSuccess = ifSuccess;
                Typ    argType      = functionInfo.signature.argTypes[i];
                Gen    ifError      = errorCont[i];
                if (argType == Typ.Number)
                {
                    ifSuccess = new Gen(delegate {
                        ei.CompileToDoubleOrNan();
                        localSuccess.Generate(ilg);
                    });
                }
                else if (argType == Typ.Function)
                {
                    ifSuccess = new Gen(delegate {
                        ei.Compile();
                        CheckType(FunctionValue.type, localSuccess, ifError);
                    });
                }
                else if (argType == Typ.Array)
                {
                    ifSuccess = new Gen(delegate {
                        ei.Compile();
                        CheckType(ArrayValue.type, localSuccess, ifError);
                    });
                }
                else if (argType == Typ.Text)
                {
                    ifSuccess = new Gen(delegate {
                        ei.Compile();
                        CheckType(TextValue.type, localSuccess, ifError);
                    });
                }
                else                 // argType.Value -- TODO: neglects to propagate ErrorValue from argument
                {
                    ifSuccess = new Gen(delegate {
                        ei.Compile();
                        localSuccess.Generate(ilg);
                    });
                }
            }
            ifSuccess.Generate(ilg);
        }
Esempio n. 30
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);
		}
Esempio n. 31
0
 // In Excel, a text used in a conditional produces the error #VALUE! -- mostly
 public override void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther)
 {
     ifOther.Generate(ilg);
 }
Esempio n. 32
0
 public override void CompileToDoubleProper(Gen ifProper, Gen ifOther)
 {
     ifOther.Generate(ilg);
 }
Esempio n. 33
0
        // Generate code to evaluate all argument expressions, including the receiver es[1]
        // if the method is an instance method, and convert their values to .NET types.

        private void CompileArgumentsAndApply(CGExpr[] es, Gen ifSuccess, Gen ifOther)
        {
            int argCount = es.Length - 1;

            // The error continuations must pop the arguments computed so far:
            Gen[] errorCont = new Gen[argCount];
            if (argCount > 0)
            {
                errorCont[0] = ifOther;
            }
            for (int i = 1; i < argCount; i++)
            {
                int ii = i;                 // Capture lvalue -- do NOT inline!
                errorCont[ii] = new Gen(delegate {
                    ilg.Emit(OpCodes.Pop);
                    errorCont[ii - 1].Generate(ilg);
                });
            }
            // Generate code, backwards, to evaluate argument expressions and
            // convert to external method's argument types
            for (int i = argCount - 1; i >= 0; i--)
            {
                // These local vars capture rvalue rather than lvalue -- do NOT inline them!
                CGExpr ei           = es[i + 1];
                Gen    localSuccess = ifSuccess;
                int    argIndex     = i;
                Type   argType      = ef.ArgType(i);
                Gen    ifError      = errorCont[i];
                // First some special cases to avoid boxing:
                if (argType == typeof(System.Double))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleOrNan();
                        localSuccess.Generate(ilg);
                    });
                }
                else if (argType == typeof(System.Single))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleOrNan();
                        ilg.Emit(OpCodes.Conv_R4);
                        localSuccess.Generate(ilg);
                    });
                }
                else if (signed32.Contains(argType))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleProper(
                            new Gen(delegate {
                            ilg.Emit(OpCodes.Conv_I4);
                            localSuccess.Generate(ilg);
                        }),
                            ifError);
                    });
                }
                else if (unsigned32.Contains(argType))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleProper(
                            new Gen(delegate {
                            ilg.Emit(OpCodes.Conv_U4);
                            localSuccess.Generate(ilg);
                        }),
                            ifError);
                    });
                }
                else if (argType == typeof(System.Int64))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleProper(
                            new Gen(delegate {
                            ilg.Emit(OpCodes.Conv_I8);
                            localSuccess.Generate(ilg);
                        }),
                            ifError);
                    });
                }
                else if (argType == typeof(System.UInt64))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleProper(
                            new Gen(delegate {
                            ilg.Emit(OpCodes.Conv_U8);
                            localSuccess.Generate(ilg);
                        }),
                            ifError);
                    });
                }
                else if (argType == typeof(System.Boolean))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.CompileToDoubleProper(
                            new Gen(delegate {
                            ilg.Emit(OpCodes.Ldc_R8, 0.0);
                            ilg.Emit(OpCodes.Ceq);
                            localSuccess.Generate(ilg);
                        }),
                            ifError);
                    });
                }
                else if (argType == typeof(System.Char))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.Compile();
                        ilg.Emit(OpCodes.Call, TextValue.toNakedCharMethod);
                        localSuccess.Generate(ilg);
                    });
                }
                else if (argType == typeof(System.String))
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.Compile();
                        UnwrapToString(localSuccess, ifError);
                    });
                }
                else                 // General cases: String[], double[], double[,], ...
                {
                    ifSuccess = new Gen(
                        delegate {
                        ei.Compile();
                        ilg.Emit(OpCodes.Call, ef.ArgConverter(argIndex).Method);
                        if (argType.IsValueType)                                 // must unbox wrapped value type, but this is too simple-minded
                        {
                            ilg.Emit(OpCodes.Unbox, argType);
                        }
                        localSuccess.Generate(ilg);
                    });
                }
            }
            ifSuccess.Generate(ilg);
        }
Esempio n. 34
0
		// In Excel, a text used in a conditional produces the error #VALUE! -- mostly
		public override void CompileCondition(Gen ifTrue, Gen ifFalse, Gen ifOther) { ifOther.Generate(ilg); }
Esempio n. 35
0
		public override void CompileToDoubleProper(Gen ifProper, Gen ifOther) { ifOther.Generate(ilg); }