public static CombinedReckoner Compile(Formula formula)
        {
            if (MODULE == null)
            {
                AssemblyName assemblyName = new AssemblyName();
                assemblyName.Name = "EmittedAssembly";

                ASSEMBLY = AssemblyBuilder.DefineDynamicAssembly(assemblyName, CollectMode ? AssemblyBuilderAccess.RunAndCollect : AssemblyBuilderAccess.Run);
                MODULE   = ASSEMBLY.DefineDynamicModule("EmittedModule");
                CLASS_ID = 0;
            }
            CLASS_ID++;

            TypeBuilder MathlineFormula = MODULE.DefineType(TYPE_PREFIX + CLASS_ID, TypeAttributes.Public, typeof(CombinedReckoner));

            Type[]             constructorArgs = { };
            ConstructorBuilder constructor     = MathlineFormula.DefineConstructor(
                MethodAttributes.Public, CallingConventions.Standard, null);

            ILGenerator constructorIL = constructor.GetILGenerator();

            constructorIL.Emit(OpCodes.Ldarg_0);
            ConstructorInfo superConstructor = typeof(Object).GetConstructor(new Type[0]);

            constructorIL.Emit(OpCodes.Call, superConstructor);
            constructorIL.Emit(OpCodes.Ret);

            Type[]          args     = { };
            MethodBuilder   fxMethod = MathlineFormula.DefineMethod("Reckon", MethodAttributes.Public | MethodAttributes.Virtual, typeof(void), args);
            ILGenerator     methodIL = fxMethod.GetILGenerator();
            CompilerContext context  = new CompilerContext();

            // first pass calculate the parameters
            // initialize and declare the parameters, start with
            // localVectorI = parameters[i];
            // next pass implements the function
            formula.Compile(methodIL, context);
            context.NextPass();
            context.GenerateLocalInit(methodIL);
            formula.Compile(methodIL, context);

            // finally return
            methodIL.Emit(OpCodes.Ret);

            // create the class...
            Type             mxt      = MathlineFormula.CreateTypeInfo();
            CombinedReckoner reckoner = (CombinedReckoner)Activator.CreateInstance(mxt, new Object[] { });

            reckoner.SetParams(context.ParamCards, context.Count);

            return(reckoner);
        }
Example #2
0
        public override void Compile(ILGenerator g, CompilerContext cc)
        {
            bool biloop = size.rows > 1 && size.cols > 1;

            if (cc.IsFirstPass())
            {
                if (!partial)
                {
                    iI = cc.AllocIndexVariable();   // i
                    lL = cc.AllocIndexVariable();   // l
                }
                expr.Compile(g, cc);
                lexpr.CompileAssign(g, cc, true, partial);
            }
            else
            {
                if (!partial)
                {
                    int   i, l, svi;
                    Label topLabel;
                    Label topLabelE;

                    topLabel  = g.DefineLabel();
                    topLabelE = g.DefineLabel();

                    i = cc.GetIndexVariable(iI);
                    l = cc.GetIndexVariable(lL);
                    // then
                    svi = cc.GetIndexVariable(0);

                    cc.SetIndexVariable(0, i);
                    cc.SetIndexVariable(1, size.rows);

                    g.Emit(OpCodes.Ldc_I4_0);   // i = 0
                    g.Emit(OpCodes.Stloc, i);
                    g.Emit(OpCodes.Ldarg_0);
                    g.Emit(OpCodes.Ldc_I4_0);
                    g.EmitCall(OpCodes.Callvirt, typeof(CombinedReckoner).GetMethod("GetRowCount", new Type[] { typeof(int) }), null);
                    g.Emit(OpCodes.Stloc, l);

                    if (size.rows > 1 || size.cols > 1)
                    {
                        // iterate rows, so move
                        int index;
                        int count;

                        index = i;
                        count = size.rows;

                        // just one loop. Set wich
                        g.MarkLabel(topLabel);          // TP:

                        lexpr.CompileAssign(g, cc, false, false);
                        expr.Compile(g, cc);                        // value
                        lexpr.CompileAssign(g, cc, true, false);

                        // increment j
                        g.Emit(OpCodes.Ldloc, index);           // 1
                        g.Emit(OpCodes.Ldc_I4_1);               // j =>
                        g.Emit(OpCodes.Add);                    // +
                        g.Emit(OpCodes.Dup);
                        g.Emit(OpCodes.Stloc, index);           // j <=

                        // here from first jump
                        //g.Emit(OpCodes.Ldc_I4, count);  // j < cols

                        g.Emit(OpCodes.Ldloc, l);
                        g.Emit(OpCodes.Blt, topLabel);
                    }
                    else
                    {
                        lexpr.CompileAssign(g, cc, false, false);
                        expr.Compile(g, cc);                        // value
                        lexpr.CompileAssign(g, cc, true, false);
                    }
                    cc.SetIndexVariable(0, svi);
                }
                else
                {
                    lexpr.CompileAssign(g, cc, false, true);
                    expr.Compile(g, cc);                        // value
                    lexpr.CompileAssign(g, cc, true, true);
                }
            }
        }
 public override void Compile(ILGenerator g, CompilerContext cc)
 {
     e.Compile(g, cc);
 }