clojure.lang.CljCompiler.Ast.ObjExpr.EmitValue C# (CSharp) Method

EmitValue() private method

private EmitValue ( object value, CljILGen ilg ) : void
value object
ilg CljILGen
return void
        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, Compiler.munge(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)
            {
                IPersistentVector args = (IPersistentVector)value;
                if (args.count() <= Tuple.MAX_SIZE)
                {
                    for (int i = 0; i < args.count(); i++)
                        EmitValue(args.nth(i), ilg);
                    ilg.Emit(OpCodes.Call, Compiler.Methods_CreateTuple[args.count()]);
                }
                else
                {
                    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);
                }
            }
        }