Exemplo n.º 1
0
        private void CreateInstanceOfWrapper(LetExpressionAST let)
        {
            string currentFunctionCodeName = let.CurrentScope.CurrentFunction.CodeName;

            TypeCodeInfo typeCodeInfo = code.GetWrapperAsociatteTo(currentFunctionCodeName);

            ILGenerator il = code.Method.GetILGenerator();

            //crear la instancia del objeto que contiene las variable mias que son usadas por otras funciones
            il.Emit(OpCodes.Newobj, typeCodeInfo.DefaultConstructor());
            il.Emit(OpCodes.Stloc_0);

            //asignarle la instancia de mi clase a esta objeto para que tenga la referencia a su padre.
            //locaL_0.parent =  this.

            if (let.CurrentScope.CurrentFunction.FunctionName != "main$")
            {
                FieldBuilder parent = typeCodeInfo.GetField("parent");
                il.Emit(OpCodes.Ldloc_0);
                //cargar el  this
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Stfld, parent);

                //darle los valores  de las variables a los campos de esta clase.
                InitilizateFieldFromParameters(let);
            }
            //obligo a que se lanze el evento que estan esperando los que inicializa las varialbles
            code.ThrowEventForFunction(currentFunctionCodeName);
        }
        /// <summary>
        /// Esta metodo annade todas los campos necesarios a la clase nested. Annade tambien un campo que es una referencia
        /// padre.
        /// </summary>
        /// <param name="code"></param>
        /// <param name="nested">El tipo nested</param>
        /// <param name="typeCodeInfo">la informacion asociada  al tipo nested</param>
        /// <param name="container">El padre del tipo nested</param>
        private void PopulateNestedTypeWithVar(ILCode code, TypeBuilder nested, TypeCodeInfo typeCodeInfo,
                                               TypeBuilder container)
        {
            //annadir un field del tipo de mi padre
            typeCodeInfo.FieldNameOfParent = "parent";
            FieldBuilder fieldRefPadreClass = nested.DefineField(typeCodeInfo.FieldNameOfParent, container,
                                                                 FieldAttributes.Public);

            //le annado a la clase TypeCodeInfo que ahora tiene un nuevo campo(la referencia al padre)
            typeCodeInfo.AddField(typeCodeInfo.FieldNameOfParent, fieldRefPadreClass);

            FunctionInfo funInfo = _functionDecl.CurrentScope.GetFunction(_functionDecl.FunctionId);

            foreach (var item in funInfo.VarsUsedForAnotherFunction)
            {
                if (item.IsParameterFunction)
                {
                    Type         fieldType = code.DefinedType[item.TypeInfo.CodeName];
                    FieldBuilder field     = nested.DefineField(item.CodeName, fieldType, FieldAttributes.Public);
                    code.DefinedField.Add(item.CodeName, field);

                    //annadir el nuevo campo a la clase que me controlo los campos de un tipo nested
                    typeCodeInfo.AddField(item.CodeName, field);
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Devuelve true si el llamado es a una funcion hija.Es decir definidas a partir de la funcion actual
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        private bool IsCallToMethodChild(ILCode code)
        {
            string       funCodeName  = _functionInvocation.CurrentScope.CurrentFunction.CodeName;
            TypeCodeInfo typeCodeInfo = code.GetWrapperAsociatteTo(funCodeName);

            return(typeCodeInfo.ContainMethodInLevel1(FunctionCodeName()));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Devuelve true si el llamado es a una funcion definida al mismo nivel del la funcion actual
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        private bool IsCallRecursiveOrMethodBrother(ILCode code)
        {
            string       funParentCodeName = _functionInvocation.CurrentScope.CurrentFunction.FunctionParent.CodeName;
            TypeCodeInfo typeCodeInfo      = code.GetWrapperAsociatteTo(funParentCodeName);

            return(typeCodeInfo.ContainMethodInLevel1(FunctionCodeName()));
        }
Exemplo n.º 5
0
        public override void GenerateCode(ILCode code, ExpressionAst rightExpr)
        {
            ILGenerator il = code.Method.GetILGenerator();

            //buscar la variable
            VarInfo varInfo = _varAst.CurrentScope.GetVarInfo(_varAst.VarId);

            //--->

            bool pushOnStack = code.PushOnStack;

            code.PushOnStack = true;

            if (_varAst.IsForeignVar)
            //aqui se entra cuando se usa una variable se usa en una funcion que no fue quien la declaro
            {
                string currentParentFunctionCodeName = _varAst.CurrentScope.CurrentFunction.FunctionParent.CodeName;
                //carga el respectivo campo de la clase contenedora.
                //como mis metodos son de instancia y las varibles tambien tengo que cargar el parametro 0
                il.Emit(OpCodes.Ldarg_0);
                //ahora viene cargar la variable de verdad.
                TypeCodeInfo typeCodeInfo = code.GetWrapperAsociatteTo(currentParentFunctionCodeName);
                while (!typeCodeInfo.ContainFieldInLevel1(varInfo.CodeName))
                {
                    //cargo el campo que representa al padre del tipo actual
                    string parentInstanceName = typeCodeInfo.FieldNameOfParent;
                    il.Emit(OpCodes.Ldfld, typeCodeInfo.GetField(parentInstanceName));
                    typeCodeInfo = typeCodeInfo.Parent;
                }
                //pongo el valor que quiero asignar en la pila
                rightExpr.Accept(CodeGenerator);
                //lo asigno.
                il.Emit(OpCodes.Stfld, typeCodeInfo.GetField(varInfo.CodeName));
            }
            else
            {
                if (varInfo.IsLocalVariable)
                {
                    rightExpr.Accept(CodeGenerator);
                    il.Emit(OpCodes.Stloc, code.DefinedLocal[varInfo.CodeName].LocalIndex);
                }
                else if (varInfo.IsParameterFunction)
                {
                    rightExpr.Accept(CodeGenerator);
                    il.Emit(OpCodes.Starg, varInfo.ParameterNumber + 1);
                }
                else // tengo que acceder a la variable a travez de la instancia que tengo como varible local.
                {
                    //se asume que el wrapper siempre esta como primera variable del metodo.
                    il.Emit(OpCodes.Ldloc_0);
                    rightExpr.Accept(CodeGenerator);
                    il.Emit(OpCodes.Stfld, code.DefinedField[varInfo.CodeName]);
                }
            }
            code.PushOnStack = pushOnStack;
        }
Exemplo n.º 6
0
        /// <summary>
        /// 转换模型
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        protected TypeCodeInfo ConvertToInfo(LxdmModel model)
        {
            if (model == null)
            {
                return(null);
            }

            TypeCodeInfo user = AutoMapper.Mapper.Map <LxdmModel, TypeCodeInfo>(model);

            return(user);
        }
Exemplo n.º 7
0
        public override Unit VisitVar(VarAST ast)
        {
            ILGenerator il = code.Method.GetILGenerator();

            //buscar la variable
            VarInfo varInfo = ast.CurrentScope.GetVarInfo(ast.VarId);
            string  currentFunctionCodeName = ast.CurrentScope.CurrentFunction.CodeName;

            if (ast.IsForeignVar) //se entra aca cuando la variable pertenece a otra funcion que no es la actual .
            {
                //carga el respectivo campo de la clase contenedora.
                //como mis metodos son de instancia y las varibles tambien tengo que cargar el parametro 0
                il.Emit(OpCodes.Ldarg_0);
                //ahora viene cargar la variable de verdad.
                TypeCodeInfo typeCodeInfo =
                    code.GetWrapperAsociatteTo(ast.CurrentScope.CurrentFunction.FunctionParent.CodeName);
                while (typeCodeInfo != null && !typeCodeInfo.ContainFieldInLevel1(varInfo.CodeName))
                {
                    //cargo el campo que representa al padre del tipo actual
                    il.Emit(OpCodes.Ldfld, typeCodeInfo.GetField(typeCodeInfo.FieldNameOfParent));
                    typeCodeInfo = typeCodeInfo.Parent;
                }
                il.Emit(OpCodes.Ldfld, typeCodeInfo.GetField(varInfo.CodeName));
            }
            else
            {
                if (varInfo.IsLocalVariable)
                {
                    il.Emit(OpCodes.Ldloc, code.DefinedLocal[varInfo.CodeName].LocalIndex);
                }
                else if (varInfo.IsParameterFunction)
                {
                    il.Emit(OpCodes.Ldarg, varInfo.ParameterNumber + 1);
                }
                else // tengo que acceder a la variable a travez de la instancia que tengo como varible local.
                {
                    TypeCodeInfo typeCodeInfo = code.GetWrapperAsociatteTo(currentFunctionCodeName);
                    //cargar esta variable local donde estan todas las variables que son usadas por  los demas metodos.
                    il.Emit(OpCodes.Ldloc_0);
                    il.Emit(OpCodes.Ldfld, typeCodeInfo.GetField(varInfo.CodeName));
                }
            }

            //ver si debo dejar el valor en la pila.
            if (!code.PushOnStack)
            {
                il.Emit(OpCodes.Pop);
            }
            return(Unit.Create());
        }
Exemplo n.º 8
0
        private void GenerateCodeForCallMethodParent(ILCode code)
        {
            ILGenerator il = code.Method.GetILGenerator();

            string       parentOfCurrentFunction = _functionInvocation.CurrentScope.CurrentFunction.FunctionParent.CodeName;
            TypeCodeInfo parentWrapper           = code.GetWrapperAsociatteTo(parentOfCurrentFunction);

            il.Emit(OpCodes.Ldarg_0);
            while (parentWrapper != null && !parentWrapper.ContainMethodInLevel1(FunctionCodeName()))
            {
                il.Emit(OpCodes.Ldfld, parentWrapper.GetField(parentWrapper.FieldNameOfParent));
                parentWrapper = parentWrapper.Parent;
            }
            //lo proximo seria llamar al metodo
        }
Exemplo n.º 9
0
        public override Unit VisitVarDeclaration(VarDeclarationAST expr)
        {
            VarInfo varInfo = expr.CurrentScope.GetVarInfo(expr.Id);
            //nombre de la variable generado
            string varCodeName = varInfo.CodeName;
            // necesito el tipo de la variable.
            string typeCodeName = varInfo.TypeInfo.CodeName;
            Type   varType      = code.DefinedType[typeCodeName];

            //aca hay que tener en cuenta que las variable que son usadas por otras funciones se declaran en la declaracion de
            //la funcion a la que pertenecen

            if (!varInfo.IsUsedForAnotherFunction)
            {
                if (!varInfo.IsParameterFunction)
                //no tengo en cuenta los parametro de funcion porque esos los declara la funcion
                {
                    //generar la variable como local a la funcion
                    ILGenerator  il    = code.Method.GetILGenerator();
                    LocalBuilder local = il.DeclareLocal(varType);
                    // local.SetLocalSymInfo(varCodeName);
                    //adicionarla a las varibles locales
                    code.DefinedLocal.Add(varCodeName, local);
                }
            }
            else
            {
                if (!varInfo.IsParameterFunction)
                {
                    string       currentFunction = expr.CurrentScope.CurrentFunction.CodeName;
                    TypeCodeInfo wrapper         = code.GetWrapperAsociatteTo(currentFunction);

                    FieldBuilder field = wrapper.Type.DefineField(varInfo.CodeName, varType, FieldAttributes.Public);
                    //añadir el field a la clase ILCode
                    code.DefinedField.Add(varInfo.CodeName, field);
                    //añadida al wrapper
                    wrapper.AddField(varCodeName, field);
                }
            }
            //generar la inicializacion de la variable
            code.OnBeginMethod += (theCode, e) => code_OnBeginMethod_var(expr, theCode, e);

            return(Unit.Create());
        }
        public MethodBuilder GenerateInstanceMethodWithClassWrapper(ILCode code)
        {
            MethodBuilder mBuilder = GetMethod(code);

            //este es el nombre de la clase que contiene a este funcion
            string parentWrapper = string.Format("Tg_{0}", FunctionParentCodeName());
            //obtengo el tipo de la clase que contiene a esta funcion
            var container = (TypeBuilder)code.DefinedType[parentWrapper];

            //generar la clase wrapper a mis variables
            string      currentWrapper = string.Format("Tg_{0}", FunctionCodeName());
            TypeBuilder typeNested     = container.DefineNestedType(currentWrapper,
                                                                    TypeAttributes.NestedPublic);

            //annadir a la clase code el tipo.
            code.DefinedType.Add(typeNested.Name, typeNested);
            //asociar el wrapper con la funcion que lo creo
            code.AsociatteMethodToWrapper(mBuilder.Name, currentWrapper);

            //tengo que asociar este tipo con su padre.
            TypeCodeInfo typeCodeInfo = code.GetWrapperAsociatteTo(FunctionCodeName());

            typeCodeInfo.Parent = code.GetWrapperAsociatteTo(FunctionParentCodeName());

            //annadir esta funcion al padre.
            //Tener en cuenta cuando se llame la funcion antes de ser declarada
            if (!typeCodeInfo.Parent.ContainMethodInLevel1(mBuilder.Name))
            {
                typeCodeInfo.Parent.AddMethod(mBuilder.Name, mBuilder);
            }

            PopulateNestedTypeWithVar(code, typeNested, typeCodeInfo, container);

            //crear la instancia de esta clase dentro de mi codigo.
            ILGenerator il = mBuilder.GetILGenerator();

            il.DeclareLocal(typeNested);
            //No annado la variable local al ILCode porque siempre sera la primera de todas.

            return(mBuilder);
        }
Exemplo n.º 11
0
        private MethodBuilder GetMethod(string funCodeName, ILCode code)
        {
            //si esta definida la uso
            if (code.DefinedMethod.ContainsKey(funCodeName))
            {
                return(code.DefinedMethod[funCodeName]);
            }

            //sino no  esta definida creo su signatura.
            //este es el nombre de la clase que contiene a este funcion
            string parentWrapper = string.Format("Tg_{0}", FunctionParentCodeName());
            //obtengo el tipo de la clase
            var container = (TypeBuilder)code.DefinedType[parentWrapper];

            Type returnType;

            Type[] parameterTypes;
            //creo los paremtros de la funcion
            bool isFunction = !string.IsNullOrEmpty(ReturnTypeId());

            //creando los parametros y el tipo de retorno
            CreateParams(code, isFunction, out returnType, out parameterTypes);

            //creo la funcion como un metodo de instancia.
            MethodBuilder mBuilder = container.DefineMethod(FunctionCodeName(), MethodAttributes.Public, returnType,
                                                            parameterTypes);

            //adiciono la nueva funcion que he declarado
            code.DefinedMethod.Add(mBuilder.Name, mBuilder);

            //Tener en cuenta cuando se llame la funcion antes de ser declarada ,hay que annadir el metodo a su padre
            string       currentFunctionParent = _functionInvocation.CurrentScope.CurrentFunction.FunctionParent.CodeName;
            TypeCodeInfo typeCodeInfo          = code.GetWrapperAsociatteTo(currentFunctionParent);

            typeCodeInfo.AddMethod(mBuilder.Name, mBuilder);
            //typcodeindo

            return(mBuilder);
        }
Exemplo n.º 12
0
        /// <summary>
        /// 自动转换映射
        /// </summary>
        /// <param name="log"></param>
        /// <returns></returns>
        private LxdmModel ConvertToModel(TypeCodeInfo user)
        {
            LxdmModel model = AutoMapper.Mapper.Map <TypeCodeInfo, LxdmModel>(user);

            return(model);
        }