コード例 #1
0
ファイル: IokeObject.cs プロジェクト: tspring/ioke
        public IList <IokeObject> GetMimics()
        {
            var result = new SaneList <IokeObject>();

            switch (body.mimicCount)
            {
            case 0:
                break;

            case 1:
                result.Add(body.mimic);
                break;

            default:
                for (int i = 0; i < body.mimicCount; i++)
                {
                    result.Add(body.mimics[i]);
                }
                break;
            }
            return(result);
        }
コード例 #2
0
ファイル: Main.cs プロジェクト: vic/ioke-outdated
        public static void Main(string[] args)
        {
            string current = System.Reflection.Assembly.GetExecutingAssembly().Location;
            string iokeHome = new FileInfo(current).Directory.Parent.FullName;
            string iokeLib = Path.Combine(iokeHome, "lib");

            Runtime r = new Runtime(new FunctionalOperatorShufflerFactory());
            r.Init();

            IokeObject context = r.Ground;
            Message mx = new Message(r, ".", null, true);
            mx.Line = 0;
            mx.Position = 0;
            IokeObject message = r.CreateMessage(mx);

            string cwd = null;

            var scripts = new SaneList<string>();
            var loadDirs = new SaneList<string>();
            bool debug = false;

            try {
                int start = 0;
                bool done = false;
                bool readStdin = false;
                bool printedSomething = false;

                for(;!done && start<args.Length;start++) {
                    string arg = args[start];
                    if(arg.Length > 0) {
                        if(arg[0] != '-') {
                            done = true;
                            break;
                        } else {
                            if(arg.Equals("--")) {
                                done = true;
                            } else if(arg.Equals("-d")) {
                                debug = true;
                                r.Debug = true;
                            } else if(arg.StartsWith("-e")) {
                                if(arg.Length == 2) {
                                    scripts.Add(args[++start]);
                                } else {
                                    scripts.Add(arg.Substring(2));
                                }
                            } else if(arg.StartsWith("-I")) {
                                if(arg.Length == 2) {
                                    loadDirs.Add(args[++start]);
                                } else {
                                    loadDirs.Add(arg.Substring(2));
                                }
                            } else if(arg.Equals("-h") || arg.Equals("--help")) {
                                Console.Error.Write(HELP);
                                return;
                            } else if(arg.Equals("--version")) {
                                Console.Error.WriteLine(getVersion());
                                printedSomething = true;
                            } else if(arg.Equals("--copyright")) {
                                Console.Error.Write(COPYRIGHT);
                                printedSomething = true;
                            } else if(arg.Equals("-")) {
                                readStdin = true;
                            } else if(arg[1] == 'C') {
                                if(arg.Length == 2) {
                                    cwd = args[++start];
                                } else {
                                    cwd = arg.Substring(2);
                                }
                            } else {
                                IokeObject condition = IokeObject.As(IokeObject.GetCellChain(r.Condition,
                                                                                             message,
                                                                                             context,
                                                                                             "Error",
                                                                                             "CommandLine",
                                                                                             "DontUnderstandOption"), null).Mimic(message, context);
                                condition.SetCell("message", message);
                                condition.SetCell("context", context);
                                condition.SetCell("receiver", context);
                                condition.SetCell("option", r.NewText(arg));
                                r.ErrorCondition(condition);
                            }
                        }
                    }
                }

                if(cwd != null) {
                    r.CurrentWorkingDirectory = cwd;
                }

                ((IokeSystem)IokeObject.dataOf(r.System)).CurrentProgram = "-e";

                string lib = Environment.GetEnvironmentVariable("ioke.lib");
                if(lib == null) {
                    lib = iokeLib;
                }
                ((IokeSystem)IokeObject.dataOf(r.System)).AddLoadPath(lib + "/ioke");
                ((IokeSystem)IokeObject.dataOf(r.System)).AddLoadPath("lib/ioke");

                foreach(string ss in loadDirs) {
                    ((IokeSystem)IokeObject.dataOf(r.System)).AddLoadPath(ss);
                }

                foreach(string script in scripts) {
                    r.EvaluateStream("-e", new StringReader(script), message, context);
                }

                if(readStdin) {
                    ((IokeSystem)IokeObject.dataOf(r.System)).CurrentProgram = "<stdin>";
                    r.EvaluateStream("<stdin>", Console.In, message, context);
                }

                if(args.Length > start) {
                    if(args.Length > (start+1)) {
                        for(int i=start+1,j=args.Length; i<j; i++) {
                            r.AddArgument(args[i]);
                        }
                    }
                    string file = args[start];
                    if(file.StartsWith("\"")) {
                        file = file.Substring(1, file.Length-1);
                    }

                    if(file.Length > 1 && file[file.Length-1] == '"') {
                        file = file.Substring(0, file.Length-1);
                    }

                    ((IokeSystem)IokeObject.dataOf(r.System)).CurrentProgram = file;
                    r.EvaluateFile(file, message, context);
                } else {
                    if(!readStdin && scripts.Count == 0 && !printedSomething) {
                        r.EvaluateString("use(\"builtin/iik\"). IIk mainLoop", message, context);
                    }
                }

                r.TearDown();

            } catch(ControlFlow.Exit e) {
                int exitVal = e.ExitValue;
                try {
                    r.TearDown();
                } catch(ControlFlow.Exit e2) {
                    exitVal = e2.ExitValue;
                }
                Environment.Exit(exitVal);
            } catch(ControlFlow e) {
                string name = e.GetType().FullName;
                System.Console.Error.WriteLine("unexpected control flow: " + name.Substring(name.LastIndexOf(".") + 1).ToLower());
                if(debug) {
                    System.Console.Error.WriteLine(e);
                }
                Environment.Exit(1);
            }
        }
コード例 #3
0
        public static DefaultArgumentsDefinition CreateFrom(IList args, int start, int end, IokeObject message, object on, IokeObject context)
        {
            Runtime          runtime   = context.runtime;
            IList <Argument> arguments = new SaneList <Argument>();
            IList <string>   keywords  = new SaneList <string>();

            int    min         = 0;
            int    max         = 0;
            bool   hadOptional = false;
            string rest        = null;
            string krest       = null;

            foreach (object obj in ArrayList.Adapter(args).GetRange(start, end - start))
            {
                Message m     = (Message)IokeObject.dataOf(obj);
                string  mname = m.Name;
                if (!"+:".Equals(mname) && m.IsKeyword())
                {
                    string     name   = mname;
                    IokeObject dValue = context.runtime.nilMessage;
                    if (m.next != null)
                    {
                        dValue = m.next;
                    }
                    arguments.Add(new KeywordArgument(name.Substring(0, name.Length - 1), dValue));
                    keywords.Add(name);
                }
                else if (mname.Equals("+"))
                {
                    string name = Message.GetName(m.Arguments(null)[0]);
                    if (name.StartsWith(":"))
                    {
                        krest = name.Substring(1);
                    }
                    else
                    {
                        rest = name;
                        max  = -1;
                    }
                    hadOptional = true;
                }
                else if (mname.Equals("+:"))
                {
                    string name = m.next != null?Message.GetName(m.next) : Message.GetName(m.Arguments(null)[0]);

                    krest       = name;
                    hadOptional = true;
                }
                else if (m.next != null)
                {
                    string name = mname;
                    hadOptional = true;
                    if (max != -1)
                    {
                        max++;
                    }
                    arguments.Add(new OptionalArgument(name, m.next));
                }
                else
                {
                    if (hadOptional)
                    {
                        int index = IndexOf(args, obj) + start;

                        IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                     message,
                                                                                     context,
                                                                                     "Error",
                                                                                     "Invocation",
                                                                                     "ArgumentWithoutDefaultValue"), context).Mimic(message, context);
                        condition.SetCell("message", message);
                        condition.SetCell("context", context);
                        condition.SetCell("receiver", on);
                        condition.SetCell("argumentName", runtime.GetSymbol(m.Name));
                        condition.SetCell("index", runtime.NewNumber(index));

                        IList newValue = IokeList.GetList(runtime.WithRestartReturningArguments(() => { runtime.ErrorCondition(condition); },
                                                                                                context,
                                                                                                new NewArgumentGivingRestart("provideDefaultValue", "defaultValue"),
                                                                                                new Restart.DefaultValuesGivingRestart("substituteNilDefault", runtime.nil, 1)));
                        if (max != -1)
                        {
                            max++;
                        }

                        arguments.Add(new OptionalArgument(m.Name, runtime.CreateMessage(Message.Wrap(IokeObject.As(newValue[0], context)))));
                    }
                    else
                    {
                        min++;
                        max++;
                        arguments.Add(new Argument(IokeObject.As(obj, context).Name));
                    }
                }
            }

            return(new DefaultArgumentsDefinition(arguments, keywords, rest, krest, min, max, false));
        }
