PageRenderTime 26ms CodeModel.GetById 13ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/IronPython_Main/Languages/Ruby/Ruby/Runtime/Globals/SpecialGlobalVariableInfo.cs

#
C# | 249 lines | 154 code | 66 blank | 29 comment | 18 complexity | 1c44479ef0e6885e2d00d9e0a33434c2 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 * ironruby@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 Microsoft.Scripting;
 18using Microsoft.Scripting.Utils;
 19using IronRuby.Builtins;
 20using System.Text;
 21using System.Diagnostics;
 22
 23namespace IronRuby.Runtime {
 24    internal sealed class SpecialGlobalVariableInfo : GlobalVariable {
 25        private readonly GlobalVariableId _id;
 26
 27        internal SpecialGlobalVariableInfo(GlobalVariableId id) {
 28            _id = id;
 29        }
 30
 31        public override object GetValue(RubyContext/*!*/ context, RubyScope scope) {
 32            switch (_id) {
 33                
 34                // regular expressions:
 35                case GlobalVariableId.MatchData:
 36                    return (scope != null) ? scope.GetInnerMostClosureScope().CurrentMatch : null;
 37
 38                case GlobalVariableId.MatchLastGroup:
 39                    return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchLastGroup() : null;
 40
 41                case GlobalVariableId.PreMatch:
 42                    return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentPreMatch() : null;
 43
 44                case GlobalVariableId.PostMatch:
 45                    return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentPostMatch() : null;
 46
 47                case GlobalVariableId.EntireMatch:
 48                    return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchGroup(0) : null;
 49
 50
 51                // exceptions:
 52                case GlobalVariableId.CurrentException:
 53                    return context.CurrentException;
 54
 55                case GlobalVariableId.CurrentExceptionBacktrace:
 56                    return context.GetCurrentExceptionBacktrace();
 57
 58
 59                // input:
 60                case GlobalVariableId.InputContent:
 61                    return context.InputProvider.Singleton;
 62
 63                case GlobalVariableId.InputFileName:
 64                    return context.InputProvider.CurrentFileName;
 65
 66                case GlobalVariableId.LastInputLine:
 67                    return (scope != null) ? scope.GetInnerMostClosureScope().LastInputLine : null;
 68
 69                case GlobalVariableId.LastInputLineNumber:
 70                    return context.InputProvider.LastInputLineNumber;
 71
 72                case GlobalVariableId.CommandLineArguments:
 73                    return context.InputProvider.CommandLineArguments;
 74
 75
 76                // output:
 77                case GlobalVariableId.OutputStream:
 78                    return context.StandardOutput;
 79
 80                case GlobalVariableId.ErrorOutputStream:
 81                    return context.StandardErrorOutput;
 82
 83                case GlobalVariableId.InputStream:
 84                    return context.StandardInput;
 85
 86
 87                // separators:
 88                case GlobalVariableId.InputSeparator:
 89                    return context.InputSeparator;
 90
 91                case GlobalVariableId.OutputSeparator:
 92                    return context.OutputSeparator;
 93
 94                case GlobalVariableId.StringSeparator:
 95                    return context.StringSeparator;
 96
 97                case GlobalVariableId.ItemSeparator:
 98                    return context.ItemSeparator;
 99
100                
101                // loader:
102                case GlobalVariableId.LoadPath:
103                    return context.Loader.LoadPaths;
104
105                case GlobalVariableId.LoadedFiles:
106                    return context.Loader.LoadedFiles;
107
108
109                // misc:
110                case GlobalVariableId.SafeLevel:
111                    return context.CurrentSafeLevel;
112
113                case GlobalVariableId.Verbose:
114                    return context.Verbose;
115
116                case GlobalVariableId.KCode:
117                    context.ReportWarning("variable $KCODE is no longer effective");
118                    return null;
119
120                case GlobalVariableId.ChildProcessExitStatus:
121                    return context.ChildProcessExitStatus;
122
123                case GlobalVariableId.CommandLineProgramPath:
124                    return context.CommandLineProgramPath;
125
126                default:
127                    throw Assert.Unreachable;
128            }
129        }
130
131        public override void SetValue(RubyContext/*!*/ context, RubyScope scope, string/*!*/ name, object value) {
132            switch (_id) {
133                // regex:
134                case GlobalVariableId.MatchData:
135                    if (scope == null) {
136                        throw ReadOnlyError(name);
137                    }
138
139                    scope.GetInnerMostClosureScope().CurrentMatch = (value != null) ? RequireType<MatchData>(value, name, "MatchData") : null;
140                    return;
141
142                case GlobalVariableId.MatchLastGroup:
143                case GlobalVariableId.PreMatch:
144                case GlobalVariableId.PostMatch:
145                case GlobalVariableId.EntireMatch:
146                    throw ReadOnlyError(name);
147                
148                
149                // exceptions:
150                case GlobalVariableId.CurrentException:
151                    context.SetCurrentException(value);
152                    return;
153
154                case GlobalVariableId.CurrentExceptionBacktrace:
155                    context.SetCurrentExceptionBacktrace(value);
156                    return;
157
158
159                // input:
160                case GlobalVariableId.LastInputLine:
161                    if (scope == null) {
162                        throw ReadOnlyError(name);
163                    }
164                    scope.GetInnerMostClosureScope().LastInputLine = value;
165                    return;
166
167                case GlobalVariableId.LastInputLineNumber:
168                    context.InputProvider.LastInputLineNumber = RequireType<int>(value, name, "Fixnum");
169                    return;
170
171                case GlobalVariableId.CommandLineArguments:
172                case GlobalVariableId.InputFileName:
173                    throw ReadOnlyError(name);
174
175                // output:
176                case GlobalVariableId.OutputStream:
177                    context.StandardOutput = RequireWriteProtocol(context, value, name);
178                    return;
179
180                case GlobalVariableId.ErrorOutputStream:
181                    context.StandardErrorOutput = RequireWriteProtocol(context, value, name);
182                    break;
183
184                case GlobalVariableId.InputStream:
185                    context.StandardInput = value;
186                    return;
187
188                // separators:
189                case GlobalVariableId.InputContent:
190                    throw ReadOnlyError(name);
191
192                case GlobalVariableId.InputSeparator:
193                    context.InputSeparator = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
194                    return;
195
196                case GlobalVariableId.OutputSeparator:
197                    context.OutputSeparator = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
198                    return;
199
200                case GlobalVariableId.StringSeparator:
201                    // type not enforced:
202                    context.StringSeparator = value;
203                    return;
204
205                case GlobalVariableId.ItemSeparator:
206                    context.ItemSeparator = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
207                    return;
208
209
210                // loader:
211                case GlobalVariableId.LoadedFiles:
212                case GlobalVariableId.LoadPath:
213                    throw ReadOnlyError(name);
214
215
216                // misc:
217                case GlobalVariableId.SafeLevel:
218                    context.SetSafeLevel(RequireType<int>(value, name, "Fixnum"));
219                    return;
220
221                case GlobalVariableId.Verbose:
222                    context.Verbose = value;
223                    return;
224
225                case GlobalVariableId.CommandLineProgramPath:
226                    context.CommandLineProgramPath = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
227                    return;
228                
229                case GlobalVariableId.KCode:
230                    context.ReportWarning("variable $KCODE is no longer effective");
231                    return;
232
233                case GlobalVariableId.ChildProcessExitStatus:
234                    throw ReadOnlyError(name);
235                    
236                default:
237                    throw Assert.Unreachable;
238            }
239        }
240    
241        private object RequireWriteProtocol(RubyContext/*!*/ context, object value, string/*!*/ variableName) {
242            if (!context.RespondTo(value, "write")) {
243                throw RubyExceptions.CreateTypeError(String.Format("${0} must have write method, {1} given", variableName, context.GetClassDisplayName(value)));
244            }
245
246            return value;
247        }
248    }
249}