Пример #1
0
        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);
            }
        }
Пример #2
0
        public static IokeObject NewFromStream(Runtime runtime, TextReader reader, IokeObject message, IokeObject context)
        {
            try {
                iokeParser parser = new iokeParser(new CommonTokenStream(new iokeLexer(new ANTLRReaderStream(reader))));
            //                  Console.Error.WriteLine("parseFully ...");
                ITree t = parser.parseFully();
            //                  Console.Error.WriteLine("t: " + t.ToStringTree());

                if(t == null) {
                    Message mx = new Message(runtime, ".", null, Type.TERMINATOR);
                    mx.Line = 0;
                    mx.Position = 0;
                    return runtime.CreateMessage(mx);
                }

                IokeObject m = FromTree(runtime, t);
            //                  Console.Error.WriteLine("m: " + m);

            //                 Console.Error.WriteLine("m1: " + m);
                OpShuffle(m);
            //                 Console.Error.WriteLine("m2: " + m);

                return m;
            } catch(Exception e) {
                runtime.ReportNativeException(e, message, context);
                return null;
            }
        }
Пример #3
0
        public static IokeObject NewFromStream(Runtime runtime, TextReader reader, IokeObject message, IokeObject context)
        {
            try {
                IokeParser parser = new IokeParser(runtime, reader, context, message);
                IokeObject m = parser.ParseFully();

                if(m == null) {
                    Message mx = new Message(runtime, ".", null, true);
                    mx.Line = 0;
                    mx.Position = 0;
                    return runtime.CreateMessage(mx);
                }

                return m;
            } catch(ControlFlow cf) {
                // Pass through!
                throw cf;
            } catch(Exception e) {
                runtime.ReportNativeException(e, message, context);
                return null;
            }
        }
Пример #4
0
        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;
        }