add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Experimental/CF/ThrowCatch
add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Experimental/CF/ThrowCatch/test.rb
File: test.rb
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Experimental/CF/ThrowCatch/test.rb;CatchThrow
@@ -1,0 +1,61 @@
+class S2
+  def to_str
+    'x2'
+  end
+end
+
+def f1
+  throw :undefined
+rescue Exception
+  puts "error: #{$!.inspect}"
+end
+
+def f2
+  throw S2.new, 'hello'
+rescue Exception
+  puts "error: #{$!.inspect}"
+else
+  puts 'else'
+ensure
+  puts 'ensure'
+end
+
+catch :x1 do
+  #f1
+end
+
+x = catch :x2 do
+  f2
+  puts 'bar'
+end
+
+p x 
+
+puts '-'*10
+
+catch :a do
+  catch :b do
+    catch :c do
+      throw :d rescue p $!
+      
+      begin
+        throw :a
+      ensure
+        throw :b
+      end  
+      
+      puts 'in c'
+    end
+    puts 'c'
+  end
+  puts 'b'
+end
+puts 'a'
+
+x = catch :foo do |*args|
+  p args
+  123  
+end
+p x
+
+
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C447714
File: Initializers.Generated.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C447714  (server)    5/23/2008 12:56 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;CatchThrow
@@ -49,7 +49,7 @@
             #endif
             // Skipped primitive: Object
             ExtendModule(typeof(System.Collections.Generic.IDictionary<System.Object, System.Object>), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__Collections__Generic__IDictionary_Instance), null, new Ruby.Builtins.RubyModule[] {def16, });
-            ExtendModule(typeof(System.Collections.IEnumerable), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def16, });
+            Ruby.Builtins.RubyModule def30 = ExtendModule(typeof(System.Collections.IEnumerable), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def16, });
             ExtendModule(typeof(System.Collections.IList), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__Collections__IList_Instance), null, new Ruby.Builtins.RubyModule[] {def16, });
             Ruby.Builtins.RubyModule def29 = ExtendModule(typeof(System.IComparable), new System.Action<Ruby.Builtins.RubyModule>(LoadSystem__IComparable_Instance), null, new Ruby.Builtins.RubyModule[] {def25, });
             DefineGlobalClass("Array", typeof(Ruby.Builtins.RubyArray), Context.ObjectClass, new System.Action<Ruby.Builtins.RubyModule>(LoadArray_Instance), new System.Action<Ruby.Builtins.RubyModule>(LoadArray_Class), new Ruby.Builtins.RubyModule[] {def16, }, new System.Delegate[] {
@@ -62,7 +62,7 @@
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, Ruby.Runtime.BlockParam, System.Object, System.Object>(Ruby.Builtins.ArrayOps.CreateArray),
             });
             DefineGlobalClass("Binding", typeof(Ruby.Builtins.Binding), Context.ObjectClass, null, null, Ruby.Builtins.RubyModule.EmptyArray, null);
-            DefineGlobalClass("ClrString", typeof(System.String), Context.ObjectClass, new System.Action<Ruby.Builtins.RubyModule>(LoadClrString_Instance), null, new Ruby.Builtins.RubyModule[] {def29, }, null);
+            DefineGlobalClass("ClrString", typeof(System.String), Context.ObjectClass, new System.Action<Ruby.Builtins.RubyModule>(LoadClrString_Instance), null, new Ruby.Builtins.RubyModule[] {def29, def30, }, null);
             DefineGlobalClass("Dir", typeof(Ruby.Builtins.RubyDir), Context.ObjectClass, new System.Action<Ruby.Builtins.RubyModule>(LoadDir_Instance), new System.Action<Ruby.Builtins.RubyModule>(LoadDir_Class), new Ruby.Builtins.RubyModule[] {def16, }, null);
             Ruby.Builtins.RubyClass def26 = Context.ExceptionClass = DefineGlobalClass("Exception", typeof(System.Exception), Context.ObjectClass, new System.Action<Ruby.Builtins.RubyModule>(LoadException_Instance), new System.Action<Ruby.Builtins.RubyModule>(LoadException_Class), Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] {
                 new Microsoft.Scripting.Utils.Function<Ruby.Builtins.MutableString, System.Exception>(Ruby.Builtins.ExceptionOps.Factory),
@@ -2211,6 +2211,10 @@
                 new Microsoft.Scripting.Utils.Function<System.Object, System.Int32, Ruby.Builtins.RubyArray>(Ruby.Builtins.Kernel.GetStackTrace),
             });
             
+            module.DefineLibraryMethod("catch", 0x2a, new System.Delegate[] {
+                new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Runtime.BlockParam, System.Object, System.Object>(Ruby.Builtins.Kernel.Catch),
+            });
+            
             module.DefineLibraryMethod("class", 0x29, new System.Delegate[] {
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Builtins.RubyClass>(Ruby.Builtins.Kernel.GetClass),
             });
@@ -2468,6 +2472,10 @@
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, System.Boolean>(Ruby.Builtins.Kernel.Tainted),
             });
             
+            module.DefineLibraryMethod("throw", 0x2a, new System.Delegate[] {
+                new Microsoft.Scripting.Utils.Action<Microsoft.Scripting.Runtime.CodeContext, System.Object, System.Object, System.Object>(Ruby.Builtins.Kernel.Throw),
+            });
+            
             module.DefineLibraryMethod("to_s", 0x29, new System.Delegate[] {
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Builtins.MutableString>(Ruby.Builtins.Kernel.ToString),
             });
