示例#1
0
文件: Base.cs 项目: goking/ioke
        public static object CellNames(IokeObject context, IokeObject message, object on, bool includeMimics, object cutoff)
        {
            if(includeMimics) {
                var visited = IdentityHashTable.Create();
                var names = new SaneArrayList();
                var visitedNames = new SaneHashSet<object>();
                var undefined = new SaneHashSet<string>();
                Runtime runtime = context.runtime;
                var toVisit = new SaneArrayList();
                toVisit.Add(on);

                while(toVisit.Count > 0) {
                    IokeObject current = IokeObject.As(toVisit[0], context);
                    toVisit.RemoveAt(0);
                    if(!visited.Contains(current)) {
                        visited[current] = null;
                        if(cutoff != current) {
                            foreach(IokeObject o in current.GetMimics()) toVisit.Add(o);
                        }

                        Cell c = current.body.firstAdded;
                        while(c != null) {
                            string s = c.name;
                            if(!undefined.Contains(s)) {
                                if(c.value == runtime.nul) {
                                    undefined.Add(s);
                                } else {
                                    object x = runtime.GetSymbol(s);
                                    if(!visitedNames.Contains(x)) {
                                        visitedNames.Add(x);
                                        names.Add(x);
                                    }
                                }
                            }

                            c = c.orderedNext;
                        }
                    }
                }

                return runtime.NewList(names);
            } else {
                var names = new SaneArrayList();
                Runtime runtime = context.runtime;

                Cell c = IokeObject.As(on, context).body.firstAdded;
                while(c != null) {
                    string s = c.name;
                    if(c.value != runtime.nul) {
                        names.Add(runtime.GetSymbol(s));
                    }
                    c = c.orderedNext;
                }
                return runtime.NewList(names);
            }
        }
示例#2
0
文件: Base.cs 项目: fronx/ioke
        public static object CellNames(IokeObject context, IokeObject message, object on, bool includeMimics, object cutoff)
        {
            if(includeMimics) {
                var visited = IdentityHashTable.Create();
                var names = new SaneArrayList();
                var visitedNames = new SaneHashSet<object>();
                var undefined = new SaneHashSet<string>();
                Runtime runtime = context.runtime;
                var toVisit = new SaneArrayList();
                toVisit.Add(on);

                while(toVisit.Count > 0) {
                    IokeObject current = IokeObject.As(toVisit[0], context);
                    toVisit.RemoveAt(0);
                    if(!visited.Contains(current)) {
                        visited[current] = null;
                        if(cutoff != current) {
                            foreach(IokeObject o in current.GetMimics()) toVisit.Add(o);
                        }

                        var mso = current.Cells;

                        foreach(string s in mso.Keys) {
                            if(!undefined.Contains(s)) {
                                if(mso[s] == runtime.nul) {
                                    undefined.Add(s);
                                } else {
                                    object x = runtime.GetSymbol(s);
                                    if(!visitedNames.Contains(x)) {
                                        visitedNames.Add(x);
                                        names.Add(x);
                                    }
                                }
                            }
                        }
                    }
                }

                return runtime.NewList(names);
            } else {
                var mso = IokeObject.As(on, context).Cells;
                var names = new SaneArrayList();
                Runtime runtime = context.runtime;

                foreach(string s in mso.Keys) {
                    if(mso[s] != runtime.nul) {
                        names.Add(runtime.GetSymbol(s));
                    }
                }

                return runtime.NewList(names);
            }
        }
示例#3
0
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "Set";
            obj.Mimics(IokeObject.As(runtime.Mixins.GetCell(null, null, "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 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 ((Message)IokeObject.dataOf(runtime.seqMessage)).SendTo(runtime.seqMessage, context, on);
                                                                            }
                                                                            case 1: {
                                                                                IokeObject code = IokeObject.As(message.Arguments[0], context);

                                                                                foreach(object o in _set) {
                                                                                    ((Message)IokeObject.dataOf(code)).EvaluateCompleteWithReceiver(code, context, context.RealContext, o);
                                                                                }
                                                                                break;
                                                                            }
                                                                            case 2: {
                                                                                LexicalContext c = new LexicalContext(context.runtime, context, "Lexical activation context for Set#each", message, 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);
                                                                                    ((Message)IokeObject.dataOf(code)).EvaluateCompleteWithoutExplicitReceiver(code, c, c.RealContext);
                                                                                }
                                                                                break;
                                                                            }
                                                                            case 3: {
                                                                                LexicalContext c = new LexicalContext(context.runtime, context, "Lexical activation context for Set#each", message, 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++));
                                                                                    ((Message)IokeObject.dataOf(code)).EvaluateCompleteWithoutExplicitReceiver(code, c, c.RealContext);
                                                                                }
                                                                                break;
                                                                            }
                                                                            }

                                                                            return onAsSet;
                                                                        })));
        }
