public static Expr Parse(ParserContext pcon, IPersistentVector form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool constant = true; IPersistentVector args = PersistentVector.EMPTY; for (int i = 0; i < form.count(); i++ ) { Expr v = Compiler.Analyze(pconToUse, form.nth(i)); args = (IPersistentVector)args.cons(v); if ( !(v is LiteralExpr) ) constant = false; } Expr ret = new VectorExpr(args); IObj iobjForm = form as IObj; if (iobjForm != null && iobjForm.meta() != null) return Compiler.OptionallyGenerateMetaInit(pcon,form, ret); else if ( constant ) { IPersistentVector rv = PersistentVector.EMPTY; for ( int i=0; i<args.count(); i++ ) { LiteralExpr ve = (LiteralExpr)args.nth(i); rv = (IPersistentVector)rv.cons(ve.Val); } return new ConstantExpr(rv); } else return ret; }
public static Expr Parse(ParserContext pcon, IPersistentSet form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool constant = true; IPersistentVector keys = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { object e = s.first(); Expr expr = Compiler.Analyze(pconToUse, e); keys = (IPersistentVector)keys.cons(expr); if (!(expr is LiteralExpr)) constant = false; } Expr ret = new SetExpr(keys); IObj iobjForm = form as IObj; if (iobjForm != null && iobjForm.meta() != null) return Compiler.OptionallyGenerateMetaInit(pcon, form, ret); else if (constant) { IPersistentSet set = PersistentHashSet.EMPTY; for (int i = 0; i < keys.count(); i++) { LiteralExpr ve = (LiteralExpr)keys.nth(i); set = (IPersistentSet)set.cons(ve.Val); } return new ConstantExpr(set); } else return ret; }
public Expr Parse(ParserContext pcon, object frm) { // frm is: (reify this-name? [interfaces] (method-name [args] body)* ) ISeq form = (ISeq)frm; ObjMethod enclosingMethod = (ObjMethod)Compiler.MethodVar.deref(); string baseName = enclosingMethod != null ? (ObjExpr.TrimGenId(enclosingMethod.Objx.Name) + "$") : (Compiler.munge(Compiler.CurrentNamespace.Name.Name) + "$"); string simpleName = "reify__" + RT.nextID(); string className = baseName + simpleName; ISeq rform = RT.next(form); IPersistentVector interfaces = ((IPersistentVector)RT.first(rform)).cons(Symbol.intern("clojure.lang.IObj")); rform = RT.next(rform); ObjExpr ret = Build(interfaces, null, null, className, Symbol.intern(className), null, rform, frm); IObj iobj = frm as IObj; if (iobj != null && iobj.meta() != null) { return(new MetaExpr(ret, MapExpr.Parse(pcon.EvalOrExpr(), iobj.meta()))); } else { return(ret); } }
public static Expr Parse(ParserContext pcon, IPersistentMap form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool keysConstant = true; bool valsConstant = true; bool allConstantKeysUnique = true; IPersistentSet constantKeys = PersistentHashSet.EMPTY; IPersistentVector keyvals = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { IMapEntry e = (IMapEntry)s.first(); Expr k = Compiler.Analyze(pconToUse, e.key()); Expr v = Compiler.Analyze(pconToUse, e.val()); keyvals = (IPersistentVector)keyvals.cons(k); keyvals = (IPersistentVector)keyvals.cons(v); if (k is LiteralExpr) { object kval = k.Eval(); if (constantKeys.contains(kval)) { allConstantKeysUnique = false; } else { constantKeys = (IPersistentSet)constantKeys.cons(kval); } } else { keysConstant = false; } if (!(v is LiteralExpr)) { valsConstant = false; } } Expr ret = new MapExpr(keyvals); if (form is IObj iobjForm && iobjForm.meta() != null) { return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret)); }
public static Expr Parse(ParserContext pcon, IPersistentMap form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool constant = true; IPersistentVector keyvals = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { IMapEntry e = (IMapEntry)s.first(); Expr k = Compiler.Analyze(pconToUse, e.key()); Expr v = Compiler.Analyze(pconToUse, e.val()); keyvals = (IPersistentVector)keyvals.cons(k); keyvals = (IPersistentVector)keyvals.cons(v); if (!(k is LiteralExpr && v is LiteralExpr)) { constant = false; } } Expr ret = new MapExpr(keyvals); IObj iobjForm = form as IObj; if (iobjForm != null && iobjForm.meta() != null) { return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret)); } else if (constant) { // This 'optimzation' works, mostly, unless you have nested map values. // The nested map values do not participate in the constants map, so you end up with the code to create the keys. // Result: huge duplication of keyword creation. 3X increase in init time to the REPL. //IPersistentMap m = PersistentHashMap.EMPTY; //for (int i = 0; i < keyvals.length(); i += 2) // m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val); //return new ConstantExpr(m); return(ret); } else { return(ret); } }
internal static List <HostArg> ParseArgs(ParserContext pcon, ISeq argSeq) { List <HostArg> args = new List <HostArg>(); for (ISeq s = argSeq; s != null; s = s.next()) { object arg = s.first(); HostArg.ParameterType paramType = HostArg.ParameterType.Standard; LocalBinding lb = null; ISeq argAsSeq = arg as ISeq; if (argAsSeq != null) { Symbol op = RT.first(argAsSeq) as Symbol; if (op != null && op.Equals(ByRefSym)) { if (RT.Length(argAsSeq) != 2) { throw new ArgumentException("Wrong number of arguments to {0}", op.Name); } object localArg = RT.second(argAsSeq); Symbol symLocalArg = localArg as Symbol; if (symLocalArg == null || (lb = Compiler.ReferenceLocal(symLocalArg)) == null) { throw new ArgumentException("Argument to {0} must be a local variable.", op.Name); } paramType = HostArg.ParameterType.ByRef; arg = localArg; } } Expr expr = Compiler.Analyze(pcon.EvalOrExpr(), arg); args.Add(new HostArg(paramType, expr, lb)); } return(args); }
public static Expr Parse(ParserContext pcon, IPersistentVector form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool constant = true; IPersistentVector args = PersistentVector.EMPTY; for (int i = 0; i < form.count(); i++) { Expr v = Compiler.Analyze(pconToUse, form.nth(i)); args = (IPersistentVector)args.cons(v); if (!(v is LiteralExpr)) { constant = false; } } Expr ret = new VectorExpr(args); IObj iobjForm = form as IObj; if (iobjForm != null && iobjForm.meta() != null) { return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret)); } else if (constant) { IPersistentVector rv = PersistentVector.EMPTY; for (int i = 0; i < args.count(); i++) { LiteralExpr ve = (LiteralExpr)args.nth(i); rv = (IPersistentVector)rv.cons(ve.Val); } return(new ConstantExpr(rv)); } else { return(ret); } }
public static Expr Parse(ParserContext pcon, IPersistentSet form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool constant = true; IPersistentVector keys = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { object e = s.first(); Expr expr = Compiler.Analyze(pconToUse, e); keys = (IPersistentVector)keys.cons(expr); if (!(expr is LiteralExpr)) { constant = false; } } Expr ret = new SetExpr(keys); IObj iobjForm = form as IObj; if (iobjForm != null && iobjForm.meta() != null) { return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret)); } else if (constant) { IPersistentSet set = PersistentHashSet.EMPTY; for (int i = 0; i < keys.count(); i++) { LiteralExpr ve = (LiteralExpr)keys.nth(i); set = (IPersistentSet)set.cons(ve.Val); } return(new ConstantExpr(set)); } else { return(ret); } }
public static Expr Parse(ParserContext pcon, IPersistentVector form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool constant = true; IPersistentVector args = PersistentVector.EMPTY; for (int i = 0; i < form.count(); i++) { Expr v = Compiler.Analyze(pconToUse, form.nth(i)); args = (IPersistentVector)args.cons(v); if (!(v is LiteralExpr)) { constant = false; } } Expr ret = new VectorExpr(args); if (form is IObj iobjForm && iobjForm.meta() != null) { return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret)); }
public Expr Parse(ParserContext pcon, object frm) { ISeq form = (ISeq)frm; // (if test then) or (if test then else) if (form.count() > 4) { throw new ParseException("Too many arguments to if"); } if (form.count() < 3) { throw new ParseException("Too few arguments to if"); } Expr testExpr = Compiler.Analyze(pcon.EvalOrExpr().SetAssign(false), RT.second(form)); Expr thenExpr = Compiler.Analyze(pcon.SetAssign(false), RT.third(form)); Expr elseExpr = Compiler.Analyze(pcon.SetAssign(false), RT.fourth(form)); return(new IfExpr((IPersistentMap)Compiler.SourceSpanVar.deref(), testExpr, thenExpr, elseExpr)); }
public static Expr Parse(ParserContext pcon, IPersistentSet form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool constant = true; IPersistentVector keys = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { object e = s.first(); Expr expr = Compiler.Analyze(pconToUse, e); keys = (IPersistentVector)keys.cons(expr); if (!(expr is LiteralExpr)) { constant = false; } } Expr ret = new SetExpr(keys); if (form is IObj iobjForm && iobjForm.meta() != null) { return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret)); }
public static Expr Parse(ParserContext pcon, IPersistentMap form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool constant = true; IPersistentVector keyvals = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { IMapEntry e = (IMapEntry)s.first(); Expr k = Compiler.Analyze(pconToUse, e.key()); Expr v = Compiler.Analyze(pconToUse, e.val()); keyvals = (IPersistentVector)keyvals.cons(k); keyvals = (IPersistentVector)keyvals.cons(v); if (!(k is LiteralExpr && v is LiteralExpr)) constant = false; } Expr ret = new MapExpr(keyvals); IObj iobjForm = form as IObj; if (iobjForm != null && iobjForm.meta() != null) return Compiler.OptionallyGenerateMetaInit(pcon, form, ret); else if (constant) { // This 'optimzation' works, mostly, unless you have nested map values. // The nested map values do not participate in the constants map, so you end up with the code to create the keys. // Result: huge duplication of keyword creation. 3X increase in init time to the REPL. //IPersistentMap m = PersistentHashMap.EMPTY; //for (int i = 0; i < keyvals.length(); i += 2) // m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val); //return new ConstantExpr(m); return ret; } else return ret; }
public Expr Parse(ParserContext pcon, object form) { ISeq sform = (ISeq)form; // form is one of: // (. x fieldname-sym) // (. x 0-ary-method) // (. x propertyname-sym) // (. x methodname-sym args)+ // (. x (methodname-sym args?)) // (. x (generic-m if (RT.Length(sform) < 3) throw new ParseException("Malformed member expression, expecting (. target member ... )"); string source = (string)Compiler.SourceVar.deref(); IPersistentMap spanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); // Compiler.GetSourceSpanMap(form); Symbol tag = Compiler.TagOf(sform); bool tailPosition = Compiler.InTailCall(pcon.Rhc); // determine static or instance // static target must be symbol, either fully.qualified.Typename or Typename that has been imported Type t = HostExpr.MaybeType(RT.second(sform), false); // at this point, t will be non-null if static Expr instance = null; if (t == null) instance = Compiler.Analyze(pcon.EvalOrExpr(),RT.second(sform)); bool isZeroArityCall = RT.Length(sform) == 3 && RT.third(sform) is Symbol; if (isZeroArityCall) { PropertyInfo pinfo = null; FieldInfo finfo = null; // TODO: Figure out if we want to handle the -propname otherwise. bool isPropName = false; Symbol sym = (Symbol)RT.third(sform); if (sym.Name[0] == '-') { isPropName = true; sym = Symbol.intern(sym.Name.Substring(1)); } string fieldName = Compiler.munge(sym.Name); // The JVM version does not have to worry about Properties. It captures 0-arity methods under fields. // We have to put in special checks here for this. // Also, when reflection is required, we have to capture 0-arity methods under the calls that // are generated by StaticFieldExpr and InstanceFieldExpr. if (t != null) { if ((finfo = Reflector.GetField(t, fieldName, true)) != null) return new StaticFieldExpr(source, spanMap, tag, t, fieldName, finfo); if ((pinfo = Reflector.GetProperty(t, fieldName, true)) != null) return new StaticPropertyExpr(source, spanMap, tag, t, fieldName, pinfo); if (!isPropName && Reflector.GetArityZeroMethod(t, fieldName, true) != null) return new StaticMethodExpr(source, spanMap, tag, t, fieldName, null, new List<HostArg>(), tailPosition); throw new MissingMemberException(t.Name, fieldName); } else if (instance != null && instance.HasClrType && instance.ClrType != null) { Type instanceType = instance.ClrType; if ((finfo = Reflector.GetField(instanceType, fieldName, false)) != null) return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, finfo); if ((pinfo = Reflector.GetProperty(instanceType, fieldName, false)) != null) return new InstancePropertyExpr(source, spanMap, tag, instance, fieldName, pinfo); if (!isPropName && Reflector.GetArityZeroMethod(instanceType, fieldName, false) != null) return new InstanceMethodExpr(source, spanMap, tag, instance, fieldName, null, new List<HostArg>(), tailPosition); if (pcon.IsAssignContext) return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null else return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName); } else { // t is null, so we know this is not a static call // If instance is null, we are screwed anyway. // If instance is not null, then we don't have a type. // So we must be in an instance call to a property, field, or 0-arity method. // The code generated by InstanceFieldExpr/InstancePropertyExpr with a null FieldInfo/PropertyInfo // will generate code to do a runtime call to a Reflector method that will check all three. //return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null //return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName); if (pcon.IsAssignContext) return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null else return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName); } } //ISeq call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form)); ISeq call; List<Type> typeArgs = null; object fourth = RT.fourth(sform); if (fourth is ISeq && RT.first(fourth) is Symbol && ((Symbol)RT.first(fourth)).Equals(TypeArgsSym)) { // We have a type args supplied for a generic method call // (. thing methodname (type-args type1 ... ) args ...) typeArgs = ParseGenericMethodTypeArgs(RT.next(fourth)); call = RT.listStar(RT.third(sform), RT.next(RT.next(RT.next(RT.next(sform))))); } else call = RT.third(sform) is ISeq ? (ISeq)RT.third(sform) : RT.next(RT.next(sform)); if (!(RT.first(call) is Symbol)) throw new ParseException("Malformed member exception"); string methodName = Compiler.munge(((Symbol)RT.first(call)).Name); List<HostArg> args = ParseArgs(pcon, RT.next(call)); return t != null ? (MethodExpr)(new StaticMethodExpr(source, spanMap, tag, t, methodName, typeArgs, args, tailPosition)) : (MethodExpr)(new InstanceMethodExpr(source, spanMap, tag, instance, methodName, typeArgs, args, tailPosition)); }
internal static Expr OptionallyGenerateMetaInit(ParserContext pcon, object form, Expr expr) { Expr ret = expr; if ( RT.meta(form) != null ) ret = new MetaExpr(ret, (MapExpr)MapExpr.Parse(pcon.EvalOrExpr(),((IObj)form).meta())); return ret; }
public Expr Parse(ParserContext pcon, object form) { ISeq sform = (ISeq)form; // form is one of: // (. x fieldname-sym) // (. x 0-ary-method) // (. x propertyname-sym) // (. x methodname-sym args)+ // (. x (methodname-sym args?)) // (. x (generic-m if (RT.Length(sform) < 3) { throw new ParseException("Malformed member expression, expecting (. target member ... )"); } string source = (string)Compiler.SourceVar.deref(); IPersistentMap spanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); // Compiler.GetSourceSpanMap(form); Symbol tag = Compiler.TagOf(sform); // determine static or instance // static target must be symbol, either fully.qualified.Typename or Typename that has been imported Type t = HostExpr.MaybeType(RT.second(sform), false); // at this point, t will be non-null if static Expr instance = null; if (t == null) { instance = Compiler.Analyze(pcon.EvalOrExpr(), RT.second(sform)); } bool isZeroArityCall = RT.Length(sform) == 3 && RT.third(sform) is Symbol; if (isZeroArityCall) { PropertyInfo pinfo = null; FieldInfo finfo = null; // TODO: Figure out if we want to handle the -propname otherwise. bool isPropName = false; Symbol sym = (Symbol)RT.third(sform); if (sym.Name[0] == '-') { isPropName = true; sym = Symbol.intern(sym.Name.Substring(1)); } string fieldName = Compiler.munge(sym.Name); // The JVM version does not have to worry about Properties. It captures 0-arity methods under fields. // We have to put in special checks here for this. // Also, when reflection is required, we have to capture 0-arity methods under the calls that // are generated by StaticFieldExpr and InstanceFieldExpr. if (t != null) { if ((finfo = Reflector.GetField(t, fieldName, true)) != null) { return(new StaticFieldExpr(source, spanMap, tag, t, fieldName, finfo)); } if ((pinfo = Reflector.GetProperty(t, fieldName, true)) != null) { return(new StaticPropertyExpr(source, spanMap, tag, t, fieldName, pinfo)); } if (!isPropName && Reflector.GetArityZeroMethod(t, fieldName, true) != null) { return(new StaticMethodExpr(source, spanMap, tag, t, fieldName, null, new List <HostArg>())); } throw new MissingMemberException(t.Name, fieldName); } else if (instance != null && instance.HasClrType && instance.ClrType != null) { Type instanceType = instance.ClrType; if ((finfo = Reflector.GetField(instanceType, fieldName, false)) != null) { return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, finfo)); } if ((pinfo = Reflector.GetProperty(instanceType, fieldName, false)) != null) { return(new InstancePropertyExpr(source, spanMap, tag, instance, fieldName, pinfo)); } if (!isPropName && Reflector.GetArityZeroMethod(instanceType, fieldName, false) != null) { return(new InstanceMethodExpr(source, spanMap, tag, instance, fieldName, null, new List <HostArg>())); } if (pcon.IsAssignContext) { return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null)); // same as InstancePropertyExpr when last arg is null } else { return(new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName)); } } else { // t is null, so we know this is not a static call // If instance is null, we are screwed anyway. // If instance is not null, then we don't have a type. // So we must be in an instance call to a property, field, or 0-arity method. // The code generated by InstanceFieldExpr/InstancePropertyExpr with a null FieldInfo/PropertyInfo // will generate code to do a runtime call to a Reflector method that will check all three. //return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null //return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName); if (pcon.IsAssignContext) { return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null)); // same as InstancePropertyExpr when last arg is null } else { return(new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName)); } } } //ISeq call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form)); ISeq call; List <Type> typeArgs = null; object fourth = RT.fourth(sform); if (fourth is ISeq && RT.first(fourth) is Symbol && ((Symbol)RT.first(fourth)).Equals(TypeArgsSym)) { // We have a type args supplied for a generic method call // (. thing methodname (type-args type1 ... ) args ...) typeArgs = ParseGenericMethodTypeArgs(RT.next(fourth)); call = RT.listStar(RT.third(sform), RT.next(RT.next(RT.next(RT.next(sform))))); } else { call = RT.third(sform) is ISeq ? (ISeq)RT.third(sform) : RT.next(RT.next(sform)); } if (!(RT.first(call) is Symbol)) { throw new ParseException("Malformed member exception"); } string methodName = Compiler.munge(((Symbol)RT.first(call)).Name); List <HostArg> args = ParseArgs(pcon, RT.next(call)); return(t != null ? (MethodExpr)(new StaticMethodExpr(source, spanMap, tag, t, methodName, typeArgs, args)) : (MethodExpr)(new InstanceMethodExpr(source, spanMap, tag, instance, methodName, typeArgs, args))); }
internal static List<HostArg> ParseArgs(ParserContext pcon, ISeq argSeq) { List<HostArg> args = new List<HostArg>(); for (ISeq s = argSeq; s != null; s = s.next()) { object arg = s.first(); HostArg.ParameterType paramType = HostArg.ParameterType.Standard; LocalBinding lb = null; ISeq argAsSeq = arg as ISeq; if (argAsSeq != null) { Symbol op = RT.first(argAsSeq) as Symbol; if (op != null && op.Equals(ByRefSym)) { if (RT.Length(argAsSeq) != 2) throw new ArgumentException("Wrong number of arguments to {0}", op.Name); object localArg = RT.second(argAsSeq); Symbol symLocalArg = localArg as Symbol; if (symLocalArg == null || (lb = Compiler.ReferenceLocal(symLocalArg)) == null) throw new ArgumentException("Argument to {0} must be a local variable.", op.Name); paramType = HostArg.ParameterType.ByRef; arg = localArg; } } Expr expr = Compiler.Analyze(pcon.EvalOrExpr(),arg); args.Add(new HostArg(paramType, expr, lb)); } return args; }
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; 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, IPersistentMap form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool keysConstant = true; bool valsConstant = true; bool allConstantKeysUnique = true; IPersistentSet constantKeys = PersistentHashSet.EMPTY; IPersistentVector keyvals = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { IMapEntry e = (IMapEntry)s.first(); Expr k = Compiler.Analyze(pconToUse, e.key()); Expr v = Compiler.Analyze(pconToUse, e.val()); keyvals = (IPersistentVector)keyvals.cons(k); keyvals = (IPersistentVector)keyvals.cons(v); if (k is LiteralExpr) { object kval = k.Eval(); if (constantKeys.contains(kval)) allConstantKeysUnique = false; else constantKeys = (IPersistentSet)constantKeys.cons(kval); } else keysConstant = false; if (!(v is LiteralExpr)) valsConstant = false; } Expr ret = new MapExpr(keyvals); IObj iobjForm = form as IObj; if (iobjForm != null && iobjForm.meta() != null) return Compiler.OptionallyGenerateMetaInit(pcon, form, ret); //else if (constant) //{ // This 'optimzation' works, mostly, unless you have nested map values. // The nested map values do not participate in the constants map, so you end up with the code to create the keys. // Result: huge duplication of keyword creation. 3X increase in init time to the REPL. // //IPersistentMap m = PersistentHashMap.EMPTY; // //for (int i = 0; i < keyvals.length(); i += 2) // // m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val); // //return new ConstantExpr(m); // return ret; //} else if (keysConstant) { // TBD: Add more detail to exception thrown below. if (!allConstantKeysUnique) throw new ArgumentException("Duplicate constant keys in map"); if (valsConstant) { // This 'optimzation' works, mostly, unless you have nested map values. // The nested map values do not participate in the constants map, so you end up with the code to create the keys. // Result: huge duplication of keyword creation. 3X increase in init time to the REPL. //IPersistentMap m = PersistentArrayMap.EMPTY; //for (int i = 0; i < keyvals.length(); i += 2) // m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val); //return new ConstantExpr(m); return ret; } else return ret; } else return ret; }
public Expr Parse(ParserContext pcon, object frm) { // frm is: (reify this-name? [interfaces] (method-name [args] body)* ) ISeq form = (ISeq)frm; ObjMethod enclosingMethod = (ObjMethod)Compiler.MethodVar.deref(); string baseName = enclosingMethod != null ? (ObjExpr.TrimGenId(enclosingMethod.Objx.Name) + "$") : (Compiler.munge(Compiler.CurrentNamespace.Name.Name) + "$"); string simpleName = "reify__" + RT.nextID(); string className = baseName + simpleName; ISeq rform = RT.next(form); IPersistentVector interfaces = ((IPersistentVector)RT.first(rform)).cons(Symbol.intern("clojure.lang.IObj")); rform = RT.next(rform); ObjExpr ret = Build(interfaces, null, null, className, Symbol.intern(className), null, rform,frm, null); IObj iobj = frm as IObj; if (iobj != null && iobj.meta() != null) return new MetaExpr(ret, MapExpr.Parse(pcon.EvalOrExpr(),iobj.meta())); else return ret; }
public Expr Parse(ParserContext pcon, object form) { // (def x) or (def x initexpr) or (def x "docstring" initexpr) string docstring = null; if (RT.count(form) == 4 && (RT.third(form) is String)) { docstring = (String)RT.third(form); form = RT.list(RT.first(form), RT.second(form), RT.fourth(form)); } if (RT.count(form) > 3) { throw new ParseException("Too many arguments to def"); } if (RT.count(form) < 2) { throw new ParseException("Too few arguments to def"); } Symbol sym = RT.second(form) as Symbol; if (sym == null) { throw new ParseException("First argument to def must be a Symbol."); } //Console.WriteLine("Def {0}", sym.Name); Var v = Compiler.LookupVar(sym, true); if (v == null) { throw new ParseException("Can't refer to qualified var that doesn't exist"); } if (!v.Namespace.Equals(Compiler.CurrentNamespace)) { if (sym.Namespace == null) { v = Compiler.CurrentNamespace.intern(sym); Compiler.RegisterVar(v); } //throw new Exception(string.Format("Name conflict, can't def {0} because namespace: {1} refers to: {2}", // sym, Compiler.CurrentNamespace.Name, v)); else { throw new ParseException("Can't create defs outside of current namespace"); } } IPersistentMap mm = sym.meta(); bool isDynamic = RT.booleanCast(RT.get(mm, Compiler.DynamicKeyword)); if (isDynamic) { v.setDynamic(); } if (!isDynamic && sym.Name.StartsWith("*") && sym.Name.EndsWith("*") && sym.Name.Length > 2) { RT.errPrintWriter().WriteLine("Warning: {0} not declared dynamic and thus is not dynamically rebindable, " + "but its name suggests otherwise. Please either indicate ^:dynamic {0} or change the name. ({1}:{2}\n", sym, Compiler.SourcePathVar.get(), Compiler.LineVar.get()); } if (RT.booleanCast(RT.get(mm, Compiler.ArglistsKeyword))) { IPersistentMap vm = v.meta(); //vm = (IPersistentMap)RT.assoc(vm, Compiler.STATIC_KEY, true); // drop quote vm = (IPersistentMap)RT.assoc(vm, Compiler.ArglistsKeyword, RT.second(mm.valAt(Compiler.ArglistsKeyword))); v.setMeta(vm); } Object source_path = Compiler.SourcePathVar.get(); source_path = source_path ?? "NO_SOURCE_FILE"; mm = (IPersistentMap)RT.assoc(mm, RT.LineKey, Compiler.LineVar.get()) .assoc(RT.ColumnKey, Compiler.ColumnVar.get()) .assoc(RT.FileKey, source_path); //.assoc(RT.SOURCE_SPAN_KEY,Compiler.SOURCE_SPAN.deref()); if (docstring != null) { mm = (IPersistentMap)RT.assoc(mm, RT.DocKey, docstring); } // Following comment in JVM version //mm = mm.without(RT.DOC_KEY) // .without(Keyword.intern(null, "arglists")) // .without(RT.FILE_KEY) // .without(RT.LINE_KEY) // .without(RT.COLUMN_KEY) // .without(Keyword.intern(null, "ns")) // .without(Keyword.intern(null, "name")) // .without(Keyword.intern(null, "added")) // .without(Keyword.intern(null, "static")); mm = (IPersistentMap)Compiler.ElideMeta(mm); Expr meta = mm == null || mm.count() == 0 ? null : Compiler.Analyze(pcon.EvalOrExpr(), mm); Expr init = Compiler.Analyze(pcon.EvalOrExpr(), RT.third(form), v.Symbol.Name); bool initProvided = RT.count(form) == 3; return(new DefExpr( (string)Compiler.SourceVar.deref(), Compiler.LineVarDeref(), Compiler.ColumnVarDeref(), v, init, meta, initProvided, isDynamic)); }
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; 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(ParserContext pcon, ISeq form) { pcon = pcon.EvalOrExpr(); Expr fexpr = Compiler.Analyze(pcon,form.first()); VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null && varFexpr.Var.Equals(Compiler.InstanceVar)) { if ( RT.second(form) is Symbol ) { Type t = HostExpr.MaybeType(RT.second(form),false); if ( t != null ) return new InstanceOfExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), t, Compiler.Analyze(pcon,RT.third(form))); } } if (varFexpr != null && pcon.Rhc != RHC.Eval) { Var v = varFexpr.Var; object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword); int arity = RT.count(form.next()); for (ISeq s = RT.seq(arglists); s != null; s = s.next()) { IPersistentVector sargs = (IPersistentVector)s.first(); if (sargs.count() == arity) { string primc = FnMethod.PrimInterface(sargs); if (primc != null) return Compiler.Analyze(pcon, RT.listStar(Symbol.intern(".invokePrim"), ((Symbol)form.first()).withMeta(RT.map(RT.TagKey, Symbol.intern(primc))), form.next())); break; } } } KeywordExpr kwFexpr = fexpr as KeywordExpr; if (kwFexpr != null && RT.count(form) == 2 && Compiler.KeywordCallsitesVar.isBound) { Expr target = Compiler.Analyze(pcon, RT.second(form)); return new KeywordInvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), Compiler.TagOf(form), kwFexpr, target); } IPersistentVector args = PersistentVector.EMPTY; for ( ISeq s = RT.seq(form.next()); s != null; s = s.next()) args = args.cons(Compiler.Analyze(pcon,s.first())); //if (args.count() > Compiler.MAX_POSITIONAL_ARITY) // throw new ArgumentException(String.Format("No more than {0} args supported", Compiler.MAX_POSITIONAL_ARITY)); return new InvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), //Compiler.GetSourceSpanMap(form), Compiler.TagOf(form), fexpr, args); }
public Expr Parse(ParserContext pcon, object form) { // (def x) or (def x initexpr) or (def x "docstring" initexpr) string docstring = null; if (RT.count(form) == 4 && (RT.third(form) is String)) { docstring = (String)RT.third(form); form = RT.list(RT.first(form), RT.second(form), RT.fourth(form)); } if (RT.count(form) > 3) throw new ParseException("Too many arguments to def"); if (RT.count(form) < 2) throw new ParseException("Too few arguments to def"); Symbol sym = RT.second(form) as Symbol; if (sym == null) throw new ParseException("First argument to def must be a Symbol."); //Console.WriteLine("Def {0}", sym.Name); Var v = Compiler.LookupVar(sym, true); if (v == null) throw new ParseException("Can't refer to qualified var that doesn't exist"); if (!v.Namespace.Equals(Compiler.CurrentNamespace)) { if (sym.Namespace == null) { v = Compiler.CurrentNamespace.intern(sym); Compiler.RegisterVar(v); } //throw new Exception(string.Format("Name conflict, can't def {0} because namespace: {1} refers to: {2}", // sym, Compiler.CurrentNamespace.Name, v)); else throw new ParseException("Can't create defs outside of current namespace"); } IPersistentMap mm = sym.meta(); bool isDynamic = RT.booleanCast(RT.get(mm, Compiler.DynamicKeyword)); if (isDynamic) v.setDynamic(); if (!isDynamic && sym.Name.StartsWith("*") && sym.Name.EndsWith("*") && sym.Name.Length > 2) { RT.errPrintWriter().WriteLine("Warning: {0} not declared dynamic and thus is not dynamically rebindable, " + "but its name suggests otherwise. Please either indicate ^:dynamic {0} or change the name. ({1}:{2}\n", sym,Compiler.SourcePathVar.get(),Compiler.LineVar.get()); } if (RT.booleanCast(RT.get(mm, Compiler.ArglistsKeyword))) { IPersistentMap vm = v.meta(); //vm = (IPersistentMap)RT.assoc(vm, Compiler.STATIC_KEY, true); // drop quote vm = (IPersistentMap)RT.assoc(vm, Compiler.ArglistsKeyword, RT.second(mm.valAt(Compiler.ArglistsKeyword))); v.setMeta(vm); } Object source_path = Compiler.SourcePathVar.get(); source_path = source_path ?? "NO_SOURCE_FILE"; mm = (IPersistentMap)RT.assoc(mm,RT.LineKey, Compiler.LineVar.get()) .assoc(RT.ColumnKey,Compiler.ColumnVar.get()) .assoc(RT.FileKey, source_path); //.assoc(RT.SOURCE_SPAN_KEY,Compiler.SOURCE_SPAN.deref()); if (docstring != null) mm = (IPersistentMap)RT.assoc(mm, RT.DocKey, docstring); // Following comment in JVM version //mm = mm.without(RT.DOC_KEY) // .without(Keyword.intern(null, "arglists")) // .without(RT.FILE_KEY) // .without(RT.LINE_KEY) // .without(RT.COLUMN_KEY) // .without(Keyword.intern(null, "ns")) // .without(Keyword.intern(null, "name")) // .without(Keyword.intern(null, "added")) // .without(Keyword.intern(null, "static")); mm = (IPersistentMap)Compiler.ElideMeta(mm); Expr meta = mm == null || mm.count() == 0 ? null : Compiler.Analyze(pcon.EvalOrExpr(),mm); Expr init = Compiler.Analyze(pcon.EvalOrExpr(),RT.third(form), v.Symbol.Name); bool initProvided = RT.count(form) == 3; return new DefExpr( (string)Compiler.SourceVar.deref(), Compiler.LineVarDeref(), Compiler.ColumnVarDeref(), v, init, meta, initProvided,isDynamic); }
public Expr Parse(ParserContext pcon, object frm) { ISeq form = (ISeq)frm; // (if test then) or (if test then else) if (form.count() > 4) throw new ParseException("Too many arguments to if"); if (form.count() < 3) throw new ParseException("Too few arguments to if"); Expr testExpr = Compiler.Analyze(pcon.EvalOrExpr().SetAssign(false),RT.second(form)); Expr thenExpr = Compiler.Analyze(pcon.SetAssign(false), RT.third(form)); Expr elseExpr = Compiler.Analyze(pcon.SetAssign(false), RT.fourth(form)); return new IfExpr((IPersistentMap)Compiler.SourceSpanVar.deref(), testExpr, thenExpr, elseExpr); }
public static Expr Parse(ParserContext pcon, ISeq form) { pcon = pcon.EvalOrExpr(); Expr fexpr = Compiler.Analyze(pcon, form.first()); VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null && varFexpr.Var.Equals(Compiler.InstanceVar)) { if (RT.second(form) is Symbol) { Type t = HostExpr.MaybeType(RT.second(form), false); if (t != null) { return(new InstanceOfExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), t, Compiler.Analyze(pcon, RT.third(form)))); } } } if (varFexpr != null && pcon.Rhc != RHC.Eval) { Var v = varFexpr.Var; object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword); int arity = RT.count(form.next()); for (ISeq s = RT.seq(arglists); s != null; s = s.next()) { IPersistentVector sargs = (IPersistentVector)s.first(); if (sargs.count() == arity) { string primc = FnMethod.PrimInterface(sargs); if (primc != null) { return(Compiler.Analyze(pcon, RT.listStar(Symbol.intern(".invokePrim"), ((Symbol)form.first()).withMeta(RT.map(RT.TagKey, Symbol.intern(primc))), form.next()))); } break; } } } KeywordExpr kwFexpr = fexpr as KeywordExpr; if (kwFexpr != null && RT.count(form) == 2 && Compiler.KeywordCallsitesVar.isBound) { Expr target = Compiler.Analyze(pcon, RT.second(form)); return(new KeywordInvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), Compiler.TagOf(form), kwFexpr, target)); } IPersistentVector args = PersistentVector.EMPTY; for (ISeq s = RT.seq(form.next()); s != null; s = s.next()) { args = args.cons(Compiler.Analyze(pcon, s.first())); } //if (args.count() > Compiler.MAX_POSITIONAL_ARITY) // throw new ArgumentException(String.Format("No more than {0} args supported", Compiler.MAX_POSITIONAL_ARITY)); return(new InvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), //Compiler.GetSourceSpanMap(form), Compiler.TagOf(form), fexpr, args)); }
public static Expr Parse(ParserContext pcon, IPersistentMap form) { ParserContext pconToUse = pcon.EvalOrExpr(); bool keysConstant = true; bool valsConstant = true; bool allConstantKeysUnique = true; IPersistentSet constantKeys = PersistentHashSet.EMPTY; IPersistentVector keyvals = PersistentVector.EMPTY; for (ISeq s = RT.seq(form); s != null; s = s.next()) { IMapEntry e = (IMapEntry)s.first(); Expr k = Compiler.Analyze(pconToUse, e.key()); Expr v = Compiler.Analyze(pconToUse, e.val()); keyvals = (IPersistentVector)keyvals.cons(k); keyvals = (IPersistentVector)keyvals.cons(v); if (k is LiteralExpr) { object kval = k.Eval(); if (constantKeys.contains(kval)) { allConstantKeysUnique = false; } else { constantKeys = (IPersistentSet)constantKeys.cons(kval); } } else { keysConstant = false; } if (!(v is LiteralExpr)) { valsConstant = false; } } Expr ret = new MapExpr(keyvals); IObj iobjForm = form as IObj; if (iobjForm != null && iobjForm.meta() != null) { return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret)); } //else if (constant) //{ // This 'optimzation' works, mostly, unless you have nested map values. // The nested map values do not participate in the constants map, so you end up with the code to create the keys. // Result: huge duplication of keyword creation. 3X increase in init time to the REPL. // //IPersistentMap m = PersistentHashMap.EMPTY; // //for (int i = 0; i < keyvals.length(); i += 2) // // m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val); // //return new ConstantExpr(m); // return ret; //} else if (keysConstant) { // TBD: Add more detail to exception thrown below. if (!allConstantKeysUnique) { throw new ArgumentException("Duplicate constant keys in map"); } if (valsConstant) { // This 'optimzation' works, mostly, unless you have nested map values. // The nested map values do not participate in the constants map, so you end up with the code to create the keys. // Result: huge duplication of keyword creation. 3X increase in init time to the REPL. //IPersistentMap m = PersistentHashMap.EMPTY; //for (int i = 0; i < keyvals.length(); i += 2) // m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val); //return new ConstantExpr(m); return(ret); } else { return(ret); } } else { return(ret); } }
public static Expr Parse(ParserContext pcon, ISeq form) { bool tailPosition = Compiler.InTailCall(pcon.Rhc); pcon = pcon.EvalOrExpr(); Expr fexpr = Compiler.Analyze(pcon, form.first()); VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null && varFexpr.Var.Equals(Compiler.InstanceVar) && RT.count(form) == 3) { Expr sexpr = Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.second(form)); if (sexpr is ConstantExpr csexpr) { Type tval = csexpr.Val as Type; if (tval != null) { return(new InstanceOfExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), tval, Compiler.Analyze(pcon, RT.third(form)))); } } } if (RT.booleanCast(Compiler.GetCompilerOption(Compiler.DirectLinkingKeyword)) && varFexpr != null && pcon.Rhc != RHC.Eval) { Var v = varFexpr.Var; if (!v.isDynamic() && !RT.booleanCast(RT.get(v.meta(), Compiler.RedefKeyword, false)) && !RT.booleanCast(RT.get(v.meta(), RT.DeclaredKey, false))) { Symbol formTag = Compiler.TagOf(form); //object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword); int arity = RT.count(form.next()); object sigtag = SigTag(arity, v); object vtag = RT.get(RT.meta(v), RT.TagKey); if (StaticInvokeExpr.Parse(v, RT.next(form), formTag ?? sigtag ?? vtag) is StaticInvokeExpr ret && !((Compiler.IsCompiling || Compiler.IsCompilingDefType) && GenContext.IsInternalAssembly(ret.Method.DeclaringType.Assembly))) { //Console.WriteLine("invoke direct: {0}", v); return(ret); } //Console.WriteLine("NOT direct: {0}", v); } } if (varFexpr != null && pcon.Rhc != RHC.Eval) { Var v = varFexpr.Var; object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword); int arity = RT.count(form.next()); for (ISeq s = RT.seq(arglists); s != null; s = s.next()) { IPersistentVector sargs = (IPersistentVector)s.first(); if (sargs.count() == arity) { string primc = FnMethod.PrimInterface(sargs); if (primc != null) { return(Compiler.Analyze(pcon, ((IObj)RT.listStar(Symbol.intern(".invokePrim"), ((Symbol)form.first()).withMeta(RT.map(RT.TagKey, Symbol.intern(primc))), form.next())).withMeta((IPersistentMap)RT.conj(RT.meta(v), RT.meta(form))))); } break; } } } if (fexpr is KeywordExpr kwFexpr && RT.count(form) == 2 && Compiler.KeywordCallsitesVar.isBound) { Expr target = Compiler.Analyze(pcon, RT.second(form)); return(new KeywordInvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), Compiler.TagOf(form), kwFexpr, target)); } IPersistentVector args = PersistentVector.EMPTY; for (ISeq s = RT.seq(form.next()); s != null; s = s.next()) { args = args.cons(Compiler.Analyze(pcon, s.first())); } //if (args.count() > Compiler.MAX_POSITIONAL_ARITY) // throw new ArgumentException(String.Format("No more than {0} args supported", Compiler.MAX_POSITIONAL_ARITY)); return(new InvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), //Compiler.GetSourceSpanMap(form), Compiler.TagOf(form), fexpr, args, tailPosition)); }
public static Expr Parse(ParserContext pcon, ISeq form) { bool tailPosition = Compiler.InTailCall(pcon.Rhc); pcon = pcon.EvalOrExpr(); Expr fexpr = Compiler.Analyze(pcon,form.first()); VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null && varFexpr.Var.Equals(Compiler.InstanceVar) && RT.count(form) == 3) { Expr sexpr = Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.second(form)); ConstantExpr csexpr = sexpr as ConstantExpr; if (csexpr != null) { Type tval = csexpr.Val as Type; if (tval != null) return new InstanceOfExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), tval, Compiler.Analyze(pcon, RT.third(form))); } } if ( RT.booleanCast(Compiler.GetCompilerOption(Compiler.DirectLinkingKeyword)) && varFexpr != null && pcon.Rhc != RHC.Eval ) { Var v = varFexpr.Var; if ( ! v.isDynamic() && !RT.booleanCast(RT.get(v.meta(), Compiler.RedefKeyword, false)) && !RT.booleanCast(RT.get(v.meta(), RT.DeclaredKey, false)) ) { Symbol formTag = Compiler.TagOf(form); object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword); int arity = RT.count(form.next()); object sigtag = SigTag(arity, v); object vtag = RT.get(RT.meta(v), RT.TagKey); StaticInvokeExpr ret = StaticInvokeExpr.Parse(v, RT.next(form), formTag ?? sigtag ?? vtag) as StaticInvokeExpr; if (ret != null && !((Compiler.IsCompiling || Compiler.IsCompilingDefType) && GenContext.IsInternalAssembly(ret.Method.DeclaringType.Assembly))) { //Console.WriteLine("invoke direct: {0}", v); return ret; } //Console.WriteLine("NOT direct: {0}", v); } } if (varFexpr != null && pcon.Rhc != RHC.Eval) { Var v = varFexpr.Var; object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword); int arity = RT.count(form.next()); for (ISeq s = RT.seq(arglists); s != null; s = s.next()) { IPersistentVector sargs = (IPersistentVector)s.first(); if (sargs.count() == arity) { string primc = FnMethod.PrimInterface(sargs); if (primc != null) return Compiler.Analyze(pcon, ((IObj)RT.listStar(Symbol.intern(".invokePrim"), ((Symbol)form.first()).withMeta(RT.map(RT.TagKey, Symbol.intern(primc))), form.next())).withMeta((IPersistentMap)RT.conj(RT.meta(v), RT.meta(form)))); break; } } } KeywordExpr kwFexpr = fexpr as KeywordExpr; if (kwFexpr != null && RT.count(form) == 2 && Compiler.KeywordCallsitesVar.isBound) { Expr target = Compiler.Analyze(pcon, RT.second(form)); return new KeywordInvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), Compiler.TagOf(form), kwFexpr, target); } IPersistentVector args = PersistentVector.EMPTY; for ( ISeq s = RT.seq(form.next()); s != null; s = s.next()) args = args.cons(Compiler.Analyze(pcon,s.first())); //if (args.count() > Compiler.MAX_POSITIONAL_ARITY) // throw new ArgumentException(String.Format("No more than {0} args supported", Compiler.MAX_POSITIONAL_ARITY)); return new InvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), //Compiler.GetSourceSpanMap(form), Compiler.TagOf(form), fexpr, args, tailPosition); }