示例#1
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)));
            })));
        }
示例#2
0
文件: Pair.cs 项目: tspring/ioke
        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)));
            })));
        }
示例#3
0
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "Regexp";

            IokeObject regexpMatch = new IokeObject(runtime, "contains behavior related to assignment", new RegexpMatch(obj, null, null));

            regexpMatch.MimicsWithoutCheck(runtime.Origin);
            regexpMatch.Init();
            obj.RegisterCell("Match", regexpMatch);

            obj.RegisterMethod(runtime.NewNativeMethod("returns a hash for the regexp",
                                                       new NativeMethod.WithNoArguments("hash", (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                Regexp r = (Regexp)IokeObject.dataOf(on);
                return(context.runtime.NewNumber(r.pattern.GetHashCode() + 13 * r.flags.GetHashCode()));
            })));

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

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

            obj.RegisterMethod(runtime.NewNativeMethod("Returns the pattern use for this regular expression",
                                                       new TypeCheckingNativeMethod.WithNoArguments("pattern", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(context.runtime.NewText(GetPattern(on)));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one argument and tries to match that argument against the current pattern. Returns nil if no match can be done, or a Regexp Match object if a match succeeds",
                                                       new TypeCheckingNativeMethod("match", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                IokeObject target = IokeObject.As(Interpreter.Send(context.runtime.asText, context, args[0]), context);
                string arg        = Text.GetText(target);
                Matcher m         = ((Regexp)IokeObject.dataOf(on)).regexp.Matcher(arg);

                if (m.Find())
                {
                    IokeObject match = regexpMatch.AllocateCopy(message, context);
                    match.MimicsWithoutCheck(regexpMatch);
                    match.Data = new RegexpMatch(IokeObject.As(on, context), m, target);
                    return(match);
                }
                else
                {
                    return(context.runtime.nil);
                }
            })));

            obj.AliasMethod("match", "=~", null, null);

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one argument that should be a text and returns a text that has all regexp meta characters quoted",
                                                       new NativeMethod("quote", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("text")
                                                                        .Arguments,
                                                                        (method, on, args, keywords, context, message) => {
                return(context.runtime.NewText(Pattern.Quote(Text.GetText(Interpreter.Send(context.runtime.asText, context, args[0])))));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one or two text arguments that describes the regular expression to create. the first text is the pattern and the second is the flags.",
                                                       new NativeMethod("from", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("pattern")
                                                                        .WithOptionalPositional("flags", "")
                                                                        .Arguments,
                                                                        (method, on, args, keywords, context, message) => {
                string pattern = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[0]));
                string flags   = "";
                if (args.Count > 1)
                {
                    flags = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[1]));
                }

                return(context.runtime.NewRegexp(pattern, flags, context, message));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one argument and tries to match that argument against the current pattern. Returns a list of all the texts that were matched.",
                                                       new TypeCheckingNativeMethod("allMatches", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                string arg = Text.GetText(Interpreter.Send(context.runtime.asText, context, args[0]));
                Matcher m  = ((Regexp)IokeObject.dataOf(on)).regexp.Matcher(arg);

                var result         = new SaneArrayList();
                MatchIterator iter = m.FindAll();
                while (iter.HasMore)
                {
                    result.Add(runtime.NewText(iter.NextMatch.Group(0)));
                }

                return(runtime.NewList(result));
            })));

            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(Regexp.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(Regexp.GetNotice(on)));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a list of all the named groups in this regular expression",
                                                       new TypeCheckingNativeMethod.WithNoArguments("names", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                var names    = Regexp.GetRegexp(on).GroupNames;
                var theNames = new SaneArrayList();
                foreach (object name in names)
                {
                    theNames.Add(context.runtime.GetSymbol(((string)name)));
                }
                return(context.runtime.NewList(theNames));
            })));
        }
示例#4
0
 public WithNoArguments(string name, RawActivate activate) : base(name, TypeCheckingArgumentsDefinition.Empty(), activate)
 {
 }
示例#5
0
文件: Dict.cs 项目: tspring/ioke
        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);
            })));
        }
示例#6
0
 public TypeCheckingNativeMethod(string name, TypeCheckingArgumentsDefinition arguments, ArgsActivate activate)
     : base(name, arguments, TypeCheckingRawActivate, activate)
 {
 }
示例#7
0
文件: IokeSet.cs 项目: tspring/ioke
        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);
            })));
        }
示例#8
0
文件: DateTime.cs 项目: tspring/ioke
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "DateTime";
            //        obj.mimics(IokeObject.as(runtime.mixins.getCell(null, null, "Comparing")), runtime.nul, runtime.nul);

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

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a new DateTime representing the current instant in time in the default TimeZone.",
                                                       new TypeCheckingNativeMethod.WithNoArguments("now", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(method.runtime.NewDateTime(System.DateTime.Now));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Expects to get one DateTime as argument, and returns the difference between this instant and that instant, in milliseconds.",
                                                       new TypeCheckingNativeMethod("-", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("subtrahend").WhichMustMimic(obj)
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                long diff = System.Convert.ToInt64(GetDateTime(on).Subtract(GetDateTime(args[0])).TotalMilliseconds);
                return(context.runtime.NewNumber(diff));
            })));

            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(DateTime.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(DateTime.GetNotice(on)));
            })));
        }
