Esempio n. 1
0
        public static void RunScript(string pth)
        {
            var basedir = Path.GetDirectoryName(pth);

            Interpreter.CreateSymbolTableDelegate extension = _ => new Dictionary <Symbol, object>()

            {
                // generic stuff
                { Symbol.FromString("sprintf"), NativeProcedure.Create <string, List <object>, string>((fmt, parts) => Sprintf(fmt, parts)) },

                // roughgrep stuff
                { Symbol.FromString("make-runner"), NativeProcedure.Create <string, string, string, object>((bin, arg, workdir) => MakeRunner(bin, arg, workdir)) },
                { Symbol.FromString("add-command"), NativeProcedure.Create <string, CmdRunner, object>((pat, cmspec) => AddCommand(pat, cmspec)) },
                { Symbol.FromString("path-rel"), NativeProcedure.Create <string, string>(s => Path.Combine(basedir, s)) },
                { Symbol.FromString("set-arg"), NativeProcedure.Create <string, object>(s => SetArg(s)) },
                { Symbol.FromString("set-tutorial"), NativeProcedure.Create <string, object>(s => SetTutorial(s)) },
            };

            var interpreter = new Interpreter(new[] { extension }, new ReadOnlyFileSystemAccessor());

            using (Stream script = File.OpenRead(pth))
                using (TextReader reader = new StreamReader(script))
                {
                    var res = interpreter.Evaluate(reader);
                    if (res.Error != null)
                    {
                        Logic.Tutorial = res.Error.Message;
                    }
                }
        }
Esempio n. 2
0
        static void Main(string[] args)
        {
            Interpreter.CreateSymbolTableDelegate extension = _ => new Dictionary <Symbol, object>()
            {
                { Symbol.FromString("get-current-os"), NativeProcedure.Create(() => GetCurrentSystem()) },
                { Symbol.FromString("chain"), new NativeProcedure(funcs => new Function(input => funcs.Cast <Function>().Select(b => input = b(input)).Last())) },
                { Symbol.FromString("say-hi"), NativeProcedure.Create <Function>(() => name => $"Hello {name}!") },
                { Symbol.FromString("man-freebsd"), NativeProcedure.Create <Function>(() => cmd => GetUrl($"https://www.freebsd.org/cgi/man.cgi?query={cmd}&format=ascii")) },
                { Symbol.FromString("man-linux"), NativeProcedure.Create <Function>(() => cmd => GetUrl($"http://man7.org/linux/man-pages/man1/{cmd}.1.html")) },
                { Symbol.FromString("truncate-string"), NativeProcedure.Create <int, Function>(len => input => ((string)input).Substring(0, len)) },
            };

            var interpreter = new Interpreter(new[] { extension }, new ReadOnlyFileSystemAccessor());

            if (args.Contains("--repl")) // start the REPL with all implemented functions
            {
                interpreter.REPL(Console.In, Console.Out);
                return;
            }
            else
            {
                // starts a TCP server that receives request (cmd <data>) and sends response back.
                var engines = new Dictionary <string, Function>();
                foreach (var fn in Directory.GetFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "*.ss"))
                {
                    Console.WriteLine($"Loading file {fn}");
                    LoadScript(interpreter, fn);
                    engines[Path.GetFileNameWithoutExtension(fn)] = (Function)interpreter.Environment[Symbol.FromString("EXECUTE")];
                }

                string ip = "127.0.0.1"; int port = 8080;
                var    server = new TcpListener(IPAddress.Parse(ip), port);
                server.Start();
                Console.WriteLine($"Server started at {ip}:{port}");

                try
                {
                    using (var c = server.AcceptTcpClient())
                        using (var cs = c.GetStream())
                            using (var sr = new StreamReader(cs))
                                using (var sw = new StreamWriter(cs))
                                {
                                    Console.WriteLine($"Client accepted at {c.Client.RemoteEndPoint}");
                                    while (!sr.EndOfStream)
                                    {
                                        string   line   = sr.ReadLine();
                                        string[] parsed = line.Split(new[] { ' ' }, 2);
                                        if (parsed.Length != 2)
                                        {
                                            sw.WriteLine($"cannot parse {line}");
                                            sw.Flush();
                                        }
                                        else
                                        {
                                            string engine = parsed[0], request = parsed[1];
                                            if (!engines.ContainsKey(engine))
                                            {
                                                sw.WriteLine($"engine not found: {engine}");
                                                sw.Flush();
                                            }
                                            else
                                            {
                                                string output = (string)(engines[engine](request));
                                                sw.WriteLine(output);
                                                sw.Flush();
                                            }
                                        }
                                    }
                                }
                }
                catch (IOException) { }
            }
        }
