public CaseExpr(IPersistentMap sourceSpan, LocalBindingExpr expr, int shift, int mask, int low, int high, Expr defaultExpr, SortedDictionary <int, Expr> tests, Dictionary <int, Expr> thens, Keyword switchType, Keyword testType, IPersistentSet skipCheck) { _sourceSpan = sourceSpan; _expr = expr; _shift = shift; _mask = mask; _low = low; _high = high; _defaultExpr = defaultExpr; _tests = tests; _thens = thens; if (switchType != _compactKey && switchType != _sparseKey) { throw new ArgumentException("Unexpected switch type: " + switchType); } _switchType = switchType; if (testType != _intKey && testType != _hashEquivKey && testType != _hashIdentityKey) { throw new ArgumentException("Unexpected test type: " + testType); } _testType = testType; _skipCheck = skipCheck; ICollection <Expr> returns = new List <Expr>(thens.Values); returns.Add(defaultExpr); _returnType = Compiler.MaybeClrType(returns); if (RT.count(skipCheck) > 0 && RT.booleanCast(RT.WarnOnReflectionVar.deref())) { RT.errPrintWriter().WriteLine("Performance warning, {0}:{1}:{2} - hash collision of some case test constants; if selected, those entries will be tested sequentially.", Compiler.SourcePathVar.deref(), Compiler.GetLineFromSpanMap(sourceSpan), Compiler.GetColumnFromSpanMap(sourceSpan)); } }
public static Expr Parse(Var v, ISeq args, object tag) { if (!v.isBound || v.get() == null) { //Console.WriteLine("Not bound: {0}", v); return(null); } Type target = v.get().GetType(); MethodInfo[] allMethods = target.GetMethods(); bool variadic = false; int argcount = RT.count(args); MethodInfo method = null; ParameterInfo[] pInfos = null; foreach (MethodInfo m in allMethods) { //Console.WriteLine("Method {0}", m.Name); if (m.IsStatic && m.Name.Equals("invokeStatic")) { pInfos = m.GetParameters(); if (argcount == pInfos.Length) { method = m; variadic = argcount > 0 && pInfos[pInfos.Length - 1].ParameterType == typeof(ISeq); break; } else if (argcount > pInfos.Length && pInfos.Length > 0 && pInfos[pInfos.Length - 1].ParameterType == typeof(ISeq)) { method = m; variadic = true; break; } } } if (method == null) { return(null); } IPersistentVector argv = PersistentVector.EMPTY; for (ISeq s = RT.seq(args); s != null; s = s.next()) { argv = argv.cons(Compiler.Analyze(new ParserContext(RHC.Expression), s.first())); } return(new StaticInvokeExpr(target, method, variadic, argv, tag)); }
public Expr Parse(object form) { // (def x) or (def x initexpr) if (RT.count(form) > 3) { throw new Exception("Too many arguments to def"); } if (RT.count(form) < 2) { throw new Exception("Too few arguments to def"); } Symbol sym = RT.second(form) as Symbol; if (sym == null) { throw new Exception("Second argument to def must be a Symbol."); } Var v = Compiler.LookupVar(sym, true); if (v == null) { throw new Exception("Can't refer to qualified var that doesn't exist"); } if (!v.Namespace.Equals(Compiler.CurrentNamespace)) { if (sym.Namespace == null) { 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 Exception("Can't create defs outside of current namespace"); } } IPersistentMap mm = sym.meta(); // TODO: add source and line info metadata. //Object source_path = SOURCE_PATH.get(); //source_path = source_path == null ? "NO_SOURCE_FILE" : source_path; //mm = (IPersistentMap)RT.assoc(mm, RT.LINE_KEY, LINE.get()).assoc(RT.FILE_KEY, source_path); Expr meta = mm == null ? null : Compiler.GenerateAST(mm); Expr init = Compiler.GenerateAST(RT.third(form), v.Symbol.Name); bool initProvided = RT.count(form) == 3; return(new DefExpr(v, init, meta, initProvided)); }
public Expr Parse(ParserContext pcon, object form) { int argCount = RT.count(form) - 1; if (argCount != 1) { IPersistentMap exData = new PersistentArrayMap(new Object[] { FormKey, form }); throw new ExceptionInfo("Wrong number of args (" + argCount + ") passed to quote", exData); } object v = RT.second(form); if (v == null) { return(Compiler.NilExprInstance); } else if (v is Boolean) { if ((bool)v) { return(Compiler.TrueExprInstance); } else { return(Compiler.FalseExprInstance); } } else if (Util.IsNumeric(v)) { return(NumberExpr.Parse(v)); } else if (v is string) { return(new StringExpr((String)v)); } else if (v is IPersistentCollection && ((IPersistentCollection)v).count() == 0) { return(new EmptyExpr(v)); } else { return(new ConstantExpr(v)); } }
public static Def createSlotMap(ISeq keys) { if (keys == null) { throw new ArgumentException("Must supply keys"); } int c = RT.count(keys); object[] v = new object[2 * c]; int i = 0; for (ISeq s = keys; s != null; s = s.next(), i++) { v[2 * i] = s.first(); v[2 * i + 1] = i; } return(new Def(keys, RT.map(v))); }
public Expr Parse(ParserContext pcon, object form) { if (pcon.Rhc == RHC.Eval) { return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "throw__" + RT.nextID())); } if (RT.Length((ISeq)form) == 1) { return(new ThrowExpr()); } if (RT.count(form) > 2) { throw new InvalidOperationException("Too many arguments to throw, throw expects a single Exception instance"); } return(new ThrowExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), RT.second(form)))); }
//(case* expr shift mask default map<minhash, [test then]> table-type test-type skip-check?) //prepared by case macro and presumed correct //case macro binds actual expr in let so expr is always a local, //no need to worry about multiple evaluation public Expr Parse(ParserContext pcon, object frm) { ISeq form = (ISeq)frm; if (pcon.Rhc == RHC.Eval) { return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "case__" + RT.nextID())); } IPersistentVector args = LazilyPersistentVector.create(form.next()); object exprForm = args.nth(0); int shift = Util.ConvertToInt(args.nth(1)); int mask = Util.ConvertToInt(args.nth(2)); object defaultForm = args.nth(3); IPersistentMap caseMap = (IPersistentMap)args.nth(4); Keyword switchType = (Keyword)args.nth(5); Keyword testType = (Keyword)args.nth(6); IPersistentSet skipCheck = RT.count(args) < 8 ? null : (IPersistentSet)args.nth(7); ISeq keys = RT.keys(caseMap); int low = Util.ConvertToInt(RT.first(keys)); int high = Util.ConvertToInt(RT.nth(keys, RT.count(keys) - 1)); LocalBindingExpr testexpr = (LocalBindingExpr)Compiler.Analyze(pcon.SetRhc(RHC.Expression), exprForm); SortedDictionary <int, Expr> tests = new SortedDictionary <int, Expr>(); Dictionary <int, Expr> thens = new Dictionary <int, Expr>(); foreach (IMapEntry me in caseMap) { int minhash = Util.ConvertToInt(me.key()); object pair = me.val(); // [test-val then-expr] object first = RT.first(pair); Expr testExpr = testType == _intKey ? NumberExpr.Parse(Util.ConvertToInt(first)) : (first == null ? Compiler.NilExprInstance : new ConstantExpr(first)); tests[minhash] = testExpr; Expr thenExpr; thenExpr = Compiler.Analyze(pcon, RT.second(pair)); thens[minhash] = thenExpr; } Expr defaultExpr; defaultExpr = Compiler.Analyze(pcon, defaultForm); return(new CaseExpr( (IPersistentMap)Compiler.SourceSpanVar.deref(), testexpr, shift, mask, low, high, defaultExpr, tests, thens, switchType, testType, skipCheck)); }
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)); }
/// <summary> /// Gets the number of items in the collection. /// </summary> /// <returns>The number of items in the collection.</returns> public override int count() { return(_vals.Length + RT.count(_ext)); }
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 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)); }
/// <summary> /// Gets the number of items in the collection. /// </summary> /// <returns>The number of items in the collection.</returns> public int count() { return(RT.count(_f) + RT.count(_r)); }
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)); }
/// <summary> /// Gets the number of items in the collection. /// </summary> /// <returns>The number of items in the collection.</returns> public override int count() { return(1 + RT.count(_more)); }
private Expression GenerateValue(object value) { bool partial = true; Expression ret; if (value is String) { ret = Expression.Constant((String)value); } else if (Util.IsPrimitive(value.GetType())) // or just IsNumeric? { ret = Expression.Constant(value); } else if (value is Type) { ret = Expression.Call( null, Compiler.Method_RT_classForName, Expression.Constant(((Type)value).FullName)); } else if (value is Symbol) { Symbol sym = (Symbol)value; ret = Expression.Call( null, Compiler.Method_Symbol_create2, Expression.Convert(Expression.Constant(sym.Namespace), typeof(string)), // can be null Expression.Constant(sym.Name)); } else if (value is Keyword) { ret = Expression.Call( null, Compiler.Method_Keyword_intern, GenerateValue(((Keyword)value).Symbol)); } else if (value is Var) { Var var = (Var)value; ret = Expression.Call( null, Compiler.Method_RT_var2, Expression.Constant(var.Namespace.Name.ToString()), Expression.Constant(var.Symbol.Name.ToString())); } else if (value is IPersistentMap) { IPersistentMap map = (IPersistentMap)value; List <object> entries = new List <object>(map.count() * 2); foreach (IMapEntry entry in map) { entries.Add(entry.key()); entries.Add(entry.val()); } Expression expr = GenerateListAsObjectArray(entries); ret = Expression.Call( null, Compiler.Method_RT_map, expr); } else if (value is IPersistentVector) { Expression expr = GenerateListAsObjectArray(value); ret = Expression.Call( null, Compiler.Method_RT_vector, expr); } else if (value is ISeq || value is IPersistentList) { Expression expr = GenerateListAsObjectArray(value); ret = Expression.Call( null, Compiler.Method_PersistentList_create, expr); } else { string cs = null; try { cs = RT.printString(value); } catch (Exception) { throw new Exception(String.Format("Can't embed object in code, maybe print-dup not defined: {0}", value)); } if (cs.Length == 0) { throw new Exception(String.Format("Can't embed unreadable object in code: " + value)); } if (cs.StartsWith("#<")) { throw new Exception(String.Format("Can't embed unreadable object in code: " + cs)); } ret = Expression.Call(Compiler.Method_RT_readString, Expression.Constant(cs)); partial = false; } if (partial) { if (value is Obj && RT.count(((Obj)value).meta()) > 0) { Expression objExpr = Expression.Convert(ret, typeof(Obj)); Expression metaExpr = Expression.Convert(GenerateValue(((Obj)value).meta()), typeof(IPersistentMap)); ret = Expression.Call( objExpr, Compiler.Method_IObj_withMeta, metaExpr); } } return(ret); }
protected Expression GenerateValue(object value) { bool partial = true; Expression ret; if (value == null) { ret = Expression.Constant(null); } else if (value is String) { ret = Expression.Constant((String)value); } else if (value is Boolean) { ret = Expression.Constant((Boolean)value); } else if (Util.IsPrimitive(value.GetType())) // or just IsNumeric? { ret = Expression.Constant(value); } else if (value is Type) { Type t = (Type)value; if (t.IsValueType) { ret = Expression.Constant(t, typeof(Type)); } else { ret = Expression.Call( null, Compiler.Method_RT_classForName, Expression.Constant(Compiler.DestubClassName(((Type)value).FullName))); } } else if (value is Symbol) { Symbol sym = (Symbol)value; ret = Expression.Call( null, Compiler.Method_Symbol_intern2, Expression.Convert(Expression.Constant(sym.Namespace), typeof(string)), // can be null Expression.Constant(sym.Name)); } else if (value is Keyword) { Keyword keyword = (Keyword)value; ret = Expression.Call( null, Compiler.Method_RT_keyword, Expression.Convert(Expression.Constant(keyword.Namespace), typeof(string)), // can be null Expression.Constant(keyword.Name)); } else if (value is Var) { Var var = (Var)value; ret = Expression.Call( null, Compiler.Method_RT_var2, Expression.Constant(var.Namespace.Name.ToString()), Expression.Constant(var.Symbol.Name.ToString())); } else if (value is IType) { IPersistentVector fields = (IPersistentVector)Reflector.InvokeStaticMethod(value.GetType(), "getBasis", Type.EmptyTypes); List <Expression> args = new List <Expression>(); for (ISeq s = RT.seq(fields); s != null; s = s.next()) { Symbol field = (Symbol)s.first(); Type k = Compiler.TagType(Compiler.TagOf(field)); object val = Reflector.GetInstanceFieldOrProperty(value, field.Name); Expression expr = GenerateValue(val); if (k.IsPrimitive) { expr = Expression.Convert(expr, k); } else { expr = Compiler.MaybeBox(expr); } args.Add(expr); } ConstructorInfo cinfo = value.GetType().GetConstructors()[0]; ret = Expression.New(cinfo, args); } else if (value is IRecord) { //MethodInfo[] minfos = value.GetType().GetMethods(BindingFlags.Static | BindingFlags.Public); ret = Expression.Call( value.GetType(), "create", Type.EmptyTypes, //new Type[] { typeof(IPersistentMap) }, GenerateValue(PersistentArrayMap.create((IDictionary)value))); } else if (value is IPersistentMap) { IPersistentMap map = (IPersistentMap)value; List <object> entries = new List <object>(map.count() * 2); foreach (IMapEntry entry in map) { entries.Add(entry.key()); entries.Add(entry.val()); } Expression expr = GenerateListAsObjectArray(entries); ret = Expression.Call( null, Compiler.Method_RT_map, expr); } else if (value is IPersistentVector) { Expression expr = GenerateListAsObjectArray(value); ret = Expression.Call( null, Compiler.Method_RT_vector, expr); } else if (value is PersistentHashSet) { ISeq vs = RT.seq(value); if (vs == null) { ret = Expression.Field(null, Compiler.Method_PersistentHashSet_EMPTY); } else { Expression expr = GenerateListAsObjectArray(vs); ret = Expression.Call( null, Compiler.Method_PersistentHashSet_create, expr); } } else if (value is ISeq || value is IPersistentList) { Expression expr = GenerateListAsObjectArray(value); ret = Expression.Call( null, Compiler.Method_PersistentList_create, expr); } else if (value is Regex) { ret = Expression.New( Compiler.Ctor_Regex_1, Expression.Constant(((Regex)value).ToString())); } else { string cs = null; try { cs = RT.printString(value); } catch (Exception) { throw new InvalidOperationException(String.Format("Can't embed object in code, maybe print-dup not defined: {0}", value)); } if (cs.Length == 0) { throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + value)); } if (cs.StartsWith("#<")) { throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + cs)); } ret = Expression.Call(Compiler.Method_RT_readString, Expression.Constant(cs)); partial = false; } if (partial) { if (value is IObj && RT.count(((IObj)value).meta()) > 0) { Expression objExpr = Expression.Convert(ret, typeof(IObj)); Expression metaExpr = Expression.Convert(GenerateValue(((IObj)value).meta()), typeof(IPersistentMap)); ret = Expression.Call( objExpr, Compiler.Method_IObj_withMeta, metaExpr); } } return(ret); }
protected void EmitValue(object value, CljILGen ilg) { bool partial = true; if (value == null) { ilg.Emit(OpCodes.Ldnull); } else if (value is String) { ilg.Emit(OpCodes.Ldstr, (String)value); } else if (value is Boolean) { ilg.EmitBoolean((Boolean)value); ilg.Emit(OpCodes.Box, typeof(bool)); } else if (value is Int32) { ilg.EmitInt((int)value); ilg.Emit(OpCodes.Box, typeof(int)); } else if (value is Int64) { ilg.EmitLong((long)value); ilg.Emit(OpCodes.Box, typeof(long)); } else if (value is Double) { ilg.EmitDouble((double)value); ilg.Emit(OpCodes.Box, typeof(double)); } else if (value is Char) { ilg.EmitChar((char)value); ilg.Emit(OpCodes.Box, typeof(char)); } else if (value is Type) { Type t = (Type)value; if (t.IsValueType) { ilg.EmitType(t); } else { //ilg.EmitString(Compiler.DestubClassName(((Type)value).FullName)); ilg.EmitString(((Type)value).FullName); ilg.EmitCall(Compiler.Method_RT_classForName); } } else if (value is Symbol) { Symbol sym = (Symbol)value; if (sym.Namespace == null) { ilg.EmitNull(); } else { ilg.EmitString(sym.Namespace); } ilg.EmitString(sym.Name); ilg.EmitCall(Compiler.Method_Symbol_intern2); } else if (value is Keyword) { Keyword keyword = (Keyword)value; if (keyword.Namespace == null) { ilg.EmitNull(); } else { ilg.EmitString(keyword.Namespace); } ilg.EmitString(keyword.Name); ilg.EmitCall(Compiler.Method_RT_keyword); } else if (value is Var) { Var var = (Var)value; ilg.EmitString(var.Namespace.Name.ToString()); ilg.EmitString(var.Symbol.Name.ToString()); ilg.EmitCall(Compiler.Method_RT_var2); } else if (value is IType) { IPersistentVector fields = (IPersistentVector)Reflector.InvokeStaticMethod(value.GetType(), "getBasis", Type.EmptyTypes); for (ISeq s = RT.seq(fields); s != null; s = s.next()) { Symbol field = (Symbol)s.first(); Type k = Compiler.TagType(Compiler.TagOf(field)); object val = Reflector.GetInstanceFieldOrProperty(value, field.Name); EmitValue(val, ilg); if (k.IsPrimitive) { ilg.Emit(OpCodes.Castclass, k); } } ConstructorInfo cinfo = value.GetType().GetConstructors()[0]; ilg.EmitNew(cinfo); } else if (value is IRecord) { //MethodInfo[] minfos = value.GetType().GetMethods(BindingFlags.Static | BindingFlags.Public); EmitValue(PersistentArrayMap.create((IDictionary)value), ilg); MethodInfo createMI = value.GetType().GetMethod("create", BindingFlags.Static | BindingFlags.Public, null, CallingConventions.Standard, new Type[] { typeof(IPersistentMap) }, null); ilg.EmitCall(createMI); } else if (value is IPersistentMap) { IPersistentMap map = (IPersistentMap)value; List <object> entries = new List <object>(map.count() * 2); foreach (IMapEntry entry in map) { entries.Add(entry.key()); entries.Add(entry.val()); } EmitListAsObjectArray(entries, ilg); ilg.EmitCall(Compiler.Method_RT_map); } else if (value is IPersistentVector) { EmitListAsObjectArray(value, ilg); ilg.EmitCall(Compiler.Method_RT_vector); } else if (value is PersistentHashSet) { ISeq vs = RT.seq(value); if (vs == null) { ilg.EmitFieldGet(Compiler.Method_PersistentHashSet_EMPTY); } else { EmitListAsObjectArray(vs, ilg); ilg.EmitCall(Compiler.Method_PersistentHashSet_create); } } else if (value is ISeq || value is IPersistentList) { EmitListAsObjectArray(value, ilg); ilg.EmitCall(Compiler.Method_PersistentList_create); } else if (value is Regex) { ilg.EmitString(((Regex)value).ToString()); ilg.EmitNew(Compiler.Ctor_Regex_1); } else { string cs = null; try { cs = RT.printString(value); } catch (Exception) { throw new InvalidOperationException(String.Format("Can't embed object in code, maybe print-dup not defined: {0}", value)); } if (cs.Length == 0) { throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + value)); } if (cs.StartsWith("#<")) { throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + cs)); } ilg.EmitString(cs); ilg.EmitCall(Compiler.Method_RT_readString); partial = false; } if (partial) { if (value is IObj && RT.count(((IObj)value).meta()) > 0) { ilg.Emit(OpCodes.Castclass, typeof(IObj)); Object m = ((IObj)value).meta(); EmitValue(Compiler.ElideMeta(m), ilg); ilg.Emit(OpCodes.Castclass, typeof(IPersistentMap)); ilg.Emit(OpCodes.Callvirt, Compiler.Method_IObj_withMeta); } } }
/// <summary> /// Gets the number of items in the collection. /// </summary> /// <returns>The number of items in the collection.</returns> public override int count() { return(RT.count(_f) + RT.count(_rseq)); }