Exemple #1
0
 private static bool IsApplicable(object pass, IokeObject message, IokeObject ctx)
 {
     if (pass != null && pass != ctx.runtime.nul && IokeObject.FindCell(IokeObject.As(pass, ctx), "applicable?") != ctx.runtime.nul)
     {
         return(IokeObject.IsObjectTrue(Send(ctx.runtime.isApplicableMessage, ctx, pass, ctx.runtime.CreateMessage(Message.Wrap(message)))));
     }
     return(true);
 }
Exemple #2
0
        public int HashCode(IokeObject self)
        {
            object cell = IokeObject.FindCell(self, "hash");

            if (cell == self.runtime.nul)
            {
                return(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(self.body));
            }
            else
            {
                return(Number.ExtractInt(Interpreter.Send(self.runtime.hashMessage, self.runtime.Ground, self), self.runtime.hashMessage, self.runtime.Ground));
            }
        }
Exemple #3
0
 public virtual object Activate(IokeObject self, IokeObject context, IokeObject message, object on)
 {
     object cell = self.FindCell(message, context, "activate");
     if(cell == context.runtime.nul) {
                        report(self, context, message, "activate");
         return context.runtime.nil;
     } else {
         IokeObject newMessage = Message.DeepCopy(message);
         newMessage.Arguments.Clear();
         newMessage.Arguments.Add(context.runtime.CreateMessage(Message.Wrap(context)));
         newMessage.Arguments.Add(context.runtime.CreateMessage(Message.Wrap(message)));
         newMessage.Arguments.Add(context.runtime.CreateMessage(Message.Wrap(IokeObject.As(on, context))));
         return IokeObject.GetOrActivate(cell, context, newMessage, self);
     }
 }
Exemple #4
0
        public virtual bool IsEqualTo(IokeObject self, object other)
        {
            object cell = IokeObject.FindCell(self, "==");

            if (cell == self.runtime.nul)
            {
                bool result = (other is IokeObject) && (object.ReferenceEquals(self.body, IokeObject.As(other, self).body));
                return(result);
            }
            else
            {
                bool result = IokeObject.IsObjectTrue(Interpreter.Send(self.runtime.eqMessage, self.runtime.Ground, self, self.runtime.CreateMessage(Message.Wrap(IokeObject.As(other, self)))));
                return(result);
            }
        }
Exemple #5
0
        private static object FindCell(IokeObject message, IokeObject ctx, object obj, string name, IokeObject recv)
        {
            Runtime runtime = ctx.runtime;
            object  cell    = IokeObject.FindCell(recv, name);
            object  passed  = null;

            while (cell == runtime.nul)
            {
                if (((cell = passed = IokeObject.FindCell(recv, "pass")) != runtime.nul) && IsApplicable(passed, message, ctx))
                {
                    return(cell);
                }
                cell = SignalNoSuchCell(message, ctx, obj, name, cell, recv);
            }
            return(cell);
        }
Exemple #6
0
        public static object ActivateFixed(IokeObject self, IokeObject context, IokeObject message, object on)
        {
            object cell = IokeObject.FindCell(self, "activate");

            if (cell == context.runtime.nul)
            {
                report(self, context, message, "activate");
                return(context.runtime.nil);
            }
            else
            {
                IokeObject newMessage = Message.DeepCopy(message);
                newMessage.Arguments.Clear();
                newMessage.Arguments.Add(context.runtime.CreateMessage(Message.Wrap(context)));
                newMessage.Arguments.Add(context.runtime.CreateMessage(Message.Wrap(message)));
                newMessage.Arguments.Add(context.runtime.CreateMessage(Message.Wrap(IokeObject.As(on, context))));
                return(Interpreter.GetOrActivate(cell, context, newMessage, self));
            }
        }
Exemple #7
0
        public virtual string ToString(IokeObject self)
        {
            object obj = self.FindCell(null, null, "kind");
            int h = HashCode(self);
            string hash = System.Convert.ToString(h, 16).ToUpper();
            if(obj is NullObject) {
                return "#<nul:" + hash + ">";
            }

            string kind = ((Text)IokeObject.dataOf(obj)).GetText();
            return "#<" + kind + ":" + hash + ">";
        }
Exemple #8
0
 public IDictionary GetOpTable(IokeObject opTable, string name, OpTableCreator creator)
 {
     IokeObject operators = IokeObject.As(opTable.FindCell(_message, _context, name), null);
     if(operators != runtime.nul && (IokeObject.dataOf(operators) is Dict)) {
         return Dict.GetMap(operators);
     } else {
         var result = creator.Create(runtime);
         opTable.SetCell(name, runtime.NewDict(result));
         return result;
     }
 }
