PageRenderTime 32ms CodeModel.GetById 18ms app.highlight 10ms RepoModel.GetById 2ms app.codeStats 0ms

/IronPython_Main/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NumericConvertInstruction.cs

#
C# | 254 lines | 219 code | 21 blank | 14 comment | 10 complexity | 17b8e65d63fe23fc14c3f3f08d98afe1 MD5 | raw file
  1/* ****************************************************************************
  2 *
  3 * Copyright (c) Microsoft Corporation. 
  4 *
  5 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
  6 * copy of the license can be found in the License.html file at the root of this distribution. If 
  7 * you cannot locate the  Apache License, Version 2.0, please send an email to 
  8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
  9 * by the terms of the Apache License, Version 2.0.
 10 *
 11 * You must not remove this notice, or any other, from this software.
 12 *
 13 *
 14 * ***************************************************************************/
 15
 16using System;
 17using System.Collections.Generic;
 18using System.Diagnostics;
 19using System.Reflection;
 20using System.Runtime.CompilerServices;
 21using Microsoft.Scripting.Runtime;
 22using Microsoft.Scripting.Utils;
 23
 24namespace Microsoft.Scripting.Interpreter {
 25    internal abstract class NumericConvertInstruction : Instruction {
 26        internal readonly TypeCode _from, _to;
 27
 28        protected NumericConvertInstruction(TypeCode from, TypeCode to) {
 29            _from = from;
 30            _to = to;
 31        }
 32
 33        public override int ConsumedStack { get { return 1; } }
 34        public override int ProducedStack { get { return 1; } }
 35
 36        public override string ToString() {
 37            return InstructionName + "(" + _from + "->" + _to + ")";
 38        }
 39
 40        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
 41        public sealed class Unchecked : NumericConvertInstruction {
 42            public override string InstructionName { get { return "UncheckedConvert"; } }
 43
 44            public Unchecked(TypeCode from, TypeCode to)
 45                : base(from, to) {
 46            }
 47
 48            public override int Run(InterpretedFrame frame) {
 49                frame.Push(Convert(frame.Pop()));
 50                return +1;
 51            }
 52
 53            private object Convert(object obj) {
 54                switch (_from) {
 55                    case TypeCode.Byte: return ConvertInt32((Byte)obj);
 56                    case TypeCode.SByte: return ConvertInt32((SByte)obj);
 57                    case TypeCode.Int16: return ConvertInt32((Int16)obj);
 58                    case TypeCode.Char: return ConvertInt32((Char)obj);
 59                    case TypeCode.Int32: return ConvertInt32((Int32)obj);
 60                    case TypeCode.Int64: return ConvertInt64((Int64)obj);
 61                    case TypeCode.UInt16: return ConvertInt32((UInt16)obj);
 62                    case TypeCode.UInt32: return ConvertInt64((UInt32)obj);
 63                    case TypeCode.UInt64: return ConvertUInt64((UInt64)obj);
 64                    case TypeCode.Single: return ConvertDouble((Single)obj);
 65                    case TypeCode.Double: return ConvertDouble((Double)obj);
 66                    default: throw Assert.Unreachable;
 67                }
 68            }
 69
 70            private object ConvertInt32(int obj) {
 71                unchecked {
 72                    switch (_to) {
 73                        case TypeCode.Byte: return (Byte)obj;
 74                        case TypeCode.SByte: return (SByte)obj;
 75                        case TypeCode.Int16: return (Int16)obj;
 76                        case TypeCode.Char: return (Char)obj;
 77                        case TypeCode.Int32: return (Int32)obj;
 78                        case TypeCode.Int64: return (Int64)obj;
 79                        case TypeCode.UInt16: return (UInt16)obj;
 80                        case TypeCode.UInt32: return (UInt32)obj;
 81                        case TypeCode.UInt64: return (UInt64)obj;
 82                        case TypeCode.Single: return (Single)obj;
 83                        case TypeCode.Double: return (Double)obj;
 84                        default: throw Assert.Unreachable;
 85                    }
 86                }
 87            }
 88
 89            private object ConvertInt64(Int64 obj) {
 90                unchecked {
 91                    switch (_to) {
 92                        case TypeCode.Byte: return (Byte)obj;
 93                        case TypeCode.SByte: return (SByte)obj;
 94                        case TypeCode.Int16: return (Int16)obj;
 95                        case TypeCode.Char: return (Char)obj;
 96                        case TypeCode.Int32: return (Int32)obj;
 97                        case TypeCode.Int64: return (Int64)obj;
 98                        case TypeCode.UInt16: return (UInt16)obj;
 99                        case TypeCode.UInt32: return (UInt32)obj;
100                        case TypeCode.UInt64: return (UInt64)obj;
101                        case TypeCode.Single: return (Single)obj;
102                        case TypeCode.Double: return (Double)obj;
103                        default: throw Assert.Unreachable;
104                    }
105                }
106            }
107
108            private object ConvertUInt64(UInt64 obj) {
109                unchecked {
110                    switch (_to) {
111                        case TypeCode.Byte: return (Byte)obj;
112                        case TypeCode.SByte: return (SByte)obj;
113                        case TypeCode.Int16: return (Int16)obj;
114                        case TypeCode.Char: return (Char)obj;
115                        case TypeCode.Int32: return (Int32)obj;
116                        case TypeCode.Int64: return (Int64)obj;
117                        case TypeCode.UInt16: return (UInt16)obj;
118                        case TypeCode.UInt32: return (UInt32)obj;
119                        case TypeCode.UInt64: return (UInt64)obj;
120                        case TypeCode.Single: return (Single)obj;
121                        case TypeCode.Double: return (Double)obj;
122                        default: throw Assert.Unreachable;
123                    }
124                }
125            }
126
127            private object ConvertDouble(Double obj) {
128                unchecked {
129                    switch (_to) {
130                        case TypeCode.Byte: return (Byte)obj;
131                        case TypeCode.SByte: return (SByte)obj;
132                        case TypeCode.Int16: return (Int16)obj;
133                        case TypeCode.Char: return (Char)obj;
134                        case TypeCode.Int32: return (Int32)obj;
135                        case TypeCode.Int64: return (Int64)obj;
136                        case TypeCode.UInt16: return (UInt16)obj;
137                        case TypeCode.UInt32: return (UInt32)obj;
138                        case TypeCode.UInt64: return (UInt64)obj;
139                        case TypeCode.Single: return (Single)obj;
140                        case TypeCode.Double: return (Double)obj;
141                        default: throw Assert.Unreachable;
142                    }
143                }
144            }
145        }
146
147        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
148        public sealed class Checked : NumericConvertInstruction {
149            public override string InstructionName { get { return "CheckedConvert"; } }
150
151            public Checked(TypeCode from, TypeCode to)
152                : base(from, to) {
153            }
154
155            public override int Run(InterpretedFrame frame) {
156                frame.Push(Convert(frame.Pop()));
157                return +1;
158            }
159
160            private object Convert(object obj) {
161                switch (_from) {
162                    case TypeCode.Byte: return ConvertInt32((Byte)obj);
163                    case TypeCode.SByte: return ConvertInt32((SByte)obj);
164                    case TypeCode.Int16: return ConvertInt32((Int16)obj);
165                    case TypeCode.Char: return ConvertInt32((Char)obj);
166                    case TypeCode.Int32: return ConvertInt32((Int32)obj);
167                    case TypeCode.Int64: return ConvertInt64((Int64)obj);
168                    case TypeCode.UInt16: return ConvertInt32((UInt16)obj);
169                    case TypeCode.UInt32: return ConvertInt64((UInt32)obj);
170                    case TypeCode.UInt64: return ConvertUInt64((UInt64)obj);
171                    case TypeCode.Single: return ConvertDouble((Single)obj);
172                    case TypeCode.Double: return ConvertDouble((Double)obj);
173                    default: throw Assert.Unreachable;
174                }
175            }
176
177            private object ConvertInt32(int obj) {
178                checked {
179                    switch (_to) {
180                        case TypeCode.Byte: return (Byte)obj;
181                        case TypeCode.SByte: return (SByte)obj;
182                        case TypeCode.Int16: return (Int16)obj;
183                        case TypeCode.Char: return (Char)obj;
184                        case TypeCode.Int32: return (Int32)obj;
185                        case TypeCode.Int64: return (Int64)obj;
186                        case TypeCode.UInt16: return (UInt16)obj;
187                        case TypeCode.UInt32: return (UInt32)obj;
188                        case TypeCode.UInt64: return (UInt64)obj;
189                        case TypeCode.Single: return (Single)obj;
190                        case TypeCode.Double: return (Double)obj;
191                        default: throw Assert.Unreachable;
192                    }
193                }
194            }
195
196            private object ConvertInt64(Int64 obj) {
197                checked {
198                    switch (_to) {
199                        case TypeCode.Byte: return (Byte)obj;
200                        case TypeCode.SByte: return (SByte)obj;
201                        case TypeCode.Int16: return (Int16)obj;
202                        case TypeCode.Char: return (Char)obj;
203                        case TypeCode.Int32: return (Int32)obj;
204                        case TypeCode.Int64: return (Int64)obj;
205                        case TypeCode.UInt16: return (UInt16)obj;
206                        case TypeCode.UInt32: return (UInt32)obj;
207                        case TypeCode.UInt64: return (UInt64)obj;
208                        case TypeCode.Single: return (Single)obj;
209                        case TypeCode.Double: return (Double)obj;
210                        default: throw Assert.Unreachable;
211                    }
212                }
213            }
214
215            private object ConvertUInt64(UInt64 obj) {
216                checked {
217                    switch (_to) {
218                        case TypeCode.Byte: return (Byte)obj;
219                        case TypeCode.SByte: return (SByte)obj;
220                        case TypeCode.Int16: return (Int16)obj;
221                        case TypeCode.Char: return (Char)obj;
222                        case TypeCode.Int32: return (Int32)obj;
223                        case TypeCode.Int64: return (Int64)obj;
224                        case TypeCode.UInt16: return (UInt16)obj;
225                        case TypeCode.UInt32: return (UInt32)obj;
226                        case TypeCode.UInt64: return (UInt64)obj;
227                        case TypeCode.Single: return (Single)obj;
228                        case TypeCode.Double: return (Double)obj;
229                        default: throw Assert.Unreachable;
230                    }
231                }
232            }
233
234            private object ConvertDouble(Double obj) {
235                checked {
236                    switch (_to) {
237                        case TypeCode.Byte: return (Byte)obj;
238                        case TypeCode.SByte: return (SByte)obj;
239                        case TypeCode.Int16: return (Int16)obj;
240                        case TypeCode.Char: return (Char)obj;
241                        case TypeCode.Int32: return (Int32)obj;
242                        case TypeCode.Int64: return (Int64)obj;
243                        case TypeCode.UInt16: return (UInt16)obj;
244                        case TypeCode.UInt32: return (UInt32)obj;
245                        case TypeCode.UInt64: return (UInt64)obj;
246                        case TypeCode.Single: return (Single)obj;
247                        case TypeCode.Double: return (Double)obj;
248                        default: throw Assert.Unreachable;
249                    }
250                }
251            }
252        }
253    }
254}