Esempio n. 3
0
        public static void Main(string[] args)
        {
            Interpreter.CreateSymbolTableDelegate extension = _ => new Dictionary <Symbol, object>()
            {
                { Symbol.FromString("say-hi"), NativeProcedure.Create <Function>(() => name => $"Hello {name}!") },
                { Symbol.FromString("truncate-string"), NativeProcedure.Create <int, Function>(len => input => ((string)input).Substring(0, len)) },
                { Symbol.FromString("dump"), NativeProcedure.Create <object>(() => Symbol.AllSymbols()) },
                { Symbol.FromString("print"), NativeProcedure.Create <object, object>((arg) => Print(arg)) },
                { Symbol.FromString("typeof"), NativeProcedure.Create <object, object>((arg) => {
                        if (null == arg)
                        {
                            return(null);
                        }
                        return(arg.GetType());
                    }) }
            };

            // TODO: math

            /*
             * 1 三角函数
             * double sin (double x);  x的正弦值
             * double cos (double x);  x的余弦值
             * double tan (double x);  x的正切值
             *
             * 2 反三角函数
             * double asin (double x); 结果介于[-PI/2, PI/2],x值域为[-1,1]
             * double acos (double x); 结果介于[0, PI],x值域为[-1,1]
             * double atan (double x); 反正切(主值), 结果介于[-PI/2, PI/2]
             * double atan2 (double y, double x); 反正切(整圆值), 结果介于[-PI, PI]
             *
             * 3 双曲三角函数
             * double sinh (double x);  x的双曲正弦值
             * double cosh (double x);  x的双曲余弦值
             * double tanh (double x);  x的双曲正切值
             *
             * 4 指数与对数
             * double exp (double x);  幂函数e^x
             * double pow (double x, double y); x^y,如果x=0且y<=0,或者x<0且y不是整型数,将产生定义域错误
             * double sqrt (double x); x的平方根,其中x>=0
             * double log (double x); 以e为底的对数,自然对数,x>0
             * double log10 (double x); 以10为底的对数,x>0
             *
             * 5 取整
             * double ceil (double x); 取上整
             * double floor (double x); 取下整
             *
             * 6 绝对值
             * double fabs (double x);  x的绝对值
             *
             * 7 标准化浮点数
             * double frexp (double x, int *exp); 标准化浮点数, x = f * 2^exp, 已知x求f, exp ( x介于[0.5, 1] )并返回f值
             * double ldexp (double x, int exp); 与frexp相反, 已知x, exp求x*2^exp
             *
             * 8 取整与取余
             * double modf (double x, double *ip); 将参数的整数部分通过指针回传, 返回小数部分,整数部分保存在*ip中
             * double fmod (double x, double y); 返回两参数相除x/y的余数,符号与x相同。如果y为0,则结果与具体的额实现有关。
             */
            // max, min, abs
            // TODO: logic(and, or)
            // TODO: c# Reflection
            // TODO: string operations (upper, lower, substring, regex)
            // TODO: hash/dict
            // TODO: set-car! set-cdr!
            // TODO: alist
            // misc: incf decf ++ -- to-delegate

            // Console.WriteLine("Args: {0}#{1} {2}", args, args.Length, args[0]);
            if (args.Length > 0 && File.Exists(args[0]))
            {
                // evaluate input file's content
                var file = args[0];
                // Console.WriteLine("Eval file ...");
                var interpreter = new Interpreter(new[] { extension }, new ReadOnlyFileSystemAccessor());

                using (TextReader reader = new StreamReader(file))
                {
                    object res = interpreter.Evaluate(reader);
                    Console.WriteLine(Utils.PrintExpr(res));
                }
            }
            else
            {
                // starts the REPL
                var interpreter = new Interpreter(new[] { extension }, new ReadOnlyFileSystemAccessor());
                var headers     = new[]
                {
                    "-----------------------------------------------",
                    "| Schemy - Scheme as a Configuration Language |",
                    "| Press Ctrl-C to exit                        |",
                    "-----------------------------------------------",
                };

                interpreter.REPL(Console.In, Console.Out, "Schemy> ", headers);
            }
        }