Exemple #9
0
        public static void Init(IokeObject obj)
        {
            obj.Kind = "Base";

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects two or more arguments, the first arguments unevaluated, the last evaluated. assigns the result of evaluating the last argument in the context of the caller, and assigns this result to the name/s provided by the first arguments. the first arguments remains unevaluated. the result of the assignment is the value assigned to the name. if the last argument is a method-like object and it's name is not set, that name will be set to the name of the cell.",
                                                           new NativeMethod("=", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositionalUnevaluated("place")
                                                                            .WithRestUnevaluated("morePlacesForDestructuring")
                                                                            .WithRequiredPositional("value")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);

                var args = message.Arguments;
                if (args.Count == 2)
                {
                    IokeObject m1 = IokeObject.As(Message.GetArguments(message)[0], context);
                    string name   = m1.Name;
                    if (m1.Arguments.Count == 0)
                    {
                        object value = Interpreter.GetEvaluatedArgument(message, 1, context);
                        IokeObject.Assign(on, name, value, context, message);

                        if (value is IokeObject)
                        {
                            if ((IokeObject.dataOf(value) is Named) && ((Named)IokeObject.dataOf(value)).Name == null)
                            {
                                ((Named)IokeObject.dataOf(value)).Name = name;
                            }
                            else if (name.Length > 0 && char.IsUpper(name[0]) && !(IokeObject.As(value, context).HasKind))
                            {
                                if (on == context.runtime.Ground || on == context.runtime.IokeGround)
                                {
                                    IokeObject.As(value, context).Kind = name;
                                }
                                else
                                {
                                    IokeObject.As(value, context).Kind = IokeObject.As(on, context).GetKind(message, context) + " " + name;
                                }
                            }
                        }

                        return(value);
                    }
                    else
                    {
                        string newName  = name + "=";
                        IList arguments = new SaneArrayList(m1.Arguments);
                        arguments.Add(Message.GetArguments(message)[1]);
                        IokeObject msg = context.runtime.NewMessageFrom(message, newName, arguments);
                        return(Interpreter.Send(msg, context, on));
                    }
                }
                else
                {
                    int lastIndex = args.Count - 1;
                    int numPlaces = lastIndex;

                    return(RecursiveDestructuring(args, numPlaces, message, context, on, Interpreter.GetEvaluatedArgument(args[lastIndex], context)));
                }
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("will return a new derivation of the receiving object. Might throw exceptions if the object is an oddball object.",
                                                           new NativeMethod.WithNoArguments("mimic", (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                return(IokeObject.As(on, context).Mimic(message, context));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument that names the cell to set, sets this cell to the result of evaluating the second argument, and returns the value set.",
                                                           new NativeMethod("cell=",
                                                                            DefaultArgumentsDefinition
                                                                            .builder()
                                                                            .WithRequiredPositional("cellName")
                                                                            .WithRequiredPositional("value")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                return(AssignCell(context, message, on, args[0], args[1]));
            })));
            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and returns the cell that matches that name, without activating even if it's activatable.",
                                                           new NativeMethod("cell", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                string name = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[0]));
                return(IokeObject.GetCell(on, message, context, name));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns a hash for the object",
                                                           new NativeMethod.WithNoArguments("hash", (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                return(context.runtime.NewNumber(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(IokeObject.As(on, context).body)));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns true if the left hand side is equal to the right hand side. exactly what this means depend on the object. the default behavior of Ioke objects is to only be equal if they are the same instance.",
                                                           new NativeMethod("==", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("other")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                IList args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                return((IokeObject.As(on, context).body == IokeObject.As(args[0], context).body) ? context.runtime.True : context.runtime.False);
            })));
            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and returns a boolean indicating whether such a cell is reachable from this point.",
                                                           new NativeMethod("cell?", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                IList args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());

                string name = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[0]));
                return(IokeObject.FindCell((IokeObject)on, name) != context.runtime.nul ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the documentation text of the object called on. anything can have a documentation text - this text will initially be nil.",
                                                           new NativeMethod.WithNoArguments("documentation",
                                                                                            (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                return(Documentation(context, message, on));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns a boolean indicating of this object should be activated or not.",
                                                           new NativeMethod.WithNoArguments("activatable",
                                                                                            (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                return(IokeObject.As(on, context).IsActivatable ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("sets the activatable flag for a specific object. this will not impact objects that mimic this object..",
                                                           new TypeCheckingNativeMethod("activatable=", TypeCheckingArgumentsDefinition.builder()
                                                                                        .WithRequiredPositional("activatableFlag")
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                IokeObject.As(on, context).SetActivatable(IokeObject.IsObjectTrue(args[0]));
                return(args[0]);
            }
                                                                                        )));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns this object",
                                                           new NativeMethod.WithNoArguments("identity",
                                                                                            (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                return(on);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("sets the documentation string for a specific object.",
                                                           new TypeCheckingNativeMethod("documentation=", TypeCheckingArgumentsDefinition.builder()
                                                                                        .WithRequiredPositional("text").WhichMustMimic(obj.runtime.Text).OrBeNil()
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                return(SetDocumentation(context, message, on, args[0]));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and returns a boolean indicating whether this cell is owned by the receiver or not. the assumption is that the cell should exist. if it doesn't exist, a NoSuchCell condition will be signalled.",
                                                           new NativeMethod("cellOwner?", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                string name = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[0]));
                return((IokeObject.FindPlace(on, message, context, name) == on) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and returns the closest object that defines such a cell. if it doesn't exist, a NoSuchCell condition will be signalled.",
                                                           new NativeMethod("cellOwner", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                string name   = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[0]));
                object result = IokeObject.FindPlace(on, message, context, name);
                if (result == context.runtime.nul)
                {
                    return(context.runtime.nil);
                }
                return(result);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and removes that cell from the current receiver. if the current receiver has no such object, signals a condition. note that if another cell with that name is available in the mimic chain, it will still be accessible after calling this method. the method returns the receiver.",
                                                           new NativeMethod("removeCell!", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                string name = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[0]));
                IokeObject.RemoveCell(on, message, context, name);
                return(on);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and makes that cell undefined in the current receiver. what that means is that from now on it will look like this cell doesn't exist in the receiver or any of its mimics. the cell will not show up if you call cellNames on the receiver or any of the receivers mimics. the undefined status can be removed by doing removeCell! on the correct cell name. a cell name that doesn't exist can still be undefined. the method returns the receiver.",
                                                           new NativeMethod("undefineCell!", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                string name = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[0]));
                IokeObject.UndefineCell(on, message, context, name);
                return(on);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("takes one optional evaluated boolean argument, which defaults to false. if false, this method returns a list of the cell names of the receiver. if true, it returns the cell names of this object and all it's mimics recursively.",
                                                           new NativeMethod("cellNames", DefaultArgumentsDefinition.builder()
                                                                            .WithOptionalPositional("includeMimics", "false")
                                                                            .WithOptionalPositional("cutoff", "nil")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                return(CellNames(context, message, on, args.Count > 0 && IokeObject.IsObjectTrue(args[0]), (args.Count > 1) ? args[1] : null));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("takes one optional evaluated boolean argument, which defaults to false. if false, this method returns a dict of the cell names and values of the receiver. if true, it returns the cell names and values of this object and all it's mimics recursively.",
                                                           new NativeMethod("cells", DefaultArgumentsDefinition.builder()
                                                                            .WithOptionalPositional("includeMimics", "false")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                return(Cells(context, message, on, args.Count > 0 && IokeObject.IsObjectTrue(args[0])));
            })));
        }
Exemple #10
0
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "Dict";
            obj.Mimics(IokeObject.As(IokeObject.FindCell(runtime.Mixins, "Sequenced"), null), runtime.nul, runtime.nul);

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns a hash for the dictionary",
                                                           new NativeMethod.WithNoArguments("hash", (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                return(context.runtime.NewNumber(((Dict)IokeObject.dataOf(on)).dict.GetHashCode()));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the left hand side dictionary is equal to the right hand side dictionary.",
                                                       new TypeCheckingNativeMethod("==", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Dict)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                Dict d       = (Dict)IokeObject.dataOf(on);
                object other = args[0];
                return(((other is IokeObject) &&
                        (IokeObject.dataOf(other) is Dict) &&
                        d.dict.Equals(((Dict)IokeObject.dataOf(other)).dict)) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes one argument, that should be a default value, and returns a new mimic of the receiver, with the default value for that new dict set to the argument",
                                                       new TypeCheckingNativeMethod("withDefault", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("defaultValue")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object newDict = IokeObject.Mimic(on, message, context);
                SetDefaultValue(newDict, IokeObject.As(args[0], context));
                return(newDict);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("creates a new Dict from the arguments provided, combined with the values in the receiver. the arguments provided will override those in the receiver. the rules for arguments are the same as for dict, except that dicts can also be provided. all positional arguments will be added before the keyword arguments.",
                                                       new TypeCheckingNativeMethod("merge", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRest("pairsAndDicts")
                                                                                    .WithKeywordRest("keywordPairs")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                var newMap = new SaneHashtable();
                foreach (DictionaryEntry de in GetMap(on))
                {
                    newMap[de.Key] = de.Value;
                }

                foreach (object o in args)
                {
                    if (IokeObject.dataOf(o) is Dict)
                    {
                        foreach (DictionaryEntry de in GetMap(o))
                        {
                            newMap[de.Key] = de.Value;
                        }
                    }
                    else if (IokeObject.dataOf(o) is Pair)
                    {
                        newMap[Pair.GetFirst(o)] = Pair.GetSecond(o);
                    }
                    else
                    {
                        newMap[o] = context.runtime.nil;
                    }
                }
                foreach (var entry in keywords)
                {
                    string s     = entry.Key;
                    object key   = context.runtime.GetSymbol(s.Substring(0, s.Length - 1));
                    object value = entry.Value;
                    if (value == null)
                    {
                        value = context.runtime.nil;
                    }
                    newMap[key] = value;
                }

                return(context.runtime.NewDict(newMap));
            })));

            obj.AliasMethod("merge", "+", null, null);

            obj.RegisterMethod(runtime.NewNativeMethod("takes one argument, the key of the element to return. if the key doesn't map to anything in the dict, returns the default value",
                                                       new TypeCheckingNativeMethod("at", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("key")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object result = Dict.GetMap(on)[args[0]];
                if (result == null)
                {
                    return(GetDefaultValue(on, context, message));
                }
                else
                {
                    return(result);
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if this dict is empty, false otherwise",
                                                       new TypeCheckingNativeMethod.WithNoArguments("empty?", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(Dict.GetMap(on).Count == 0 ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes one argument, the key to check if it is in the dict.",
                                                       new TypeCheckingNativeMethod("key?", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("key")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                return((Dict.GetMap(on).Contains(args[0])) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes two arguments, the key of the element to set and the value to set it too. returns the value set",
                                                       new TypeCheckingNativeMethod("[]=", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("key")
                                                                                    .WithRequiredPositional("value")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                Dict.GetMap(on)[args[0]] = args[1];
                return(args[1]);
            })));


            obj.RegisterMethod(runtime.NewNativeMethod("Returns the number of pairs contained in this dict.",
                                                       new TypeCheckingNativeMethod.WithNoArguments("size", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(runtime.NewNumber(Dict.GetMap(on).Count));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a text inspection of the object",
                                                       new TypeCheckingNativeMethod.WithNoArguments("inspect", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(method.runtime.NewText(Dict.GetInspect(on)));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a brief text inspection of the object",
                                                       new TypeCheckingNativeMethod.WithNoArguments("notice", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(method.runtime.NewText(Dict.GetNotice(on)));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns all the keys of this dict",
                                                       new TypeCheckingNativeMethod.WithNoArguments("keys", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(method.runtime.NewSet(Dict.GetKeys(on)));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a new sequence to iterate over this dictionary",
                                                       new TypeCheckingNativeMethod.WithNoArguments("seq", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                IokeObject ob = method.runtime.KeyValueIteratorSequence.AllocateCopy(null, null);
                ob.MimicsWithoutCheck(method.runtime.KeyValueIteratorSequence);
                ob.Data = new Sequence.KeyValueIteratorSequence(Dict.GetMap(on).GetEnumerator());
                return(ob);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes either one or two or three arguments. if one argument is given, it should be a message chain that will be sent to each object in the dict. the result will be thrown away. if two arguments are given, the first is an unevaluated name that will be set to each of the entries in the dict in succession, and then the second argument will be evaluated in a scope with that argument in it. if three arguments is given, the first one is an unevaluated name that will be set to the index of each element, and the other two arguments are the name of the argument for the value, and the actual code. the code will evaluate in a lexical context, and if the argument name is available outside the context, it will be shadowed. the method will return the dict. the entries yielded will be mimics of Pair.",
                                                       new NativeMethod("each", DefaultArgumentsDefinition.builder()
                                                                        .WithOptionalPositionalUnevaluated("indexOrArgOrCode")
                                                                        .WithOptionalPositionalUnevaluated("argOrCode")
                                                                        .WithOptionalPositionalUnevaluated("code")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                on = runtime.Dict.ConvertToThis(on, message, context);

                var ls = Dict.GetMap(on);
                switch (message.Arguments.Count)
                {
                case 0: {
                    return(Interpreter.Send(runtime.seqMessage, context, on));
                }

                case 1: {
                    IokeObject code = IokeObject.As(message.Arguments[0], context);

                    foreach (DictionaryEntry o in ls)
                    {
                        context.runtime.interpreter.Evaluate(code, context, context.RealContext, runtime.NewPair(o.Key, o.Value));
                    }
                    break;
                }

                case 2: {
                    IokeObject c    = context.runtime.NewLexicalContext(context, "Lexical activation context for Dict#each", context);
                    string name     = IokeObject.As(message.Arguments[0], context).Name;
                    IokeObject code = IokeObject.As(message.Arguments[1], context);

                    foreach (DictionaryEntry o in ls)
                    {
                        c.SetCell(name, runtime.NewPair(o.Key, o.Value));
                        context.runtime.interpreter.Evaluate(code, c, c.RealContext, c);
                    }
                    break;
                }

                case 3: {
                    IokeObject c    = context.runtime.NewLexicalContext(context, "Lexical activation context for Dict#each", context);
                    string iname    = IokeObject.As(message.Arguments[0], context).Name;
                    string name     = IokeObject.As(message.Arguments[1], context).Name;
                    IokeObject code = IokeObject.As(message.Arguments[2], context);

                    int index = 0;
                    foreach (DictionaryEntry o in ls)
                    {
                        c.SetCell(name, runtime.NewPair(o.Key, o.Value));
                        c.SetCell(iname, runtime.NewNumber(index++));
                        context.runtime.interpreter.Evaluate(code, c, c.RealContext, c);
                    }
                    break;
                }
                }
                return(on);
            })));
        }
Exemple #11
0
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "Pair";
            obj.Mimics(IokeObject.As(IokeObject.FindCell(runtime.Mixins, "Enumerable"), null), runtime.nul, runtime.nul);
            obj.Mimics(IokeObject.As(IokeObject.FindCell(runtime.Mixins, "Comparing"), null), runtime.nul, runtime.nul);

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns a hash for the pair",
                                                           new NativeMethod.WithNoArguments("hash", (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                var one = ((Pair)IokeObject.dataOf(on)).first.GetHashCode();
                var two = ((Pair)IokeObject.dataOf(on)).second.GetHashCode();
                return(context.runtime.NewNumber(one + 13 * two));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the left hand side pair is equal to the right hand side pair.",
                                                       new TypeCheckingNativeMethod("==", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Pair)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                Pair d       = (Pair)IokeObject.dataOf(on);
                object other = args[0];

                return(((other is IokeObject) &&
                        (IokeObject.dataOf(other) is Pair) &&
                        d.first.Equals(((Pair)IokeObject.dataOf(other)).first) &&
                        d.second.Equals(((Pair)IokeObject.dataOf(other)).second)) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns the first value",
                                                       new TypeCheckingNativeMethod.WithNoArguments("first", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(((Pair)IokeObject.dataOf(on)).first);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns the first value",
                                                       new TypeCheckingNativeMethod.WithNoArguments("key", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(((Pair)IokeObject.dataOf(on)).first);
            })));


            obj.RegisterMethod(runtime.NewNativeMethod("Returns the second value",
                                                       new TypeCheckingNativeMethod.WithNoArguments("second", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(((Pair)IokeObject.dataOf(on)).second);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns the second value",
                                                       new TypeCheckingNativeMethod.WithNoArguments("value", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(((Pair)IokeObject.dataOf(on)).second);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a text inspection of the object",
                                                       new TypeCheckingNativeMethod.WithNoArguments("inspect", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(method.runtime.NewText(Pair.GetInspect(on)));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a brief text inspection of the object",
                                                       new TypeCheckingNativeMethod.WithNoArguments("notice", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(method.runtime.NewText(Pair.GetNotice(on)));
            })));
        }
Exemple #12
0
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "Range";
            obj.Mimics(IokeObject.As(IokeObject.FindCell(runtime.Mixins, "Sequenced"), null), runtime.nul, runtime.nul);

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the left hand side range is equal to the right hand side range.",
                                                       new TypeCheckingNativeMethod("==", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Range)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                Range d      = (Range)IokeObject.dataOf(on);
                object other = args[0];

                return(((other is IokeObject) &&
                        (IokeObject.dataOf(other) is Range) &&
                        d.inclusive == ((Range)IokeObject.dataOf(other)).inclusive &&
                        d.from.Equals(((Range)IokeObject.dataOf(other)).from) &&
                        d.to.Equals(((Range)IokeObject.dataOf(other)).to)) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("will return a new inclusive Range based on the two arguments",
                                                       new NativeMethod("inclusive", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("from")
                                                                        .WithRequiredPositional("to")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());

                object from = args[0];
                object to   = args[1];

                bool comparing = IokeObject.IsMimic(from, IokeObject.As(context.runtime.Mixins.body.Get("Comparing"), context), context);
                bool inverted  = false;

                if (comparing)
                {
                    object result = Interpreter.Send(context.runtime.spaceShipMessage, context, from, to);
                    if (result != context.runtime.nil && Number.ExtractInt(result, message, context) == 1)
                    {
                        inverted = true;
                    }
                }

                return(runtime.NewRange(IokeObject.As(from, context), IokeObject.As(to, context), true, inverted));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("will return a new exclusive Range based on the two arguments",
                                                       new NativeMethod("exclusive", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("from")
                                                                        .WithRequiredPositional("to")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());

                object from = args[0];
                object to   = args[1];

                bool comparing = IokeObject.IsMimic(from, IokeObject.As(context.runtime.Mixins.body.Get("Comparing"), context), context);
                bool inverted  = false;

                if (comparing)
                {
                    object result = Interpreter.Send(context.runtime.spaceShipMessage, context, from, to);
                    if (result != context.runtime.nil && Number.ExtractInt(result, message, context) == 1)
                    {
                        inverted = true;
                    }
                }

                return(runtime.NewRange(IokeObject.As(from, context), IokeObject.As(to, context), false, inverted));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the receiver is an exclusive range, false otherwise",
                                                       new NativeMethod.WithNoArguments("exclusive?",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                return(((Range)IokeObject.dataOf(on)).inclusive ? context.runtime.False : context.runtime.True);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the receiver is an inclusive range, false otherwise",
                                                       new NativeMethod.WithNoArguments("inclusive?",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                return(((Range)IokeObject.dataOf(on)).inclusive ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the 'from' part of the range",
                                                       new TypeCheckingNativeMethod.WithNoArguments("from", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(((Range)IokeObject.dataOf(on)).from);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the 'to' part of the range",
                                                       new NativeMethod.WithNoArguments("to",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                return(((Range)IokeObject.dataOf(on)).to);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a new sequence to iterate over this range",
                                                       new TypeCheckingNativeMethod.WithNoArguments("seq", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                IokeObject ob = method.runtime.Iterator2Sequence.AllocateCopy(null, null);
                ob.MimicsWithoutCheck(method.runtime.Iterator2Sequence);
                Range r = ((Range)IokeObject.dataOf(on));
                ob.Data = new Sequence.Iterator2Sequence(new RangeIterator(r.from, r.to, r.inclusive, r.inverted, context, message));
                return(ob);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes either one or two or three arguments. if one argument is given, it should be a message chain that will be sent to each object in the range. the result will be thrown away. if two arguments are given, the first is an unevaluated name that will be set to each of the values in the range in succession, and then the second argument will be evaluated in a scope with that argument in it. if three arguments is given, the first one is an unevaluated name that will be set to the index of each element, and the other two arguments are the name of the argument for the value, and the actual code. the code will evaluate in a lexical context, and if the argument name is available outside the context, it will be shadowed. the method will return the range.",
                                                       new NativeMethod("each", DefaultArgumentsDefinition.builder()
                                                                        .WithOptionalPositionalUnevaluated("indexOrArgOrCode")
                                                                        .WithOptionalPositionalUnevaluated("argOrCode")
                                                                        .WithOptionalPositionalUnevaluated("code")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                IokeObject from = IokeObject.As(((Range)IokeObject.dataOf(on)).from, context);
                IokeObject to   = IokeObject.As(((Range)IokeObject.dataOf(on)).to, context);
                bool inclusive  = ((Range)IokeObject.dataOf(on)).inclusive;

                IokeObject messageToSend = context.runtime.succMessage;
                if (((Range)IokeObject.dataOf(on)).inverted)
                {
                    messageToSend = context.runtime.predMessage;
                }

                switch (message.Arguments.Count)
                {
                case 0: {
                    return(Interpreter.Send(runtime.seqMessage, context, on));
                }

                case 1: {
                    IokeObject code = IokeObject.As(message.Arguments[0], context);

                    object current = from;

                    while (!IokeObject.IsObjectTrue(Interpreter.Send(context.runtime.eqMessage, context, current, to)))
                    {
                        context.runtime.interpreter.Evaluate(code, context, context.RealContext, current);
                        current = Interpreter.Send(messageToSend, context, current);
                    }
                    if (inclusive)
                    {
                        context.runtime.interpreter.Evaluate(code, context, context.RealContext, current);
                    }

                    break;
                }

                case 2: {
                    IokeObject c    = context.runtime.NewLexicalContext(context, "Lexical activation context for Range#each", context);
                    string name     = IokeObject.As(message.Arguments[0], context).Name;
                    IokeObject code = IokeObject.As(message.Arguments[1], context);

                    object current = from;

                    while (!IokeObject.IsObjectTrue(Interpreter.Send(context.runtime.eqMessage, context, current, to)))
                    {
                        c.SetCell(name, current);
                        context.runtime.interpreter.Evaluate(code, c, c.RealContext, c);
                        current = Interpreter.Send(messageToSend, context, current);
                    }
                    if (inclusive)
                    {
                        c.SetCell(name, current);
                        context.runtime.interpreter.Evaluate(code, c, c.RealContext, c);
                    }

                    break;
                }

                case 3: {
                    IokeObject c    = context.runtime.NewLexicalContext(context, "Lexical activation context for Range#each", context);
                    string iname    = IokeObject.As(message.Arguments[0], context).Name;
                    string name     = IokeObject.As(message.Arguments[1], context).Name;
                    IokeObject code = IokeObject.As(message.Arguments[2], context);

                    int index = 0;

                    object current = from;

                    while (!IokeObject.IsObjectTrue(Interpreter.Send(context.runtime.eqMessage, context, current, to)))
                    {
                        c.SetCell(name, current);
                        c.SetCell(iname, runtime.NewNumber(index++));
                        context.runtime.interpreter.Evaluate(code, c, c.RealContext, c);
                        current = Interpreter.Send(messageToSend, context, current);
                    }
                    if (inclusive)
                    {
                        c.SetCell(name, current);
                        c.SetCell(iname, runtime.NewNumber(index++));
                        context.runtime.interpreter.Evaluate(code, c, c.RealContext, c);
                    }

                    break;
                }
                }
                return(on);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the argument is within the confines of this range. how this comparison is done depends on if the object mimics Comparing. If it does, < and > will be used. If not, all the available entries in this range will be enumerated using 'succ'/'pred' until either the end or the element we're looking for is found. in that case, comparison is done with '=='",
                                                       new NativeMethod("===", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("other")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                object other = args[0];

                IokeObject from = IokeObject.As(((Range)IokeObject.dataOf(on)).from, context);
                IokeObject to   = IokeObject.As(((Range)IokeObject.dataOf(on)).to, context);
                bool comparing  = IokeObject.IsMimic(from, IokeObject.As(context.runtime.Mixins.body.Get("Comparing"), context));
                bool inclusive  = ((Range)IokeObject.dataOf(on)).inclusive;

                if (comparing)
                {
                    IokeObject firstMessage           = context.runtime.lteMessage;
                    IokeObject secondMessageInclusive = context.runtime.gteMessage;
                    IokeObject secondMessageExclusive = context.runtime.gtMessage;

                    if (((Range)IokeObject.dataOf(on)).inverted)
                    {
                        firstMessage           = context.runtime.gteMessage;
                        secondMessageInclusive = context.runtime.lteMessage;
                        secondMessageExclusive = context.runtime.ltMessage;
                    }

                    if (IokeObject.IsObjectTrue(Interpreter.Send(firstMessage, context, from, other)) &&
                        ((inclusive &&
                          IokeObject.IsObjectTrue(Interpreter.Send(secondMessageInclusive, context, to, other))) ||
                         IokeObject.IsObjectTrue(Interpreter.Send(secondMessageExclusive, context, to, other))))
                    {
                        return(context.runtime.True);
                    }
                    else
                    {
                        return(context.runtime.False);
                    }
                }
                else
                {
                    IokeObject messageToSend = context.runtime.succMessage;
                    if (((Range)IokeObject.dataOf(on)).inverted)
                    {
                        messageToSend = context.runtime.predMessage;
                    }

                    object current = from;

                    while (!IokeObject.IsObjectTrue(Interpreter.Send(context.runtime.eqMessage, context, current, to)))
                    {
                        if (IokeObject.IsObjectTrue(Interpreter.Send(context.runtime.eqMessage, context, current, other)))
                        {
                            return(context.runtime.True);
                        }
                        current = Interpreter.Send(messageToSend, context, current);
                    }

                    if (inclusive && IokeObject.IsObjectTrue(Interpreter.Send(context.runtime.eqMessage, context, to, other)))
                    {
                        return(context.runtime.True);
                    }
                    return(context.runtime.False);
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a text inspection of the object",
                                                       new NativeMethod.WithNoArguments("inspect",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                return(method.runtime.NewText(Range.GetInspect(on)));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a brief text inspection of the object",
                                                       new NativeMethod.WithNoArguments("notice",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                return(method.runtime.NewText(Range.GetNotice(on)));
            })));
        }
Exemple #13
0
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "Set";
            obj.Mimics(IokeObject.As(IokeObject.FindCell(runtime.Mixins, "Sequenced"), null), runtime.nul, runtime.nul);

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns a hash for the set",
                                                           new NativeMethod.WithNoArguments("hash", (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                return(context.runtime.NewNumber(((IokeSet)IokeObject.dataOf(on))._set.GetHashCode()));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the left hand side set is equal to the right hand side set.",
                                                       new TypeCheckingNativeMethod("==", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Set)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                IokeSet d    = (IokeSet)IokeObject.dataOf(on);
                object other = args[0];
                return(((other is IokeObject) &&
                        (IokeObject.dataOf(other) is IokeSet) &&
                        d._set.Equals(((IokeSet)IokeObject.dataOf(other))._set)) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a text inspection of the object",
                                                       new TypeCheckingNativeMethod.WithNoArguments("inspect", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(method.runtime.NewText(IokeSet.GetInspect(on)));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Converts this set to use identity semantics, and then returns it.",
                                                       new TypeCheckingNativeMethod.WithNoArguments("withIdentitySemantics!", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                IokeSet ss = (IokeSet)IokeObject.dataOf(on);
                ss._set    = new SaneHashSet <object>(ss._set, new IdentityHashTable.IdentityEqualityComparer());
                return(on);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a brief text inspection of the object",
                                                       new TypeCheckingNativeMethod.WithNoArguments("notice", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(method.runtime.NewText(IokeSet.GetNotice(on)));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if this set is empty, false otherwise",
                                                       new TypeCheckingNativeMethod.WithNoArguments("empty?", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(((IokeSet)IokeObject.dataOf(on)).Set.Count == 0 ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Adds the argument to this set, if it's not already in the set. Returns the set after adding the object.",
                                                       new TypeCheckingNativeMethod("<<", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("value")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                ((IokeSet)IokeObject.dataOf(on))._set.Add(args[0]);
                return(on);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Removes the argument from the set, if it's in the set. Returns the set after removing the object.",
                                                       new TypeCheckingNativeMethod("remove!", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("value")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                ((IokeSet)IokeObject.dataOf(on))._set.Remove(args[0]);
                return(on);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a new set that contains the receivers elements and the elements of the set sent in as the argument.",
                                                       new TypeCheckingNativeMethod("+", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("otherSet").WhichMustMimic(obj)
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                var newSet = new SaneHashSet <object>();
                newSet.UnionWith(((IokeSet)IokeObject.dataOf(on)).Set);
                newSet.UnionWith(((IokeSet)IokeObject.dataOf(args[0])).Set);
                return(context.runtime.NewSet(newSet));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a new set that is the intersection of the receiver and the argument.",
                                                       new TypeCheckingNativeMethod("\u2229", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("otherSet").WhichMustMimic(obj)
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                var newSet = new SaneHashSet <object>();
                newSet.UnionWith(((IokeSet)IokeObject.dataOf(on)).Set);
                newSet.IntersectWith(((IokeSet)IokeObject.dataOf(args[0])).Set);
                return(context.runtime.NewSet(newSet));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if this set is a subset of the argument set",
                                                       new TypeCheckingNativeMethod("\u2286", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("otherSet").WhichMustMimic(obj)
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                var one    = ((IokeSet)IokeObject.dataOf(args[0])).Set;
                var two    = ((IokeSet)IokeObject.dataOf(on)).Set;
                var result = two.IsSubsetOf(one);
                return(result ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if this set is a proper subset of the argument set",
                                                       new TypeCheckingNativeMethod("\u2282", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("otherSet").WhichMustMimic(obj)
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                var one    = ((IokeSet)IokeObject.dataOf(args[0])).Set;
                var two    = ((IokeSet)IokeObject.dataOf(on)).Set;
                var result = two.IsProperSubsetOf(one);
                if (one.Count == 0 && two.Count == 0)
                {
                    result = false;
                }
                return(result ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if this set is a superset of the argument set",
                                                       new TypeCheckingNativeMethod("\u2287", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("otherSet").WhichMustMimic(obj)
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                var one    = ((IokeSet)IokeObject.dataOf(args[0])).Set;
                var two    = ((IokeSet)IokeObject.dataOf(on)).Set;
                var result = two.IsSupersetOf(one);
                return(result ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if this set is a proper superset of the argument set",
                                                       new TypeCheckingNativeMethod("\u2283", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("otherSet").WhichMustMimic(obj)
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                var one    = ((IokeSet)IokeObject.dataOf(args[0])).Set;
                var two    = ((IokeSet)IokeObject.dataOf(on)).Set;
                var result = two.IsProperSupersetOf(one);
                return(result ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the receiver includes the evaluated argument, otherwise false",
                                                       new TypeCheckingNativeMethod("include?", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("object")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                return(((IokeSet)IokeObject.dataOf(on)).Set.Contains(args[0]) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a new sequence to iterate over this set",
                                                       new TypeCheckingNativeMethod.WithNoArguments("seq", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                IokeObject ob = method.runtime.IteratorSequence.AllocateCopy(null, null);
                ob.MimicsWithoutCheck(method.runtime.IteratorSequence);
                ob.Data = new Sequence.IteratorSequence(((IokeSet)IokeObject.dataOf(on))._set.GetEnumerator());
                return(ob);
            })));


            obj.RegisterMethod(runtime.NewNativeMethod("takes either one, two or three arguments. if one argument is given, it should be a message chain that will be sent to each object in the set. the result will be thrown away. if two arguments are given, the first is an unevaluated name that will be set to each of the values in the set in succession, and then the second argument will be evaluated in a scope with that argument in it. if three arguments is given, the first one is an unevaluated name that will be set to the index of each element, and the other two arguments are the name of the argument for the value, and the actual code. the code will evaluate in a lexical context, and if the argument name is available outside the context, it will be shadowed. the method will return the set. the iteration order is not defined.",
                                                       new NativeMethod("each", DefaultArgumentsDefinition.builder()
                                                                        .WithOptionalPositionalUnevaluated("indexOrArgOrCode")
                                                                        .WithOptionalPositionalUnevaluated("argOrCode")
                                                                        .WithOptionalPositionalUnevaluated("code")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);

                object onAsSet = context.runtime.Set.ConvertToThis(on, message, context);
                var _set       = ((IokeSet)IokeObject.dataOf(onAsSet))._set;

                switch (message.Arguments.Count)
                {
                case 0: {
                    return(Interpreter.Send(runtime.seqMessage, context, on));
                }

                case 1: {
                    IokeObject code = IokeObject.As(message.Arguments[0], context);

                    foreach (object o in _set)
                    {
                        context.runtime.interpreter.Evaluate(code, context, context.RealContext, o);
                    }
                    break;
                }

                case 2: {
                    IokeObject c    = context.runtime.NewLexicalContext(context, "Lexical activation context for Set#each", context);
                    string name     = IokeObject.As(message.Arguments[0], context).Name;
                    IokeObject code = IokeObject.As(message.Arguments[1], context);

                    foreach (object o in _set)
                    {
                        c.SetCell(name, o);
                        context.runtime.interpreter.Evaluate(code, c, c.RealContext, c);
                    }
                    break;
                }

                case 3: {
                    IokeObject c    = context.runtime.NewLexicalContext(context, "Lexical activation context for Set#each", context);
                    string iname    = IokeObject.As(message.Arguments[0], context).Name;
                    string name     = IokeObject.As(message.Arguments[1], context).Name;
                    IokeObject code = IokeObject.As(message.Arguments[2], context);

                    int index = 0;
                    foreach (object o in _set)
                    {
                        c.SetCell(name, o);
                        c.SetCell(iname, runtime.NewNumber(index++));
                        context.runtime.interpreter.Evaluate(code, c, c.RealContext, c);
                    }
                    break;
                }
                }

                return(onAsSet);
            })));
        }
Exemple #14
0
 private static IDictionary GetOpTable(IokeParser parser, IokeObject opTable, string name, OpTableCreator creator)
 {
     IokeObject operators = IokeObject.As(opTable.FindCell(parser.message, parser.context, name), null);
     if(operators != parser.runtime.nul && (IokeObject.dataOf(operators) is Dict)) {
         return Dict.GetMap(operators);
     } else {
         IDictionary result = creator.Create(parser.runtime);
         opTable.SetCell(name, parser.runtime.NewDict(result));
         return result;
     }
 }
Exemple #15
0
        public static void Init(Runtime runtime)
        {
            IokeObject obj = new IokeObject(runtime, "Allows access to the internals of any object without actually using methods on that object");

            obj.Kind = "Reflector";
            obj.MimicsWithoutCheck(runtime.Origin);
            runtime.IokeGround.RegisterCell("Reflector", obj);

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the documentation text of the object given as argument. anything can have a documentation text - this text will initially be nil.",
                                                           new TypeCheckingNativeMethod("other:documentation", TypeCheckingArgumentsDefinition.builder()
                                                                                        .WithRequiredPositional("other")
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                return(Base.Documentation(context, message, args[0]));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("sets the documentation string for a specific object.",
                                                           new TypeCheckingNativeMethod("other:documentation=", TypeCheckingArgumentsDefinition.builder()
                                                                                        .WithRequiredPositional("other")
                                                                                        .WithRequiredPositional("text").WhichMustMimic(obj.runtime.Text).OrBeNil()
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                return(Base.SetDocumentation(context, message, args[0], args[1]));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("will return a new derivation of the receiving object. Might throw exceptions if the object is an oddball object.",
                                                           new TypeCheckingNativeMethod("other:mimic", TypeCheckingArgumentsDefinition.builder()
                                                                                        .WithRequiredPositional("other")
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                return(IokeObject.As(args[0], context).Mimic(message, context));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument that names the cell to set, sets this cell to the result of evaluating the second argument, and returns the value set.",
                                                           new NativeMethod("other:cell=",
                                                                            DefaultArgumentsDefinition
                                                                            .builder()
                                                                            .WithRequiredPositional("other")
                                                                            .WithRequiredPositional("cellName")
                                                                            .WithRequiredPositional("value")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                return(Base.AssignCell(context, message, args[0], args[1], args[2]));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and returns the cell that matches that name, without activating even if it's activatable.",
                                                           new NativeMethod("other:cell", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("other")
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                string name = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[1]));
                return(IokeObject.GetCell(args[0], message, context, name));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and returns a boolean indicating whether such a cell is reachable from this point.",
                                                           new NativeMethod("other:cell?", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("other")
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                IList args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());

                string name = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[1]));
                return(IokeObject.FindCell((IokeObject)args[0], name) != context.runtime.nul ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and returns a boolean indicating whether this cell is owned by the receiver or not. the assumption is that the cell should exist. if it doesn't exist, a NoSuchCell condition will be signalled.",
                                                           new NativeMethod("other:cellOwner?", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("other")
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                string name = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[1]));
                return((IokeObject.FindPlace(args[0], message, context, name) == args[0]) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and returns the closest object that defines such a cell. if it doesn't exist, a NoSuchCell condition will be signalled.",
                                                           new NativeMethod("other:cellOwner", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("other")
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                string name   = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[1]));
                object result = IokeObject.FindPlace(args[0], message, context, name);
                if (result == context.runtime.nul)
                {
                    return(context.runtime.nil);
                }
                return(result);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and removes that cell from the current receiver. if the current receiver has no such object, signals a condition. note that if another cell with that name is available in the mimic chain, it will still be accessible after calling this method. the method returns the receiver.",
                                                           new NativeMethod("other:removeCell!", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("other")
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                string name = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[1]));
                IokeObject.RemoveCell(args[0], message, context, name);
                return(args[0]);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("expects one evaluated text or symbol argument and makes that cell undefined in the current receiver. what that means is that from now on it will look like this cell doesn't exist in the receiver or any of its mimics. the cell will not show up if you call cellNames on the receiver or any of the receivers mimics. the undefined status can be removed by doing removeCell! on the correct cell name. a cell name that doesn't exist can still be undefined. the method returns the receiver.",
                                                           new NativeMethod("other:undefineCell!", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("other")
                                                                            .WithRequiredPositional("cellName")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                string name = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[1]));
                IokeObject.UndefineCell(args[0], message, context, name);
                return(args[0]);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("takes one optional evaluated boolean argument, which defaults to false. if false, this method returns a list of the cell names of the receiver. if true, it returns the cell names of this object and all it's mimics recursively.",
                                                           new NativeMethod("other:cellNames", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("other")
                                                                            .WithOptionalPositional("includeMimics", "false")
                                                                            .WithOptionalPositional("cutoff", "nil")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                return(Base.CellNames(context, message, args[0], args.Count > 1 && IokeObject.IsObjectTrue(args[1]), (args.Count > 2) ? args[2] : null));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("takes one optional evaluated boolean argument, which defaults to false. if false, this method returns a dict of the cell names and values of the receiver. if true, it returns the cell names and values of this object and all it's mimics recursively.",
                                                           new NativeMethod("other:cells", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("other")
                                                                            .WithOptionalPositional("includeMimics", "false")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                return(Base.Cells(context, message, args[0], args.Count > 1 && IokeObject.IsObjectTrue(args[1])));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one evaluated argument and returns either true or false if this object or one of it's mimics mimics that argument",
                                                       new NativeMethod("other:mimics?", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("other")
                                                                        .WithRequiredPositional("potentialMimic")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());

                IokeObject arg = IokeObject.As(args[1], context);
                if (IokeObject.IsMimic(args[0], arg, context))
                {
                    return(context.runtime.True);
                }
                else
                {
                    return(context.runtime.False);
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("modifies the receiver to be in all ways identical to the argument. if the receiver is nil, true or false, this method can't be used - but those are the only exceptions. it's generally not recommended to use it on kinds and objects that are important for the Ioke runtime, since the result might be highly unpredictable.",
                                                       new NativeMethod("other:become!", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("other")
                                                                        .WithRequiredPositional("objectToBecome")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                IokeObject me    = IokeObject.As(args[0], context);
                IokeObject other = IokeObject.As(args[1], context);

                if (args[0] == context.runtime.nil || args[0] == context.runtime.True || args[0] == context.runtime.False)
                {
                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(context.runtime.Condition,
                                                                                 message,
                                                                                 context,
                                                                                 "Error",
                                                                                 "CantMimicOddball"), context).Mimic(message, context);
                    condition.SetCell("message", message);
                    condition.SetCell("context", context);
                    condition.SetCell("receiver", args[0]);
                    context.runtime.ErrorCondition(condition);
                }

                me.Become(other, message, context);

                return(args[0]);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a text hex representation of the receiver in upper case hex literal, starting with 0x. This value is based on System.identityHashCode, and as such is not totally guaranteed to be totally unique. but almost.",
                                                       new TypeCheckingNativeMethod("other:uniqueHexId", TypeCheckingArgumentsDefinition.builder()
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                return(context.runtime.NewText("0x" + System.Convert.ToString(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(IokeObject.As(args[0], context).body), 16).ToUpper()));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the evaluated argument is the same reference as the receiver, false otherwise.",
                                                       new NativeMethod("other:same?", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("other")
                                                                        .WithRequiredPositional("other")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                return(IokeObject.Same(args[0], args[1]) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes the name of a message to send, and the arguments to give it. send should generally behave exactly as if you had sent the message itself - except that you can give a variable containing the name.",
                                                       new NativeMethod("other:send", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("other")
                                                                        .WithRequiredPositional("messageName")
                                                                        .WithRestUnevaluated("arguments")
                                                                        .WithKeywordRestUnevaluated("keywordArguments")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                object _recv = Interpreter.GetEvaluatedArgument(message, 0, context);
                object _name = Interpreter.GetEvaluatedArgument(message, 1, context);
                string name  = Text.GetText(Interpreter.Send(runtime.asText, context, _name));

                IokeObject newMessage = Message.DeepCopy(message);
                newMessage.Arguments.RemoveAt(0);
                newMessage.Arguments.RemoveAt(0);
                Message.SetName(newMessage, name);
                return(Interpreter.Send(newMessage, context, _recv));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one evaluated Text argument and returns either true or false if this object or one of it's mimics have the kind of the name specified",
                                                       new TypeCheckingNativeMethod("other:kind?", TypeCheckingArgumentsDefinition.builder()
                                                                                    .WithRequiredPositional("other")
                                                                                    .WithRequiredPositional("name").WhichMustMimic(runtime.Text)
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                string kind = Text.GetText(args[1]);
                return(IokeObject.IsKind(args[0], kind, context) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one evaluated argument and returns either true or false if this object or one of it's mimics mimics that argument. exactly the same as 'mimics?'",
                                                       new NativeMethod("other:is?", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("other")
                                                                        .WithRequiredPositional("potentialMimic")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());

                IokeObject arg = IokeObject.As(args[1], context);
                return(IokeObject.IsMimic(args[0], arg, context) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a list of all the mimics of the receiver. it will not be the same list as is used to back the object, so modifications to this list will not show up in the object.",
                                                       new TypeCheckingNativeMethod("other:mimics", TypeCheckingArgumentsDefinition.builder()
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                var l = new SaneArrayList();
                foreach (object x in IokeObject.GetMimics(args[0], context))
                {
                    l.Add(x);
                }
                return(context.runtime.NewList(l));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("removes all mimics on the receiver, and returns the receiver",
                                                       new TypeCheckingNativeMethod("other:removeAllMimics!", TypeCheckingArgumentsDefinition.builder()
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                IokeObject.RemoveAllMimics(args[0], message, context);
                return(args[0]);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("removes the argument mimic from the list of all mimics on the receiver. will do nothing if the receiver has no such mimic. it returns the receiver",
                                                       new NativeMethod("other:removeMimic!", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("other")
                                                                        .WithRequiredPositional("mimicToRemove")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                IokeObject.RemoveMimic(args[0], args[1], message, context);
                return(args[0]);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one evaluated argument and adds it to the list of mimics for the receiver. the receiver will be returned.",
                                                       new NativeMethod("other:mimic!", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("other")
                                                                        .WithRequiredPositional("newMimic")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                IokeObject newMimic = IokeObject.As(args[1], context);
                IokeObject.As(args[0], context).Mimics(newMimic, message, context);
                return(args[0]);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one evaluated argument and prepends it to the list of mimics for the receiver. the receiver will be returned.",
                                                       new NativeMethod("other:prependMimic!", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("other")
                                                                        .WithRequiredPositional("newMimic")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                IokeObject newMimic = IokeObject.As(args[1], context);
                IokeObject.As(args[0], context).Mimics(0, newMimic, message, context);
                return(args[0]);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the receiver is frozen, otherwise false",
                                                       new TypeCheckingNativeMethod("other:frozen?", TypeCheckingArgumentsDefinition.builder()
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                return(IokeObject.As(args[0], context).IsFrozen ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("ensures that the receiver is frozen",
                                                       new TypeCheckingNativeMethod("other:freeze!", TypeCheckingArgumentsDefinition.builder()
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                IokeObject.Freeze(args[0]);
                return(args[0]);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("ensures that the receiver is not frozen",
                                                       new TypeCheckingNativeMethod("other:thaw!", TypeCheckingArgumentsDefinition.builder()
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                IokeObject.Thaw(args[0]);
                return(args[0]);
            })));
        }
Exemple #16
0
        public static void Init(IokeObject obj) {
            obj.Kind = "Locals";
            obj.body.mimicCount = 0;

            obj.SetCell("=",         obj.runtime.Base.body.Get("="));
            var assgn = IokeObject.As(obj.runtime.DefaultBehavior.body.Get("Assignment"), null).body;
            obj.SetCell("++",        assgn.Get("++"));
            obj.SetCell("--",        assgn.Get("--"));
            obj.SetCell("+=",        assgn.Get("+="));
            obj.SetCell("-=",        assgn.Get("-="));
            obj.SetCell("/=",        assgn.Get("/="));
            obj.SetCell("*=",        assgn.Get("*="));
            obj.SetCell("%=",        assgn.Get("%="));
            obj.SetCell("**=",       assgn.Get("**="));
            obj.SetCell("&=",        assgn.Get("&="));
            obj.SetCell("|=",        assgn.Get("|="));
            obj.SetCell("^=",        assgn.Get("^="));
            obj.SetCell("<<=",       assgn.Get("<<="));
            obj.SetCell(">>=",       assgn.Get(">>="));
            obj.SetCell("&&=",       assgn.Get("&&="));
            obj.SetCell("||=",       assgn.Get("||="));
            obj.SetCell("cell",         obj.runtime.Base.body.Get("cell"));
            obj.SetCell("cell=",         obj.runtime.Base.body.Get("cell="));
            obj.SetCell("cells",         obj.runtime.Base.body.Get("cells"));
            obj.SetCell("cellNames",         obj.runtime.Base.body.Get("cellNames"));
            obj.SetCell("removeCell!",         obj.runtime.Base.body.Get("removeCell!"));
            obj.SetCell("undefineCell!",         obj.runtime.Base.body.Get("undefineCell!"));
            obj.SetCell("cellOwner?",         obj.runtime.Base.body.Get("cellOwner?"));
            obj.SetCell("cellOwner",         obj.runtime.Base.body.Get("cellOwner"));
            obj.SetCell("identity",         obj.runtime.Base.body.Get("identity"));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("will pass along the call to the real self object of this context.",
                                                           new NativeMethod("pass", DefaultArgumentsDefinition.builder()
                                                                            .WithRestUnevaluated("arguments")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                                                                                object selfDelegate = IokeObject.As(on, context).Self;
                                                                                if(selfDelegate != null && selfDelegate != on) {
                                                                                    return Interpreter.Perform(selfDelegate, context, message);
                                                                                }
                                                                                return context.runtime.nil;
                                                                            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("will return a text representation of the current stack trace",
                                                           new NativeMethod.WithNoArguments("stackTraceAsText",
                                                                                            (method, context, m, on, outer) => {
                                                                                                outer.ArgumentsDefinition.CheckArgumentCount(context, m, on);
                                                                                                Runtime runtime = context.runtime;
                                                                                                StringBuilder sb = new StringBuilder();

                                                                                                IokeObject current = IokeObject.As(on, context);
                                                                                                while("Locals".Equals(current.GetKind(m, context))) {
                                                                                                    IokeObject message = IokeObject.As(IokeObject.GetCell(current, m, context, "currentMessage"), context);
                                                                                                    IokeObject start = message;

                                                                                                    while(Message.GetPrev(start) != null && Message.GetPrev(start).Line == message.Line) {
                                                                                                        start = Message.GetPrev(start);
                                                                                                    }

                                                                                                    string s1 = Message.Code(start);

                                                                                                    int ix = s1.IndexOf("\n");
                                                                                                    if(ix > -1) {
                                                                                                        ix--;
                                                                                                    }

                                                                                                    sb.Append(string.Format(" {0,-48} {1}\n",
                                                                                                                            (ix == -1 ? s1 : s1.Substring(0,ix)),
                                                                                                                            "[" + message.File + ":" + message.Line + ":" + message.Position + GetContextMessageName(IokeObject.As(current.body.Get("surroundingContext"), context)) + "]"));


                                                                                                    current = IokeObject.As(IokeObject.FindCell(current, "surroundingContext"), context);
                                                                                                }

                                                                                                return runtime.NewText(sb.ToString());
                                                                                            })));
        }
Exemple #17
0
        public Levels(IokeObject msg, IokeObject context, IokeObject message)
        {
            this.runtime = context.runtime;
            this._context = context;
            this._message = message;

            IokeObject opTable = IokeObject.As(msg.FindCell(_message, _context, "OperatorTable"), null);
            if(opTable == runtime.nul) {
                opTable = runtime.NewFromOrigin();
                opTable.Kind = "Message OperatorTable";
                runtime.Message.SetCell("OperatorTable", opTable);
                opTable.SetCell("precedenceLevelCount", runtime.NewNumber(OP_LEVEL_MAX));
            }

            this.operatorTable = GetOpTable(opTable, "operators", new BinaryOpTableCreator());
            this.trinaryOperatorTable = GetOpTable(opTable, "trinaryOperators", new TrinaryOpTableCreator());
            this.invertedOperatorTable = GetOpTable(opTable, "invertedOperators", new InvertedOpTableCreator());
            this.stack = new SaneList<Level>();
            this.Reset();
        }
        public int GetEvaluatedArguments(IokeObject context, IokeObject message, object on, IList argumentsWithoutKeywords, IDictionary <string, object> givenKeywords)
        {
            Runtime runtime   = context.runtime;
            IList   arguments = message.Arguments;
            int     argCount  = 0;

            foreach (object o in arguments)
            {
                if (Message.IsKeyword(o))
                {
                    givenKeywords[IokeObject.As(o, context).Name] = Interpreter.GetEvaluatedArgument(((Message)IokeObject.dataOf(o)).next, context);
                }
                else if (Message.HasName(o, "*") && IokeObject.As(o, context).Arguments.Count == 1)    // Splat
                {
                    object result = Interpreter.GetEvaluatedArgument(IokeObject.As(o, context).Arguments[0], context);
                    if (IokeObject.dataOf(result) is IokeList)
                    {
                        IList elements = IokeList.GetList(result);
                        foreach (object ox in elements)
                        {
                            argumentsWithoutKeywords.Add(ox);
                        }
                        argCount += elements.Count;
                    }
                    else if (IokeObject.dataOf(result) is Dict)
                    {
                        IDictionary keys = Dict.GetMap(result);
                        foreach (DictionaryEntry me in keys)
                        {
                            givenKeywords[Text.GetText(IokeObject.ConvertToText(me.Key, message, context, true)) + ":"] = me.Value;
                        }
                    }
                    else if (IokeObject.FindCell((IokeObject)result, "asTuple") != runtime.nul)
                    {
                        object   tupledValue = Interpreter.Send(runtime.asTuple, context, result);
                        object[] values      = Tuple.GetElements(tupledValue);
                        foreach (object val in values)
                        {
                            argumentsWithoutKeywords.Add(val);
                        }
                        argCount += values.Length;
                    }
                    else
                    {
                        IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                     message,
                                                                                     context,
                                                                                     "Error",
                                                                                     "Invocation",
                                                                                     "NotSpreadable"), context).Mimic(message, context);
                        condition.SetCell("message", message);
                        condition.SetCell("context", context);
                        condition.SetCell("receiver", on);
                        condition.SetCell("given", result);

                        IList outp = IokeList.GetList(runtime.WithRestartReturningArguments(() => { runtime.ErrorCondition(condition); },
                                                                                            context,
                                                                                            new Restart.DefaultValuesGivingRestart("ignoreArgument", runtime.nil, 0),
                                                                                            new Restart.DefaultValuesGivingRestart("takeArgumentAsIs", IokeObject.As(result, context), 1)
                                                                                            ));

                        foreach (object ox in outp)
                        {
                            argumentsWithoutKeywords.Add(ox);
                        }
                        argCount += outp.Count;
                    }
                }
                else
                {
                    var xx = Interpreter.GetEvaluatedArgument(o, context);
                    argumentsWithoutKeywords.Add(xx);
                    argCount++;
                }
            }

            while (argCount < min || (max != -1 && argCount > max))
            {
                int finalArgCount = argCount;
                if (argCount < min)
                {
                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                 message,
                                                                                 context,
                                                                                 "Error",
                                                                                 "Invocation",
                                                                                 "TooFewArguments"), context).Mimic(message, context);
                    condition.SetCell("message", message);
                    condition.SetCell("context", context);
                    condition.SetCell("receiver", on);
                    condition.SetCell("missing", runtime.NewNumber(min - argCount));

                    IList newArguments = IokeList.GetList(runtime.WithRestartReturningArguments(() => { runtime.ErrorCondition(condition); },
                                                                                                context,
                                                                                                new NewArgumentGivingRestart("provideExtraArguments"),
                                                                                                new Restart.DefaultValuesGivingRestart("substituteNilArguments", runtime.nil, min - argCount)));

                    foreach (object ox in newArguments)
                    {
                        argumentsWithoutKeywords.Add(ox);
                    }
                    argCount += newArguments.Count;
                }
                else
                {
                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                 message,
                                                                                 context,
                                                                                 "Error",
                                                                                 "Invocation",
                                                                                 "TooManyArguments"), context).Mimic(message, context);
                    condition.SetCell("message", message);
                    condition.SetCell("context", context);
                    condition.SetCell("receiver", on);
                    condition.SetCell("extra", runtime.NewList(ArrayList.Adapter(argumentsWithoutKeywords).GetRange(max, finalArgCount - max)));

                    runtime.WithReturningRestart("ignoreExtraArguments", context, () => { runtime.ErrorCondition(condition); });
                    argCount = max;
                }
            }

            var intersection = new SaneHashSet <string>(givenKeywords.Keys);

            foreach (string k in keywords)
            {
                intersection.Remove(k);
            }

            if (krest == null && intersection.Count > 0)
            {
                IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                             message,
                                                                             context,
                                                                             "Error",
                                                                             "Invocation",
                                                                             "MismatchedKeywords"), context).Mimic(message, context);
                condition.SetCell("message", message);
                condition.SetCell("context", context);
                condition.SetCell("receiver", on);

                IList expected = new SaneArrayList();
                foreach (string s in keywords)
                {
                    expected.Add(runtime.NewText(s));
                }

                condition.SetCell("expected", runtime.NewList(expected));

                IList extra = new SaneArrayList();
                foreach (string s in intersection)
                {
                    extra.Add(runtime.NewText(s));
                }
                condition.SetCell("extra", runtime.NewList(extra));
                runtime.WithReturningRestart("ignoreExtraKeywords", context, () => { runtime.ErrorCondition(condition); });
            }

            return(argCount);
        }
Exemple #19
0
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "Text";
            obj.Mimics(IokeObject.As(IokeObject.FindCell(runtime.Mixins, "Comparing"), null), runtime.nul, runtime.nul);

            obj.RegisterMethod(runtime.NewNativeMethod("returns a hash for the text",
                                                       new NativeMethod.WithNoArguments("hash", (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                return(context.runtime.NewNumber(((Text)IokeObject.dataOf(on)).text.GetHashCode()));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the left hand side text is equal to the right hand side text.",
                                                       new TypeCheckingNativeMethod("==", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Text)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                Text d       = (Text)IokeObject.dataOf(on);
                object other = args[0];

                return(((other is IokeObject) &&
                        (IokeObject.dataOf(other) is Text) &&
                        ((on == context.runtime.Text || other == context.runtime.Text) ? on == other :
                         d.text.Equals(((Text)IokeObject.dataOf(other)).text))) ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a text representation of the object",
                                                       new NativeMethod.WithNoArguments("asText",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                return(on);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes any number of arguments, and expects the text receiver to contain format specifications. The currently supported specifications are only %s and %{, %}. These have several parameters that can be used. See the spec for more info about these. The format method will return a new text based on the content of the receiver, and the arguments given.",
                                                       new TypeCheckingNativeMethod("format", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRest("replacements")
                                                                                    .Arguments,
                                                                                    (self, on, args, keywords, context, message) => {
                StringBuilder result = new StringBuilder();
                Format(on, message, context, args, result);
                return(context.runtime.NewText(result.ToString()));
            })));


            obj.RegisterMethod(obj.runtime.NewNativeMethod("Converts the content of this text into a rational value",
                                                           new TypeCheckingNativeMethod.WithNoArguments("toRational", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                return(Text.ToRational(on, context, message));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Converts the content of this text into a decimal value",
                                                           new TypeCheckingNativeMethod.WithNoArguments("toDecimal", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                return(Text.ToDecimal(on, context, message));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns a text inspection of the object",
                                                           new TypeCheckingNativeMethod.WithNoArguments("inspect", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                return(self.runtime.NewText(Text.GetInspect(on)));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns a brief text inspection of the object",
                                                           new TypeCheckingNativeMethod.WithNoArguments("notice", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                return(self.runtime.NewText(Text.GetInspect(on)));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns a text where all non-safe characters have been replaced with safe ones",
                                                           new TypeCheckingNativeMethod.WithNoArguments("makeXMLSafe", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                return(self.runtime.NewText(new StringUtils().XmlSafe(Text.GetText(on))));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns a lower case version of this text",
                                                           new TypeCheckingNativeMethod.WithNoArguments("lower", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                return(self.runtime.NewText(Text.GetText(on).ToLower()));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns an upper case version of this text",
                                                           new TypeCheckingNativeMethod.WithNoArguments("upper", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                return(self.runtime.NewText(Text.GetText(on).ToUpper()));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns a version of this text with leading and trailing whitespace removed",
                                                           new TypeCheckingNativeMethod.WithNoArguments("trim", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                return(self.runtime.NewText(Text.GetText(on).Trim()));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns an array of texts split around the argument",
                                                           new TypeCheckingNativeMethod("split", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithOptionalPositional("splitAround", "")
                                                                                        .Arguments,
                                                                                        (self, on, args, keywords, context, message) => {
                string real = Text.GetText(on);
                var r       = new SaneArrayList();
                Pattern p   = null;

                if (args.Count == 0)
                {
                    p = new Pattern("\\s");
                }
                else
                {
                    object arg = args[0];
                    if (IokeObject.dataOf(arg) is Regexp)
                    {
                        p = Regexp.GetRegexp(arg);
                    }
                    else
                    {
                        string around = Text.GetText(arg);
                        p             = new Pattern(Pattern.Quote(around));
                    }
                }

                RETokenizer tok  = new RETokenizer(p, real);
                tok.EmptyEnabled = false;
                while (tok.HasMore)
                {
                    r.Add(context.runtime.NewText(tok.NextToken));
                }

                return(context.runtime.NewList(r));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Takes two text arguments where the first is the substring to replace, and the second is the replacement to insert. Will only replace the first match, if any is found, and return a new Text with the result.",
                                                           new TypeCheckingNativeMethod("replace", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithRequiredPositional("pattern")
                                                                                        .WithRequiredPositional("replacement")
                                                                                        .Arguments,
                                                                                        (self, on, args, keywords, context, message) => {
                string initial = Text.GetText(on);
                string repl    = Text.GetText(args[1]);

                object arg = args[0];

                Pattern pat = null;
                if (IokeObject.dataOf(arg) is Regexp)
                {
                    pat = Regexp.GetRegexp(arg);
                }
                else
                {
                    string around = Text.GetText(arg);
                    pat           = new Pattern(Pattern.Quote(around));
                }

                Replacer r    = pat.Replacer(repl);
                string result = r.ReplaceFirst(initial);

                return(context.runtime.NewText(result));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Takes two text arguments where the first is the substring to replace, and the second is the replacement to insert. Will replace all matches, if any is found, and return a new Text with the result.",
                                                           new TypeCheckingNativeMethod("replaceAll", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithRequiredPositional("pattern")
                                                                                        .WithRequiredPositional("replacement")
                                                                                        .Arguments,
                                                                                        (self, on, args, keywords, context, message) => {
                string initial = Text.GetText(on);
                string repl    = Text.GetText(args[1]);

                object arg = args[0];

                Pattern pat = null;
                if (IokeObject.dataOf(arg) is Regexp)
                {
                    pat = Regexp.GetRegexp(arg);
                }
                else
                {
                    string around = Text.GetText(arg);
                    pat           = new Pattern(Pattern.Quote(around));
                }

                Replacer r    = pat.Replacer(repl);
                String result = r.Replace(initial);

                return(context.runtime.NewText(result));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns the length of this text",
                                                           new TypeCheckingNativeMethod.WithNoArguments("length", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                return(context.runtime.NewNumber(GetText(on).Length));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("compares this text against the argument, returning -1, 0 or 1 based on which one is lexically larger",
                                                           new TypeCheckingNativeMethod("<=>", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithRequiredPositional("other")
                                                                                        .Arguments,
                                                                                        (self, on, args, keywords, context, message) => {
                object arg = args[0];

                if (!(IokeObject.dataOf(arg) is Text))
                {
                    arg = IokeObject.ConvertToText(arg, message, context, false);
                    if (!(IokeObject.dataOf(arg) is Text))
                    {
                        // Can't compare, so bail out
                        return(context.runtime.nil);
                    }
                }

                if (on == context.runtime.Text || arg == context.runtime.Text)
                {
                    if (on == arg)
                    {
                        return(context.runtime.NewNumber(0));
                    }
                    return(context.runtime.nil);
                }

                int result = string.CompareOrdinal(Text.GetText(on), Text.GetText(arg));
                if (result < 0)
                {
                    result = -1;
                }
                else if (result > 0)
                {
                    result = 1;
                }

                return(context.runtime.NewNumber(result));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("takes one argument, that can be either an index or a range of two indicis. this slicing works the same as for Lists, so you can index from the end, both with the single index and with the range.",
                                                           new TypeCheckingNativeMethod("[]", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithRequiredPositional("index")
                                                                                        .Arguments,
                                                                                        (self, on, args, keywords, context, message) => {
                object arg    = args[0];
                IokeData data = IokeObject.dataOf(arg);

                if (data is Range)
                {
                    int first = Number.ExtractInt(Range.GetFrom(arg), message, context);

                    if (first < 0)
                    {
                        return(context.runtime.NewText(""));
                    }

                    int last       = Number.ExtractInt(Range.GetTo(arg), message, context);
                    bool inclusive = Range.IsInclusive(arg);

                    string str = GetText(on);
                    int size   = str.Length;

                    if (last < 0)
                    {
                        last = size + last;
                    }

                    if (last < 0)
                    {
                        return(context.runtime.NewText(""));
                    }

                    if (last >= size)
                    {
                        last = inclusive ? size - 1 : size;
                    }

                    if (first > last || (!inclusive && first == last))
                    {
                        return(context.runtime.NewText(""));
                    }

                    if (!inclusive)
                    {
                        last--;
                    }

                    return(context.runtime.NewText(str.Substring(first, (last + 1) - first)));
                }
                else if (data is Number)
                {
                    string str = GetText(on);
                    int len    = str.Length;

                    int ix = ((Number)data).AsNativeInteger();

                    if (ix < 0)
                    {
                        ix = len + ix;
                    }

                    if (ix >= 0 && ix < len)
                    {
                        return(context.runtime.NewNumber(str[ix]));
                    }
                    else
                    {
                        return(context.runtime.nil);
                    }
                }

                return(on);
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns a symbol representing the Unicode category of the character",
                                                           new TypeCheckingNativeMethod.WithNoArguments("category", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                string character = GetText(on);
                if (character.Length == 1)
                {
                    return(context.runtime.GetSymbol(UnicodeBlock.Of(character[0])));
                }

                IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                             message,
                                                                             context,
                                                                             "Error",
                                                                             "Default"), context).Mimic(message, context);
                condition.SetCell("message", message);
                condition.SetCell("context", context);
                condition.SetCell("receiver", on);
                condition.SetCell("text", context.runtime.NewText("Text does not contain exactly one character"));

                runtime.ErrorCondition(condition);
                return(null);
            })));
            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns a new text where all the escapes in the current text have been evaluated - exactly as if another parsing step had been applied. This does not evaluate embedded code, though.",
                                                           new TypeCheckingNativeMethod.WithNoArguments("evaluateEscapes", obj,
                                                                                                        (self, on, args, keywords, context, message) => {
                return(context.runtime.NewText(new StringUtils().ReplaceEscapes(GetText(on))));
            })));
        }