コード例 #4
0
ファイル: Message.cs プロジェクト: fronx/ioke
        public static IokeObject FromTree(Runtime runtime, ITree tree)
        {
            //             Console.Error.WriteLine(" fromTree(" + tree.ToStringTree() + ")");
            Message m = null;
            int argStart = 0;

            if(!tree.IsNil) {
                switch(tree.Type) {
                case iokeParser.RegexpLiteral: {
                    string s = tree.Text;
                    char first = s[0];
                    char second = s[1];
                    char last = s[s.Length-1];
                    if(first == '#' && last != '{') {
                        if(second == 'r') {
                            int lastIndex = s.LastIndexOf(']');
                            m = new Message(runtime, "internal:createRegexp", s.Substring(3, lastIndex-3));
                            m.arguments.Add(s.Substring(lastIndex+1));
                        } else {
                            int lastIndex = s.LastIndexOf('/');
                            m = new Message(runtime, "internal:createRegexp", s.Substring(2, lastIndex-2));
                            m.arguments.Add(s.Substring(lastIndex+1));
                        }
                        m.Line = tree.Line;
                        m.Position = tree.CharPositionInLine;
                        return runtime.CreateMessage(m);
                    } else if(first == '}' && last == '{') {
                        m = new Message(runtime, "internal:createText", s.Substring(1, s.Length-3), Type.MIDDLE_RE_INTERPOLATION);
                        m.Line = tree.Line;
                        m.Position = tree.CharPositionInLine;
                        return runtime.CreateMessage(m);
                    } else if(first == '}') {
                        int lastIndex = s.LastIndexOf('/');
                        if(lastIndex == -1) {
                            lastIndex = s.LastIndexOf(']');
                        }
                        m = new Message(runtime, "internal:createText", s.Substring(1, lastIndex-1), Type.END_RE_INTERPOLATION);
                        m.arguments.Add(s.Substring(lastIndex+1));
                        m.Line = tree.Line;
                        m.Position = tree.CharPositionInLine;
                        return runtime.CreateMessage(m);
                    } else {
                        m = new Message(runtime, "internal:createText", s.Substring(2, s.Length-4), Type.START_RE_INTERPOLATION);
                        m.Line = tree.Line;
                        m.Position = tree.CharPositionInLine;
                        return runtime.CreateMessage(m);
                    }
                }
                case iokeParser.StringLiteral: {
                    string s = tree.Text;
                    char first = s[0];
                    char last = s[s.Length-1];
                    if(first == '"' && last == '"') {
                        m = new Message(runtime, "internal:createText", s.Substring(1, s.Length-2));
                        m.Line = tree.Line;
                        m.Position = tree.CharPositionInLine;
                        return runtime.CreateMessage(m);
                    } else if(first == '#' && last == ']') {
                        m = new Message(runtime, "internal:createText", s.Substring(2, s.Length-3));
                        m.Line = tree.Line;
                        m.Position = tree.CharPositionInLine;
                        return runtime.CreateMessage(m);
                    } else {
                        if(first == '}' && (last == '"' || last == ']')) { // This is an ending
                            m = new Message(runtime, "internal:createText", s.Substring(1, s.Length-2), Type.END_INTERPOLATION);
                            m.Line = tree.Line;
                            m.Position = tree.CharPositionInLine;
                            return runtime.CreateMessage(m);
                        } else if(first == '"') { // This is a beginning
                            m = new Message(runtime, "internal:createText", s.Substring(1, s.Length-3), Type.START_INTERPOLATION);
                            m.Line = tree.Line;
                            m.Position = tree.CharPositionInLine;
                            return runtime.CreateMessage(m);
                        } else if(first == '#') { // This is a beginning
                            m = new Message(runtime, "internal:createText", s.Substring(2, s.Length-4), Type.START_INTERPOLATION);
                            m.Line = tree.Line;
                            m.Position = tree.CharPositionInLine;
                            return runtime.CreateMessage(m);
                        } else { // This is in the middle
                            m = new Message(runtime, "internal:createText", s.Substring(1, s.Length-3), Type.MIDDLE_INTERPOLATION);
                            m.Line = tree.Line;
                            m.Position = tree.CharPositionInLine;
                            return runtime.CreateMessage(m);
                        }
                    }
                }
                case iokeParser.NumberLiteral:
                    m = new Message(runtime, "internal:createNumber", tree.Text);
                    m.Line = tree.Line;
                    m.Position = tree.CharPositionInLine;
                    return runtime.CreateMessage(m);
                case iokeParser.DecimalLiteral:
                    m = new Message(runtime, "internal:createDecimal", tree.Text);
                    m.Line = tree.Line;
                    m.Position = tree.CharPositionInLine;
                    return runtime.CreateMessage(m);
                case iokeParser.UnitLiteral: {
                    string text = tree.Text;
                    int ending = text.Length-1;
                    while(!Char.IsDigit(text[ending])) {
                        ending--;
                    }
                    Message mex = new Message(runtime, "internal:createNumber", text.Substring(0, ending+1));
                    mex.Line = tree.Line;
                    mex.Position = tree.CharPositionInLine;
                    m = new Message(runtime, "internal:createUnit", runtime.CreateMessage(mex));
                    m.Line = tree.Line;
                    m.Position = tree.CharPositionInLine;
                    return runtime.CreateMessage(m);
                }
                case iokeParser.UnitDecimalLiteral: {
                    string text = tree.Text;
                    int ending = text.Length-1;
                    while(!Char.IsDigit(text[ending])) {
                        ending--;
                    }
                    Message mex = new Message(runtime, "internal:createDecimal", text.Substring(0, ending+1));
                    mex.Line = tree.Line;
                    mex.Position = tree.CharPositionInLine;
                    m = new Message(runtime, "internal:createUnit", mex);
                    m.Line = tree.Line;
                    m.Position = tree.CharPositionInLine;
                    return runtime.CreateMessage(m);
                }
                case iokeParser.Identifier:
                    m = new Message(runtime, tree.Text);
                    m.Line = tree.Line;
                    m.Position = tree.CharPositionInLine;
                    return runtime.CreateMessage(m);
                case iokeParser.Terminator:
                    m = new Message(runtime, ".", null, Type.TERMINATOR);
                    m.Line = tree.Line;
                    m.Position = tree.CharPositionInLine;
                    return runtime.CreateMessage(m);
                case iokeParser.Comma:
                    m = new Message(runtime, ",", null, Type.SEPARATOR);
                    m.Line = tree.Line;
                    m.Position = tree.CharPositionInLine;
                    return runtime.CreateMessage(m);
                case iokeParser.MESSAGE: {
                    string text = tree.GetChild(0).Text;
                    m = new Message(runtime, text);
                    int count = tree.ChildCount;
                    argStart = 1;
                    if(count > 1) {
                        int diff = tree.GetChild(1).CharPositionInLine - (tree.CharPositionInLine+text.Length);
                        if(diff != 0) {
                            m.type = Type.DETACH;
                        }
                        argStart = 2;
                    }

                    break;
                }
                default:
                    Console.Error.WriteLine("ERROR: Can't handle " + tree + " : " + tree.Type);
                    return null;
                }

                m.Line = tree.Line;
                m.Position = tree.CharPositionInLine;
            }

            IokeObject mx = m == null ? (IokeObject)null : runtime.CreateMessage(m);

            object head = null;
            IList<IokeObject> currents = new SaneList<IokeObject>();

            IList<IList<IokeObject>> oldCurrents = new SaneList<IList<IokeObject>>();
            IList<object> oldHeads = new SaneList<object>();
            IList<IokeObject> oldMx = new SaneList<IokeObject>();

            for(int i=argStart,j=tree.ChildCount; i<j; i++) {
                IokeObject created = FromTree(runtime, tree.GetChild(i));

                switch(Message.typeOf(created)) {
                case Type.START_INTERPOLATION:{
                    Message mvv = new Message(runtime, "internal:concatenateText");
                    mvv.Line = tree.Line;
                    mvv.Position = tree.CharPositionInLine;
                    oldCurrents.Insert(0, currents);
                    oldHeads.Insert(0, head);
                    oldMx.Insert(0, mx);

                    currents = new SaneList<IokeObject>();
                    head = created;
                    mx = runtime.CreateMessage(mvv);

                    created = runtime.CreateMessage(new Message(runtime, ",", null, Type.SEPARATOR));
                    break;
                }
                case Type.START_RE_INTERPOLATION:{
                    Message mvv = new Message(runtime, "internal:compositeRegexp");
                    mvv.Line = tree.Line;
                    mvv.Position = tree.CharPositionInLine;
                    oldCurrents.Insert(0, currents);
                    oldHeads.Insert(0, head);
                    oldMx.Insert(0, mx);

                    currents = new SaneList<IokeObject>();
                    head = created.Arguments[0];
                    mx = runtime.CreateMessage(mvv);

                    created = runtime.CreateMessage(new Message(runtime, ",", null, Type.SEPARATOR));
                    break;
                }
                case Type.MIDDLE_INTERPOLATION:
                    mx.Arguments.Add(head);

                    currents.Clear();
                    head = created;

                    created = runtime.CreateMessage(new Message(runtime, ",", null, Type.SEPARATOR));
                    break;
                case Type.MIDDLE_RE_INTERPOLATION:
                    mx.Arguments.Add(head);

                    currents.Clear();
                    head = created.Arguments[0];

                    created = runtime.CreateMessage(new Message(runtime, ",", null, Type.SEPARATOR));
                    break;
                case Type.END_INTERPOLATION:
                    mx.Arguments.Add(head);
                    mx.Arguments.Add(created);

                    currents = oldCurrents[0];
                    oldCurrents.RemoveAt(0);

                    head = oldHeads[0];
                    oldHeads.RemoveAt(0);

                    created = mx;

                    mx = oldMx[0];
                    oldMx.RemoveAt(0);

                    break;
                case Type.END_RE_INTERPOLATION:
                    mx.Arguments.Add(head);
                    mx.Arguments.Add(created.Arguments[0]);
                    mx.Arguments.Add(created.Arguments[1]);

                    currents = oldCurrents[0];
                    oldCurrents.RemoveAt(0);

                    head = oldHeads[0];
                    oldHeads.RemoveAt(0);

                    created = mx;

                    mx = oldMx[0];
                    oldMx.RemoveAt(0);
                    break;
                }

                if(Message.typeOf(created) == Type.TERMINATOR && head == null && currents.Count == 0) {
                    continue;
                }

                if(Message.typeOf(created) == Type.SEPARATOR && mx != null) {
                    mx.Arguments.Add(head);
                    currents.Clear();
                    head = null;
                } else {
                    if(Message.typeOf(created) == Type.TERMINATOR && currents.Count > 1) {
                        while(currents.Count > 1) {
                            currents.RemoveAt(0);
                        }
                    }
                    Message.SetPrev(created, currents.Count > 0 ? currents[0] : null);

                    if(head == null && Message.typeOf(created) != Type.TERMINATOR) {
                        head = created;
                    }

                    if(currents.Count > 0) {
                        Message.SetNextOfLast(currents[0], created);
                        currents[0] = created;
                    } else {
                        currents.Insert(0, created);
                    }
                }
            }

            if(mx != null && head != null) {
                mx.Arguments.Add(head);
            }

            return mx == null ? (IokeObject)head : mx;
        }
