protected object DoesNotUnderstand(STMessage msg) { if (Map.ContainsKey(msg.Selector)) return Map[msg.Selector]; var t = Type.GetType(string.Format("{0}.{1}", FullName, msg.Selector.Name)); if (t == null) { foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { t = asm.GetType(string.Format("{0}.{1}", FullName, msg.Selector.Name)); if (t != null) break; } } if (t != null) { var @class = STClass.GetForCLR(t, t.Name); Map[msg.Selector] = @class; return @class; } var ns = new STNamespace(msg.Selector.Name, FullName + "." + msg.Selector.Name); Map[msg.Selector] = ns; return ns; /* try { return Class.Superclass.RouteMessage(new STMessage(this, STSymbol.Get("doesNotUnderstand:"), msg)); } catch (MessageNotUnderstood) { Console.Error.WriteLine ("No one implements doesNotUnderstand:! Bailing out."); return STUndefinedObject.Instance; } */ }
public static STObject DoesNotUnderstand(STObject self, STMessage msg) { try { return self.HandleDoesNotUnderstand(msg); } catch (MessageNotUnderstood) { Transcript.WriteLine("{0} doesNotUnderstand: #{1}", msg.Receiver.Class, msg.Selector.Name); } return STUndefinedObject.Instance; }
public override STObject HandleDoesNotUnderstand(STMessage msg) { List<STSymbol> parms = new List<STSymbol>(); var symbolClass = STClass.GetForCLR(typeof(STSymbol), "Symbol"); foreach (var obj in msg.Parameters) { if (obj.Class != symbolClass) throw new Exception("Pass the names to bind to keyword parameters as symbols, not " + obj.Class.Plural); parms.Add(obj as STSymbol); } return new STMethodPrototype(BuildingClass, msg.Selector, parms.ToArray()); }
public override STObject Invoke(STMessage message) { try { var instanceCtx = message.Receiver.InstanceContext; var invocationCtx = new LocalContext (instanceCtx); for (int i = 0, max = Prototype.ParameterNames.Length; i < max; ++i) invocationCtx.SetVariable(Prototype.ParameterNames[i].Name, message.Parameters[i]); return Block.EvaluateWith(invocationCtx); } catch (ReturnException e) { return e.Value; } }
public override STObject HandleDoesNotUnderstand(STMessage msg) { if (Type == null) return base.HandleDoesNotUnderstand(msg); // System Console writeLine: { 'thing1' . 'thing2' } // --> System.Console.WriteLine("thing1", "thing2"); Console.WriteLine ("Hrm odd"); if (msg.Parameters.Length > 1) return base.HandleDoesNotUnderstand(msg); string name = msg.Selector.Name.Trim(':'); name = char.ToUpper(name[0]) + name.Substring(1); STObject[] parms = msg.Parameters; if (name == "New") name = ".ctor"; if (parms.Length > 0) { if (parms[0].Class == STClass.GetForCLR(typeof(Irontalk.Array), "Array")) { // Expand the array into the arguments we want... var array = parms[0] as Irontalk.Array; parms = new STObject[array.Size()]; for (long i = 1, max = array.Size(); i <= max; ++i) parms[i - 1] = STInstance.For(array.At(i)); } } STObject[] stobj = parms; object[] native = new object[stobj.Length]; Type[] types = new Type[stobj.Length]; for (int i = 0, max = stobj.Length; i < max; ++i) { native[i] = stobj[i].Native; types[i] = native[i].GetType(); } MethodInfo method = null; if (stobj.Length <= 1 && name != ".ctor") { var props = Type.GetProperties(BindingFlags.Public | BindingFlags.Static); foreach (var prop in props) { if (prop.Name == name) { if (stobj.Length == 0) method = prop.GetGetMethod(); else method = prop.GetSetMethod(); break; } } } if (name == ".ctor") { var ctor = Type.GetConstructor(BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance, null, types, null); if (ctor == null) { Console.WriteLine ("failed to find matching constructor!"); return base.HandleDoesNotUnderstand(msg); } return STInstance.For(ctor.Invoke(native)); } if (method == null) { method = Type.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, types, null); } if (method != null) { object result = method.Invoke(null, native); if (method.ReturnType == typeof(void)) return msg.Receiver; return STInstance.For(result); } return base.HandleDoesNotUnderstand(msg); #if false if (Type == null) return base.HandleDidNotUnderstand(msg); Console.WriteLine ("Attempting to route message via .NET"); // System Console writeLine: { 'thing1' . 'thing2' } // --> System.Console.WriteLine("thing1", "thing2"); string name = msg.Selector.Name.Replace(":", ""); name = char.ToUpper(name[0]) + name.Substring(1); STObject[] stobj = msg.Parameters; object[] native = new object[stobj.Length]; Type[] types = new Type[stobj.Length]; for (int i = 0, max = stobj.Length; i < max; ++i) { native[i] = stobj[i].Native; types[i] = native[i].GetType(); } MethodInfo method = null; if (stobj.Length == 0) { var props = Type.GetProperties(BindingFlags.Public | BindingFlags.Static); foreach (var prop in props) { if (prop.Name == name) { method = prop.GetGetMethod(); break; } } } if (method == null) method = Type.GetMethod(name, BindingFlags.Static, null, types, null); if (method != null) { object result = method.Invoke(null, native); if (result is STObject) return result as STObject; return new STInstance(result); } return base.HandleDidNotUnderstand(msg); #endif }
public abstract STObject Invoke(STMessage message);
public static string ToString(STMessage m) { return (m.Receiver as STMetaclass).Name; }
public MessageNotUnderstood(STMessage msg) : base("Message #" + msg.Selector.Name + " not understood") { PendingMessage = msg; }
public override STObject Invoke(STMessage message) { object result; if (method != null) { var stobj = new List<STObject>(); var parmInfo = method.GetParameters(); List<object> native = new List<object> (); if (parmInfo.Length > 0 || message.Parameters.Length > 0) { if (PassReceiver) stobj.Add(message.Receiver); stobj.AddRange(message.Parameters); for (int i = 0, max = stobj.Count; i < max; ++i) { var parmType = parmInfo[i].ParameterType; if (parmType == typeof(STObject) || parmType.IsSubclassOf(typeof(STObject))) { native.Add (stobj[i]); } else { native.Add(stobj[i].Native); } } } try { result = method.Invoke(message.Receiver.MethodReceiver, native.ToArray()); } catch (TargetInvocationException tie) { throw tie.InnerException; } if (method.ReturnType == typeof(void)) result = message.Receiver; } else if (@delegate != null) { result = @delegate(message); } else { throw new Exception ("This runtime-delegated message has no implementation!"); } if (result is STObject) return result as STObject; return new STInstance(result); }
public virtual STObject Send(STSymbol message, params STObject[] args) { STMessage msg = new STMessage (this, message, args); try { return Class.RouteMessage(msg); } catch (MessageNotUnderstood e) { if (message.Name == "doesNotUnderstand:") throw e; // avoid infinite recursion return Send (STSymbol.Get("doesNotUnderstand:"), msg); } }
public virtual STObject HandleDoesNotUnderstand(STMessage msg) { throw new MessageNotUnderstood(msg); }
public STObject RouteMessage(STMessage msg) { if (STDebug.SuperclassTraversal) Console.WriteLine("(routing #{0}) - visiting: {1}", msg.Selector.Name, Name); STCompiledMethod method; if (STDebug.VerboseRouting) { Console.WriteLine("Routing {0} on class {1}", msg.Selector.Name, this.Name); Console.WriteLine("Available messages: "); foreach (var kvp in MethodDictionary) { Console.WriteLine(" - {0}", kvp.Key); } } if (MethodDictionary.TryGetValue(msg.Selector, out method)) { if (STDebug.MessageRouting) Console.WriteLine("Message routed to class {0}", Name); return method.Invoke(msg); } if (Superclass != null) return Superclass.RouteMessage(msg); if (STDebug.VerboseRouting) Console.Error.WriteLine ("throwing doesNotUnderstand: error"); throw new MessageNotUnderstood(msg); }