/// <summary> /// (defmethod name "arg1 arg2" "(expression1)" "(expression 2)" [...]) /// Created methods used for DefClass <br /> /// </summary> /// <param name="args"></param> /// <param name="e"></param> /// <returns></returns> public static object DefMethod(Cons args, Environment e) { string name; string[] _args; string commands = ""; name = args.First().ToString(); _args = args.Second().ToString().Split(new string[] {" "}, StringSplitOptions.None);; for (int i = 2; i < args.Length(); i++) commands += args.Nth(i) + " "; commands = commands.Replace("\\", "\\\\"); commands = commands.Replace("\"", "\\\""); //FIXME: //code = code.Replace("\n", "\\n"); DefinedMethod ret = new DefinedMethod(commands, name, _args); e.AssignLocal(Symbol.FromName(name), ret); Console.WriteLine("Assigned '" + ret.Name + "' as a DefinedMethod"); return ret; }
public static Type CreateClass(string className, string superClass, string interfaces, DefinedMethod[] LSharpCode) { StringBuilder source = new StringBuilder("using System;\n"); source.AppendLine("using LSharp; "); if (superClass == null) source.AppendLine(string.Format("class {0} {{",className)); else source.AppendLine(string.Format("class {0} : {1} {{",className, superClass)); foreach (DefinedMethod method in LSharpCode) { try { source.Append("public object " + method.Name + "("); // 9/30/11 fixed so 0 arguments are allowed. if (method.args.Length > 0 & !string.IsNullOrEmpty(method.args[0])) { source.Append("object " + method.args[0]); for (int i = 1; i < method.args.Length; i++) source.Append(", object " + method.args[i]); } source.Append(") {\n"); source.Append("object retValue = null;"); source.Append("\tLSharp.Environment env = new LSharp.Environment();\n"); if (method.args.Length > 0 & !string.IsNullOrEmpty(method.args[0])) { source.AppendLine("\tRuntime.EvalString(\"(= " + method.args[0] + " \" + " + method.args[0] + " + \")\", env);"); for (int i = 1; i < method.args.Length; i++) source.AppendLine("\tRuntime.EvalString(\"(= " + method.args[i] + " \" + " + method.args[i] + " + \")\", env);"); } source.Append("\tretValue = Runtime.Eval(Reader.Read(new System.IO.StringReader(\"" + method.Commands + "\"), ReadTable.DefaultReadTable()), env);\n"); source.Append("return retValue;\n"); // TODO: return results of above commands source.Append("}\n"); } catch (Exception e) { Console.WriteLine(e.Message); source.AppendLine("// ERROR: " + e.Message); } } source.AppendLine("}"); Console.WriteLine(source.ToString()); CSharpCodeProvider cscompiler = new CSharpCodeProvider(); ICodeCompiler compiler = cscompiler.CreateCompiler(); CompilerParameters compparams = new CompilerParameters(); compparams.GenerateInMemory = true; compparams.ReferencedAssemblies.Add("LSharp.dll"); // foreach (Assembly a in AssemblyCache.Instance().Assemblies()) { // compparams.ReferencedAssemblies.Add(a.FullName); // } CompilerResults compresult = compiler.CompileAssemblyFromSource( compparams, source.ToString()); if ( compresult == null | compresult.Errors.Count > 0 ) { foreach (CompilerError e in compresult.Errors) { Console.WriteLine(e); } throw new Exception("class creation error"); } Object o = TypeCache.FindType(className); if (o != null) { Assembly a = Assembly.GetAssembly(o as Type); AssemblyCache.Instance().Remove(a); } AssemblyCache.Instance().Add(compresult.CompiledAssembly); return compresult.CompiledAssembly.GetType(className); }
/// <summary> /// Creates a dynamic class /// (defclass "classname" "inheritsfrom" [defmethod]) /// e.g. (defclass "class1" "Object" DefinedMethods*) /// </summary> /// <param name="args"></param> /// <param name="environment"></param> /// <returns></returns> public static Object DefClass(Cons args, Environment environment) { string className = args.First().ToString(); string superClass = args.Second().ToString(); DefinedMethod[] methods = new DefinedMethod[args.Length() - 2]; for (int i = 2; i < args.Length(); i++) { try { Symbol toFind = (Symbol) args.Nth(i); object foundMethod = environment.GetValue(toFind); methods[i - 2] = (DefinedMethod) foundMethod; } catch (Exception e ) { Console.WriteLine("DEFCLASS ERROR: " + e.Message + " " + e.StackTrace); } } return ClassBuilder.CreateClass(className, superClass, "", methods); }