Пример #1
0
        static void GenerateFields(object fields, string n, RecordTypeDescriptor rtd, TypeGen tg, object fieldtypes)
        {
            object[] f      = RequiresNotNull <object[]>(fields);
            object[] ftypes = RequiresNotNull <object[]>(fieldtypes);

            List <FieldDescriptor> rtd_fields = new List <FieldDescriptor>();

            for (int i = 0; i < f.Length; i++)
            {
                Cons c = (Cons)f[i];
                // check for recursive definition
                Type t = rtd.Name == SymbolTable.IdToString((SymbolId)ftypes[i]) ?
                         rtd.tg.TypeBuilder :
                         ClrGenerator.ExtractTypeInfo(List(SymbolTable.StringToObject("quote"), ftypes[i]));

                // can this ever be null given ExtractTypeInfo throws?
                if (t == null)
                {
                    ClrGenerator.ClrSyntaxError("GenerateFields", "type not found", ftypes[i]);
                }

                string fname = SymbolTable.IdToString(RequiresNotNull <SymbolId>(Second(c)));
                // we use standard names here, they will be mapped to the given names
                string aname = n + "-" + fname;
                string mname = n + "-" + fname + "-set!";

                var fd = new FieldDescriptor {
                    Name = fname
                };

                FieldAttributes fattrs = FieldAttributes.Public;// | FieldAttributes.InitOnly;
                if (c.car == SymbolTable.StringToObject("mutable"))
                {
                    fd.mutable = true;
                    //fattrs &= ~FieldAttributes.InitOnly;
                }
                FieldSlot s = tg.AddField(t, fname, fattrs) as FieldSlot;

                fd.field = s.Field;

                PropertyBuilder pi = tg.TypeBuilder.DefineProperty(fname, PropertyAttributes.None, t, new Type[0]);

                // accesor

                MethodBuilder ab = tg.TypeBuilder.DefineMethod(aname, MethodAttributes.Public | MethodAttributes.Static,
                                                               t, new Type[] { tg.TypeBuilder });

                ab.DefineParameter(1, ParameterAttributes.None, n);

                ILGenerator agen = ab.GetILGenerator();
                agen.Emit(OpCodes.Ldarg_0);
                //agen.Emit(OpCodes.Castclass, tg.TypeBuilder);
                agen.Emit(OpCodes.Ldfld, fd.field);
                agen.Emit(OpCodes.Ret);

                fd.accessor = ab;
                pi.SetGetMethod(ab);

                // mutator
                if (fd.mutable)
                {
                    MethodBuilder mb = tg.TypeBuilder.DefineMethod(mname, MethodAttributes.Public | MethodAttributes.Static,
                                                                   typeof(object), new Type[] { tg.TypeBuilder, t });

                    mb.DefineParameter(1, ParameterAttributes.None, n);

                    ILGenerator mgen = mb.GetILGenerator();
                    mgen.Emit(OpCodes.Ldarg_0);
                    //mgen.Emit(OpCodes.Castclass, tg.TypeBuilder);
                    mgen.Emit(OpCodes.Ldarg_1);
                    mgen.Emit(OpCodes.Stfld, fd.field);
                    mgen.Emit(OpCodes.Ldsfld, Compiler.Generator.Unspecified);
                    mgen.Emit(OpCodes.Ret);

                    fd.mutator = mb;
                    pi.SetSetMethod(mb);
                }

                rtd_fields.Add(fd);
            }

            rtd.fields = rtd_fields.ToArray();
        }
Пример #2
0
    static void GenerateFields(object fields, string n, RecordTypeDescriptor rtd, TypeGen tg, object fieldtypes)
    {
      object[] f = RequiresNotNull<object[]>(fields);
      object[] ftypes = RequiresNotNull<object[]>(fieldtypes);

      List<FieldDescriptor> rtd_fields = new List<FieldDescriptor>();

      for (int i = 0; i < f.Length; i++)
      {
        Cons c = (Cons) f[i];
        Type t = ClrGenerator.ExtractTypeInfo(List(SymbolTable.StringToObject("quote"), ftypes[i]));

        if (t == null)
        {
          ClrGenerator.ClrSyntaxError("GenerateFields", "type not found", ftypes[i]);
        }

        string fname = SymbolTable.IdToString(RequiresNotNull<SymbolId>(Second(c)));
        // we use standard names here, they will be mapped to the given names
        string aname = n + "-" + fname;
        string mname = n + "-" + fname + "-set!";

        var fd = new FieldDescriptor { Name = fname };

        FieldAttributes fattrs = FieldAttributes.Public | FieldAttributes.InitOnly;
        if (c.car == SymbolTable.StringToObject("mutable"))
        {
          fd.mutable = true;
          fattrs &= ~FieldAttributes.InitOnly;
        }
        FieldSlot s = tg.AddField(t, fname, fattrs) as FieldSlot;

        fd.field = s.Field;

        PropertyBuilder pi = tg.TypeBuilder.DefineProperty(fname, PropertyAttributes.None, t, new Type[0]);

        // accesor 

        MethodBuilder ab = tg.TypeBuilder.DefineMethod(aname, MethodAttributes.Public | MethodAttributes.Static,
          t, new Type[] { tg.TypeBuilder });

        ab.DefineParameter(1, ParameterAttributes.None, n);

        ILGenerator agen = ab.GetILGenerator();
        agen.Emit(OpCodes.Ldarg_0);
        //agen.Emit(OpCodes.Castclass, tg.TypeBuilder);
        agen.Emit(OpCodes.Ldfld, fd.field);
        agen.Emit(OpCodes.Ret);

        fd.accessor = ab;
        pi.SetGetMethod(ab);

        // mutator
        if (fd.mutable)
        {
          MethodBuilder mb = tg.TypeBuilder.DefineMethod(mname, MethodAttributes.Public | MethodAttributes.Static,
            typeof(object), new Type[] { tg.TypeBuilder, t });

          mb.DefineParameter(1, ParameterAttributes.None, n);

          ILGenerator mgen = mb.GetILGenerator();
          mgen.Emit(OpCodes.Ldarg_0);
          //mgen.Emit(OpCodes.Castclass, tg.TypeBuilder);
          mgen.Emit(OpCodes.Ldarg_1);
          mgen.Emit(OpCodes.Stfld, fd.field);
          mgen.Emit(OpCodes.Ldsfld, Compiler.Generator.Unspecified);
          mgen.Emit(OpCodes.Ret);

          fd.mutator = mb;
          pi.SetSetMethod(mb);
        }

        rtd_fields.Add(fd);
      }

      rtd.fields = rtd_fields.ToArray();
    }