Esempio n. 4
0
        public static Interpreter CreateItpl()
        {
            Interpreter.CreateSymbolTableDelegate appExt = _ => new Dictionary <Symbol, object>()
            {
                { Symbol.FromString("repl"), NativeProcedure.Create(() => { RunRepl(); return(None.Instance); }) },

                { Symbol.FromString("os-system"), NativeProcedure.Create <string, string, Process>((cmd, arg) =>
                                                                                                   ConvenienceRun(cmd, arg, null)) },
                { Symbol.FromString("unzip"), NativeProcedure.Create <string, string, None>((zipfile, targetdir) =>
                    {
                        ZipFile.ExtractToDirectory(zipfile, targetdir);
                        return(None.Instance);
                    }) },
                { Symbol.FromString("wget"), NativeProcedure.Create <string, string, None>((url, fname) =>
                    {
                        new WebClient().DownloadFile(url, fname);
                        return(None.Instance);
                    }) },

                { Symbol.FromString("ps-wait"), NativeProcedure.Create <Process, int>(p => {
                        p.WaitForExit();
                        return(p.ExitCode);
                    }) },

                { Symbol.FromString("print"), NativeProcedure.Create <object, object>(o => {
                        Console.WriteLine(Schemy.Utils.PrintExpr(o));
                        return(None.Instance);
                    }) },

                { Symbol.FromString("os-exit"), NativeProcedure.Create <int, object>(exitCode => {
                        System.Environment.Exit(exitCode);
                        return(None.Instance);
                    }) },
                { Symbol.FromString("cd"), NativeProcedure.Create <string, None>(path => {
                        System.Environment.CurrentDirectory = path;
                        return(None.Instance);
                    }) },

                { Symbol.FromString("pwd"), NativeProcedure.Create(() => System.Environment.CurrentDirectory) },
                { Sym("getenv"), NativeProcedure.Create <string, string>((s) => System.Environment.GetEnvironmentVariable(s)) },

                { Sym("path-join"), NativeProcedure.Create <List <object>, string> (parts => Path.Combine(parts.Cast <string>().ToArray())) },
                { Sym("path-tempfile"), NativeProcedure.Create(() => Path.GetTempFileName()) },
                { Sym("path-temppath"), NativeProcedure.Create(() => Path.GetTempPath()) },
                { Sym("path-random"), NativeProcedure.Create(() => Path.GetRandomFileName()) },
                { Sym("path-remove"), NativeProcedure.Create <string, None>(pth => {
                        File.Delete(pth);
                        return(None.Instance);
                    }) },
                { Sym("s-format"), NativeProcedure.Create <string, List <object>, string>((formatString, args) =>
                                                                                          String.Format(formatString, args.ToArray())) },
                { Sym("help"), NativeProcedure.Create(() => AppInterpreter.Environment.store.Keys.Select(k => k.AsString).Cast <object>().ToList()) },
                { Symbol.FromString("s-join"), NativeProcedure.Create <string, List <object>, string> ((sep, strings) => String.Join(sep, strings.Cast <string>().ToArray())) },
                { Symbol.FromString("guess-file"), NativeProcedure.Create <string, List <object>, string>((defaultName, l) =>
                    {
                        var found = l.Cast <string>().FirstOrDefault(e => File.Exists(e));
                        return(found == null ? defaultName : found);
                    }) },
            };
            var itpl = new Interpreter(new[] { appExt });

            return(itpl);
        }