/// <summary> /// Creates a new environment which has access to a previous environment /// </summary> public Environment(Environment environment) { this.previousEnvironment = environment; AssignLocal(Symbol.FromName("environment"), this); }
/// <summary> /// (let symbol value expression*) /// </summary> public static Object Let(Cons args, LSharp.Environment environment) { string v = //"//(let " + Printer.ConsToString(args) + ")" + NewLine + "{" + NewLine; LSharp.Environment localEnvironment = new LSharp.Environment(environment); v += GenerateAssignLocal((Symbol) args.First(), Generate(args.Second(),environment), localEnvironment); foreach (object item in (Cons)args.Cddr()) { v += Generate(item, localEnvironment); } return v + "}" + NewLine; }
/// <summary> /// (to variable limit expression) /// </summary> public static Object To(Cons args, LSharp.Environment environment) { string v = //"//(to " + Printer.ConsToString(args) + ")" + NewLine + "{" + NewLine; LSharp.Environment localEnvironment = new LSharp.Environment(environment); v += GenerateAssignLocal(args.First() as Symbol, 0, localEnvironment); v += Generate(args.Second(),environment); string lbl = MakeUnique("endstop"); v += string.Format(@" int {1} = (int)retval; while ({0} < {1}) {{ ", localEnvironment.GetValue(args.First() as Symbol), lbl); foreach (object item in (Cons)args.Cddr()) { v += Generate(item, localEnvironment); } v += localEnvironment.GetValue(args.First() as Symbol) + "++;"; v += "}" + NewLine; v += string.Format(@" retval = null; "); return v + "}" + NewLine; }
/// <summary> /// (each symbol IEnumerable expression) /// </summary> public static Object ForEach(Cons args, LSharp.Environment environment) { //string v = "//(each " + Printer.ConsToString(args) + ")" + NewLine; string v = ""; LSharp.Environment localEnvironment = new LSharp.Environment(environment); Symbol variable = (Symbol) args.First(); string vn = localEnvironment.AssignLocal(variable, MakeUnique(variable.Name)) as string; v += Generate(args.Second(),environment) + string.Format(@" foreach (object {0} in (System.Collections.IEnumerable)retval) {{", vn); foreach (object item in (Cons)args.Cddr()) { v += Generate(item, localEnvironment); } v += "}" + NewLine; return v; }
/// <summary> /// (for initialiser test iterator statement) /// </summary> public static Object For(Cons args, LSharp.Environment environment) { //string v = "//(for " + Printer.ConsToString(args) + ")" + NewLine + "{" + NewLine; string v = "{" + NewLine; LSharp.Environment localEnvironment = new LSharp.Environment(environment); v += Generate(args.First(),localEnvironment); v += Generate(args.Second(),localEnvironment); v += @"while ((Conversions.ObjectToBoolean(retval)) { "; foreach (object item in (Cons)args.Cdddr()) { v += Generate(item, localEnvironment); } v += Generate(args.Third(),localEnvironment); v += Generate(args.Second(),localEnvironment); v += @"} "; return v + "}" + NewLine; }
public static CompilerResults CompileExe(string infile, LSharp.Environment environment) { currsymbols.Clear(); extracode = string.Empty; LSharp.Environment localEnvironment = new LSharp.Environment(environment); using (TextReader r = File.OpenText(infile)) { string src = "(do " + r.ReadToEnd() + ")"; object fc = Reader.Read(new StringReader(src), ReadTable.DefaultReadTable()); // reads string into parsed data try { Runtime.Eval(fc, environment); // so that .NET calls work... fix this } catch (Exception) { // quietly ignore. } string gc = Compiler.Generate(fc, localEnvironment); string code = @" using System; sealed class generated { [STAThread] static int Main(string[] cmdargs) { LSharp.Environment environment = new LSharp.Environment(); object retval = null; "; code += gc; code += @" if (retval is int) { return (int) retval; } return 0; } "; code += extracode; code += @" }"; CompilerResults cr=null; if (false) //(args.processonly) { string outfile = Path.ChangeExtension(infile, ".cs"); using (TextWriter w = File.CreateText(outfile)) { w.WriteLine(code); return null; } } else { if (false) //(args.optimize) { copts.CompilerOptions = "/o+"; } else { copts.CompilerOptions = "/o-"; } copts.IncludeDebugInformation = true; //args.debug; copts.GenerateExecutable = true; //args.target == Target.Exe; copts.GenerateExecutable = true; string name = Path.ChangeExtension(infile, copts.GenerateExecutable ? ".exe" : ".dll"); Console.WriteLine(code); // to see the code created File.WriteAllText(Path.ChangeExtension(infile, ".cs"), code); // write to a *.cs file copts.OutputAssembly = name; cr = comp.CompileAssemblyFromSource(copts, code); if (cr.NativeCompilerReturnValue == 0) { return cr; } else { foreach (CompilerError err in cr.Errors) { Console.Error.WriteLine("Compiler error: {0}", err.ToString()); } } //} } return cr; } }
/// <summary> /// (compile symbols*) /// </summary> public static CompilerResults CompileDll(Cons args, LSharp.Environment environment) { currsymbols.Clear(); extracode = string.Empty; LSharp.Environment localEnvironment = new LSharp.Environment(environment); string name = MakeUnique("gen"); while (File.Exists(name + ".dll")) { name = MakeUnique("gen"); } string gc = Closure(args, localEnvironment) as string; if (gc.Length == 0) { return null; } string code = string.Format(@" public sealed class {0} {{ ", name); code += gc; code += extracode; code += "\n}"; copts.GenerateExecutable = false; copts.OutputAssembly = name + ".dll"; CompilerResults cr = comp.CompileAssemblyFromSource(copts, code); if (cr.NativeCompilerReturnValue == 0) { //Assembly genass = cr.CompiledAssembly; //return Runtime.Import(genass.Location, environment); } else { foreach (CompilerError err in cr.Errors) { Console.Error.WriteLine("Compiler error: {0}", err); } return cr; } return cr; }
/// <summary> /// (with ((symbol value)* ) expression*) /// </summary> public static Object With(Cons args, LSharp.Environment environment) { string v = //"//(with " + Printer.ConsToString(args) + ")" + NewLine + "{" + NewLine; Cons bindings = (Cons)args.First(); LSharp.Environment localEnvironment = new LSharp.Environment(environment); while ((bindings != null) && (bindings.Length() > 1)) { v += GenerateAssignLocal((Symbol) bindings.First(), Generate(bindings.Second(),environment), localEnvironment); bindings = (Cons)bindings.Cddr(); } foreach (object item in (Cons)args.Cdr()) { v += Generate(item, localEnvironment); } return v + "}"; }