The base class of all Irontalk objects. Objects which do not have STObject as a base class are wrapped using the T:Irontalk.STInstance class.
コード例 #1
0
ファイル: STCharDelegate.cs プロジェクト: rezonant/irontalk
        public static long Sub(char self, STObject other)
        {
            if (other.Native is char)
                return self - (char)other.Native;
            else if (typeof(long).IsAssignableFrom(other.Native.GetType()))
                return self - (long)other.Native;

            throw new InvalidOperationException("Operand to #- must be coercible to Char");
        }
コード例 #2
0
ファイル: STObjectDelegate.cs プロジェクト: rezonant/irontalk
 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
ファイル: LocalContext.cs プロジェクト: rezonant/irontalk
        public override bool SetVariable(string name, STObject value)
        {
            if (ExplicitVariables) {
                if (!variables.ContainsKey(name)) {
                    if (ParentContext.SetVariable(name, value)) return true;
                    throw new Exception("No such variable " + name);
                }
            }

            variables[name] = value;
            return true;
        }
コード例 #4
0
ファイル: STDoubleDelegate.cs プロジェクト: rezonant/irontalk
        public static double Coerce(STObject sto)
        {
            var o = sto.Native;

            if (typeof(double).IsAssignableFrom(o.GetType()))
                return (double)o;

            if (typeof(long).IsAssignableFrom(o.GetType()))
                return (double)(long)o;

            throw new InvalidOperationException("Input must be coercible to Float");
        }
コード例 #5
0
ファイル: Smalltalk.cs プロジェクト: rezonant/irontalk
        public void Import(STObject nsObj)
        {
            var ns = nsObj as STNamespace;

            if (ns == null)
                throw new Exception ("Argument must be a Namespace");

            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) {
                foreach (var type in assembly.GetTypes()) {
                    if (type.Namespace == ns.FullName) {
                        var @class = STClass.GetForCLR(type, type.Name);
                        GlobalContext.Instance.AtPut(@class.Name, @class);
                    }
                }
            }
        }
コード例 #6
0
ファイル: STObjectDelegate.cs プロジェクト: rezonant/irontalk
 public static bool NotEqual(STObject self, STObject other)
 {
     return !self.Native.Equals(other.Native);
 }
コード例 #7
0
ファイル: STObjectDelegate.cs プロジェクト: rezonant/irontalk
 public static bool Identity(STObject self, STObject other)
 {
     return self.Native == other.Native;
 }
コード例 #8
0
ファイル: Compiler.cs プロジェクト: rezonant/irontalk
 public STObject EvaluateUnarySend(STObject receiver, Node unarySend, Context context)
 {
     receiver = receiver.Dereference();
     return receiver.Send(STSymbol.Get((unarySend.GetChildAt(0) as Token).Image));
 }
コード例 #9
0
ファイル: STBlock.cs プロジェクト: rezonant/irontalk
        public STObject Evaluate(STObject value, STObject value2)
        {
            if (BlockArgumentNames.Length != 2)
                throw new Exception("Incorrect number of arguments for block (expected " + BlockArgumentNames.Length + ")");

            Context.SetVariable(BlockArgumentNames[0], value);
            Context.SetVariable(BlockArgumentNames[1], value2);

            if (Compiled != null)
                throw new NotImplementedException();

            var eval = new BlockEvaluator (this, Compiler, this.Context);
            Visit (eval);
            return eval.Result;
        }
コード例 #10
0
 public static string ToString(STObject @bool)
 {
     return ((bool)@bool.Native).ToString().ToLower();
 }
コード例 #11
0
ファイル: STDoubleDelegate.cs プロジェクト: rezonant/irontalk
 public static double Mul(double self, STObject other)
 {
     return self * Coerce(other);
 }
コード例 #12
0
ファイル: STDoubleDelegate.cs プロジェクト: rezonant/irontalk
 public static bool LtEq(double self, STObject other)
 {
     return self <= Coerce(other);
 }
コード例 #13
0
ファイル: STDoubleDelegate.cs プロジェクト: rezonant/irontalk
 public static bool Gt(double self, STObject other)
 {
     return self > Coerce(other);
 }
コード例 #14
0
ファイル: STDoubleDelegate.cs プロジェクト: rezonant/irontalk
 public static double Div(double self, STObject other)
 {
     return self / Coerce(other);
 }
コード例 #15
0
ファイル: STDoubleDelegate.cs プロジェクト: rezonant/irontalk
 public static double Add(double self, STObject other)
 {
     return self + Coerce(other);
 }
