Represents a message being passed to a receiver
Inheritance: STObject
示例#1
0
        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;
            }
            */
        }
示例#2
0
 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;
 }
示例#3
0
        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());
        }
示例#4
0
        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;
            }
        }
示例#5
0
        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
        }
示例#6
0
 public abstract STObject Invoke(STMessage message);
示例#7
0
 public static string ToString(STMessage m)
 {
     return (m.Receiver as STMetaclass).Name;
 }
示例#8
0
 public MessageNotUnderstood(STMessage msg)
     : base("Message #" + msg.Selector.Name + " not understood")
 {
     PendingMessage = msg;
 }
示例#9
0
        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);
        }
示例#10
0
 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);
     }
 }
示例#11
0
 public virtual STObject HandleDoesNotUnderstand(STMessage msg)
 {
     throw new MessageNotUnderstood(msg);
 }
示例#12
0
        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);
        }