static void EmitPrimitive(CljILGen ilg, object val) { switch (Type.GetTypeCode(val.GetType())) { case TypeCode.Boolean: ilg.EmitBoolean((bool)val); break; case TypeCode.Byte: ilg.EmitByte((byte)val); break; case TypeCode.Char: ilg.EmitChar((char)val); break; case TypeCode.Decimal: ilg.EmitDecimal((decimal)val); break; case TypeCode.Double: ilg.EmitDouble((double)val); break; case TypeCode.Int16: ilg.EmitShort((short)val); break; case TypeCode.Int32: ilg.EmitInt((int)val); break; case TypeCode.Int64: ilg.EmitLong((long)val); break; case TypeCode.SByte: ilg.EmitSByte((sbyte)val); break; case TypeCode.Single: ilg.EmitSingle((float)val); break; case TypeCode.UInt16: ilg.EmitUShort((ushort)val); break; case TypeCode.UInt32: ilg.EmitUInt((uint)val); break; case TypeCode.UInt64: ilg.EmitULong((ulong)val); break; default: throw new InvalidOperationException("Unknown constant type in EmitPrimitive"); } }
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); } } }
static void EmitPrimitive(CljILGen ilg, object val) { switch (Type.GetTypeCode(val.GetType()) ) { case TypeCode.Boolean: ilg.EmitBoolean((bool)val); break; case TypeCode.Byte: ilg.EmitByte((byte)val); break; case TypeCode.Char: ilg.EmitChar((char)val); break; case TypeCode.Decimal: ilg.EmitDecimal((decimal)val); break; case TypeCode.Double: ilg.EmitDouble((double)val); break; case TypeCode.Int16: ilg.EmitShort((short)val); break; case TypeCode.Int32: ilg.EmitInt((int)val); break; case TypeCode.Int64: ilg.EmitLong((long)val); break; case TypeCode.SByte: ilg.EmitSByte((sbyte)val); break; case TypeCode.Single: ilg.EmitSingle((float)val); break; case TypeCode.UInt16: ilg.EmitUShort((ushort)val); break; case TypeCode.UInt32: ilg.EmitUInt((uint)val); break; case TypeCode.UInt64: ilg.EmitULong((ulong)val); break; default: throw new InvalidOperationException("Unknown constant type in EmitPrimitive"); } }
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); } } }