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"); }
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 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; }
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"); }
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); } } } }
public static bool NotEqual(STObject self, STObject other) { return !self.Native.Equals(other.Native); }
public static bool Identity(STObject self, STObject other) { return self.Native == other.Native; }
public STObject EvaluateUnarySend(STObject receiver, Node unarySend, Context context) { receiver = receiver.Dereference(); return receiver.Send(STSymbol.Get((unarySend.GetChildAt(0) as Token).Image)); }
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; }
public static string ToString(STObject @bool) { return ((bool)@bool.Native).ToString().ToLower(); }
public static double Mul(double self, STObject other) { return self * Coerce(other); }
public static bool LtEq(double self, STObject other) { return self <= Coerce(other); }
public static bool Gt(double self, STObject other) { return self > Coerce(other); }
public static double Div(double self, STObject other) { return self / Coerce(other); }
public static double Add(double self, STObject other) { return self + Coerce(other); }
public ReturnException(STObject value, Context context) : base("The value " + value + " is being returned") { Value = value; }
public static bool NotIdentical(STObject self, STObject other) { return self.Native != other.Native; }
public static double Sub(double self, STObject other) { return self - Coerce(other); }
public static string ToString(STObject self) { return self.ToString(); }
public void VisitStatement(Node statement) { Result = Compiler.EvaluateStatement(statement, Context); }
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; }
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); }
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; }
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; }
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]); }
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'"); }
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 static bool Equality(STObject self, STObject other) { return self.Native.Equals(other.Native); }
public STClass SubclassNamespaceWith(STSymbol name, STObject nsObj, STBlock blockObj) { var @class = SubclassNamespace(name, nsObj); @class.With(blockObj as STBlock); return @class; }
public static STClassDescription GetClass(STObject self) { return self.Class; }