public override void GenerateCode(ILGenerator gen, CodeFlow cf) { LeftOperand.GenerateCode(gen, cf); var leftDesc = LeftOperand.ExitDescriptor; var exitDesc = _exitTypeDescriptor; if (exitDesc == null) { throw new InvalidOperationException("No exit type descriptor"); } CodeFlow.InsertNumericUnboxOrPrimitiveTypeCoercion(gen, leftDesc, exitDesc); if (_children.Length > 1) { cf.EnterCompilationScope(); RightOperand.GenerateCode(gen, cf); var rightDesc = RightOperand.ExitDescriptor; cf.ExitCompilationScope(); CodeFlow.InsertNumericUnboxOrPrimitiveTypeCoercion(gen, rightDesc, exitDesc); gen.Emit(OpCodes.Sub); } else { gen.Emit(OpCodes.Neg); } cf.PushDescriptor(_exitTypeDescriptor); }
public override void GenerateCode(ILGenerator gen, CodeFlow cf) { if (_exitTypeDescriptor == TypeDescriptor.STRING) { gen.Emit(OpCodes.Newobj, _sbConstructor); Walk(gen, cf, LeftOperand); Walk(gen, cf, RightOperand); gen.Emit(OpCodes.Callvirt, _toString); } else { _children[0].GenerateCode(gen, cf); var leftDesc = _children[0].ExitDescriptor; var exitDesc = _exitTypeDescriptor; if (exitDesc == null) { throw new InvalidOperationException("No exit type descriptor"); } CodeFlow.InsertNumericUnboxOrPrimitiveTypeCoercion(gen, leftDesc, exitDesc); if (_children.Length > 1) { cf.EnterCompilationScope(); _children[1].GenerateCode(gen, cf); var rightDesc = _children[1].ExitDescriptor; cf.ExitCompilationScope(); CodeFlow.InsertNumericUnboxOrPrimitiveTypeCoercion(gen, rightDesc, exitDesc); gen.Emit(OpCodes.Add); } } cf.PushDescriptor(_exitTypeDescriptor); }