示例#9
0
文件: Arity.cs 项目: tspring/ioke
        public override void Init(IokeObject obj)
        {
            obj.Kind = "Arity";

            obj.SetCell("taking:nothing", GetArity(obj, Taking.Nothing));
            obj.SetCell("taking:everything", GetArity(obj, Taking.Everything));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Create an Arity object from the given messages. The list of unevaluated messages given to this method will be used as if they were the arguments part of a DefaultMethod definition.",
                                                           new TypeCheckingNativeMethod("from", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithRestUnevaluated("arguments")
                                                                                        .Arguments,
                                                                                        (self, on, args, keywords, context, message) => {
                if (message.Arguments.Count == 0)
                {
                    return(TakingNothing(self));
                }
                DefaultArgumentsDefinition def = DefaultArgumentsDefinition.CreateFrom(message.Arguments, 0, message.Arguments.Count, message, on, context);
                return(GetArity(self, def));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the names for positional arguments",
                                                           new TypeCheckingNativeMethod("positionals", TypeCheckingArgumentsDefinition.builder()
                                                                                        .WithOptionalPositional("includeOptionals", "true")
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                Arity a              = (Arity)IokeObject.dataOf(on);
                var names            = new SaneArrayList();
                bool includeOptional = args.Count == 0 ? true : IokeObject.IsObjectTrue(args[0]);
                if (a.argumentsDefinition != null)
                {
                    foreach (DefaultArgumentsDefinition.Argument argument in a.argumentsDefinition.Arguments)
                    {
                        if (argument is DefaultArgumentsDefinition.KeywordArgument)
                        {
                            continue;
                        }
                        if (argument is DefaultArgumentsDefinition.OptionalArgument)
                        {
                            if (includeOptional)
                            {
                                names.Add(method.runtime.GetSymbol(argument.Name));
                            }
                        }
                        else
                        {
                            names.Add(method.runtime.GetSymbol(argument.Name));
                        }
                    }
                }
                return(method.runtime.NewList(names));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the names for keyword arguments",
                                                           new TypeCheckingNativeMethod.WithNoArguments("keywords", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                Arity a   = (Arity)IokeObject.dataOf(on);
                var names = new SaneArrayList();
                if (a.argumentsDefinition != null)
                {
                    foreach (string name in a.argumentsDefinition.Keywords)
                    {
                        names.Add(method.runtime.GetSymbol(name.Substring(0, name.Length - 1)));
                    }
                }
                return(method.runtime.NewList(names));
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the symbol name for the krest argument.",
                                                           new TypeCheckingNativeMethod.WithNoArguments("krest", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                Arity a = (Arity)IokeObject.dataOf(on);
                if (a.argumentsDefinition != null)
                {
                    string name = a.argumentsDefinition.KrestName;
                    if (name == null)
                    {
                        return(method.runtime.nil);
                    }
                    else
                    {
                        return(method.runtime.GetSymbol(name));
                    }
                }
                else
                {
                    return(method.runtime.nil);
                }
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the symbol name for the rest argument.",
                                                           new TypeCheckingNativeMethod.WithNoArguments("rest", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                Arity a = (Arity)IokeObject.dataOf(on);
                if (a.argumentsDefinition != null)
                {
                    string name = a.argumentsDefinition.RestName;
                    if (name == null)
                    {
                        return(method.runtime.nil);
                    }
                    else
                    {
                        return(method.runtime.GetSymbol(name));
                    }
                }
                else
                {
                    return(method.runtime.nil);
                }
            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the text representation of this arity",
                                                           new TypeCheckingNativeMethod.WithNoArguments("asText", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                Arity a = (Arity)IokeObject.dataOf(on);
                if (a.taking == Taking.Everything)
                {
                    return(method.runtime.NewText("..."));
                }
                else if (a.taking == Taking.Nothing)
                {
                    return(method.runtime.NewText(""));
                }
                return(method.runtime.NewText(a.argumentsDefinition.GetCode(false)));
            })));
        }
示例#10
0
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "IO";

            obj.RegisterMethod(runtime.NewNativeMethod("Prints a text representation of the argument and a newline to the current IO object",
                                                       new TypeCheckingNativeMethod("println",
                                                                                    TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Io)
                                                                                    .WithOptionalPositional("object", "nil")
                                                                                    .Arguments,
                                                                                    (self, on, args, keywords, context, message) => {
                try {
                    if (args.Count > 0)
                    {
                        IokeIO.GetWriter(on).Write(Interpreter.Send(context.runtime.asText, context, args[0]).ToString());
                    }

                    IokeIO.GetWriter(on).Write("\n");
                    IokeIO.GetWriter(on).Flush();
                } catch (IOException e) {
                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                 message,
                                                                                 context,
                                                                                 "Error",
                                                                                 "IO"), context).Mimic(message, context);
                    condition.SetCell("message", message);
                    condition.SetCell("context", context);
                    condition.SetCell("receiver", on);
                    condition.SetCell("exceptionMessage", runtime.NewText(e.Message));
                    var st = new System.Diagnostics.StackTrace(e);
                    var ob = new SaneArrayList();
                    foreach (var frame in st.GetFrames())
                    {
                        ob.Add(runtime.NewText(frame.ToString()));
                    }
                    condition.SetCell("exceptionStackTrace", runtime.NewList(ob));

                    runtime.WithReturningRestart("ignore", context, () => { runtime.ErrorCondition(condition); });
                }

                return(context.runtime.nil);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Prints a text representation of the argument to the current IO object",
                                                       new TypeCheckingNativeMethod("print",
                                                                                    TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Io)
                                                                                    .WithRequiredPositional("object")
                                                                                    .Arguments,
                                                                                    (self, on, args, keywords, context, message) => {
                try {
                    IokeIO.GetWriter(on).Write(Interpreter.Send(context.runtime.asText, context, args[0]).ToString());
                    IokeIO.GetWriter(on).Flush();
                } catch (IOException e) {
                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                 message,
                                                                                 context,
                                                                                 "Error",
                                                                                 "IO"), context).Mimic(message, context);
                    condition.SetCell("message", message);
                    condition.SetCell("context", context);
                    condition.SetCell("receiver", on);
                    condition.SetCell("exceptionMessage", runtime.NewText(e.Message));
                    var st = new System.Diagnostics.StackTrace(e);
                    var ob = new SaneArrayList();
                    foreach (var frame in st.GetFrames())
                    {
                        ob.Add(runtime.NewText(frame.ToString()));
                    }
                    condition.SetCell("exceptionStackTrace", runtime.NewList(ob));

                    runtime.WithReturningRestart("ignore", context, () => { runtime.ErrorCondition(condition); });
                }

                return(context.runtime.nil);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("tries to read as much as possible and return a message chain representing what's been read",
                                                       new TypeCheckingNativeMethod.WithNoArguments("read", obj,
                                                                                                    (self, on, args, keywords, context, message) => {
                try {
                    string line = IokeIO.GetReader(on).ReadLine();
                    return(Message.NewFromStream(context.runtime, new StringReader(line), message, context));
                } catch (IOException e) {
                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                 message,
                                                                                 context,
                                                                                 "Error",
                                                                                 "IO"), context).Mimic(message, context);
                    condition.SetCell("message", message);
                    condition.SetCell("context", context);
                    condition.SetCell("receiver", on);
                    condition.SetCell("exceptionMessage", runtime.NewText(e.Message));
                    var st = new System.Diagnostics.StackTrace(e);
                    var ob = new SaneArrayList();
                    foreach (var frame in st.GetFrames())
                    {
                        ob.Add(runtime.NewText(frame.ToString()));
                    }
                    condition.SetCell("exceptionStackTrace", runtime.NewList(ob));

                    runtime.WithReturningRestart("ignore", context, () => { runtime.ErrorCondition(condition); });
                }

                return(context.runtime.nil);
            })));
        }