コード例 #16
0
ファイル: Compiler.cs プロジェクト: rezonant/irontalk
 public ReturnException(STObject value, Context context)
     : base("The value " + value + " is being returned")
 {
     Value = value;
 }
コード例 #17
0
ファイル: STObjectDelegate.cs プロジェクト: rezonant/irontalk
 public static bool NotIdentical(STObject self, STObject other)
 {
     return self.Native != other.Native;
 }
コード例 #18
0
ファイル: STDoubleDelegate.cs プロジェクト: rezonant/irontalk
 public static double Sub(double self, STObject other)
 {
     return self - Coerce(other);
 }
コード例 #19
0
ファイル: STObjectDelegate.cs プロジェクト: rezonant/irontalk
 public static string ToString(STObject self)
 {
     return self.ToString();
 }
コード例 #20
0
ファイル: BlockEvaluator.cs プロジェクト: rezonant/irontalk
 public void VisitStatement(Node statement)
 {
     Result = Compiler.EvaluateStatement(statement, Context);
 }
コード例 #21
0
        public static STObject IfTrue(STObject self, STObject aBlockObj)
        {
            var aBlock = aBlockObj as STBlock;
            if (aBlock == null)
                throw new Exception ("Argument to ifTrue: must be a block");
            if (aBlock.BlockArgumentNames.Length > 0)
                throw new Exception("Argument to ifTrue: has too many arguments");
            if (self.Class != STClass.GetForCLR(typeof(bool), "Boolean"))
                throw new Exception("ifTrue: Non-boolean receiver");

            if ((bool)self.Native)
                return aBlock.Evaluate();

            return self;
        }
コード例 #22
0
ファイル: STClass.cs プロジェクト: rezonant/irontalk
        public STCompiledMethod DefineWith(STObject symObj, STObject blockObj)
        {
            var sym = symObj as STSymbol;
            var block = blockObj as STBlock;

            if (sym == null)
                throw new Exception("First parameter must be the symbol for the message to define");

            if (block == null)
                throw new Exception("Second parameter must be a block");

            return CompleteMethod(Define(symObj), block);
        }
コード例 #23
0
 public static STObject IfFalse(STObject self, STObject aBlockObj)
 {
     var aBlock = aBlockObj as STBlock;
     if (aBlock == null)
         throw new Exception ("Argument to ifTrue: must be a block");
     if (aBlock.BlockArgumentNames.Length > 0)
         throw new Exception("Argument to ifTrue: has too many arguments");
     if ((bool)self.Native)
         return aBlock.Evaluate();
     return self;
 }
コード例 #24
0
ファイル: STClass.cs プロジェクト: rezonant/irontalk
        public STClass SubclassNamespace(STSymbol name, STObject nsObj)
        {
            var ns = nsObj as STNamespace;

            if (ns == null)
                throw new Exception ("namespace parameter must hold a valid Namespace object, not " + nsObj.GetType().FullName);

            var @class = Subclass(name);
            ns.Install(name, @class);

            return @class;
        }
コード例 #25
0
ファイル: STClass.cs プロジェクト: rezonant/irontalk
        public STMethodPrototype Define(STObject symObj)
        {
            var sym = symObj as STSymbol;

            if (sym == null)
                throw new Exception("Argument must be the symbol for the message to define");

            return new STMethodPrototype(this, sym, new STSymbol[0]);
        }
コード例 #26
0
ファイル: Compiler.cs プロジェクト: rezonant/irontalk
 public STObject EvaluateSimpleSend(STObject receiver, Node simpleSend, Context context)
 {
     var child = simpleSend.GetChildAt(0);
     if (child.Name == "unary_send")
         return EvaluateUnarySend(receiver, child, context);
     else if (child.Name == "binary_send")
         return EvaluateBinarySend(receiver, child, context);
     else
         throw new NotImplementedException("Unhandled grammar production within 'simple_send'");
 }
コード例 #27
0
ファイル: STClass.cs プロジェクト: rezonant/irontalk
        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
        }
コード例 #28
0
ファイル: STObjectDelegate.cs プロジェクト: rezonant/irontalk
 public static bool Equality(STObject self, STObject other)
 {
     return self.Native.Equals(other.Native);
 }
コード例 #29
0
ファイル: STClass.cs プロジェクト: rezonant/irontalk
 public STClass SubclassNamespaceWith(STSymbol name, STObject nsObj, STBlock blockObj)
 {
     var @class = SubclassNamespace(name, nsObj);
     @class.With(blockObj as STBlock);
     return @class;
 }
コード例 #30
0
ファイル: STObjectDelegate.cs プロジェクト: rezonant/irontalk
 public static STClassDescription GetClass(STObject self)
 {
     return self.Class;
 }