public static Expr Parse(ParserContext pcon, ISeq form, string name) { ISeq origForm = form; FnExpr fn = new FnExpr(Compiler.TagOf(form)); fn._src = form; if (((IMeta)form.first()).meta() != null) { fn._onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE)); } fn.ComputeNames(form, name); // Java: fn.objtype = Type.getObjectType(fn.internalName) -- makes no sense for us, this is ASM only. List<string> prims = new List<string>(); try { Var.pushThreadBindings(RT.map( Compiler.CONSTANTS, PersistentVector.EMPTY, Compiler.CONSTANT_IDS, new IdentityHashMap(), Compiler.KEYWORDS, PersistentHashMap.EMPTY, Compiler.VARS, PersistentHashMap.EMPTY, Compiler.KEYWORD_CALLSITES,PersistentVector.EMPTY, Compiler.PROTOCOL_CALLSITES,PersistentVector.EMPTY, Compiler.VAR_CALLSITES,Compiler.EmptyVarCallSites(), Compiler.NO_RECUR,null)); //arglist might be preceded by symbol naming this fn if (RT.second(form) is Symbol) { Symbol nm = (Symbol)RT.second(form); fn._thisName = nm.Name; fn.IsStatic = false; // RT.booleanCast(RT.get(nm.meta(), Compiler.STATIC_KEY)); form = RT.cons(Compiler.FN, RT.next(RT.next(form))); } // Normalize body //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...) //turn former into latter if (RT.second(form) is IPersistentVector) form = RT.list(Compiler.FN, RT.next(form)); SortedDictionary<int, FnMethod> methods = new SortedDictionary<int, FnMethod>(); FnMethod variadicMethod = null; for (ISeq s = RT.next(form); s != null; s = RT.next(s)) { FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s),fn.IsStatic); if (f.IsVariadic) { if (variadicMethod == null) variadicMethod = f; else throw new Exception("Can't have more than 1 variadic overload"); } else if (!methods.ContainsKey(f.RequiredArity)) methods[f.RequiredArity] = f; else throw new Exception("Can't have 2 overloads with the same arity."); if (f.Prim != null) prims.Add(f.Prim); } if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams) throw new Exception("Can't have fixed arity methods with more params than the variadic method."); if ( fn.IsStatic && fn.Closes.count() > 0 ) throw new ArgumentException("static fns can't be closures"); IPersistentCollection allMethods = null; foreach (FnMethod method in methods.Values) allMethods = RT.conj(allMethods, method); if (variadicMethod != null) allMethods = RT.conj(allMethods, variadicMethod); fn._methods = allMethods; fn._variadicMethod = variadicMethod; fn.Keywords = (IPersistentMap)Compiler.KEYWORDS.deref(); fn.Vars = (IPersistentMap)Compiler.VARS.deref(); fn.Constants = (PersistentVector)Compiler.CONSTANTS.deref(); fn.KeywordCallsites = (IPersistentVector)Compiler.KEYWORD_CALLSITES.deref(); fn.ProtocolCallsites = (IPersistentVector)Compiler.PROTOCOL_CALLSITES.deref(); fn.VarCallsites = (IPersistentSet)Compiler.VAR_CALLSITES.deref(); fn._constantsID = RT.nextID(); } finally { Var.popThreadBindings(); } IPersistentMap fmeta = RT.meta(origForm); if (fmeta != null) fmeta = fmeta.without(RT.LINE_KEY).without(RT.FILE_KEY); fn._hasMeta = RT.count(fmeta) > 0; if (Compiler.IsCompiling || prims.Count > 0) { GenContext context = Compiler.COMPILER_CONTEXT.get() as GenContext ?? Compiler.EvalContext; GenContext genC = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString()); IPersistentVector primTypes = PersistentVector.EMPTY; foreach (string typename in prims) primTypes = primTypes.cons(Type.GetType(typename)); fn.Compile( fn.IsVariadic ? typeof(RestFn) : typeof(AFunction), null, primTypes, fn.OnceOnly, genC); } else { fn.CompiledType = fn.GetPrecompiledType(); fn.FnMode = FnMode.Light; } if (fn.SupportsMeta) return new MetaExpr(fn, MapExpr.Parse(pcon.EvEx(),fmeta)); else return fn; }
public static Expr Parse(object frm, string name, bool isRecurContext) { ISeq form = (ISeq)frm; FnExpr fn = new FnExpr(Compiler.TagOf(form)); if (((IMeta)form.first()).meta() != null) { fn._onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE)); fn._superName = (string)RT.get(RT.meta(form.first()), KW_SUPER_NAME); } fn.ComputeNames(form, name); try { Var.pushThreadBindings(RT.map( Compiler.CONSTANTS, PersistentVector.EMPTY, Compiler.KEYWORDS, PersistentHashMap.EMPTY, Compiler.VARS, PersistentHashMap.EMPTY)); //arglist might be preceded by symbol naming this fn if (RT.second(form) is Symbol) { fn._thisName = ((Symbol)RT.second(form)).Name; form = RT.cons(Compiler.FN, RT.next(RT.next(form))); } // Normalize body // If it is (fn [arg...] body ...), turn it into // (fn ([arg...] body...)) // so that we can treat uniformly as (fn ([arg...] body...) ([arg...] body...) ... ) if (RT.second(form) is IPersistentVector) form = RT.list(Compiler.FN, RT.next(form)); fn._line = (int)Compiler.LINE.deref(); FnMethod variadicMethod = null; SortedDictionary<int, FnMethod> methods = new SortedDictionary<int, FnMethod>(); for (ISeq s = RT.next(form); s != null; s = RT.next(s)) { FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s)); if (f.IsVariadic) { if (variadicMethod == null) variadicMethod = f; else throw new Exception("Can't have more than 1 variadic overload"); } else if (!methods.ContainsKey(f.RequiredArity)) methods[f.RequiredArity] = f; else throw new Exception("Can't have 2 overloads with the same arity."); } if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams) throw new Exception("Can't have fixed arity methods with more params than the variadic method."); IPersistentCollection allMethods = null; foreach (FnMethod method in methods.Values) allMethods = RT.conj(allMethods, method); if (variadicMethod != null) allMethods = RT.conj(allMethods, variadicMethod); fn._methods = allMethods; fn._variadicMethod = variadicMethod; fn._keywords = (IPersistentMap)Compiler.KEYWORDS.deref(); fn._vars = (IPersistentMap)Compiler.VARS.deref(); fn._constants = (PersistentVector)Compiler.CONSTANTS.deref(); fn._constantsID = RT.nextID(); } finally { Var.popThreadBindings(); } // JAVA: fn.compile(); return fn; }
public static Expr Parse(ParserContext pcon, ISeq form, string name) { ISeq origForm = form; FnExpr fn = new FnExpr(Compiler.TagOf(form)); fn._src = form; if (((IMeta)form.first()).meta() != null) { fn._onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE)); } fn.ComputeNames(form, name); List<string> prims = new List<string>(); //arglist might be preceded by symbol naming this fn if (RT.second(form) is Symbol) { Symbol nm = (Symbol)RT.second(form); fn._thisName = nm.Name; fn._isStatic = false; // RT.booleanCast(RT.get(nm.meta(), Compiler.STATIC_KEY)); form = RT.cons(Compiler.FnSym, RT.next(RT.next(form))); } // Normalize body //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...) //turn former into latter if (RT.second(form) is IPersistentVector) form = RT.list(Compiler.FnSym, RT.next(form)); fn.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); GenContext newContext = null; // Uncomment -if- to enable light compilation (and see below) //bool hasPrimDecls = HasPrimDecls((ISeq)RT.next(form)); //if (Compiler.IsCompiling || hasPrimDecls || fn.IsStatic) //{ GenContext context = Compiler.CompilerContextVar.deref() as GenContext ?? Compiler.EvalContext; newContext = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString()); Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, newContext)); //} try { try { Var.pushThreadBindings(RT.mapUniqueKeys( Compiler.ConstantsVar, PersistentVector.EMPTY, Compiler.ConstantIdsVar, new IdentityHashMap(), Compiler.KeywordsVar, PersistentHashMap.EMPTY, Compiler.VarsVar, PersistentHashMap.EMPTY, Compiler.KeywordCallsitesVar, PersistentVector.EMPTY, Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY, Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(), Compiler.NoRecurVar, null)); SortedDictionary<int, FnMethod> methods = new SortedDictionary<int, FnMethod>(); FnMethod variadicMethod = null; for (ISeq s = RT.next(form); s != null; s = RT.next(s)) { FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), fn._isStatic); if (f.IsVariadic) { if (variadicMethod == null) variadicMethod = f; else throw new ParseException("Can't have more than 1 variadic overload"); } else if (!methods.ContainsKey(f.RequiredArity)) methods[f.RequiredArity] = f; else throw new ParseException("Can't have 2 overloads with the same arity."); if (f.Prim != null) prims.Add(f.Prim); } if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams) throw new ParseException("Can't have fixed arity methods with more params than the variadic method."); if (fn._isStatic && fn.Closes.count() > 0) throw new ParseException("static fns can't be closures"); IPersistentCollection allMethods = null; foreach (FnMethod method in methods.Values) allMethods = RT.conj(allMethods, method); if (variadicMethod != null) allMethods = RT.conj(allMethods, variadicMethod); fn._methods = allMethods; fn._variadicMethod = variadicMethod; fn.Keywords = (IPersistentMap)Compiler.KeywordsVar.deref(); fn.Vars = (IPersistentMap)Compiler.VarsVar.deref(); fn.Constants = (PersistentVector)Compiler.ConstantsVar.deref(); fn.KeywordCallsites = (IPersistentVector)Compiler.KeywordCallsitesVar.deref(); fn.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref(); fn.VarCallsites = (IPersistentSet)Compiler.VarCallsitesVar.deref(); fn._constantsID = RT.nextID(); } finally { Var.popThreadBindings(); } IPersistentMap fmeta = RT.meta(origForm); if (fmeta != null) fmeta = fmeta.without(RT.LineKey).without(RT.ColumnKey).without(RT.SourceSpanKey).without(RT.FileKey); fn._hasMeta = RT.count(fmeta) > 0; // Uncomment if/else to enable light compilation (and see above) //if (Compiler.IsCompiling || prims.Count > 0|| fn.IsStatic) //{ IPersistentVector primTypes = PersistentVector.EMPTY; foreach (string typename in prims) primTypes = primTypes.cons(Type.GetType(typename)); fn.Compile( fn.IsVariadic ? typeof(RestFn) : typeof(AFunction), null, primTypes, fn._onceOnly, newContext); //} //else //{ // fn.FnMode = FnMode.Light; // fn.LightCompile(fn.GetPrecompiledType(), Compiler.EvalContext); //} if (fn.SupportsMeta) return new MetaExpr(fn, MapExpr.Parse(pcon.EvalOrExpr(), fmeta)); else return fn; } finally { if (newContext != null) Var.popThreadBindings(); } }
public static Expr Parse(ParserContext pcon, ISeq form, string name) { ISeq origForm = form; FnExpr fn = new FnExpr(Compiler.TagOf(form)); fn.Src = form; if (((IMeta)form.first()).meta() != null) { fn.OnceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE)); } fn.ComputeNames(form, name); List <string> prims = new List <string>(); //arglist might be preceded by symbol naming this fn Symbol nm = RT.second(form) as Symbol; if (nm != null) { fn.ThisName = nm.Name; fn.IsStatic = false; // RT.booleanCast(RT.get(nm.meta(), Compiler.STATIC_KEY)); form = RT.cons(Compiler.FnSym, RT.next(RT.next(form))); } // Normalize body //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...) //turn former into latter if (RT.second(form) is IPersistentVector) { form = RT.list(Compiler.FnSym, RT.next(form)); } fn.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); GenContext newContext = null; GenContext context = Compiler.CompilerContextVar.deref() as GenContext ?? Compiler.EvalContext; newContext = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString()); Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, newContext)); try { try { Var.pushThreadBindings(RT.mapUniqueKeys( Compiler.ConstantsVar, PersistentVector.EMPTY, Compiler.ConstantIdsVar, new IdentityHashMap(), Compiler.KeywordsVar, PersistentHashMap.EMPTY, Compiler.VarsVar, PersistentHashMap.EMPTY, Compiler.KeywordCallsitesVar, PersistentVector.EMPTY, Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY, Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(), Compiler.NoRecurVar, null)); SortedDictionary <int, FnMethod> methods = new SortedDictionary <int, FnMethod>(); FnMethod variadicMethod = null; for (ISeq s = RT.next(form); s != null; s = RT.next(s)) { FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), fn.IsStatic); if (f.IsVariadic) { if (variadicMethod == null) { variadicMethod = f; } else { throw new ParseException("Can't have more than 1 variadic overload"); } } else if (!methods.ContainsKey(f.RequiredArity)) { methods[f.RequiredArity] = f; } else { throw new ParseException("Can't have 2 overloads with the same arity."); } if (f.Prim != null) { prims.Add(f.Prim); } } if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams) { throw new ParseException("Can't have fixed arity methods with more params than the variadic method."); } if (fn.IsStatic && fn.Closes.count() > 0) { throw new ParseException("static fns can't be closures"); } IPersistentCollection allMethods = null; foreach (FnMethod method in methods.Values) { allMethods = RT.conj(allMethods, method); } if (variadicMethod != null) { allMethods = RT.conj(allMethods, variadicMethod); } fn.Methods = allMethods; fn._variadicMethod = variadicMethod; fn.Keywords = (IPersistentMap)Compiler.KeywordsVar.deref(); fn.Vars = (IPersistentMap)Compiler.VarsVar.deref(); fn.Constants = (PersistentVector)Compiler.ConstantsVar.deref(); fn.KeywordCallsites = (IPersistentVector)Compiler.KeywordCallsitesVar.deref(); fn.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref(); fn.VarCallsites = (IPersistentSet)Compiler.VarCallsitesVar.deref(); fn.ConstantsID = RT.nextID(); } finally { Var.popThreadBindings(); } IPersistentMap fmeta = RT.meta(origForm); if (fmeta != null) { fmeta = fmeta.without(RT.LineKey).without(RT.ColumnKey).without(RT.SourceSpanKey).without(RT.FileKey); } fn._hasMeta = RT.count(fmeta) > 0; IPersistentVector primTypes = PersistentVector.EMPTY; foreach (string typename in prims) { primTypes = primTypes.cons(Type.GetType(typename)); } fn.Compile( fn.IsVariadic ? typeof(RestFn) : typeof(AFunction), null, primTypes, fn.OnceOnly, newContext); if (fn.SupportsMeta) { return(new MetaExpr(fn, MapExpr.Parse(pcon.EvalOrExpr(), fmeta))); } else { return(fn); } } finally { if (newContext != null) { Var.popThreadBindings(); } } }
public static Expr Parse(ParserContext pcon, ISeq form, string name) { ISeq origForm = form; FnExpr fn = new FnExpr(Compiler.TagOf(form)); fn.Src = form; Keyword retKey = Keyword.intern(null, "rettag"); // TODO: make static object retTag = RT.get(RT.meta(form), retKey); ObjMethod enclosingMethod = (ObjMethod)Compiler.MethodVar.deref(); fn._hasEnclosingMethod = enclosingMethod != null; if (((IMeta)form.first()).meta() != null) { fn.OnceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE)); } fn.ComputeNames(form, name); List<string> prims = new List<string>(); //arglist might be preceded by symbol naming this fn Symbol nm = RT.second(form) as Symbol; if (nm != null) { fn.ThisName = nm.Name; form = RT.cons(Compiler.FnSym, RT.next(RT.next(form))); } // Normalize body //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...) //turn former into latter if (RT.second(form) is IPersistentVector) form = RT.list(Compiler.FnSym, RT.next(form)); fn.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); GenContext newContext = null; GenContext context = Compiler.CompilerContextVar.deref() as GenContext ?? Compiler.EvalContext; newContext = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString()); Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, newContext)); try { try { Var.pushThreadBindings(RT.mapUniqueKeys( Compiler.ConstantsVar, PersistentVector.EMPTY, Compiler.ConstantIdsVar, new IdentityHashMap(), Compiler.KeywordsVar, PersistentHashMap.EMPTY, Compiler.VarsVar, PersistentHashMap.EMPTY, Compiler.KeywordCallsitesVar, PersistentVector.EMPTY, Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY, Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(), Compiler.NoRecurVar, null)); SortedDictionary<int, FnMethod> methods = new SortedDictionary<int, FnMethod>(); FnMethod variadicMethod = null; bool usesThis = false; for (ISeq s = RT.next(form); s != null; s = RT.next(s)) { FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), retTag); if ( f.UsesThis) { //Console.WriteLine("{0} uses this",fn.Name); usesThis = true; } if (f.IsVariadic) { if (variadicMethod == null) variadicMethod = f; else throw new ParseException("Can't have more than 1 variadic overload"); } else if (!methods.ContainsKey(f.RequiredArity)) methods[f.RequiredArity] = f; else throw new ParseException("Can't have 2 overloads with the same arity."); if (f.Prim != null) prims.Add(f.Prim); } if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams) throw new ParseException("Can't have fixed arity methods with more params than the variadic method."); fn.CanBeDirect = !fn._hasEnclosingMethod && fn.Closes.count() == 0 && !usesThis; IPersistentCollection allMethods = null; foreach (FnMethod method in methods.Values) allMethods = RT.conj(allMethods, method); if (variadicMethod != null) allMethods = RT.conj(allMethods, variadicMethod); if ( fn.CanBeDirect ) { for (ISeq s = RT.seq(allMethods); s != null; s = s.next()) { FnMethod fm = s.first() as FnMethod; if ( fm.Locals != null) { for (ISeq sl = RT.seq(RT.keys(fm.Locals)); sl != null; sl = sl.next()) { LocalBinding lb = sl.first() as LocalBinding; if ( lb.IsArg) lb.Index -= 1; } } } } fn.Methods = allMethods; fn._variadicMethod = variadicMethod; fn.Keywords = (IPersistentMap)Compiler.KeywordsVar.deref(); fn.Vars = (IPersistentMap)Compiler.VarsVar.deref(); fn.Constants = (PersistentVector)Compiler.ConstantsVar.deref(); fn.KeywordCallsites = (IPersistentVector)Compiler.KeywordCallsitesVar.deref(); fn.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref(); fn.VarCallsites = (IPersistentSet)Compiler.VarCallsitesVar.deref(); fn.ConstantsID = RT.nextID(); } finally { Var.popThreadBindings(); } IPersistentMap fmeta = RT.meta(origForm); if (fmeta != null) fmeta = fmeta.without(RT.LineKey).without(RT.ColumnKey).without(RT.SourceSpanKey).without(RT.FileKey).without(retKey); fn._hasMeta = RT.count(fmeta) > 0; IPersistentVector primTypes = PersistentVector.EMPTY; foreach (string typename in prims) primTypes = primTypes.cons(Type.GetType(typename)); fn.Compile( fn.IsVariadic ? typeof(RestFn) : typeof(AFunction), null, primTypes, fn.OnceOnly, newContext); if (fn.SupportsMeta) return new MetaExpr(fn, MapExpr.Parse(pcon.EvalOrExpr(), fmeta)); else return fn; } finally { if (newContext != null) Var.popThreadBindings(); } }
public static Expr Parse(object frm, string name) { ISeq form = (ISeq)frm; FnExpr fn = new FnExpr(Compiler.TagOf(form)); if (((IMeta)form.first()).meta() != null) { fn._onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE)); fn._superName = (string)RT.get(RT.meta(form.first()), KW_SUPER_NAME); } fn.ComputeNames(form, name); try { Var.pushThreadBindings(RT.map( Compiler.CONSTANTS, PersistentVector.EMPTY, Compiler.KEYWORDS, PersistentHashMap.EMPTY, Compiler.VARS, PersistentHashMap.EMPTY)); //arglist might be preceded by symbol naming this fn if (RT.second(form) is Symbol) { fn._thisName = ((Symbol)RT.second(form)).Name; form = RT.cons(Compiler.FN, RT.next(RT.next(form))); } // Normalize body // If it is (fn [arg...] body ...), turn it into // (fn ([arg...] body...)) // so that we can treat uniformly as (fn ([arg...] body...) ([arg...] body...) ... ) if (RT.second(form) is IPersistentVector) { form = RT.list(Compiler.FN, RT.next(form)); } FnMethod variadicMethod = null; SortedDictionary <int, FnMethod> methods = new SortedDictionary <int, FnMethod>(); for (ISeq s = RT.next(form); s != null; s = RT.next(s)) { FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s)); if (f.IsVariadic) { if (variadicMethod == null) { variadicMethod = f; } else { throw new Exception("Can't have more than 1 variadic overload"); } } else if (!methods.ContainsKey(f.RequiredArity)) { methods[f.RequiredArity] = f; } else { throw new Exception("Can't have 2 overloads with the same arity."); } } if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams) { throw new Exception("Can't have fixed arity methods with more params than the variadic method."); } IPersistentCollection allMethods = null; foreach (FnMethod method in methods.Values) { allMethods = RT.conj(allMethods, method); } if (variadicMethod != null) { allMethods = RT.conj(allMethods, variadicMethod); } fn._methods = allMethods; fn._variadicMethod = variadicMethod; fn._keywords = (IPersistentMap)Compiler.KEYWORDS.deref(); fn._vars = (IPersistentMap)Compiler.VARS.deref(); fn._constants = (PersistentVector)Compiler.CONSTANTS.deref(); fn._constantsID = RT.nextID(); } finally { Var.popThreadBindings(); } // JAVA: fn.compile(); return(fn); }