示例#11
0
文件: Hook.cs 项目: tspring/ioke
        public static void Init(Runtime runtime)
        {
            IokeObject obj = new IokeObject(runtime, "A hook allow you to observe what happens to a specific object. All hooks have Hook in their mimic chain.");

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

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one or more arguments to hook into and returns a new Hook connected to them.",
                                                       new TypeCheckingNativeMethod("into", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("firstConnected")
                                                                                    .WithRest("restConnected")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                IokeObject hook = obj.AllocateCopy(context, message);
                hook.MimicsWithoutCheck(obj);

                IList objs = new SaneArrayList();
                foreach (object o in args)
                {
                    objs.Add(IokeObject.As(o, context));
                }
                Hook h    = new Hook(objs);
                hook.Data = h;
                h.Rewire(hook);
                return(hook);
            })));


            obj.RegisterMethod(runtime.NewNativeMethod("returns the objects this hook is connected to",
                                                       new TypeCheckingNativeMethod.WithNoArguments("connectedObjects", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                Hook h  = (Hook)IokeObject.dataOf(on);
                IList l = new SaneArrayList(h.connected);
                return(method.runtime.NewList(l));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one argument and will add that to the list of connected objects",
                                                       new TypeCheckingNativeMethod("hook!", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("objectToHookInto")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                Hook h = (Hook)IokeObject.dataOf(on);
                h.connected.Add(IokeObject.As(args[0], context));
                h.Rewire(IokeObject.As(on, context));
                return(on);
            })));
        }
示例#12
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])));
            })));
        }