示例#4
0
        private void AssignArgumentValues(IokeObject locals, IokeObject context, IokeObject message, object on, IList argumentsWithoutKeywords, IDictionary<string, object> givenKeywords, int argCount)
        {
            Runtime runtime = context.runtime;

            var intersection = new SaneHashSet<string>(givenKeywords.Keys);
            foreach(string k in keywords) intersection.Remove(k);

            int ix = 0;
            for(int i=0, j=this.arguments.Count;i<j;i++) {
                Argument a = this.arguments[i];

                if(a is KeywordArgument) {
                    string nm = a.Name + ":";
                    object result = null;
                    if(givenKeywords.ContainsKey(nm)) {
                        object given = givenKeywords[nm];
                        result = given;
                        locals.SetCell(a.Name, result);
                    } else {
                        object defVal = ((KeywordArgument)a).DefaultValue;
                        if(!(defVal is string)) {
                            IokeObject m1 = IokeObject.As(defVal, context);
                            result = ((Message)IokeObject.dataOf(m1)).EvaluateCompleteWithoutExplicitReceiver(m1, locals, locals.RealContext);
                            locals.SetCell(a.Name, result);
                        }
                    }
                } else if((a is OptionalArgument) && ix>=argCount) {
                    object defVal = ((OptionalArgument)a).DefaultValue;
                    if(!(defVal is string)) {
                        IokeObject m2 = IokeObject.As(defVal, context);
                        locals.SetCell(a.Name, ((Message)IokeObject.dataOf(m2)).EvaluateCompleteWithoutExplicitReceiver(m2, locals, locals.RealContext));
                    }
                } else {
                    locals.SetCell(a.Name, argumentsWithoutKeywords[ix++]);
                }
            }

            if(krest != null) {
                var krests = new SaneHashtable();
                foreach(string s in intersection) {
                    object given = givenKeywords[s];
                    object result = given;
                    krests[runtime.GetSymbol(s.Substring(0, s.Length-1))] = result;
                }

                locals.SetCell(krest, runtime.NewDict(krests));
            }

            if(rest != null) {
                IList rests = new SaneArrayList();
                for(int j=argumentsWithoutKeywords.Count;ix<j;ix++) {
                    rests.Add(argumentsWithoutKeywords[ix]);
                }

                locals.SetCell(rest, runtime.NewList(rests));
            }
        }
示例#5
0
        public int GetEvaluatedArguments(IokeObject context, IokeObject message, object on, IList argumentsWithoutKeywords, IDictionary<string, object> givenKeywords)
        {
            Runtime runtime = context.runtime;
            IList arguments = message.Arguments;
            int argCount = 0;

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

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

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

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

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

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

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

            var intersection = new SaneHashSet<string>(givenKeywords.Keys);
            foreach(string k in keywords) intersection.Remove(k);

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

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

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

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

            return argCount;
        }
示例#6
0
文件: Runtime.cs 项目: goking/ioke
 public IokeObject NewSet(ICollection objs)
 {
     IokeObject obj = this.Set.AllocateCopy(null, null);
     obj.MimicsWithoutCheck(this.Set);
     var hh = new SaneHashSet<object>();
     foreach(object o in objs) hh.Add(o);
     obj.Data = new IokeSet(hh);
     return obj;
 }
示例#7
0
文件: Base.cs 项目: fronx/ioke
        public static object Cells(IokeObject context, IokeObject message, object on, bool includeMimics)
        {
            var cells = new SaneOrderedDictionary();
            Runtime runtime = context.runtime;

            if(includeMimics) {
                var visited = IdentityHashTable.Create();
                var undefined = new SaneHashSet<string>();
                var toVisit = new SaneArrayList();
                toVisit.Add(on);

                while(toVisit.Count > 0) {
                    IokeObject current = IokeObject.As(toVisit[0], context);
                    toVisit.RemoveAt(0);
                    if(!visited.Contains(current)) {
                        visited[current] = null;
                        foreach(IokeObject o in current.GetMimics()) toVisit.Add(o);
                        var mso = current.Cells;

                        foreach(string s in mso.Keys) {
                            if(!undefined.Contains(s)) {
                                object val = mso[s];
                                if(val == runtime.nul) {
                                    undefined.Add(s);
                                } else {
                                    object x = runtime.GetSymbol(s);
                                    if(!cells.Contains(x)) {
                                        cells[x] = val;
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                var mso = IokeObject.As(on, context).Cells;

                foreach(string s in mso.Keys) {
                    object val = mso[s];
                    if(val != runtime.nul) {
                        cells[runtime.GetSymbol(s)] = val;
                    }
                }
            }
            return runtime.NewDict(cells);
        }
示例#8
0
        public static object CellNames(IokeObject context, IokeObject message, object on, bool includeMimics, object cutoff)
        {
            if (includeMimics)
            {
                var     visited      = IdentityHashTable.Create();
                var     names        = new SaneArrayList();
                var     visitedNames = new SaneHashSet <object>();
                var     undefined    = new SaneHashSet <string>();
                Runtime runtime      = context.runtime;
                var     toVisit      = new SaneArrayList();
                toVisit.Add(on);

                while (toVisit.Count > 0)
                {
                    IokeObject current = IokeObject.As(toVisit[0], context);
                    toVisit.RemoveAt(0);
                    if (!visited.Contains(current))
                    {
                        visited[current] = null;
                        if (cutoff != current)
                        {
                            foreach (IokeObject o in current.GetMimics())
                            {
                                toVisit.Add(o);
                            }
                        }

                        Cell c = current.body.firstAdded;
                        while (c != null)
                        {
                            string s = c.name;
                            if (!undefined.Contains(s))
                            {
                                if (c.value == runtime.nul)
                                {
                                    undefined.Add(s);
                                }
                                else
                                {
                                    object x = runtime.GetSymbol(s);
                                    if (!visitedNames.Contains(x))
                                    {
                                        visitedNames.Add(x);
                                        names.Add(x);
                                    }
                                }
                            }

                            c = c.orderedNext;
                        }
                    }
                }

                return(runtime.NewList(names));
            }
            else
            {
                var     names   = new SaneArrayList();
                Runtime runtime = context.runtime;

                Cell c = IokeObject.As(on, context).body.firstAdded;
                while (c != null)
                {
                    string s = c.name;
                    if (c.value != runtime.nul)
                    {
                        names.Add(runtime.GetSymbol(s));
                    }
                    c = c.orderedNext;
                }
                return(runtime.NewList(names));
            }
        }