@@ -2492,6 +2500,10 @@
                 new Microsoft.Scripting.Utils.Function<System.Object, System.Int32, Ruby.Builtins.RubyArray>(Ruby.Builtins.Kernel.GetStackTrace),
             });
             
+            module.DefineLibraryMethod("catch", 0x31, new System.Delegate[] {
+                new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Runtime.BlockParam, System.Object, System.Object>(Ruby.Builtins.Kernel.Catch),
+            });
+            
             module.DefineLibraryMethod("eval", 0x31, new System.Delegate[] {
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Builtins.MutableString, Ruby.Builtins.Binding, Ruby.Builtins.MutableString, System.Int32, System.Object>(Ruby.Builtins.Kernel.Evaluate),
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Builtins.MutableString, Ruby.Builtins.Proc, Ruby.Builtins.MutableString, System.Int32, System.Object>(Ruby.Builtins.Kernel.Evaluate),
@@ -2613,6 +2625,10 @@
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, System.Object, System.Object>(Ruby.Builtins.Kernel.ToString),
             });
             
+            module.DefineLibraryMethod("throw", 0x31, new System.Delegate[] {
+                new Microsoft.Scripting.Utils.Action<Microsoft.Scripting.Runtime.CodeContext, System.Object, System.Object, System.Object>(Ruby.Builtins.Kernel.Throw),
+            });
+            
         }
         
         private void LoadMarshal_Instance(Ruby.Builtins.RubyModule/*!*/ module) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C447221
File: Kernel.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C447221  (server)    5/23/2008 11:39 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;CatchThrow
@@ -141,7 +141,6 @@
             return RubyExceptionData.CreateBacktrace(trace.GetFrames(), skipFrames);
         }
 
-        //catch
         //chomp
         //chomp!
         //chop
@@ -546,14 +545,77 @@
         //syscall
         //system
         //test
-        //throw
+
         //trace_var
         //trap
         //untrace_var
         //warn
 
+        #region throw, catch 
+
+        private sealed class ThrowCatchUnwinder : StackUnwinder {
+            private readonly SymbolId _symbol;
+            public SymbolId Symbol { get { return _symbol; } }
+
+            internal ThrowCatchUnwinder(SymbolId symbol, object returnValue)
+                : base(returnValue) {
+                _symbol = symbol;
+            }
+        }
+
+        [ThreadStatic]
+        private static Stack<SymbolId> _catchSymbols;
+
+        private static readonly DynamicSite<BlockParam, SymbolId, object>/*!*/ _CatchSite =
+            CallSiteFactory.CreateSimpleCallSite<BlockParam, SymbolId, object>(RubyContext.RubyBinder);
+
+        [RubyMethod("catch", RubyMethodAttributes.PrivateInstance)]
+        [RubyMethod("catch", RubyMethodAttributes.PublicSingleton)]
+        public static object Catch(CodeContext/*!*/ context, object self, BlockParam/*!*/ block, object symbol) {
+            if (block == null) {
+                throw new LocalJumpError("no block given");
+            }
+
+            SymbolId sym = Protocols.CastToSymbol(context, symbol);
+
+            try {
+                if (_catchSymbols == null) {
+                    _catchSymbols = new Stack<SymbolId>();
+                }
+                _catchSymbols.Push(sym);
+
+                try {
+                    object result = _CatchSite.Invoke(context, block, sym);
+                    block.BlockJumped(result);
+                    return result;
+                } catch (ThrowCatchUnwinder unwinder) {
+                    if (unwinder.Symbol == sym) {
+                        return unwinder.ReturnValue;
+                    }
+
+                    throw;
+                }
+            } finally {
+                _catchSymbols.Pop();
+            }
+        }
+
+        [RubyMethod("throw", RubyMethodAttributes.PrivateInstance)]
+        [RubyMethod("throw", RubyMethodAttributes.PublicSingleton)]
+        public static void Throw(CodeContext/*!*/ context, object self, object symbol, [DefaultParameterValue(null)]object returnValue) {
+            SymbolId sym = Protocols.CastToSymbol(context, symbol);
+
+            if (_catchSymbols == null || !_catchSymbols.Contains(sym)) {
+                throw RubyExceptions.CreateNameError(String.Format("uncaught throw `{0}'", SymbolTable.IdToString(sym)));
+            }
+
+            throw new ThrowCatchUnwinder(sym, returnValue);
+        }
+
         #endregion
 
+        #endregion
+
         #region Public Instance Methods
 
         #region ==, ===, eql?, equal?, hash
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;C444795
File: RubyContext.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;C444795  (server)    5/23/2008 11:32 AM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;CatchThrow
@@ -233,13 +233,13 @@
 
             StringBuilder sb = new StringBuilder();
             if (bt != null && bt.Count > 0) {
-                sb.AppendFormat("{0}: {1} ({2})", bt[0], data.Message, className);
+                sb.AppendFormat("{0}: {1} ({2})", bt[0], data.Message, className).AppendLine();
 
                 for (int i = 1; i < bt.Count; i++) {
-                    sb.AppendLine().Append("\tfrom ").Append(bt[i]);
+                    sb.Append("\tfrom ").Append(bt[i]).AppendLine();
                 }
             } else {
-                sb.AppendFormat("unknown: {0} ({1})", data.Message, className);
+                sb.AppendFormat("unknown: {0} ({1})", data.Message, className).AppendLine();
             }
 
             // display the raw CLR exception & strack trace if requested
@@ -247,6 +247,7 @@
                 sb.AppendLine().AppendLine();
                 sb.AppendLine("CLR exception:");
                 sb.Append(base.FormatException(exception));
+                sb.AppendLine();
             }
 
             return sb.ToString();
===================================================================
