PageRenderTime 61ms CodeModel.GetById 17ms 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
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, CPL-1.0, CC-BY-SA-3.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1, Apache-2.0
  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. using System;
  16. using Microsoft.Scripting;
  17. using Microsoft.Scripting.Utils;
  18. using IronRuby.Builtins;
  19. using System.Text;
  20. using System.Diagnostics;
  21. namespace IronRuby.Runtime {
  22. internal sealed class SpecialGlobalVariableInfo : GlobalVariable {
  23. private readonly GlobalVariableId _id;
  24. internal SpecialGlobalVariableInfo(GlobalVariableId id) {
  25. _id = id;
  26. }
  27. public override object GetValue(RubyContext/*!*/ context, RubyScope scope) {
  28. switch (_id) {
  29. // regular expressions:
  30. case GlobalVariableId.MatchData:
  31. return (scope != null) ? scope.GetInnerMostClosureScope().CurrentMatch : null;
  32. case GlobalVariableId.MatchLastGroup:
  33. return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchLastGroup() : null;
  34. case GlobalVariableId.PreMatch:
  35. return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentPreMatch() : null;
  36. case GlobalVariableId.PostMatch:
  37. return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentPostMatch() : null;
  38. case GlobalVariableId.EntireMatch:
  39. return (scope != null) ? scope.GetInnerMostClosureScope().GetCurrentMatchGroup(0) : null;
  40. // exceptions:
  41. case GlobalVariableId.CurrentException:
  42. return context.CurrentException;
  43. case GlobalVariableId.CurrentExceptionBacktrace:
  44. return context.GetCurrentExceptionBacktrace();
  45. // input:
  46. case GlobalVariableId.InputContent:
  47. return context.InputProvider.Singleton;
  48. case GlobalVariableId.InputFileName:
  49. return context.InputProvider.CurrentFileName;
  50. case GlobalVariableId.LastInputLine:
  51. return (scope != null) ? scope.GetInnerMostClosureScope().LastInputLine : null;
  52. case GlobalVariableId.LastInputLineNumber:
  53. return context.InputProvider.LastInputLineNumber;
  54. case GlobalVariableId.CommandLineArguments:
  55. return context.InputProvider.CommandLineArguments;
  56. // output:
  57. case GlobalVariableId.OutputStream:
  58. return context.StandardOutput;
  59. case GlobalVariableId.ErrorOutputStream:
  60. return context.StandardErrorOutput;
  61. case GlobalVariableId.InputStream:
  62. return context.StandardInput;
  63. // separators:
  64. case GlobalVariableId.InputSeparator:
  65. return context.InputSeparator;
  66. case GlobalVariableId.OutputSeparator:
  67. return context.OutputSeparator;
  68. case GlobalVariableId.StringSeparator:
  69. return context.StringSeparator;
  70. case GlobalVariableId.ItemSeparator:
  71. return context.ItemSeparator;
  72. // loader:
  73. case GlobalVariableId.LoadPath:
  74. return context.Loader.LoadPaths;
  75. case GlobalVariableId.LoadedFiles:
  76. return context.Loader.LoadedFiles;
  77. // misc:
  78. case GlobalVariableId.SafeLevel:
  79. return context.CurrentSafeLevel;
  80. case GlobalVariableId.Verbose:
  81. return context.Verbose;
  82. case GlobalVariableId.KCode:
  83. context.ReportWarning("variable $KCODE is no longer effective");
  84. return null;
  85. case GlobalVariableId.ChildProcessExitStatus:
  86. return context.ChildProcessExitStatus;
  87. case GlobalVariableId.CommandLineProgramPath:
  88. return context.CommandLineProgramPath;
  89. default:
  90. throw Assert.Unreachable;
  91. }
  92. }
  93. public override void SetValue(RubyContext/*!*/ context, RubyScope scope, string/*!*/ name, object value) {
  94. switch (_id) {
  95. // regex:
  96. case GlobalVariableId.MatchData:
  97. if (scope == null) {
  98. throw ReadOnlyError(name);
  99. }
  100. scope.GetInnerMostClosureScope().CurrentMatch = (value != null) ? RequireType<MatchData>(value, name, "MatchData") : null;
  101. return;
  102. case GlobalVariableId.MatchLastGroup:
  103. case GlobalVariableId.PreMatch:
  104. case GlobalVariableId.PostMatch:
  105. case GlobalVariableId.EntireMatch:
  106. throw ReadOnlyError(name);
  107. // exceptions:
  108. case GlobalVariableId.CurrentException:
  109. context.SetCurrentException(value);
  110. return;
  111. case GlobalVariableId.CurrentExceptionBacktrace:
  112. context.SetCurrentExceptionBacktrace(value);
  113. return;
  114. // input:
  115. case GlobalVariableId.LastInputLine:
  116. if (scope == null) {
  117. throw ReadOnlyError(name);
  118. }
  119. scope.GetInnerMostClosureScope().LastInputLine = value;
  120. return;
  121. case GlobalVariableId.LastInputLineNumber:
  122. context.InputProvider.LastInputLineNumber = RequireType<int>(value, name, "Fixnum");
  123. return;
  124. case GlobalVariableId.CommandLineArguments:
  125. case GlobalVariableId.InputFileName:
  126. throw ReadOnlyError(name);
  127. // output:
  128. case GlobalVariableId.OutputStream:
  129. context.StandardOutput = RequireWriteProtocol(context, value, name);
  130. return;
  131. case GlobalVariableId.ErrorOutputStream:
  132. context.StandardErrorOutput = RequireWriteProtocol(context, value, name);
  133. break;
  134. case GlobalVariableId.InputStream:
  135. context.StandardInput = value;
  136. return;
  137. // separators:
  138. case GlobalVariableId.InputContent:
  139. throw ReadOnlyError(name);
  140. case GlobalVariableId.InputSeparator:
  141. context.InputSeparator = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
  142. return;
  143. case GlobalVariableId.OutputSeparator:
  144. context.OutputSeparator = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
  145. return;
  146. case GlobalVariableId.StringSeparator:
  147. // type not enforced:
  148. context.StringSeparator = value;
  149. return;
  150. case GlobalVariableId.ItemSeparator:
  151. context.ItemSeparator = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
  152. return;
  153. // loader:
  154. case GlobalVariableId.LoadedFiles:
  155. case GlobalVariableId.LoadPath:
  156. throw ReadOnlyError(name);
  157. // misc:
  158. case GlobalVariableId.SafeLevel:
  159. context.SetSafeLevel(RequireType<int>(value, name, "Fixnum"));
  160. return;
  161. case GlobalVariableId.Verbose:
  162. context.Verbose = value;
  163. return;
  164. case GlobalVariableId.CommandLineProgramPath:
  165. context.CommandLineProgramPath = (value != null) ? RequireType<MutableString>(value, name, "String") : null;
  166. return;
  167. case GlobalVariableId.KCode:
  168. context.ReportWarning("variable $KCODE is no longer effective");
  169. return;
  170. case GlobalVariableId.ChildProcessExitStatus:
  171. throw ReadOnlyError(name);
  172. default:
  173. throw Assert.Unreachable;
  174. }
  175. }
  176. private object RequireWriteProtocol(RubyContext/*!*/ context, object value, string/*!*/ variableName) {
  177. if (!context.RespondTo(value, "write")) {
  178. throw RubyExceptions.CreateTypeError(String.Format("${0} must have write method, {1} given", variableName, context.GetClassDisplayName(value)));
  179. }
  180. return value;
  181. }
  182. }
  183. }