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;
        }
Example #2
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());
        }
Example #3
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);
        }
Example #4
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
        }