Пример #3
0
        public static RecordTypeDescriptor Create(Type type, string name, string uid, bool opaque, RecordTypeDescriptor parentrtd)
        {
            var rtd = new RecordTypeDescriptor
            {
                type      = type,
                Name      = name,
                predicate = type.GetMethod(name + "?"),
                uid       = uid,
                @sealed   = type.IsSealed,
                opaque    = opaque,
                Parent    = parentrtd
            };

            Records.typedescriptors[type] = rtd;

            MethodInfo ci     = type.GetMethod("make");
            var        pari   = ci.GetParameters();
            int        pcount = pari.Length;

            if (pcount < 9 && !(pcount == 1 && pari[0].ParameterType == typeof(object[])))
            {
                rtd.Constructor = CreateCallable(ci);
            }
            else
            {
                rtd.Constructor = Closure.Create(Delegate.CreateDelegate(typeof(CallTargetN), ci)) as Callable;
            }

            rtd.DefaultConstructor = CreateCallable(type.GetMethod("$make", Type.EmptyTypes));
            rtd.DefaultInit        = CreateCallable(type.GetMethod("$init"));

            rtd.Predicate = Closure.Create(Delegate.CreateDelegate(typeof(CallTarget1), rtd.predicate)) as Callable;

            var flds = new List <FieldDescriptor>();

            foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
            {
                var fd = new FieldDescriptor {
                    Name = fi.Name
                };

                fd.field = fi;

                var pi = type.GetProperty(fi.Name);

                fd.accessor = pi.GetGetMethod();

                fd.Accessor = CreateCallable(fd.accessor);

                if (pi.CanWrite)
                {
                    fd.mutator = pi.GetSetMethod();

                    fd.Mutator = CreateCallable(fd.mutator);
                }
                else
                {
                    fd.Mutator = Builtins.FALSE;
                }

                flds.Add(fd);
            }

            rtd.fields = flds.ToArray();

            return(rtd);
        }
Пример #4
0
    public static RecordTypeDescriptor Create(Type type, string name, string uid, RecordTypeDescriptor parentrtd)
    {
      var rtd = new RecordTypeDescriptor
      {
        type = type,
        Name = name,
        predicate = type.GetMethod(name + "?"),
        uid = uid,
        @sealed = type.IsSealed,
        Parent = parentrtd

      };

      Records.typedescriptors[type] = rtd;

      MethodInfo ci = type.GetMethod("make");
      var pari = ci.GetParameters();
      int pcount = pari.Length;

      if (pcount < 9 && !(pcount == 1 && pari[0].ParameterType == typeof(object[])))
      {
        rtd.Constructor = CreateCallable(ci);
      }
      else
      {
        rtd.Constructor = Closure.Create(Delegate.CreateDelegate(typeof(CallTargetN), ci)) as Callable;
      }

      rtd.Predicate = Closure.Create(Delegate.CreateDelegate(typeof(CallTarget1), rtd.predicate)) as Callable;

      var flds = new List<FieldDescriptor>();

      foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
      {
        var fd = new FieldDescriptor { Name = fi.Name };

        fd.field = fi;

        var pi = type.GetProperty(fi.Name);

        fd.accessor = pi.GetGetMethod();

        fd.Accessor = CreateCallable(fd.accessor);

        if (pi.CanWrite)
        {
          fd.mutator = pi.GetSetMethod();

          fd.Mutator = CreateCallable(fd.mutator);
        }
        else
        {
          fd.Mutator = Builtins.FALSE;
        }

        flds.Add(fd);
      }

      rtd.fields = flds.ToArray();

      return rtd;
    }