示例#13
0
文件: Decimal.cs 项目: tspring/ioke
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind        = "Number Decimal";
            runtime.Decimal = obj;

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

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

            obj.RegisterMethod(runtime.NewNativeMethod("returns the square root of the receiver. this should return the same result as calling ** with 0.5",
                                                       new TypeCheckingNativeMethod.WithNoArguments("sqrt", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                BigDecimal value = ((Decimal)IokeObject.dataOf(on)).value;

                if (value.CompareTo(BigDecimal.ZERO) < 1)
                {
                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(context.runtime.Condition,
                                                                                 message,
                                                                                 context,
                                                                                 "Error",
                                                                                 "Arithmetic"), context).Mimic(message, context);
                    condition.SetCell("message", message);
                    condition.SetCell("context", context);
                    condition.SetCell("receiver", on);

                    context.runtime.ErrorCondition(condition);
                }

                return(runtime.NewDecimal(new BigSquareRoot().Get(value)));
            })));

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

            obj.RegisterMethod(obj.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(Decimal.GetInspect(on)));
            })));

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

            obj.RegisterMethod(runtime.NewNativeMethod("compares this number against the argument, true if this number is the same, otherwise false",
                                                       new TypeCheckingNativeMethod("==", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object arg = args[0];
                if (IokeObject.dataOf(arg) is Number)
                {
                    return((Decimal.GetValue(on).CompareTo(Number.GetValue(arg).AsBigDecimal()) == 0) ? context.runtime.True : context.runtime.False);
                }
                else if (IokeObject.dataOf(arg) is Decimal)
                {
                    return((Decimal.GetValue(on).CompareTo(Decimal.GetValue(arg)) == 0) ? context.runtime.True : context.runtime.False);
                }
                else
                {
                    return(context.runtime.False);
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("compares this number against the argument, returning -1, 0 or 1 based on which one is larger. if the argument is a rational, it will be converted into a form suitable for comparing against a decimal, and then compared. if the argument is neither a Rational nor a Decimal, it tries to call asDecimal, and if that doesn't work it returns nil.",
                                                       new TypeCheckingNativeMethod("<=>", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object arg    = args[0];
                IokeData data = IokeObject.dataOf(arg);

                if (data is Number)
                {
                    return(context.runtime.NewNumber(Decimal.GetValue(on).CompareTo(Number.GetValue(arg).AsBigDecimal())));
                }
                else
                {
                    if (!(data is Decimal))
                    {
                        arg = IokeObject.ConvertToDecimal(arg, message, context, false);
                        if (!(IokeObject.dataOf(arg) is Decimal))
                        {
                            // Can't compare, so bail out
                            return(context.runtime.nil);
                        }
                    }

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

                    return(context.runtime.NewNumber(Decimal.GetValue(on).CompareTo(Decimal.GetValue(arg))));
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the difference between this number and the argument. if the argument is a rational, it will be converted into a form suitable for subtracting against a decimal, and then subtracted. if the argument is neither a Rational nor a Decimal, it tries to call asDecimal, and if that fails it signals a condition.",
                                                       new TypeCheckingNativeMethod("-", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("subtrahend")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object arg = args[0];

                IokeData data = IokeObject.dataOf(arg);

                if (data is Number)
                {
                    return(context.runtime.NewDecimal(Decimal.GetValue(on).subtract(Number.GetValue(arg).AsBigDecimal())));
                }
                else
                {
                    if (!(data is Decimal))
                    {
                        arg = IokeObject.ConvertToDecimal(arg, message, context, true);
                    }

                    return(context.runtime.NewDecimal(Decimal.GetValue(on).subtract(Decimal.GetValue(arg))));
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the sum of this number and the argument. if the argument is a rational, it will be converted into a form suitable for addition against a decimal, and then added. if the argument is neither a Rational nor a Decimal, it tries to call asDecimal, and if that fails it signals a condition.",
                                                       new TypeCheckingNativeMethod("+", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("addend")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object arg    = args[0];
                IokeData data = IokeObject.dataOf(arg);

                if (data is Number)
                {
                    return(context.runtime.NewDecimal(Decimal.GetValue(on).add(Number.GetValue(arg).AsBigDecimal())));
                }
                else
                {
                    if (!(data is Decimal))
                    {
                        arg = IokeObject.ConvertToDecimal(arg, message, context, true);
                    }

                    return(context.runtime.NewDecimal(Decimal.GetValue(on).add(Decimal.GetValue(arg))));
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the product of this number and the argument. if the argument is a rational, the receiver will be converted into a form suitable for multiplying against a decimal, and then multiplied. if the argument is neither a Rational nor a Decimal, it tries to call asDecimal, and if that fails it signals a condition.",
                                                       new TypeCheckingNativeMethod("*", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("multiplier")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object arg = args[0];

                IokeData data = IokeObject.dataOf(arg);

                if (data is Number)
                {
                    return(context.runtime.NewDecimal(Decimal.GetValue(on).multiply(Number.GetValue(arg).AsBigDecimal())));
                }
                else
                {
                    if (!(data is Decimal))
                    {
                        arg = IokeObject.ConvertToDecimal(arg, message, context, true);
                    }

                    return(context.runtime.NewDecimal(Decimal.GetValue(on).multiply(Decimal.GetValue(arg))));
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns this number to the power of the argument (which has to be an integer)",
                                                       new TypeCheckingNativeMethod("**", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("exponent")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object arg    = args[0];
                IokeData data = IokeObject.dataOf(arg);

                if (!(data is Number))
                {
                    arg = IokeObject.ConvertToRational(arg, message, context, true);
                }
                return(context.runtime.NewDecimal(Decimal.GetValue(on).pow(Number.IntValue(arg).intValue())));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the quotient of this number and the argument.",
                                                       new TypeCheckingNativeMethod("/", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("divisor")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object arg    = args[0];
                IokeData data = IokeObject.dataOf(arg);

                if (data is Number)
                {
                    return(context.runtime.NewDecimal(Decimal.GetValue(on).divide(Number.GetValue(arg).AsBigDecimal())));
                }
                else
                {
                    if (!(data is Decimal))
                    {
                        arg = IokeObject.ConvertToDecimal(arg, message, context, true);
                    }

                    while (Decimal.GetValue(arg).CompareTo(BigDecimal.ZERO) == 0)
                    {
                        IokeObject condition = IokeObject.As(IokeObject.GetCellChain(context.runtime.Condition,
                                                                                     message,
                                                                                     context,
                                                                                     "Error",
                                                                                     "Arithmetic",
                                                                                     "DivisionByZero"), context).Mimic(message, context);
                        condition.SetCell("message", message);
                        condition.SetCell("context", context);
                        condition.SetCell("receiver", on);

                        object[] newCell = new object[] { arg };

                        context.runtime.WithRestartReturningArguments(() => { context.runtime.ErrorCondition(condition); },
                                                                      context,
                                                                      new IokeObject.UseValue("newValue", newCell));
                        arg = newCell[0];
                    }

                    BigDecimal result = null;
                    try {
                        result = Decimal.GetValue(on).divide(Decimal.GetValue(arg), BigDecimal.ROUND_UNNECESSARY);
                    } catch (System.ArithmeticException) {
                        result = Decimal.GetValue(on).divide(Decimal.GetValue(arg), MathContext.DECIMAL128);
                    }
                    return(context.runtime.NewDecimal(result));
                }
            })));
        }
示例#14
0
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "Call";

            obj.RegisterMethod(runtime.NewNativeMethod("takes one evaluated text or symbol argument and resends the current message to that method/macro on the current receiver.",
                                                       new TypeCheckingNativeMethod("resendToMethod", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Call)
                                                                                    .WithRequiredPositional("cellName")
                                                                                    .Arguments,
                                                                                    (self, _on, args, keywords, context, _message) => {
                Call c       = (Call)IokeObject.dataOf(_on);
                string name  = Text.GetText(Interpreter.Send(runtime.asText, context, args[0]));
                IokeObject m = Message.Copy(c.message);
                Message.SetName(m, name);
                return(Interpreter.Send(m, c.surroundingContext, c.on));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes one evaluated object and resends the current message with that object as the new receiver",
                                                       new TypeCheckingNativeMethod("resendToReceiver", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Call)
                                                                                    .WithRequiredPositional("newReceiver")
                                                                                    .Arguments,
                                                                                    (self, _on, args, keywords, context, _message) => {
                Call c = (Call)IokeObject.dataOf(_on);
                return(Interpreter.Send(c.message, c.surroundingContext, args[0]));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a list of all the unevaluated arguments",
                                                       new TypeCheckingNativeMethod.WithNoArguments("arguments",
                                                                                                    runtime.Call,
                                                                                                    (method, _on, args, keywords, context, _message) => {
                return(context.runtime.NewList(((Call)IokeObject.dataOf(_on)).message.Arguments));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the ground of the place this call originated",
                                                       new TypeCheckingNativeMethod.WithNoArguments("ground",
                                                                                                    runtime.Call,
                                                                                                    (method, _on, args, keywords, context, _message) => {
                return(((Call)IokeObject.dataOf(_on)).surroundingContext);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the receiver of the call",
                                                       new TypeCheckingNativeMethod.WithNoArguments("receiver",
                                                                                                    runtime.Call,
                                                                                                    (method, _on, args, keywords, context, _message) => {
                return(((Call)IokeObject.dataOf(_on)).on);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the currently executing context",
                                                       new TypeCheckingNativeMethod.WithNoArguments("currentContext",
                                                                                                    runtime.Call,
                                                                                                    (method, _on, args, keywords, context, _message) => {
                return(((Call)IokeObject.dataOf(_on)).ctx);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the message that started this call",
                                                       new TypeCheckingNativeMethod.WithNoArguments("message",
                                                                                                    runtime.Call,
                                                                                                    (method, _on, args, keywords, context, _message) => {
                return(((Call)IokeObject.dataOf(_on)).message);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a list of the result of evaluating all the arguments to this call",
                                                       new TypeCheckingNativeMethod.WithNoArguments("evaluatedArguments",
                                                                                                    runtime.Call,
                                                                                                    (method, _on, args, keywords, context, _message) => {
                IokeObject msg = ((Call)IokeObject.dataOf(_on)).message;
                return(context.runtime.NewList(Interpreter.GetEvaluatedArguments(msg, ((Call)IokeObject.dataOf(_on)).surroundingContext)));
            })));


            obj.RegisterMethod(runtime.NewNativeMethod("uhm. this is a strange one. really.",
                                                       new TypeCheckingNativeMethod("resendToValue", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Call)
                                                                                    .WithRequiredPositional("value")
                                                                                    .WithOptionalPositional("newSelf", "nil")
                                                                                    .Arguments,
                                                                                    (method, _on, args, keywords, context, _message) => {
                Call c      = (Call)IokeObject.dataOf(_on);
                object self = c.on;
                if (args.Count > 1)
                {
                    self = args[1];
                }

                return(Interpreter.GetOrActivate(args[0], c.surroundingContext, c.message, self));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("uhm. this one isn't too bad.",
                                                       new TypeCheckingNativeMethod("activateValue", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Call)
                                                                                    .WithRequiredPositional("value")
                                                                                    .WithOptionalPositional("newSelf", "nil")
                                                                                    .WithKeywordRest("valuesToAdd")
                                                                                    .Arguments,
                                                                                    (method, _on, args, keys, context, _message) => {
                Call c      = (Call)IokeObject.dataOf(_on);
                object self = c.on;
                if (args.Count > 1)
                {
                    self = args[1];
                }

                return(Interpreter.ActivateWithData(IokeObject.As(args[0], context), c.surroundingContext, c.message, self, keys));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("I really ought to write documentation for these methods, but I don't know how to describe what they do.",
                                                       new TypeCheckingNativeMethod("activateValueWithCachedArguments", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Call)
                                                                                    .WithRequiredPositional("value")
                                                                                    .WithOptionalPositional("newSelf", "nil")
                                                                                    .WithKeywordRest("valuesToAdd")
                                                                                    .Arguments,
                                                                                    (method, _on, args, keys, context, _message) => {
                Call c      = (Call)IokeObject.dataOf(_on);
                object self = c.on;
                if (args.Count > 1)
                {
                    self = args[1];
                }

                return(Interpreter.ActivateWithCallAndData(IokeObject.As(args[0], context), c.surroundingContext, c.message, self, _on, keys));
            })));
        }
示例#15
0
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "Regexp Match";

            obj.RegisterMethod(runtime.NewNativeMethod("Returns the target that this match was created against",
                                                       new TypeCheckingNativeMethod.WithNoArguments("target", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(GetTarget(on));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a list of all the named groups in the regular expression used to create this match",
                                                       new TypeCheckingNativeMethod.WithNoArguments("names", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                var names    = Regexp.GetRegexp(GetRegexp(on)).GroupNames;
                var theNames = new SaneArrayList();
                foreach (object name in names)
                {
                    theNames.Add(context.runtime.GetSymbol(((string)name)));
                }
                return(context.runtime.NewList(theNames));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the part of the target before the text that matched",
                                                       new TypeCheckingNativeMethod.WithNoArguments("beforeMatch", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(context.runtime.NewText(GetMatchResult(on).Prefix));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the part of the target after the text that matched",
                                                       new TypeCheckingNativeMethod.WithNoArguments("afterMatch", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(context.runtime.NewText(GetMatchResult(on).Suffix));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns the text that matched",
                                                       new TypeCheckingNativeMethod.WithNoArguments("match", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(context.runtime.NewText(GetMatchResult(on).Group(0)));
            })));

            obj.AliasMethod("match", "asText", null, null);

            obj.RegisterMethod(runtime.NewNativeMethod("returns the number of groups available in this match",
                                                       new TypeCheckingNativeMethod.WithNoArguments("length", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(context.runtime.NewNumber(GetMatchResult(on).GroupCount));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a list of all groups captured in this match. if a group is not matched it will be nil in the list. the actual match text is not included in this list.",
                                                       new TypeCheckingNativeMethod.WithNoArguments("captures", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                var groups     = new SaneArrayList();
                MatchResult mr = GetMatchResult(on);
                int len        = mr.GroupCount;
                for (int i = 1; i < len; i++)
                {
                    if (mr.IsCaptured(i))
                    {
                        groups.Add(context.runtime.NewText(mr.Group(i)));
                    }
                    else
                    {
                        groups.Add(context.runtime.nil);
                    }
                }

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

            obj.RegisterMethod(runtime.NewNativeMethod("returns a list of all groups captured in this match. if a group is not matched it will be nil in the list. the actual match text is the first element in the list.",
                                                       new TypeCheckingNativeMethod.WithNoArguments("asList", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                var groups     = new SaneArrayList();
                MatchResult mr = GetMatchResult(on);
                int len        = mr.GroupCount;
                for (int i = 0; i < len; i++)
                {
                    if (mr.IsCaptured(i))
                    {
                        groups.Add(context.runtime.NewText(mr.Group(i)));
                    }
                    else
                    {
                        groups.Add(context.runtime.nil);
                    }
                }

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

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one optional argument that should be either a number or a symbol. this should be the name or index of a group to return the start index for. if no index is supplied, 0 is the default. if the group in question wasn't matched, returns -1.",
                                                       new TypeCheckingNativeMethod("start", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithOptionalPositional("index", "0")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                int index = 0;

                if (args.Count > 0)
                {
                    object arg = args[0];
                    if (IokeObject.dataOf(arg) is Number)
                    {
                        index = Number.ExtractInt(arg, message, context);
                    }
                    else
                    {
                        string namedIndex = Text.GetText(Interpreter.Send(context.runtime.asText, context, arg));
                        int ix            = -1;
                        try {
                            ix = Regexp.GetRegexp(GetRegexp(on)).GroupId(namedIndex);
                        } catch (Exception) {
                            return(context.runtime.NewNumber(-1));
                        }
                        index = ix;
                    }
                }
                MatchResult mr = GetMatchResult(on);
                if (index < mr.GroupCount && mr.IsCaptured(index))
                {
                    return(context.runtime.NewNumber(mr.GetStart(index)));
                }
                else
                {
                    return(context.runtime.NewNumber(-1));
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one optional argument that should be either a number or a symbol. this should be the name or index of a group to return the end index for. if no index is supplied, 0 is the default. if the group in question wasn't matched, returns -1.",
                                                       new TypeCheckingNativeMethod("end", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithOptionalPositional("index", "0")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                int index = 0;

                if (args.Count > 0)
                {
                    object arg = args[0];
                    if (IokeObject.dataOf(arg) is Number)
                    {
                        index = Number.ExtractInt(arg, message, context);
                    }
                    else
                    {
                        string namedIndex = Text.GetText(Interpreter.Send(context.runtime.asText, context, arg));
                        int ix            = -1;
                        try {
                            ix = Regexp.GetRegexp(GetRegexp(on)).GroupId(namedIndex);
                        } catch (Exception) {
                            return(context.runtime.NewNumber(-1));
                        }
                        index = ix;
                    }
                }
                MatchResult mr = GetMatchResult(on);
                if (index < mr.GroupCount && mr.IsCaptured(index))
                {
                    return(context.runtime.NewNumber(mr.GetEnd(index)));
                }
                else
                {
                    return(context.runtime.NewNumber(-1));
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one optional argument that should be either a number or a symbol. this should be the name or index of a group to return the start and end index for. if no index is supplied, 0 is the default. if the group in question wasn't matched, returns nil, otherwise a pair of the start and end indices.",
                                                       new TypeCheckingNativeMethod("offset", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithOptionalPositional("index", "0")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                int index = 0;

                if (args.Count > 0)
                {
                    object arg = args[0];
                    if (IokeObject.dataOf(arg) is Number)
                    {
                        index = Number.ExtractInt(arg, message, context);
                    }
                    else
                    {
                        string namedIndex = Text.GetText(Interpreter.Send(context.runtime.asText, context, arg));
                        int ix            = -1;
                        try {
                            ix = Regexp.GetRegexp(GetRegexp(on)).GroupId(namedIndex);
                        } catch (Exception) {
                            return(context.runtime.nil);
                        }
                        index = ix;
                    }
                }
                MatchResult mr = GetMatchResult(on);
                if (index < mr.GroupCount && mr.IsCaptured(index))
                {
                    return(context.runtime.NewPair(context.runtime.NewNumber(mr.GetStart(index)), context.runtime.NewNumber(mr.GetEnd(index))));
                }
                else
                {
                    return(context.runtime.nil);
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one indexing argument that should be either a number, a range, a text or a symbol. if it's a number or a range of numbers, these will specify the index of the capture to return. 0 is the whole match. negative indices are interpreted in the usual way. if the range is out of range it will only use as many groups as there are. if it's a text or a sym it will be interpreted as a the name of a named group to return. if an index isn't correct or wasn't matched, it returns nil in those places.",
                                                       new TypeCheckingNativeMethod("[]", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("index")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object arg = args[0];

                MatchResult mr = GetMatchResult(on);

                if ((IokeObject.dataOf(arg) is Symbol) || (IokeObject.dataOf(arg) is Text))
                {
                    string namedIndex = Text.GetText(Interpreter.Send(context.runtime.asText, context, arg));
                    int ix            = -1;
                    try {
                        ix = Regexp.GetRegexp(GetRegexp(on)).GroupId(namedIndex);
                    } catch (Exception) {
                        return(context.runtime.nil);
                    }
                    if (!mr.IsCaptured(ix))
                    {
                        return(context.runtime.nil);
                    }
                    return(context.runtime.NewText(mr.Group(ix)));
                }
                else
                {
                    int size = mr.GroupCount;

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

                        if (first < 0)
                        {
                            return(context.runtime.NewList(new SaneArrayList()));
                        }

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


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

                        if (last < 0)
                        {
                            return(context.runtime.NewList(new SaneArrayList()));
                        }

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

                        if (first > last || (!inclusive && first == last))
                        {
                            return(context.runtime.NewList(new SaneArrayList()));
                        }

                        if (!inclusive)
                        {
                            last--;
                        }

                        var result = new SaneArrayList();
                        for (int i = first; i < last + 1; i++)
                        {
                            if (!mr.IsCaptured(i))
                            {
                                result.Add(context.runtime.nil);
                            }
                            else
                            {
                                result.Add(context.runtime.NewText(mr.Group(i)));
                            }
                        }

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

                    if (!(IokeObject.dataOf(arg) is Number))
                    {
                        arg = IokeObject.ConvertToNumber(arg, message, context);
                    }
                    int index = ((Number)IokeObject.dataOf(arg)).AsNativeInteger();
                    if (index < 0)
                    {
                        index = size + index;
                    }

                    if (index >= 0 && index < size && mr.IsCaptured(index))
                    {
                        return(context.runtime.NewText(mr.Group(index)));
                    }
                    else
                    {
                        return(context.runtime.nil);
                    }
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("will get the named group corresponding to the name of the message, or nil if the named group hasn't been matched. will signal a condition if no such group is defined.",
                                                       new TypeCheckingNativeMethod("pass", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                MatchResult mr = GetMatchResult(on);
                string name    = Message.GetName(message);

                int ix = -1;
                try {
                    ix = Regexp.GetRegexp(GetRegexp(on)).GroupId(name);
                } catch (Exception) {
                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(message.runtime.Condition,
                                                                                 message,
                                                                                 context,
                                                                                 "Error",
                                                                                 "NoSuchCell"), context).Mimic(message, context);
                    condition.SetCell("message", message);
                    condition.SetCell("context", context);
                    condition.SetCell("receiver", on);
                    condition.SetCell("cellName", message.runtime.GetSymbol(name));

                    message.runtime.WithReturningRestart("ignore", context, () => { condition.runtime.ErrorCondition(condition); });
                    return(context.runtime.nil);
                }

                if (mr.IsCaptured(ix))
                {
                    return(context.runtime.NewText(mr.Group(ix)));
                }
                else
                {
                    return(context.runtime.nil);
                }
            })));
        }
示例#16
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]);
            })));
        }
示例#17
0
 public WithNoArguments(string name, object mimic, ArgsActivate activate) : base(name, TypeCheckingArgumentsDefinition.EmptyButReceiverMustMimic(mimic), activate)
 {
 }
示例#18
0
文件: Tuple.cs 项目: tspring/ioke
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

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


            obj.RegisterMethod(runtime.NewNativeMethod("will modify the tuple, initializing it to contain the specified arguments",
                                                       new TypeCheckingNativeMethod("private:initializeWith", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Tuple)
                                                                                    .WithRest("values")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                IokeObject.As(on, context).Data = new Tuple(((ArrayList)args).ToArray());
                return(on);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a new method that can be used to access an element of a tuple based on the index",
                                                       new TypeCheckingNativeMethod("private:accessor", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Tuple)
                                                                                    .WithRequiredPositional("index")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                int index = Number.ExtractInt(args[0], message, context);
                return(runtime.NewNativeMethod("Returns the object at index " + index + " in the receiving tuple",
                                               new TypeCheckingNativeMethod.WithNoArguments("_" + index, runtime.Tuple,
                                                                                            (method2, on2, args2, keywords2, context2, message2) => {
                    return ((Tuple)IokeObject.dataOf(on2)).elements[index];
                })));
            })));


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

                bool notResult = false;
                if ((other is IokeObject) &&
                    (IokeObject.dataOf(other) is Tuple))
                {
                    var d2  = ((Tuple)IokeObject.dataOf(other)).elements;
                    int len = d.Length;
                    if (len == d2.Length)
                    {
                        for (int i = 0; i < len; i++)
                        {
                            if (!d[i].Equals(d2[i]))
                            {
                                notResult = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        notResult = true;
                    }
                }
                else
                {
                    notResult = true;
                }

                return(!notResult ? context.runtime.True : context.runtime.False);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Compares this object against the argument. The comparison is only based on the elements inside the tuple, which are in turn compared using <=>.",
                                                       new TypeCheckingNativeMethod("<=>", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(obj)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                object arg = args[0];
                var one    = ((Tuple)IokeObject.dataOf(on)).elements;
                var two    = ((Tuple)IokeObject.dataOf(arg)).elements;

                int len = System.Math.Min(one.Length, two.Length);
                SpaceshipComparator sc = new SpaceshipComparator(context, message);

                for (int i = 0; i < len; i++)
                {
                    int v = sc.Compare(one[i], two[i]);
                    if (v != 0)
                    {
                        return(context.runtime.NewNumber(v));
                    }
                }

                len = one.Length - two.Length;

                if (len == 0)
                {
                    return(context.runtime.NewNumber(0));
                }
                if (len > 0)
                {
                    return(context.runtime.NewNumber(1));
                }
                return(context.runtime.NewNumber(-1));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns the arity of this tuple",
                                                       new TypeCheckingNativeMethod.WithNoArguments("arity", runtime.Tuple,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(context.runtime.NewNumber(((Tuple)IokeObject.dataOf(on)).elements.Length));
            })));
            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(Tuple.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(Tuple.GetNotice(on)));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Returns a list representation of this tuple",
                                                       new TypeCheckingNativeMethod.WithNoArguments("asList", obj,
                                                                                                    (method, on, args, keywords, context, message) => {
                return(method.runtime.NewList(new SaneArrayList(((Tuple)IokeObject.dataOf(on)).elements)));
            })));
        }
示例#19
0
 public TypeCheckingNativeMethod(string name, TypeCheckingArgumentsDefinition arguments, ArgsActivate activate) : base(name, arguments, TypeCheckingRawActivate, activate)
 {
 }
示例#20
0
        public static void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "DefaultBehavior Reflection";

            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("mimics?", DefaultArgumentsDefinition.builder()
                                                                        .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[0], context);
                if (IokeObject.IsMimic(on, 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("become!", DefaultArgumentsDefinition.builder()
                                                                        .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(on, context);
                IokeObject other = IokeObject.As(args[0], context);

                if (on == context.runtime.nil || on == context.runtime.True || on == 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", on);
                    context.runtime.ErrorCondition(condition);
                }

                me.Become(other, message, context);

                return(on);
            })));

            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 NativeMethod.WithNoArguments("uniqueHexId",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                return(context.runtime.NewText("0x" + System.Convert.ToString(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(IokeObject.As(on, context).body), 16).ToUpper()));
            })));

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

            obj.RegisterMethod(runtime.NewNativeMethod("returns true if the evaluated argument is the same reference as the receiver, false otherwise.",
                                                       new NativeMethod("same?", 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>());
                return(IokeObject.Same(on, args[0]) ? 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("send", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("messageName")
                                                                        .WithRestUnevaluated("arguments")
                                                                        .WithKeywordRestUnevaluated("keywordArguments")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                object _name = Interpreter.GetEvaluatedArgument(message, 0, context);
                string name  = Text.GetText(Interpreter.Send(runtime.asText, context, _name));

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

            obj.RegisterMethod(runtime.NewNativeMethod("returns false 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) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                return(!IokeObject.Equals(on, Interpreter.GetEvaluatedArgument(message, 0, context)) ? context.runtime.True : context.runtime.False);
            })));

            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("kind?", TypeCheckingArgumentsDefinition.builder()
                                                                                    .WithRequiredPositional("name").WhichMustMimic(runtime.Text)
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                string kind = Text.GetText(args[0]);
                return(IokeObject.IsKind(on, 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("is?", DefaultArgumentsDefinition.builder()
                                                                        .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[0], context);
                return(IokeObject.IsMimic(on, 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 NativeMethod.WithNoArguments("mimics",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                var l = new SaneArrayList();
                foreach (object x in IokeObject.GetMimics(on, context))
                {
                    l.Add(x);
                }
                return(context.runtime.NewList(l));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("removes all mimics on the receiver, and returns the receiver",
                                                       new NativeMethod.WithNoArguments("removeAllMimics!",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                IokeObject.RemoveAllMimics(on, message, context);
                return(on);
            })));

            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("removeMimic!", DefaultArgumentsDefinition.builder()
                                                                        .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(on, args[0], message, context);
                return(on);
            })));

            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("mimic!", DefaultArgumentsDefinition.builder()
                                                                        .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[0], context);
                IokeObject.As(on, context).Mimics(newMimic, message, context);
                return(on);
            })));

            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("prependMimic!", DefaultArgumentsDefinition.builder()
                                                                        .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[0], context);
                IokeObject.As(on, context).Mimics(0, newMimic, message, context);
                return(on);
            })));

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

            obj.RegisterMethod(runtime.NewNativeMethod("ensures that the receiver is frozen",
                                                       new NativeMethod.WithNoArguments("freeze!",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                IokeObject.Freeze(on);
                return(on);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("ensures that the receiver is not frozen",
                                                       new NativeMethod.WithNoArguments("thaw!",
                                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, new SaneArrayList(), new SaneDictionary <string, object>());
                IokeObject.Thaw(on);
                return(on);
            })));
        }
示例#21
0
 TypeCheckingNativeMethod(string name, TypeCheckingArgumentsDefinition arguments, RawActivate activate) : base(name, arguments, activate, null)
 {
 }
示例#22
0
 TypeCheckingNativeMethod(string name, TypeCheckingArgumentsDefinition arguments, RawActivate activate)
     : base(name, arguments, activate, null)
 {
 }
示例#23
0
文件: Text.cs 项目: tspring/ioke
        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))));
            })));
        }