コード例 #5
0
ファイル: Message.cs プロジェクト: fronx/ioke
        public override void Init(IokeObject obj)
        {
            obj.Kind = "Message";
            obj.Mimics(IokeObject.As(obj.runtime.Mixins.GetCell(null, null, "Enumerable"), null), obj.runtime.nul, obj.runtime.nul);

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Will rearrange this message and all submessages to follow regular C style operator precedence rules. Will use Message OperatorTable to guide this operation. The operation is mutating, but should not change anything if done twice.", new NativeMethod.WithNoArguments("shuffleOperators", (method, context, message, on, outer) => {
                            IOperatorShuffler levels = method.runtime.operatorShufflerFactory.Create(IokeObject.As(on, context), context, message);
                            var expressions = new SaneList<IokeObject>();
                            if(on is IokeObject) {
                                expressions.Insert(0, IokeObject.As(on, context));
                                while(expressions.Count > 0) {
                                    IokeObject n = expressions[0];
                                    expressions.RemoveAt(0);
                                    do {
                                        levels.Attach(n, expressions);
                                        foreach(object o in n.Arguments) {
                                            if(o is IokeObject) {
                                                expressions.Insert(0, IokeObject.As(o, context));
                                            }
                                        }
                                    } while((n = Message.GetNext(n)) != null);

                                    levels.NextMessage(expressions);
                                }
                            }

                            return on;
                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Takes one or more evaluated arguments and sends this message chain to where the first argument is ground, and if there are more arguments, the second is the receiver, and the rest will be the arguments",
                                                               new NativeMethod("evaluateOn", DefaultArgumentsDefinition.builder()
                                                                                .WithRequiredPositional("ground")
                                                                                .WithOptionalPositional("receiver", "ground")
                                                                                .WithRest("arguments")
                                                                                .Arguments,
                                                                                (method, on, args, keywords, context, message) => {
                                                                                    IokeObject messageGround = IokeObject.As(args[0], context);
                                                                                    IokeObject receiver = messageGround;
                                                                                    int size = args.Count;
                                                                                    if(size > 1) {
                                                                                        receiver = IokeObject.As(args[1], context);
                                                                                        if(size > 2) {
                                                                                            IokeObject m = IokeObject.As(on, context).AllocateCopy(IokeObject.As(on, context), context);
                                                                                            m.Arguments.Clear();
                                                                                            for(int ix=2;ix<size;ix++) {
                                                                                                m.Arguments.Add(args[ix]);
                                                                                            }
                                                                                            on = m;
                                                                                        }
                                                                                    }

                                                                                    IokeObject msg = IokeObject.As(on, context);
                                                                                    return ((Message)IokeObject.dataOf(msg)).EvaluateCompleteWithReceiver(msg, messageGround, messageGround, receiver);
                                                                                })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns a deep clone of this message chain, starting at the current point.",
                                                           new TypeCheckingNativeMethod.WithNoArguments("deepCopy", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return Message.DeepCopy(on);
                                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns a code representation of the object",
                                                           new TypeCheckingNativeMethod.WithNoArguments("code", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return method.runtime.NewText(((Message)IokeObject.dataOf(on)).Code());
                                                           })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns the unevaluated arguments for this message",
                                                           new TypeCheckingNativeMethod.WithNoArguments("arguments", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return context.runtime.NewList(((Message)IokeObject.dataOf(on)).arguments);
                                                           })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Returns a formatted code representation of the object",
                                                           new TypeCheckingNativeMethod.WithNoArguments("formattedCode", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return method.runtime.NewText(Message.FormattedCode(IokeObject.As(on, context), 0, context));
                                                           })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the name of this message",
                                                           new TypeCheckingNativeMethod.WithNoArguments("name", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return method.runtime.GetSymbol(((Message)IokeObject.dataOf(on)).name);
                                                           })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("sets the name of the message and then returns that name",
                                                           new TypeCheckingNativeMethod("name=", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithRequiredPositional("newName")
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                                                                                            object o = args[0];
                                                                                            string name = null;
                                                                                            if(IokeObject.dataOf(o) is Symbol) {
                                                                                                name = Symbol.GetText(o);
                                                                                            } else if(IokeObject.dataOf(o) is Text) {
                                                                                                name = Text.GetText(o);
                                                                                            } else {
                                                                                                name = Text.GetText(IokeObject.ConvertToText(o, message, context, true));
                                                                                            }

                                                                                            Message.SetName(IokeObject.As(on, context), name);
                                                                                            return o;
                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("sets the next pointer of the message and then returns that pointer",
                                                           new TypeCheckingNativeMethod("next=", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithRequiredPositional("newNext")
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                                                                                            object o = args[0];
                                                                                            if(o == context.runtime.nil) {
                                                                                                Message.SetNext(IokeObject.As(on, context), null);
                                                                                            } else {
                                                                                                o = context.runtime.Message.ConvertToThis(o, message, context);
                                                                                                Message.SetNext(IokeObject.As(on, context), IokeObject.As(o, context));
                                                                                            }
                                                                                            return o;
                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("sets the prev pointer of the message and then returns that pointer",
                                                           new TypeCheckingNativeMethod("prev=", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithRequiredPositional("newPrev")
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                                                                                            object o = args[0];
                                                                                            if(o == context.runtime.nil) {
                                                                                                Message.SetPrev(IokeObject.As(on, context), null);
                                                                                            } else {
                                                                                                o = context.runtime.Message.ConvertToThis(o, message, context);
                                                                                                Message.SetPrev(IokeObject.As(on, context), IokeObject.As(o, context));
                                                                                            }
                                                                                            return o;
                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the file name where this message is written",
                                                           new TypeCheckingNativeMethod.WithNoArguments("filename", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return method.runtime.NewText(((Message)IokeObject.dataOf(on)).file);
                                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the line where this message is written",
                                                           new TypeCheckingNativeMethod.WithNoArguments("line", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return method.runtime.NewNumber(((Message)IokeObject.dataOf(on)).line);
                                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the position on the line where this message is written",
                                                           new TypeCheckingNativeMethod.WithNoArguments("position", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return method.runtime.NewNumber(((Message)IokeObject.dataOf(on)).pos);
                                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the next message in the chain, or nil",
                                                           new TypeCheckingNativeMethod.WithNoArguments("next", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            IokeObject next = ((Message)IokeObject.dataOf(on)).next;
                                                                                                            if(next == null) {
                                                                                                                return context.runtime.nil;
                                                                                                            } else {
                                                                                                                return next;
                                                                                                            }
                                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the last message in the chain",
                                                           new TypeCheckingNativeMethod.WithNoArguments("last", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            IokeObject current = IokeObject.As(on, context);
                                                                                                            while(GetNext(current) != null) {
                                                                                                                current = GetNext(current);
                                                                                                            }
                                                                                                            return current;
                                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns the previous message in the chain, or nil",
                                                           new TypeCheckingNativeMethod.WithNoArguments("prev", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            IokeObject prev = ((Message)IokeObject.dataOf(on)).prev;
                                                                                                            if(prev == null) {
                                                                                                                return context.runtime.nil;
                                                                                                            } else {
                                                                                                                return prev;
                                                                                                            }
                                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns true when this message is a terminator, otherwise false",
                                                           new TypeCheckingNativeMethod.WithNoArguments("terminator?", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return Message.IsTerminator(on) ? context.runtime.True : context.runtime.False;
                                                                                                        })));
            obj.RegisterMethod(obj.runtime.NewNativeMethod("takes one index, and a context and returns the evaluated argument at that index.",
                                                           new NativeMethod("evalArgAt", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("argumentIndex")
                                                                            .WithRequiredPositional("context")
                                                                            .Arguments,
                                                                            (method, on, args, keywords, context, message) => {
                                                                                int index = Number.ExtractInt(args[0], message, context);
                                                                                IokeObject newContext = IokeObject.As(args[1], context);
                                                                                IokeObject _m =  IokeObject.As(on, context);
                                                                                return ((Message)IokeObject.dataOf(_m)).GetEvaluatedArgument(_m, index, newContext);
                                                                            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Takes one evaluated argument and returns a message that wraps the value of that argument.",
                                                           new NativeMethod("wrap", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("value")
                                                                            .Arguments,
                                                                            (method, on, args, keywords, context, message) => {
                                                                                return context.runtime.CreateMessage(Message.Wrap(IokeObject.As(args[0], context)));
                                                                            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("evaluates the argument and makes it the new next pointer of the receiver. it also modifies the argument so its prev pointer points back to this message. if the argument is nil, the next pointer will be erased. it then returns the receiving message.",
                                                           new TypeCheckingNativeMethod("->", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithRequiredPositional("nextMessage")
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                                                                                            object arg = args[0];
                                                                                            if(arg == context.runtime.nil) {
                                                                                                Message.SetNext(IokeObject.As(on, context), null);
                                                                                            } else {
                                                                                                arg = context.runtime.Message.ConvertToThis(arg, message, context);
                                                                                                Message.SetNext(IokeObject.As(on, context), IokeObject.As(arg, context));
                                                                                                Message.SetPrev(IokeObject.As(arg, context), IokeObject.As(on, context));
                                                                                            }
                                                                                            return arg;
                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("evaluates the argument and adds it to the beginning of the argument list of this message. it then returns the receiving message.",
                                                           new NativeMethod(">>", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("newArgument")
                                                                            .Arguments,
                                                                            (method, on, args, keywords, context, message) => {
                                                                                IokeObject.As(on, context).Arguments.Insert(0, args[0]);
                                                                                return on;
                                                                            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("evaluates the argument and adds it to the argument list of this message. it then returns the receiving message.",
                                                           new NativeMethod("appendArgument", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("newArgument")
                                                                            .Arguments,
                                                                            (method, on, args, keywords, context, message) => {
                                                                                IokeObject.As(on, context).Arguments.Add(args[0]);
                                                                                return on;
                                                                            })));
            obj.AliasMethod("appendArgument", "<<", null, null);

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns a string that describes this message as a stack trace elemtn",
                                                           new TypeCheckingNativeMethod.WithNoArguments("asStackTraceText", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return context.runtime.NewText(Message.GetStackTraceText(on));
                                                                                                        })));
            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns true if this message is a keyword parameter or not",
                                                           new TypeCheckingNativeMethod.WithNoArguments("keyword?", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return ((Message)IokeObject.dataOf(on)).IsKeyword() ? context.runtime.True : context.runtime.False;
                                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("returns true if this message is a symbol message or not",
                                                           new TypeCheckingNativeMethod.WithNoArguments("symbol?", obj,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return ((Message)IokeObject.dataOf(on)).IsSymbolMessage ? context.runtime.True : context.runtime.False;
                                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("takes either one or two arguments. if one argument is given, it should be a message chain that will be sent to each message in the chain, recursively. 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 messages in the chain in succession, and then the second argument will be evaluated in a scope with that argument in it. 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 original message.",
                                                           new NativeMethod("walk", DefaultArgumentsDefinition.builder()
                                                                            .WithOptionalPositionalUnevaluated("argOrCode")
                                                                            .WithOptionalPositionalUnevaluated("code")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                                                                                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);

                                                                                object onAsMessage = context.runtime.Message.ConvertToThis(on, message, context);

                                                                                switch(message.Arguments.Count) {
                                                                                case 1: {
                                                                                    IokeObject code = IokeObject.As(message.Arguments[0], context);
                                                                                    WalkWithReceiver(context, onAsMessage, code);
                                                                                    break;
                                                                                }
                                                                                case 2: {
                                                                                    LexicalContext c = new LexicalContext(context.runtime, context, "Lexical activation context for Message#walk", message, context);
                                                                                    string name = IokeObject.As(message.Arguments[0], context).Name;
                                                                                    IokeObject code = IokeObject.As(message.Arguments[1], context);

                                                                                    WalkWithoutExplicitReceiver(onAsMessage, c, name, code);
                                                                                    break;
                                                                                }
                                                                                }
                                                                                return onAsMessage;

                                                                            })));

            obj.RegisterMethod(obj.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 message in the chain. 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 messages in the chain 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 message, 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 original message.",
                                                           new NativeMethod("each",  DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositionalUnevaluated("indexOrArgOrCode")
                                                                            .WithOptionalPositionalUnevaluated("argOrCode")
                                                                            .WithOptionalPositionalUnevaluated("code")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                                                                                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);

                                                                                object onAsMessage = context.runtime.Message.ConvertToThis(on, message, context);

                                                                                Runtime runtime = context.runtime;
                                                                                switch(message.Arguments.Count) {
                                                                                case 1: {
                                                                                    IokeObject code = IokeObject.As(message.Arguments[0], context);
                                                                                    object o = onAsMessage;
                                                                                    while(o != null) {
                                                                                        ((Message)IokeObject.dataOf(code)).EvaluateCompleteWithReceiver(code, context, context.RealContext, o);
                                                                                        o = GetNext(o);
                                                                                    }

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

                                                                                    object o = onAsMessage;
                                                                                    while(o != null) {
                                                                                        c.SetCell(name, o);
                                                                                        ((Message)IokeObject.dataOf(code)).EvaluateCompleteWithoutExplicitReceiver(code, c, c.RealContext);
                                                                                        o = GetNext(o);
                                                                                    }
                                                                                    break;
                                                                                }
                                                                                case 3: {
                                                                                    LexicalContext c = new LexicalContext(context.runtime, context, "Lexical activation context for List#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;
                                                                                    object o = onAsMessage;
                                                                                    while(o != null) {
                                                                                        c.SetCell(name, o);
                                                                                        c.SetCell(iname, runtime.NewNumber(index++));
                                                                                        ((Message)IokeObject.dataOf(code)).EvaluateCompleteWithoutExplicitReceiver(code, c, c.RealContext);
                                                                                        o = GetNext(o);
                                                                                    }
                                                                                    break;
                                                                                }
                                                                                }
                                                                                return onAsMessage;
                                                                            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Takes one evaluated argument and sends this message to that argument",
                                                           new NativeMethod("sendTo", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositional("newReceiver")
                                                                            .WithOptionalPositional("context", "nil")
                                                                            .Arguments,
                                                                            (method, on, args, keywords, context, message) => {
                                                                                IokeObject realReceiver = IokeObject.As(args[0], context);
                                                                                IokeObject realContext = realReceiver;
                                                                                if(args.Count > 1) {
                                                                                    realContext = IokeObject.As(args[1], context);
                                                                                }

                                                                                IokeObject msg = IokeObject.As(on, context);
                                                                                return ((Message)IokeObject.dataOf(msg)).SendTo(msg, realContext, realReceiver);
                                                                            })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("sets the arguments for this message. if given nil the arguments list will be creared, otherwise the list given as arguments will be used. it then returns the receiving message.",
                                                           new TypeCheckingNativeMethod("arguments=", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(obj)
                                                                                        .WithRequiredPositional("newArguments")
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                                                                                            object arg = args[0];
                                                                                            IokeObject.As(on, method).Arguments.Clear();
                                                                                            if(arg == context.runtime.nil) {
                                                                                                // no arguments for this message
                                                                                            } else if (IokeObject.dataOf(arg) is IokeList) {
                                                                                                var elements = IokeList.GetList(arg);
                                                                                                var arg1 = IokeObject.As(on, method).Arguments;
                                                                                                foreach(object o in elements) arg1.Add(o);
                                                                                            } else {
                                                                                                IokeObject.As(on, method).Arguments.Insert(0, arg);
                                                                                            }
                                                                                            return on;
                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Takes one evaluated argument and returns the message resulting from parsing and operator shuffling the resulting message.",
                                                           new TypeCheckingNativeMethod("fromText", TypeCheckingArgumentsDefinition.builder()
                                                                                        .WithRequiredPositional("code").WhichMustMimic(obj.runtime.Text)
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                                                                                            string code = Text.GetText(args[0]);
                                                                                            return Message.NewFromStream(context.runtime, new StringReader(code), message, context);
                                                                                        })));

            obj.RegisterMethod(obj.runtime.NewNativeMethod("Takes one evaluated argument and executes the contents of that text in the current context and returns the result of that.",
                                                           new TypeCheckingNativeMethod("doText", TypeCheckingArgumentsDefinition.builder()
                                                                                        .WithRequiredPositional("code").WhichMustMimic(obj.runtime.Text)
                                                                                        .Arguments,
                                                                                        (method, on, args, keywords, context, message) => {
                                                                                            string code = Text.GetText(args[0]);
                                                                                            return context.runtime.EvaluateString(code, message, context);
                                                                                        })));
        }
コード例 #6
0
ファイル: Runtime.cs プロジェクト: goking/ioke
        public IList<HandlerInfo> FindActiveHandlersFor(IokeObject condition, BindIndex stopIndex)
        {
            var result = new SaneList<HandlerInfo>();

            foreach(IList<HandlerInfo> lrp in Handlers) {
                foreach(HandlerInfo rp in lrp) {
                    if(rp.index.LessThan(stopIndex)) {
                        return result;
                    }

                    foreach(object possibleKind in rp.applicableConditions) {
                        if(IokeObject.IsMimic(condition, IokeObject.As(possibleKind, condition))) {
                            result.Add(rp);
                        }
                    }
                }
            }

            return result;
        }
コード例 #7
0
        public static DefaultArgumentsDefinition CreateFrom(IList args, int start, int end, IokeObject message, object on, IokeObject context)
        {
            Runtime runtime = context.runtime;
            IList<Argument> arguments = new SaneList<Argument>();
            IList<string> keywords = new SaneList<string>();

            int min = 0;
            int max = 0;
            bool hadOptional = false;
            string rest = null;
            string krest = null;

            foreach(object obj in ArrayList.Adapter(args).GetRange(start, end-start)) {
                Message m = (Message)IokeObject.dataOf(obj);
                string mname = m.Name;
                if(!"+:".Equals(mname) && m.IsKeyword()) {
                    string name = mname;
                    IokeObject dValue = context.runtime.nilMessage;
                    if(m.next != null) {
                        dValue = m.next;
                    }
                    arguments.Add(new KeywordArgument(name.Substring(0, name.Length-1), dValue));
                    keywords.Add(name);
                } else if(mname.Equals("+")) {
                    string name = Message.GetName(m.Arguments(null)[0]);
                    if(name.StartsWith(":")) {
                        krest = name.Substring(1);
                    } else {
                        rest = name;
                        max = -1;
                    }
                    hadOptional = true;
                } else if(mname.Equals("+:")) {
                    string name = m.next != null ? Message.GetName(m.next) : Message.GetName(m.Arguments(null)[0]);
                    krest = name;
                    hadOptional = true;
                } else if(m.next != null) {
                    string name = mname;
                    hadOptional = true;
                    if(max != -1) {
                        max++;
                    }
                    arguments.Add(new OptionalArgument(name, m.next));
                } else {
                    if(hadOptional) {
                        int index = IndexOf(args, obj) + start;

                        IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                     message,
                                                                                     context,
                                                                                     "Error",
                                                                                     "Invocation",
                                                                                     "ArgumentWithoutDefaultValue"), context).Mimic(message, context);
                        condition.SetCell("message", message);
                        condition.SetCell("context", context);
                        condition.SetCell("receiver", on);
                        condition.SetCell("argumentName", runtime.GetSymbol(m.Name));
                        condition.SetCell("index", runtime.NewNumber(index));

                        IList newValue = IokeList.GetList(runtime.WithRestartReturningArguments(()=>{runtime.ErrorCondition(condition);},
                                                                                                context,
                                                                                                new NewArgumentGivingRestart("provideDefaultValue", "defaultValue"),
                                                                                                new Restart.DefaultValuesGivingRestart("substituteNilDefault", runtime.nil, 1)));
                        if(max != -1) {
                            max++;
                        }

                        arguments.Add(new OptionalArgument(m.Name, runtime.CreateMessage(Message.Wrap(IokeObject.As(newValue[0], context)))));
                    } else {
                        min++;
                        max++;
                        arguments.Add(new Argument(IokeObject.As(obj, context).Name));
                    }
                }
            }

            return new DefaultArgumentsDefinition(arguments, keywords, rest, krest, min, max, false);
        }
コード例 #8
0
ファイル: Runtime.cs プロジェクト: goking/ioke
 public object WithReturningRescue(IokeObject context, object toReturn, RunnableWithReturnAndControlFlow nativeRescue)
 {
     IList<RescueInfo> rescues = new SaneList<RescueInfo>();
     IokeObject rr = IokeObject.As(Interpreter.Send(this.mimicMessage, context, this.Rescue), context);
     IList conds = new SaneArrayList();
     conds.Add(this.Condition);
     rescues.Add(new RescueInfo(rr, conds, rescues, GetBindIndex()));
     RegisterRescues(rescues);
     try {
         return nativeRescue();
     } catch(ControlFlow.Rescue e) {
         if(e.GetRescue.token == rescues) {
             return toReturn;
         } else {
             throw e;
         }
     } finally {
         UnregisterRescues(rescues);
     }
 }
コード例 #9
0
ファイル: Runtime.cs プロジェクト: goking/ioke
        public void WithReturningRestart(string name, IokeObject context, RunnableWithControlFlow code)
        {
            IokeObject rr = IokeObject.As(Interpreter.Send(this.mimicMessage, context, this.Restart), context);
            IokeObject.SetCell(rr, "name", GetSymbol(name), context);
            IokeObject.SetCell(rr, "argumentNames", NewList(new SaneArrayList()), context);

            IList<RestartInfo> rrs = new SaneList<RestartInfo>();
            BindIndex index = GetBindIndex();
            rrs.Insert(0, new RestartInfo(name, rr, rrs, index, null));
            index = index.NextCol();
            RegisterRestarts(rrs);

            try {
                code();
            } catch(ControlFlow.Restart e) {
                if(e.GetRestart.token == rrs) {
                    return;
                } else {
                    throw e;
                }
            } finally {
                UnregisterRestarts(rrs);
            }
        }
コード例 #10
0
ファイル: Runtime.cs プロジェクト: goking/ioke
        public object WithRestartReturningArguments(RunnableWithControlFlow code, IokeObject context, params Restart.NativeRestart[] restarts)
        {
            IList<RestartInfo> rrs = new SaneList<RestartInfo>();
            BindIndex index = GetBindIndex();

            foreach(Restart.NativeRestart rjr in restarts) {
                IokeObject rr = IokeObject.As(Interpreter.Send(this.mimicMessage, context, this.Restart), context);
                IokeObject.SetCell(rr, "name", GetSymbol(rjr.Name), context);

                IList args = new SaneArrayList();
                foreach(string argName in rjr.ArgumentNames) {
                    args.Add(GetSymbol(argName));
                }

                IokeObject.SetCell(rr, "name", GetSymbol(rjr.Name), context);
                IokeObject.SetCell(rr, "argumentNames", NewList(args), context);

                string report = rjr.Report();
                if(report != null) {
                    IokeObject.SetCell(rr, "report", EvaluateString("fn(r, \"" + report + "\")", this.Message, this.Ground), context);
                }

                rrs.Insert(0, new RestartInfo(rjr.Name, rr, rrs, index, rjr));
                index = index.NextCol();
            }
            RegisterRestarts(rrs);

            try {
                code();
                return new SaneArrayList();
            } catch(ControlFlow.Restart e) {
                RestartInfo ri = null;
                if((ri = e.GetRestart).token == rrs) {
                    Restart.NativeRestart currentRjr = (Restart.NativeRestart)ri.data;
                    IokeObject result = currentRjr.Invoke(context, e.Arguments);
                    return result;
                } else {
                    throw e;
                }
            } finally {
                UnregisterRestarts(rrs);
            }
        }
コード例 #11
0
ファイル: ConditionsBehavior.cs プロジェクト: goking/ioke
        public static void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;
            obj.Kind = "DefaultBehavior Conditions";

            obj.RegisterMethod(runtime.NewNativeMethod("takes one optional unevaluated parameter (this should be the first if provided), that is the name of the restart to create. this will default to nil. takes two keyword arguments, report: and test:. These should both be lexical blocks. if not provided, there will be reasonable defaults. the only required argument is something that evaluates into a lexical block. this block is what will be executed when the restart is invoked. will return a Restart mimic.",
                                                       new NativeMethod("restart", DefaultArgumentsDefinition.builder()
                                                                        .WithOptionalPositionalUnevaluated("name")
                                                                        .WithKeyword("report")
                                                                        .WithKeyword("test")
                                                                        .WithRequiredPositional("action")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                                                                            outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);

                                                                            string name = null;
                                                                            IokeObject report = null;
                                                                            IokeObject test = null;
                                                                            IokeObject code = null;

                                                                            IList args = message.Arguments;
                                                                            int argCount = args.Count;
                                                                            if(argCount > 4) {
                                                                                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(args).GetRange(4, argCount-4)));
                                                                                runtime.WithReturningRestart("ignoreExtraArguments", context, () => {runtime.ErrorCondition(condition);});
                                                                                argCount = 4;
                                                                            } else if(argCount < 1) {
                                                                                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(1-argCount));

                                                                                runtime.ErrorCondition(condition);
                                                                            }

                                                                            for(int i=0; i<argCount; i++) {
                                                                                object o = args[i];
                                                                                Message m = (Message)IokeObject.dataOf(o);
                                                                                if(m.IsKeyword()) {
                                                                                    string n = m.Name;
                                                                                    if(n.Equals("report:")) {
                                                                                        report = IokeObject.As(runtime.interpreter.Evaluate(m.next, context, context.RealContext, context), context);
                                                                                    } else if(n.Equals("test:")) {
                                                                                        test = IokeObject.As(runtime.interpreter.Evaluate(m.next, context, context.RealContext, context), context);
                                                                                    } else {
                                                                                        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);
                                                                                        condition.SetCell("expected", runtime.NewList(new SaneArrayList(new object[]{runtime.NewText("report:"), runtime.NewText("test:")})));
                                                                                        IList extra = new SaneArrayList();
                                                                                        extra.Add(runtime.NewText(n));
                                                                                        condition.SetCell("extra", runtime.NewList(extra));

                                                                                        runtime.WithReturningRestart("ignoreExtraKeywords", context, () => {runtime.ErrorCondition(condition);});
                                                                                    }
                                                                                } else {
                                                                                    if(code != null) {
                                                                                        name = code.Name;
                                                                                        code = IokeObject.As(o, context);
                                                                                    } else {
                                                                                        code = IokeObject.As(o, context);
                                                                                    }
                                                                                }
                                                                            }

                                                                            code = IokeObject.As(runtime.interpreter.Evaluate(code, context, context.RealContext, context), context);
                                                                            object restart = Interpreter.Send(runtime.mimicMessage, context, runtime.Restart);

                                                                            IokeObject.SetCell(restart, "code", code, context);

                                                                            if(null != name) {
                                                                                IokeObject.SetCell(restart, "name", runtime.GetSymbol(name), context);
                                                                            }

                                                                            if(null != test) {
                                                                                IokeObject.SetCell(restart, "test", test, context);
                                                                            }

                                                                            if(null != report) {
                                                                                IokeObject.SetCell(restart, "report", report, context);
                                                                            }

                                                                            return restart;
                                                                        })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes zero or more arguments that should evaluate to a condition mimic - this list will match all the conditions this Rescue should be able to catch. the last argument is not optional, and should be something activatable that takes one argument - the condition instance. will return a Rescue mimic.",
                                                       new NativeMethod("rescue", DefaultArgumentsDefinition.builder()
                                                                        .WithRest("conditionsAndAction")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                                                                            outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                                                                            int count = message.Arguments.Count;
                                                                            IList conds = new SaneArrayList();
                                                                            for(int i=0, j=count-1; i<j; i++) {
                                                                                conds.Add(Interpreter.GetEvaluatedArgument(message, i, context));
                                                                            }

                                                                            if(conds.Count == 0) {
                                                                                conds.Add(context.runtime.Condition);
                                                                            }

                                                                            object handler = Interpreter.GetEvaluatedArgument(message, count-1, context);
                                                                            object rescue = Interpreter.Send(context.runtime.mimicMessage, context, context.runtime.Rescue);

                                                                            IokeObject.SetCell(rescue, "handler", handler, context);
                                                                            IokeObject.SetCell(rescue, "conditions", context.runtime.NewList(conds), context);

                                                                            return rescue;
                                                                        })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes zero or more arguments that should evaluate to a condition mimic - this list will match all the conditions this Handler should be able to catch. the last argument is not optional, and should be something activatable that takes one argument - the condition instance. will return a Handler mimic.",
                                                       new NativeMethod("handle", DefaultArgumentsDefinition.builder()
                                                                        .WithRest("conditionsAndAction")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                                                                            outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                                                                            int count = message.Arguments.Count;
                                                                            IList conds = new SaneArrayList();
                                                                            for(int i=0, j=count-1; i<j; i++) {
                                                                                conds.Add(Interpreter.GetEvaluatedArgument(message, i, context));
                                                                            }

                                                                            if(conds.Count == 0) {
                                                                                conds.Add(context.runtime.Condition);
                                                                            }

                                                                            object code = Interpreter.GetEvaluatedArgument(message, count-1, context);
                                                                            object handle = Interpreter.Send(context.runtime.mimicMessage, context, context.runtime.Handler);

                                                                            IokeObject.SetCell(handle, "handler", code, context);
                                                                            IokeObject.SetCell(handle, "conditions", context.runtime.NewList(conds), context);

                                                                            return handle;
                                                                        })));

            obj.RegisterMethod(runtime.NewNativeMethod("will evaluate all arguments, and expects all except for the last to be a Restart. bind will associate these restarts for the duration of the execution of the last argument and then unbind them again. it will return the result of the last argument, or if a restart is executed it will instead return the result of that invocation.",
                                                       new NativeMethod("bind", DefaultArgumentsDefinition.builder()
                                                                        .WithRestUnevaluated("bindablesAndCode")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                                                                            outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);

                                                                            IList args = message.Arguments;
                                                                            int argCount = args.Count;
                                                                            if(argCount == 0) {
                                                                                return context.runtime.nil;
                                                                            }

                                                                            IokeObject code = IokeObject.As(args[argCount-1], context);
                                                                            var restarts = new SaneList<Runtime.RestartInfo>();
                                                                            var rescues = new SaneList<Runtime.RescueInfo>();
                                                                            var handlers = new SaneList<Runtime.HandlerInfo>();

                                                                            Runtime.BindIndex index = context.runtime.GetBindIndex();

                                                                            bool doUnregister = true;

                                                                            try {
                                                                                foreach(object o in ArrayList.Adapter(args).GetRange(0, argCount-1)) {
                                                                                    IokeObject msg = IokeObject.As(o, context);
                                                                                    IokeObject bindable = IokeObject.As(runtime.interpreter.Evaluate(msg, context, context.RealContext, context), context);
                                                                                    bool loop = false;
                                                                                    do {
                                                                                        loop = false;
                                                                                        if(IokeObject.IsKind(bindable, "Restart")) {
                                                                                            object ioName = Interpreter.Send(runtime.nameMessage, context, bindable);
                                                                                            string name = null;
                                                                                            if(ioName != runtime.nil) {
                                                                                                name = Symbol.GetText(ioName);
                                                                                            }
                                                                                            restarts.Insert(0, new Runtime.RestartInfo(name, bindable, restarts, index, null));
                                                                                            index = index.NextCol();
                                                                                        } else if(IokeObject.IsKind(bindable, "Rescue")) {
                                                                                            object conditions = Interpreter.Send(runtime.conditionsMessage, context, bindable);
                                                                                            var applicable = IokeList.GetList(conditions);
                                                                                            rescues.Insert(0, new Runtime.RescueInfo(bindable, applicable, rescues, index));
                                                                                            index = index.NextCol();
                                                                                        } else if(IokeObject.IsKind(bindable, "Handler")) {
                                                                                            object conditions = Interpreter.Send(runtime.conditionsMessage, context, bindable);
                                                                                            var applicable = IokeList.GetList(conditions);
                                                                                            handlers.Insert(0, new Runtime.HandlerInfo(bindable, applicable, handlers, index));
                                                                                            index = index.NextCol();
                                                                                        } else {
                                                                                            IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                                                                                         message,
                                                                                                                                                         context,
                                                                                                                                                         "Error",
                                                                                                                                                         "Type",
                                                                                                                                                         "IncorrectType"), context).Mimic(message, context);
                                                                                            condition.SetCell("message", message);
                                                                                            condition.SetCell("context", context);
                                                                                            condition.SetCell("receiver", on);
                                                                                            condition.SetCell("expectedType", runtime.GetSymbol("Bindable"));

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

                                                                                            runtime.WithRestartReturningArguments(() => { runtime.ErrorCondition(condition); }, context, new IokeObject.UseValue("bindable", newCell));
                                                                                            bindable = IokeObject.As(newCell[0], context);
                                                                                            loop = true;
                                                                                        }
                                                                                    } while(loop);
                                                                                    loop = false;
                                                                                }
                                                                                runtime.RegisterRestarts(restarts);
                                                                                runtime.RegisterRescues(rescues);
                                                                                runtime.RegisterHandlers(handlers);

                                                                                return runtime.interpreter.Evaluate(code, context, context.RealContext, context);
                                                                            } catch(ControlFlow.Restart e) {
                                                                                Runtime.RestartInfo ri = null;
                                                                                if((ri = e.GetRestart).token == restarts) {
                                                                                    runtime.UnregisterHandlers(handlers);
                                                                                    runtime.UnregisterRescues(rescues);
                                                                                    runtime.UnregisterRestarts(restarts);
                                                                                    doUnregister = false;
                                                                                    return Interpreter.Send(runtime.callMessage, context, Interpreter.Send(runtime.codeMessage, context, ri.restart), e.Arguments);
                                                                                } else {
                                                                                    throw e;
                                                                                }
                                                                            } catch(ControlFlow.Rescue e) {
                                                                                Runtime.RescueInfo ri = null;
                                                                                if((ri = e.GetRescue).token == rescues) {
                                                                                    runtime.UnregisterHandlers(handlers);
                                                                                    runtime.UnregisterRescues(rescues);
                                                                                    runtime.UnregisterRestarts(restarts);
                                                                                    doUnregister = false;
                                                                                    return Interpreter.Send(runtime.callMessage, context, Interpreter.Send(runtime.handlerMessage, context, ri.rescue), e.Condition);
                                                                                } else {
                                                                                    throw e;
                                                                                }
                                                                            } finally {
                                                                                if(doUnregister) {
                                                                                    runtime.UnregisterHandlers(handlers);
                                                                                    runtime.UnregisterRescues(rescues);
                                                                                    runtime.UnregisterRestarts(restarts);
                                                                                }
                                                                            }
                                                                        })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes either a name (as a symbol) or a Restart instance. if the restart is active, will transfer control to it, supplying the rest of the given arguments to that restart.",
                                                       new NativeMethod("invokeRestart", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("nameOrRestart")
                                                                        .WithRest("arguments")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                                                                            IList posArgs = new SaneArrayList();
                                                                            outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, posArgs, new SaneDictionary<string, object>());

                                                                            IokeObject restart = IokeObject.As(posArgs[0], context);
                                                                            Runtime.RestartInfo realRestart = null;
                                                                            var args = new SaneArrayList();
                                                                            if(restart.IsSymbol) {
                                                                                string name = Symbol.GetText(restart);
                                                                                realRestart = context.runtime.FindActiveRestart(name);
                                                                                if(null == realRestart) {
                                                                                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                                                                                 message,
                                                                                                                                                 context,
                                                                                                                                                 "Error",
                                                                                                                                                 "RestartNotActive"), context).Mimic(message, context);
                                                                                    condition.SetCell("message", message);
                                                                                    condition.SetCell("context", context);
                                                                                    condition.SetCell("receiver", on);
                                                                                    condition.SetCell("restart", restart);

                                                                                    runtime.WithReturningRestart("ignoreMissingRestart", context, ()=>{runtime.ErrorCondition(condition);});
                                                                                    return runtime.nil;
                                                                                }
                                                                            } else {
                                                                                realRestart = context.runtime.FindActiveRestart(restart);
                                                                                if(null == realRestart) {
                                                                                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                                                                                 message,
                                                                                                                                                 context,
                                                                                                                                                 "Error",
                                                                                                                                                 "RestartNotActive"), context).Mimic(message, context);
                                                                                    condition.SetCell("message", message);
                                                                                    condition.SetCell("context", context);
                                                                                    condition.SetCell("receiver", on);
                                                                                    condition.SetCell("restart", restart);

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

                                                                            int argCount = posArgs.Count;
                                                                            for(int i = 1;i<argCount;i++) {
                                                                                args.Add(posArgs[i]);
                                                                            }

                                                                            throw new ControlFlow.Restart(realRestart, args);
                                                                        })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes either a name (as a symbol) or a Restart instance. if the restart is active, will return that restart, otherwise returns nil.",
                                                       new NativeMethod("findRestart", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("nameOrRestart")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                                                                            IList args = new SaneArrayList();
                                                                            outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary<string, object>());

                                                                            IokeObject restart = IokeObject.As(args[0], context);
                                                                            Runtime.RestartInfo realRestart = null;
                                                                            while(!(restart.IsSymbol || restart.GetKind(message, context).Equals("Restart"))) {
                                                                                IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                                                                             message,
                                                                                                                                             context,
                                                                                                                                             "Error",
                                                                                                                                             "Type",
                                                                                                                                             "IncorrectType"), context).Mimic(message, context);
                                                                                condition.SetCell("message", message);
                                                                                condition.SetCell("context", context);
                                                                                condition.SetCell("receiver", on);
                                                                                condition.SetCell("expectedType", runtime.GetSymbol("Restart"));

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

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

                                                                            if(restart.IsSymbol) {
                                                                                string name = Symbol.GetText(restart);
                                                                                realRestart = runtime.FindActiveRestart(name);
                                                                            } else if(restart.GetKind(message, context).Equals("Restart")) {
                                                                                realRestart = runtime.FindActiveRestart(restart);
                                                                            }
                                                                            if(realRestart == null) {
                                                                                return runtime.nil;
                                                                            } else {
                                                                                return realRestart.restart;
                                                                            }
                                                                        })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes an optional condition to specify - returns all restarts that are applicable to that condition. closer restarts will be first in the list",
                                                       new NativeMethod("availableRestarts", DefaultArgumentsDefinition.builder()
                                                                        .WithOptionalPositional("condition", "Condition")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                                                                            IList args = new SaneArrayList();
                                                                            outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary<string, object>());
                                                                            object toLookFor = runtime.Condition;
                                                                            if(args.Count > 0) {
                                                                                toLookFor = args[0];
                                                                            }

                                                                            var result = new SaneArrayList();
                                                                            var activeRestarts = runtime.ActiveRestarts;

                                                                            foreach(var lri in activeRestarts) {
                                                                                foreach(var rri in lri) {
                                                                                    if(IokeObject.IsObjectTrue(Interpreter.Send(runtime.callMessage, context, Interpreter.Send(runtime.testMessage, context, rri.restart), toLookFor))) {
                                                                                        result.Add(rri.restart);
                                                                                    }
                                                                                }
                                                                            }

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

            obj.RegisterMethod(runtime.NewNativeMethod("takes one or more datums descibing the condition to signal. this datum can be either a mimic of a Condition, in which case it will be signalled directly, or it can be a mimic of a Condition with arguments, in which case it will first be mimicked and the arguments assigned in some way. finally, if the argument is a Text, a mimic of Condition Default will be signalled, with the provided text.",
                                                       new NativeMethod("signal!", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("datum")
                                                                        .WithKeywordRest("conditionArguments")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                                                                            IList positionalArgs = new SaneArrayList();
                                                                            IDictionary<string, object> keywordArgs = new SaneDictionary<string, object>();
                                                                            outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, positionalArgs, keywordArgs);
                                                                            object datum = positionalArgs[0];
                                                                            return Signal(datum, positionalArgs, keywordArgs, message, context);
                                                                        })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes the same kind of arguments as 'signal!', and will signal a condition. the default condition used is Condition Error Default. if no rescue or restart is invoked error! will report the condition to System err and exit the currently running Ioke VM. this might be a problem when exceptions happen inside of running Java code, as callbacks and so on.. if 'System currentDebugger' is non-nil, it will be invoked before the exiting of the VM. the exit can only be avoided by invoking a restart. that means that error! will never return. ",
                                                       new NativeMethod("error!", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("datum")
                                                                        .WithKeywordRest("errorArguments")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                                                                            IList positionalArgs = new SaneArrayList();
                                                                            IDictionary<string, object> keywordArgs = new SaneDictionary<string, object>();
                                                                            outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, positionalArgs, keywordArgs);

                                                                            object datum = positionalArgs[0];

                                                                            if(IokeObject.dataOf(datum) is Text) {
                                                                                object oldDatum = datum;
                                                                                datum = IokeObject.As(IokeObject.GetCellChain(runtime.Condition, message, context, "Error", "Default"), context).Mimic(message, context);
                                                                                IokeObject.SetCell(datum, message, context, "text", oldDatum);
                                                                            }

                                                                            IokeObject condition = Signal(datum, positionalArgs, keywordArgs, message, context);
                                                                            IokeObject err = IokeObject.As(context.runtime.System.GetCell(message, context, "err"), context);

                                                                            Interpreter.Send(context.runtime.printMessage, context, err, context.runtime.NewText("*** - "));
                                                                            Interpreter.Send(context.runtime.printlnMessage, context, err, Interpreter.Send(context.runtime.reportMessage, context, condition));

                                                                            IokeObject currentDebugger = IokeObject.As(Interpreter.Send(context.runtime.currentDebuggerMessage, context, context.runtime.System), context);

                                                                            if(!currentDebugger.IsNil) {
                                                                                Interpreter.Send(context.runtime.invokeMessage, context, currentDebugger, condition, context);
                                                                            }

                                                                            throw new ControlFlow.Exit(condition);
                                                                        })));
        }
