internal static object Compile(TextReader rdr, string sourceDirectory, string sourceName, string relativePath) { if (CompilePathVar.deref() == null) throw new InvalidOperationException("*compile-path* not set"); object eofVal = new object(); object form; //string sourcePath = sourceDirectory == null ? sourceName : sourceDirectory + "\\" + sourceName; string sourcePath = relativePath; LineNumberingTextReader lntr = rdr as LineNumberingTextReader ?? new LineNumberingTextReader(rdr); GenContext context = GenContext.CreateWithExternalAssembly(relativePath, ".dll", true); GenContext evalContext = GenContext.CreateWithInternalAssembly("EvalForCompile", false); Var.pushThreadBindings(RT.map( SourcePathVar, sourcePath, SourceVar, sourceName, MethodVar, null, LocalEnvVar, null, LoopLocalsVar, null, NextLocalNumVar, 0, RT.CurrentNSVar, RT.CurrentNSVar.deref(), //LINE_BEFORE, lntr.LineNumber, //LINE_AFTER, lntr.LineNumber, DocumentInfoVar, Expression.SymbolDocument(sourceName), // I hope this is enough ConstantsVar, PersistentVector.EMPTY, ConstantIdsVar, new IdentityHashMap(), KeywordsVar, PersistentHashMap.EMPTY, VarsVar, PersistentHashMap.EMPTY, RT.UncheckedMathVar, RT.UncheckedMathVar.deref(), RT.WarnOnReflectionVar, RT.WarnOnReflectionVar.deref(), RT.DataReadersVar, RT.DataReadersVar.deref(), //KEYWORD_CALLSITES, PersistentVector.EMPTY, // jvm doesn't do this, don't know why //VAR_CALLSITES, EmptyVarCallSites(), // jvm doesn't do this, don't know why //PROTOCOL_CALLSITES, PersistentVector.EMPTY, // jvm doesn't do this, don't know why CompilerContextVar, context )); try { FnExpr objx = new FnExpr(null); objx.InternalName = sourcePath.Replace(Path.PathSeparator, '/').Substring(0, sourcePath.LastIndexOf('.')) + "__init"; TypeBuilder exprTB = context.AssemblyGen.DefinePublicType("__REPL__", typeof(object), true); //List<string> names = new List<string>(); List<Expr> exprs = new List<Expr>(); int i = 0; while ((form = LispReader.read(lntr, false, eofVal, false)) != eofVal) { //Java version: LINE_AFTER.set(lntr.LineNumber); Compile1(context, evalContext, exprTB, form, exprs, ref i); //Java version: LINE_BEFORE.set(lntr.LineNumber); } exprTB.CreateType(); // Need to put the loader init in its own type because we can't generate calls on the MethodBuilders // until after their types have been closed. TypeBuilder initTB = context.AssemblyGen.DefinePublicType("__Init__", typeof(object), true); Expression pushNSExpr = Expression.Call(null, Method_Compiler_PushNS); Expression popExpr = Expression.Call(null, Method_Var_popThreadBindings); BodyExpr bodyExpr = new BodyExpr(PersistentVector.create1(exprs)); FnMethod method = new FnMethod(objx, null, bodyExpr); objx.AddMethod(method); objx.Keywords = (IPersistentMap)KeywordsVar.deref(); objx.Vars = (IPersistentMap)VarsVar.deref(); objx.Constants = (PersistentVector)ConstantsVar.deref(); //objx.KeywordCallsites = (IPersistentVector)KEYWORD_CALLSITES.deref(); //objx.ProtocolCallsites = (IPersistentVector)PROTOCOL_CALLSITES.deref(); //objx.VarCallsites = (IPersistentSet)VAR_CALLSITES.deref(); objx.KeywordCallsites = PersistentVector.EMPTY; objx.ProtocolCallsites = PersistentVector.EMPTY; objx.VarCallsites = (IPersistentSet)EmptyVarCallSites(); objx.Compile(typeof(AFunction), null, PersistentVector.EMPTY, false, context); Expression fnNew = objx.GenCode(RHC.Expression,objx,context); Expression fnInvoke = Expression.Call(fnNew, fnNew.Type.GetMethod("invoke", System.Type.EmptyTypes)); Expression tryCatch = Expression.TryCatchFinally(fnInvoke, popExpr); Expression body = Expression.Block(pushNSExpr, tryCatch); // create initializer call MethodBuilder mbInit = initTB.DefineMethod("Initialize", MethodAttributes.Public | MethodAttributes.Static); LambdaExpression initFn = Expression.Lambda(body); //initFn.CompileToMethod(mbInit, DebugInfoGenerator.CreatePdbGenerator()); initFn.CompileToMethod(mbInit, context.IsDebuggable); initTB.CreateType(); context.SaveAssembly(); } catch (LispReader.ReaderException e) { throw new CompilerException(sourcePath, e.Line, e.InnerException); } finally { Var.popThreadBindings(); } return null; }
internal static object Compile(TextReader rdr, string sourceDirectory, string sourceName, string relativePath) { if (COMPILE_PATH.deref() == null) throw new Exception("*compile-path* not set"); object eofVal = new object(); object form; //string sourcePath = sourceDirectory == null ? sourceName : sourceDirectory + "\\" + sourceName; string sourcePath = relativePath; LineNumberingTextReader lntr = (rdr is LineNumberingTextReader) ? (LineNumberingTextReader)rdr : new LineNumberingTextReader(rdr); GenContext context = new GenContext(sourceName, ".dll", sourceDirectory, true); GenContext evalContext = new GenContext("EvalForCompile", false); Var.pushThreadBindings(RT.map( SOURCE_PATH, sourcePath, SOURCE, sourceName, METHOD, null, LOCAL_ENV, null, LOOP_LOCALS, null, NEXT_LOCAL_NUM, 0, RT.CURRENT_NS, RT.CURRENT_NS.deref(), //LINE_BEFORE, lntr.LineNumber, //LINE_AFTER, lntr.LineNumber, DOCUMENT_INFO, Expression.SymbolDocument(sourceName), // I hope this is enough CONSTANTS, PersistentVector.EMPTY, CONSTANT_IDS, new IdentityHashMap(), KEYWORDS, PersistentHashMap.EMPTY, VARS, PersistentHashMap.EMPTY, KEYWORD_CALLSITES, PersistentVector.EMPTY, // jvm doesn't do this, don't know why VAR_CALLSITES, PersistentVector.EMPTY, // jvm doesn't do this, don't know why PROTOCOL_CALLSITES, PersistentVector.EMPTY, // jvm doesn't do this, don't know why COMPILER_CONTEXT, context )); try { FnExpr objx = new FnExpr(null); objx.InternalName = sourcePath.Replace(Path.PathSeparator, '/').Substring(0, sourcePath.LastIndexOf('.')) + "__init"; TypeBuilder exprTB = context.AssemblyGen.DefinePublicType("__REPL__", typeof(object), true); //List<string> names = new List<string>(); List<Expr> exprs = new List<Expr>(); int i = 0; while ((form = LispReader.read(lntr, false, eofVal, false)) != eofVal) { //Java version: LINE_AFTER.set(lntr.LineNumber); Compile1(context, evalContext, exprTB, form, exprs, ref i); //Java version: LINE_BEFORE.set(lntr.LineNumber); } Type exprType = exprTB.CreateType(); // Need to put the loader init in its own type because we can't generate calls on the MethodBuilders // until after their types have been closed. TypeBuilder initTB = context.AssemblyGen.DefinePublicType("__Init__", typeof(object), true); Expression pushNSExpr = Expression.Call(null, Method_Compiler_PushNS); Expression popExpr = Expression.Call(null, Method_Var_popThreadBindings); BodyExpr bodyExpr = new BodyExpr(PersistentVector.create1(exprs)); FnMethod method = new FnMethod(objx, null, bodyExpr); objx.AddMethod(method); objx.Keywords = (IPersistentMap)KEYWORDS.deref(); objx.Vars = (IPersistentMap)VARS.deref(); objx.Constants = (PersistentVector)CONSTANTS.deref(); objx.KeywordCallsites = (IPersistentVector)KEYWORD_CALLSITES.deref(); objx.ProtocolCallsites = (IPersistentVector)PROTOCOL_CALLSITES.deref(); objx.VarCallsites = (IPersistentVector)VAR_CALLSITES.deref(); objx.Compile(typeof(AFunction), PersistentVector.EMPTY, false, context); Expression fnNew = objx.GenCode(RHC.Expression,objx,context); Expression fnInvoke = Expression.Call(fnNew, fnNew.Type.GetMethod("invoke", System.Type.EmptyTypes)); Expression tryCatch = Expression.TryCatchFinally(fnInvoke, popExpr); Expression body = Expression.Block(pushNSExpr, tryCatch); // create initializer call MethodBuilder mbInit = initTB.DefineMethod("Initialize", MethodAttributes.Public | MethodAttributes.Static); LambdaExpression initFn = Expression.Lambda(body); //initFn.CompileToMethod(mbInit, DebugInfoGenerator.CreatePdbGenerator()); initFn.CompileToMethod(mbInit, context.IsDebuggable); initTB.CreateType(); context.SaveAssembly(); } catch (LispReader.ReaderException e) { throw new CompilerException(sourceName, e.Line, e.InnerException); } finally { Var.popThreadBindings(); } return null; }