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; } } }
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) { } } }
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); } }
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); }