コード例 #12
0
ファイル: Main.cs プロジェクト: tspring/ioke
        public static void Main(string[] args)
        {
            string current  = System.Reflection.Assembly.GetExecutingAssembly().Location;
            string iokeHome = new FileInfo(current).Directory.Parent.FullName;
            string iokeLib  = Path.Combine(iokeHome, "lib");

            Runtime r = new Runtime();

            r.Init();

            IokeObject context = r.Ground;
            Message    mx      = new Message(r, ".", null, true);

            mx.Line     = 0;
            mx.Position = 0;
            IokeObject message = r.CreateMessage(mx);

            string cwd = null;

            var  scripts  = new SaneList <string>();
            var  loadDirs = new SaneList <string>();
            bool debug    = false;

            try {
                int  start            = 0;
                bool done             = false;
                bool readStdin        = false;
                bool printedSomething = false;

                for (; !done && start < args.Length; start++)
                {
                    string arg = args[start];
                    if (arg.Length > 0)
                    {
                        if (arg[0] != '-')
                        {
                            done = true;
                            break;
                        }
                        else
                        {
                            if (arg.Equals("--"))
                            {
                                done = true;
                            }
                            else if (arg.Equals("-d"))
                            {
                                debug   = true;
                                r.Debug = true;
                            }
                            else if (arg.StartsWith("-e"))
                            {
                                if (arg.Length == 2)
                                {
                                    scripts.Add(args[++start]);
                                }
                                else
                                {
                                    scripts.Add(arg.Substring(2));
                                }
                            }
                            else if (arg.StartsWith("-I"))
                            {
                                if (arg.Length == 2)
                                {
                                    loadDirs.Add(args[++start]);
                                }
                                else
                                {
                                    loadDirs.Add(arg.Substring(2));
                                }
                            }
                            else if (arg.Equals("-h") || arg.Equals("--help"))
                            {
                                Console.Error.Write(HELP);
                                return;
                            }
                            else if (arg.Equals("--version"))
                            {
                                Console.Error.WriteLine(getVersion());
                                printedSomething = true;
                            }
                            else if (arg.Equals("--copyright"))
                            {
                                Console.Error.Write(COPYRIGHT);
                                printedSomething = true;
                            }
                            else if (arg.Equals("-"))
                            {
                                readStdin = true;
                            }
                            else if (arg[1] == 'C')
                            {
                                if (arg.Length == 2)
                                {
                                    cwd = args[++start];
                                }
                                else
                                {
                                    cwd = arg.Substring(2);
                                }
                            }
                            else
                            {
                                IokeObject condition = IokeObject.As(IokeObject.GetCellChain(r.Condition,
                                                                                             message,
                                                                                             context,
                                                                                             "Error",
                                                                                             "CommandLine",
                                                                                             "DontUnderstandOption"), null).Mimic(message, context);
                                condition.SetCell("message", message);
                                condition.SetCell("context", context);
                                condition.SetCell("receiver", context);
                                condition.SetCell("option", r.NewText(arg));
                                r.ErrorCondition(condition);
                            }
                        }
                    }
                }

                if (cwd != null)
                {
                    r.CurrentWorkingDirectory = cwd;
                }

                ((IokeSystem)IokeObject.dataOf(r.System)).CurrentProgram = "-e";

                string lib = Environment.GetEnvironmentVariable("ioke.lib");
                if (lib == null)
                {
                    lib = iokeLib;
                }
                ((IokeSystem)IokeObject.dataOf(r.System)).AddLoadPath(lib + "/ioke");
                ((IokeSystem)IokeObject.dataOf(r.System)).AddLoadPath("lib/ioke");

                foreach (string ss in loadDirs)
                {
                    ((IokeSystem)IokeObject.dataOf(r.System)).AddLoadPath(ss);
                }

                foreach (string script in scripts)
                {
                    r.EvaluateStream("-e", new StringReader(script), message, context);
                }

                if (readStdin)
                {
                    ((IokeSystem)IokeObject.dataOf(r.System)).CurrentProgram = "<stdin>";
                    r.EvaluateStream("<stdin>", Console.In, message, context);
                }

                if (args.Length > start)
                {
                    if (args.Length > (start + 1))
                    {
                        for (int i = start + 1, j = args.Length; i < j; i++)
                        {
                            r.AddArgument(args[i]);
                        }
                    }
                    string file = args[start];
                    if (file.StartsWith("\""))
                    {
                        file = file.Substring(1, file.Length - 1);
                    }

                    if (file.Length > 1 && file[file.Length - 1] == '"')
                    {
                        file = file.Substring(0, file.Length - 1);
                    }

                    ((IokeSystem)IokeObject.dataOf(r.System)).CurrentProgram = file;
                    r.EvaluateFile(file, message, context);
                }
                else
                {
                    if (!readStdin && scripts.Count == 0 && !printedSomething)
                    {
                        r.EvaluateString("use(\"builtin/iik\"). IIk mainLoop", message, context);
                    }
                }

                r.TearDown();
            } catch (ControlFlow.Exit e) {
                int exitVal = e.ExitValue;
                try {
                    r.TearDown();
                } catch (ControlFlow.Exit e2) {
                    exitVal = e2.ExitValue;
                }
                Environment.Exit(exitVal);
            } catch (ControlFlow e) {
                string name = e.GetType().FullName;
                System.Console.Error.WriteLine("unexpected control flow: " + name.Substring(name.LastIndexOf(".") + 1).ToLower());
                if (debug)
                {
                    System.Console.Error.WriteLine(e);
                }
                Environment.Exit(1);
            }
        }
