예제 #1
0
        /// <summary>
        /// Emit a mixin router from a class to the mixin body methods.
        /// </summary>
        public void emitMixinRouter(Method m)
        {
            string parent = FanUtil.toDotnetTypeName(m.parent());
            string name   = FanUtil.toDotnetMethodName(m.name());
            string ret    = FanUtil.toDotnetTypeName(m.inheritedReturns());

            string[] parTypes   = new string[] { parent };
            List     pars       = m.@params();
            int      paramCount = pars.sz();

            // find first param with default value
            int firstDefault = paramCount;

            for (int i = 0; i < paramCount; i++)
            {
                if (((Param)pars.get(i)).hasDefault())
                {
                    firstDefault = i; break;
                }
            }

            // generate routers
            for (int i = firstDefault; i <= paramCount; i++)
            {
                string[] myParams     = new string[i];
                string[] myParamNames = new string[i];
                string[] implParams   = new string[i + 1];
                implParams[0] = parent;

                for (int j = 0; j < i; j++)
                {
                    Param  param = (Param)m.@params().get(j);
                    Type   pt    = param.type();
                    string s     = FanUtil.toDotnetTypeName(pt);
                    myParams[j]       = s;
                    myParamNames[j]   = param.name();
                    implParams[j + 1] = s;
                }

                // CLR requires public virtual
                PERWAPI.MethAttr attr = PERWAPI.MethAttr.Public | PERWAPI.MethAttr.Virtual;

                PERWAPI.CILInstructions code = emitter.emitMethod(name, ret, myParamNames, myParams,
                                                                  attr, new string[0], new string[0]);
                code.Inst(PERWAPI.Op.ldarg_0); // push this
                for (int p = 0; p < i; p++)
                {
                    // push args
                    Param param = (Param)m.@params().get(p);
                    FCodeEmit.loadVar(code, FanUtil.toDotnetStackType(param.type()), p + 1);
                }
                PERWAPI.Method meth = emitter.findMethod(parent + "_", name, implParams, ret);
                code.MethInst(PERWAPI.MethodOp.call, meth);
                code.Inst(PERWAPI.Op.ret);
            }
        }
예제 #2
0
파일: Fan.cs 프로젝트: syatanic/fantom
        static int callMain(Type t, Method m)
        {
            // check parameter type and build main arguments
            List args;
            List pars = m.@params();

            if (pars.sz() == 0)
            {
                args = null;
            }
            else if (((Param)pars.get(0)).type().@is(Sys.StrType.toListOf()) &&
                     (pars.sz() == 1 || ((Param)pars.get(1)).hasDefault()))
            {
                args = new List(Sys.ObjType, new object[] { Env.cur().args() });
            }
            else
            {
                System.Console.WriteLine("ERROR: Invalid parameters for main: " + m.signature());
                return(-1);
            }

            // invoke
            try
            {
                if (m.isStatic())
                {
                    return(toResult(m.callList(args)));
                }
                else
                {
                    return(toResult(m.callOn(t.make(), args)));
                }
            }
            catch (Err.Val ex)
            {
                ex.err().trace();
                return(-1);
            }
        }
예제 #3
0
        //////////////////////////////////////////////////////////////////////////
        // Complex
        //////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// complex := type [fields]
        /// fields  := "{" field (eos field)* "}"
        /// field   := name "=" obj
        /// </summary>
        private object readComplex(int line, Type t, bool root)
        {
            Map  toSet = new Map(Sys.FieldType, Sys.ObjType.toNullable());
            List toAdd = new List(Sys.ObjType.toNullable());

            // read fields/collection into toSet/toAdd
            readComplexFields(t, toSet, toAdd);

            // get the make constructor
            Method makeCtor = t.method("make", false);

            if (makeCtor == null || !makeCtor.isPublic())
            {
                throw err("Missing public constructor " + t.qname() + ".make", line);
            }

            // get argument lists
            List args = null;

            if (root && options != null)
            {
                args = (List)options.get("makeArgs");
            }

            // construct object
            object obj          = null;
            bool   setAfterCtor = true;

            try
            {
                // if first parameter is an function then pass toSet
                // as an it-block for setting the fields
                Param p = (Param)makeCtor.@params().first();
                if (args == null && p != null && p.type().fits(Sys.FuncType))
                {
                    args         = new List(Sys.ObjType).add(Field.makeSetFunc(toSet));
                    setAfterCtor = false;
                }

                // invoke make to construct object
                obj = makeCtor.callList(args);
            }
            catch (System.Exception e)
            {
                throw err("Cannot make " + t + ": " + e, line, e);
            }

            // set fields (if not passed to ctor as it-block)
            if (setAfterCtor && toSet.size() > 0)
            {
                IDictionaryEnumerator en = toSet.pairsIterator();
                while (en.MoveNext())
                {
                    complexSet(obj, (Field)en.Key, en.Value, line);
                }
            }

            // add
            if (toAdd.size() > 0)
            {
                Method addMethod = t.method("add", false);
                if (addMethod == null)
                {
                    throw err("Method not found: " + t.qname() + ".add", line);
                }
                for (int i = 0; i < toAdd.sz(); ++i)
                {
                    complexAdd(t, obj, addMethod, toAdd.get(i), line);
                }
            }

            return(obj);
        }