Esempio n. 1
0
        public static void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "DefaultBehavior Literals";

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one evaluated argument that is expected to be a Text, and returns the symbol corresponding to that text",
                                                       new NativeMethod(":", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("symbolText")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());

                string sym = Text.GetText(Interpreter.Send(runtime.asText, context, args[0]));
                return(runtime.GetSymbol(sym));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("Takes one evaluated argument and returns a new Pair of the receiver and the argument",
                                                       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(context.runtime.NewPair(on, args[0]));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("returns a new message with the name given as argument to this method.",
                                                       new NativeMethod("message", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("name")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());

                object o = args[0];

                string name = null;
                if (IokeObject.dataOf(o) is Text)
                {
                    name = Text.GetText(o);
                }
                else
                {
                    name = Text.GetText(Interpreter.Send(context.runtime.asText, context, o));
                }

                Message m      = new Message(context.runtime, name);
                IokeObject ret = context.runtime.CreateMessage(m);
                if (".".Equals(name))
                {
                    Message.SetIsTerminator(ret, true);
                }
                Message.CopySourceLocation(message, ret);
                return(ret);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("creates a new Set from the result of evaluating all arguments provided.",
                                                       new NativeMethod("set", DefaultArgumentsDefinition.builder()
                                                                        .WithRest("elements")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                var args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                return(context.runtime.NewSet(args));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("creates a new Dict from the arguments provided. these arguments can be two different things - either a keyword argument, or a pair. if it's a keyword argument, the entry added to the dict for it will be a symbol with the name from the keyword, without the ending colon. if it's not a keyword, it is expected to be an evaluated pair, where the first part of the pair is the key, and the second part is the value.",
                                                       new NativeMethod("dict", DefaultArgumentsDefinition.builder()
                                                                        .WithRest("pairs")
                                                                        .WithKeywordRest("keywordPairs")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                var arguments = message.Arguments;
                var moo       = new SaneHashtable(arguments.Count);

                foreach (object o in arguments)
                {
                    object key, value;
                    if (Message.IsKeyword(o))
                    {
                        string str = Message.GetName(o);
                        key        = context.runtime.GetSymbol(str.Substring(0, str.Length - 1));
                        if (Message.GetNext(o) != null)
                        {
                            value = Interpreter.GetEvaluatedArgument(Message.GetNext(o), context);
                        }
                        else
                        {
                            value = context.runtime.nil;
                        }
                    }
                    else
                    {
                        object result = Interpreter.GetEvaluatedArgument(o, context);
                        if ((result is IokeObject) && (IokeObject.dataOf(result) is Pair))
                        {
                            key   = Pair.GetFirst(result);
                            value = Pair.GetSecond(result);
                        }
                        else
                        {
                            key   = result;
                            value = context.runtime.nil;
                        }
                    }

                    moo[key] = value;
                }

                return(context.runtime.NewDict(moo));
            })));
        }
Esempio n. 2
0
File: Dict.cs Progetto: 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);
            })));
        }
Esempio n. 3
0
File: Text.cs Progetto: tspring/ioke
        private static int FormatString(string format, int index, IokeObject message, IokeObject context, IList positionalArgs, StringBuilder result)
        {
            int           argIndex        = 0;
            int           formatIndex     = index;
            int           justify         = 0;
            bool          splat           = false;
            bool          splatPairs      = false;
            bool          negativeJustify = false;
            bool          doAgain         = false;
            int           formatLength    = format.Length;
            object        arg             = null;
            StringBuilder missingText     = new StringBuilder();
            object        seq             = null;
            IList         args            = null;

            while (formatIndex < formatLength)
            {
                char c = format[formatIndex++];
                switch (c)
                {
                case '%':
                    justify = 0;
                    missingText.Append(c);
                    do
                    {
                        doAgain = false;
                        if (formatIndex < formatLength)
                        {
                            c = format[formatIndex++];
                            missingText.Append(c);

                            switch (c)
                            {
                            case '*':
                                splat   = true;
                                doAgain = true;
                                break;

                            case ':':
                                splatPairs = true;
                                doAgain    = true;
                                break;

                            case ']':
                                return(formatIndex);

                            case '[':
                                arg = positionalArgs[argIndex++];
                                int endLoop = -1;

                                seq = Interpreter.Send(context.runtime.seqMessage, context, arg);

                                while (IokeObject.IsObjectTrue(Interpreter.Send(context.runtime.nextPMessage, context, seq)))
                                {
                                    object receiver = Interpreter.Send(context.runtime.nextMessage, context, seq);

                                    if (splat)
                                    {
                                        args = IokeList.GetList(receiver);
                                    }
                                    else if (splatPairs)
                                    {
                                        args = new SaneArrayList()
                                        {
                                            Pair.GetFirst(receiver), Pair.GetSecond(receiver)
                                        };
                                    }
                                    else
                                    {
                                        args = new SaneArrayList()
                                        {
                                            receiver
                                        };
                                    }

                                    int newVal = FormatString(format, formatIndex, message, context, args, result);
                                    endLoop = newVal;
                                }

                                splat      = false;
                                splatPairs = false;

                                if (endLoop == -1)
                                {
                                    int opened = 1;
                                    while (opened > 0 && formatIndex < formatLength)
                                    {
                                        char c2 = format[formatIndex++];
                                        if (c2 == '%' && formatIndex < formatLength)
                                        {
                                            c2 = format[formatIndex++];
                                            if (c2 == '[')
                                            {
                                                opened++;
                                            }
                                            else if (c2 == ']')
                                            {
                                                opened--;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    formatIndex = endLoop;
                                }
                                break;

                            case 's':
                                arg = positionalArgs[argIndex++];
                                object txt = IokeObject.TryConvertToText(arg, message, context);
                                if (txt == null)
                                {
                                    txt = Interpreter.Send(context.runtime.asText, context, arg);
                                }
                                string outTxt = Text.GetText(txt);

                                if (outTxt.Length < justify)
                                {
                                    int    missing = justify - outTxt.Length;
                                    char[] spaces  = new char[missing];
                                    for (int ixx = 0; ixx < spaces.Length; ixx++)
                                    {
                                        spaces[ixx] = ' ';
                                    }
                                    if (negativeJustify)
                                    {
                                        result.Append(outTxt);
                                        result.Append(spaces);
                                    }
                                    else
                                    {
                                        result.Append(spaces);
                                        result.Append(outTxt);
                                    }
                                }
                                else
                                {
                                    result.Append(outTxt);
                                }
                                break;

                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                justify *= 10;
                                justify += (c - '0');
                                doAgain  = true;
                                break;

                            case '-':
                                negativeJustify = !negativeJustify;
                                doAgain         = true;
                                break;

                            default:
                                result.Append(missingText);
                                missingText = new StringBuilder();
                                break;
                            }
                        }
                        else
                        {
                            result.Append(missingText);
                            missingText = new StringBuilder();
                        }
                    } while(doAgain);
                    break;

                default:
                    result.Append(c);
                    break;
                }
            }
            return(formatLength);
        }