コード例 #13
0
ファイル: IokeObject.cs プロジェクト: goking/ioke
 public IList<IokeObject> GetMimics()
 {
     var result = new SaneList<IokeObject>();
     switch(body.mimicCount) {
     case 0:
         break;
     case 1:
         result.Add(body.mimic);
         break;
     default:
         for(int i=0; i<body.mimicCount; i++) {
             result.Add(body.mimics[i]);
         }
         break;
     }
     return result;
 }
コード例 #14
0
        public static void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;

            obj.Kind = "DefaultBehavior Conditions";

            obj.RegisterMethod(runtime.NewNativeMethod("takes one optional unevaluated parameter (this should be the first if provided), that is the name of the restart to create. this will default to nil. takes two keyword arguments, report: and test:. These should both be lexical blocks. if not provided, there will be reasonable defaults. the only required argument is something that evaluates into a lexical block. this block is what will be executed when the restart is invoked. will return a Restart mimic.",
                                                       new NativeMethod("restart", DefaultArgumentsDefinition.builder()
                                                                        .WithOptionalPositionalUnevaluated("name")
                                                                        .WithKeyword("report")
                                                                        .WithKeyword("test")
                                                                        .WithRequiredPositional("action")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);

                string name       = null;
                IokeObject report = null;
                IokeObject test   = null;
                IokeObject code   = null;

                IList args   = message.Arguments;
                int argCount = args.Count;
                if (argCount > 4)
                {
                    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(args).GetRange(4, argCount - 4)));
                    runtime.WithReturningRestart("ignoreExtraArguments", context, () => { runtime.ErrorCondition(condition); });
                    argCount = 4;
                }
                else if (argCount < 1)
                {
                    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(1 - argCount));

                    runtime.ErrorCondition(condition);
                }

                for (int i = 0; i < argCount; i++)
                {
                    object o  = args[i];
                    Message m = (Message)IokeObject.dataOf(o);
                    if (m.IsKeyword())
                    {
                        string n = m.Name;
                        if (n.Equals("report:"))
                        {
                            report = IokeObject.As(runtime.interpreter.Evaluate(m.next, context, context.RealContext, context), context);
                        }
                        else if (n.Equals("test:"))
                        {
                            test = IokeObject.As(runtime.interpreter.Evaluate(m.next, context, context.RealContext, context), context);
                        }
                        else
                        {
                            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);
                            condition.SetCell("expected", runtime.NewList(new SaneArrayList(new object[] { runtime.NewText("report:"), runtime.NewText("test:") })));
                            IList extra = new SaneArrayList();
                            extra.Add(runtime.NewText(n));
                            condition.SetCell("extra", runtime.NewList(extra));

                            runtime.WithReturningRestart("ignoreExtraKeywords", context, () => { runtime.ErrorCondition(condition); });
                        }
                    }
                    else
                    {
                        if (code != null)
                        {
                            name = code.Name;
                            code = IokeObject.As(o, context);
                        }
                        else
                        {
                            code = IokeObject.As(o, context);
                        }
                    }
                }

                code           = IokeObject.As(runtime.interpreter.Evaluate(code, context, context.RealContext, context), context);
                object restart = Interpreter.Send(runtime.mimicMessage, context, runtime.Restart);

                IokeObject.SetCell(restart, "code", code, context);

                if (null != name)
                {
                    IokeObject.SetCell(restart, "name", runtime.GetSymbol(name), context);
                }

                if (null != test)
                {
                    IokeObject.SetCell(restart, "test", test, context);
                }

                if (null != report)
                {
                    IokeObject.SetCell(restart, "report", report, context);
                }

                return(restart);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes zero or more arguments that should evaluate to a condition mimic - this list will match all the conditions this Rescue should be able to catch. the last argument is not optional, and should be something activatable that takes one argument - the condition instance. will return a Rescue mimic.",
                                                       new NativeMethod("rescue", DefaultArgumentsDefinition.builder()
                                                                        .WithRest("conditionsAndAction")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                int count   = message.Arguments.Count;
                IList conds = new SaneArrayList();
                for (int i = 0, j = count - 1; i < j; i++)
                {
                    conds.Add(Interpreter.GetEvaluatedArgument(message, i, context));
                }

                if (conds.Count == 0)
                {
                    conds.Add(context.runtime.Condition);
                }

                object handler = Interpreter.GetEvaluatedArgument(message, count - 1, context);
                object rescue  = Interpreter.Send(context.runtime.mimicMessage, context, context.runtime.Rescue);

                IokeObject.SetCell(rescue, "handler", handler, context);
                IokeObject.SetCell(rescue, "conditions", context.runtime.NewList(conds), context);

                return(rescue);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes zero or more arguments that should evaluate to a condition mimic - this list will match all the conditions this Handler should be able to catch. the last argument is not optional, and should be something activatable that takes one argument - the condition instance. will return a Handler mimic.",
                                                       new NativeMethod("handle", DefaultArgumentsDefinition.builder()
                                                                        .WithRest("conditionsAndAction")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                int count   = message.Arguments.Count;
                IList conds = new SaneArrayList();
                for (int i = 0, j = count - 1; i < j; i++)
                {
                    conds.Add(Interpreter.GetEvaluatedArgument(message, i, context));
                }

                if (conds.Count == 0)
                {
                    conds.Add(context.runtime.Condition);
                }

                object code   = Interpreter.GetEvaluatedArgument(message, count - 1, context);
                object handle = Interpreter.Send(context.runtime.mimicMessage, context, context.runtime.Handler);

                IokeObject.SetCell(handle, "handler", code, context);
                IokeObject.SetCell(handle, "conditions", context.runtime.NewList(conds), context);

                return(handle);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("will evaluate all arguments, and expects all except for the last to be a Restart. bind will associate these restarts for the duration of the execution of the last argument and then unbind them again. it will return the result of the last argument, or if a restart is executed it will instead return the result of that invocation.",
                                                       new NativeMethod("bind", DefaultArgumentsDefinition.builder()
                                                                        .WithRestUnevaluated("bindablesAndCode")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);

                IList args   = message.Arguments;
                int argCount = args.Count;
                if (argCount == 0)
                {
                    return(context.runtime.nil);
                }

                IokeObject code = IokeObject.As(args[argCount - 1], context);
                var restarts    = new SaneList <Runtime.RestartInfo>();
                var rescues     = new SaneList <Runtime.RescueInfo>();
                var handlers    = new SaneList <Runtime.HandlerInfo>();

                Runtime.BindIndex index = context.runtime.GetBindIndex();

                bool doUnregister = true;

                try {
                    foreach (object o in ArrayList.Adapter(args).GetRange(0, argCount - 1))
                    {
                        IokeObject msg      = IokeObject.As(o, context);
                        IokeObject bindable = IokeObject.As(runtime.interpreter.Evaluate(msg, context, context.RealContext, context), context);
                        bool loop           = false;
                        do
                        {
                            loop = false;
                            if (IokeObject.IsKind(bindable, "Restart"))
                            {
                                object ioName = Interpreter.Send(runtime.nameMessage, context, bindable);
                                string name   = null;
                                if (ioName != runtime.nil)
                                {
                                    name = Symbol.GetText(ioName);
                                }
                                restarts.Insert(0, new Runtime.RestartInfo(name, bindable, restarts, index, null));
                                index = index.NextCol();
                            }
                            else if (IokeObject.IsKind(bindable, "Rescue"))
                            {
                                object conditions = Interpreter.Send(runtime.conditionsMessage, context, bindable);
                                var applicable    = IokeList.GetList(conditions);
                                rescues.Insert(0, new Runtime.RescueInfo(bindable, applicable, rescues, index));
                                index = index.NextCol();
                            }
                            else if (IokeObject.IsKind(bindable, "Handler"))
                            {
                                object conditions = Interpreter.Send(runtime.conditionsMessage, context, bindable);
                                var applicable    = IokeList.GetList(conditions);
                                handlers.Insert(0, new Runtime.HandlerInfo(bindable, applicable, handlers, index));
                                index = index.NextCol();
                            }
                            else
                            {
                                IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                             message,
                                                                                             context,
                                                                                             "Error",
                                                                                             "Type",
                                                                                             "IncorrectType"), context).Mimic(message, context);
                                condition.SetCell("message", message);
                                condition.SetCell("context", context);
                                condition.SetCell("receiver", on);
                                condition.SetCell("expectedType", runtime.GetSymbol("Bindable"));

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

                                runtime.WithRestartReturningArguments(() => { runtime.ErrorCondition(condition); }, context, new IokeObject.UseValue("bindable", newCell));
                                bindable = IokeObject.As(newCell[0], context);
                                loop     = true;
                            }
                        } while(loop);
                        loop = false;
                    }
                    runtime.RegisterRestarts(restarts);
                    runtime.RegisterRescues(rescues);
                    runtime.RegisterHandlers(handlers);

                    return(runtime.interpreter.Evaluate(code, context, context.RealContext, context));
                } catch (ControlFlow.Restart e) {
                    Runtime.RestartInfo ri = null;
                    if ((ri = e.GetRestart).token == restarts)
                    {
                        runtime.UnregisterHandlers(handlers);
                        runtime.UnregisterRescues(rescues);
                        runtime.UnregisterRestarts(restarts);
                        doUnregister = false;
                        return(Interpreter.Send(runtime.callMessage, context, Interpreter.Send(runtime.codeMessage, context, ri.restart), e.Arguments));
                    }
                    else
                    {
                        throw e;
                    }
                } catch (ControlFlow.Rescue e) {
                    Runtime.RescueInfo ri = null;
                    if ((ri = e.GetRescue).token == rescues)
                    {
                        runtime.UnregisterHandlers(handlers);
                        runtime.UnregisterRescues(rescues);
                        runtime.UnregisterRestarts(restarts);
                        doUnregister = false;
                        return(Interpreter.Send(runtime.callMessage, context, Interpreter.Send(runtime.handlerMessage, context, ri.rescue), e.Condition));
                    }
                    else
                    {
                        throw e;
                    }
                } finally {
                    if (doUnregister)
                    {
                        runtime.UnregisterHandlers(handlers);
                        runtime.UnregisterRescues(rescues);
                        runtime.UnregisterRestarts(restarts);
                    }
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes either a name (as a symbol) or a Restart instance. if the restart is active, will transfer control to it, supplying the rest of the given arguments to that restart.",
                                                       new NativeMethod("invokeRestart", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("nameOrRestart")
                                                                        .WithRest("arguments")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                IList posArgs = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, posArgs, new SaneDictionary <string, object>());

                IokeObject restart = IokeObject.As(posArgs[0], context);
                Runtime.RestartInfo realRestart = null;
                var args = new SaneArrayList();
                if (restart.IsSymbol)
                {
                    string name = Symbol.GetText(restart);
                    realRestart = context.runtime.FindActiveRestart(name);
                    if (null == realRestart)
                    {
                        IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                     message,
                                                                                     context,
                                                                                     "Error",
                                                                                     "RestartNotActive"), context).Mimic(message, context);
                        condition.SetCell("message", message);
                        condition.SetCell("context", context);
                        condition.SetCell("receiver", on);
                        condition.SetCell("restart", restart);

                        runtime.WithReturningRestart("ignoreMissingRestart", context, () => { runtime.ErrorCondition(condition); });
                        return(runtime.nil);
                    }
                }
                else
                {
                    realRestart = context.runtime.FindActiveRestart(restart);
                    if (null == realRestart)
                    {
                        IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                     message,
                                                                                     context,
                                                                                     "Error",
                                                                                     "RestartNotActive"), context).Mimic(message, context);
                        condition.SetCell("message", message);
                        condition.SetCell("context", context);
                        condition.SetCell("receiver", on);
                        condition.SetCell("restart", restart);

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

                int argCount = posArgs.Count;
                for (int i = 1; i < argCount; i++)
                {
                    args.Add(posArgs[i]);
                }

                throw new ControlFlow.Restart(realRestart, args);
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes either a name (as a symbol) or a Restart instance. if the restart is active, will return that restart, otherwise returns nil.",
                                                       new NativeMethod("findRestart", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("nameOrRestart")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                IList args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());

                IokeObject restart = IokeObject.As(args[0], context);
                Runtime.RestartInfo realRestart = null;
                while (!(restart.IsSymbol || restart.GetKind(message, context).Equals("Restart")))
                {
                    IokeObject condition = IokeObject.As(IokeObject.GetCellChain(runtime.Condition,
                                                                                 message,
                                                                                 context,
                                                                                 "Error",
                                                                                 "Type",
                                                                                 "IncorrectType"), context).Mimic(message, context);
                    condition.SetCell("message", message);
                    condition.SetCell("context", context);
                    condition.SetCell("receiver", on);
                    condition.SetCell("expectedType", runtime.GetSymbol("Restart"));

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

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

                if (restart.IsSymbol)
                {
                    string name = Symbol.GetText(restart);
                    realRestart = runtime.FindActiveRestart(name);
                }
                else if (restart.GetKind(message, context).Equals("Restart"))
                {
                    realRestart = runtime.FindActiveRestart(restart);
                }
                if (realRestart == null)
                {
                    return(runtime.nil);
                }
                else
                {
                    return(realRestart.restart);
                }
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes an optional condition to specify - returns all restarts that are applicable to that condition. closer restarts will be first in the list",
                                                       new NativeMethod("availableRestarts", DefaultArgumentsDefinition.builder()
                                                                        .WithOptionalPositional("condition", "Condition")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                IList args = new SaneArrayList();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary <string, object>());
                object toLookFor = runtime.Condition;
                if (args.Count > 0)
                {
                    toLookFor = args[0];
                }

                var result         = new SaneArrayList();
                var activeRestarts = runtime.ActiveRestarts;

                foreach (var lri in activeRestarts)
                {
                    foreach (var rri in lri)
                    {
                        if (IokeObject.IsObjectTrue(Interpreter.Send(runtime.callMessage, context, Interpreter.Send(runtime.testMessage, context, rri.restart), toLookFor)))
                        {
                            result.Add(rri.restart);
                        }
                    }
                }

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

            obj.RegisterMethod(runtime.NewNativeMethod("takes one or more datums descibing the condition to signal. this datum can be either a mimic of a Condition, in which case it will be signalled directly, or it can be a mimic of a Condition with arguments, in which case it will first be mimicked and the arguments assigned in some way. finally, if the argument is a Text, a mimic of Condition Default will be signalled, with the provided text.",
                                                       new NativeMethod("signal!", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("datum")
                                                                        .WithKeywordRest("conditionArguments")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                IList positionalArgs = new SaneArrayList();
                IDictionary <string, object> keywordArgs = new SaneDictionary <string, object>();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, positionalArgs, keywordArgs);
                object datum = positionalArgs[0];
                return(Signal(datum, positionalArgs, keywordArgs, message, context));
            })));

            obj.RegisterMethod(runtime.NewNativeMethod("takes the same kind of arguments as 'signal!', and will signal a condition. the default condition used is Condition Error Default. if no rescue or restart is invoked error! will report the condition to System err and exit the currently running Ioke VM. this might be a problem when exceptions happen inside of running Java code, as callbacks and so on.. if 'System currentDebugger' is non-nil, it will be invoked before the exiting of the VM. the exit can only be avoided by invoking a restart. that means that error! will never return. ",
                                                       new NativeMethod("error!", DefaultArgumentsDefinition.builder()
                                                                        .WithRequiredPositional("datum")
                                                                        .WithKeywordRest("errorArguments")
                                                                        .Arguments,
                                                                        (method, context, message, on, outer) => {
                IList positionalArgs = new SaneArrayList();
                IDictionary <string, object> keywordArgs = new SaneDictionary <string, object>();
                outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, positionalArgs, keywordArgs);

                object datum = positionalArgs[0];

                if (IokeObject.dataOf(datum) is Text)
                {
                    object oldDatum = datum;
                    datum           = IokeObject.As(IokeObject.GetCellChain(runtime.Condition, message, context, "Error", "Default"), context).Mimic(message, context);
                    IokeObject.SetCell(datum, message, context, "text", oldDatum);
                }

                IokeObject condition = Signal(datum, positionalArgs, keywordArgs, message, context);
                IokeObject err       = IokeObject.As(context.runtime.System.GetCell(message, context, "err"), context);

                Interpreter.Send(context.runtime.printMessage, context, err, context.runtime.NewText("*** - "));
                Interpreter.Send(context.runtime.printlnMessage, context, err, Interpreter.Send(context.runtime.reportMessage, context, condition));

                IokeObject currentDebugger = IokeObject.As(Interpreter.Send(context.runtime.currentDebuggerMessage, context, context.runtime.System), context);

                if (!currentDebugger.IsNil)
                {
                    Interpreter.Send(context.runtime.invokeMessage, context, currentDebugger, condition, context);
                }

                throw new ControlFlow.Exit(condition);
            })));
        }