public IHolderCil Visit(CaseExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil)
        {
            var value = new LocalCil($"_value{cilTree.LocalCils.Count}");

            cilTree.LocalCils.Add(value);
            var expr0 = Visit(parserRule.expresion, cilTree, contextCil);
            //is void
            var TypeValue   = new LocalCil($"_TypeValue{cilTree.LocalCils.Count}");
            var not_is_void = new LocalCil($"not_is_void{cilTree.LocalCils.Count}");

            cilTree.LocalCils.Add(TypeValue);
            cilTree.LocalCils.Add(not_is_void);
            cilTree.ThreeDirInses.Add(new TypeOf(TypeValue, expr0));
            cilTree.ThreeDirInses.Add(new NotEqualCil(not_is_void, TypeValue, CilAst.GetTypeCilByName("void")));

            //lanzamos el error

            Visit_Runtime_Error_whit_Cond(not_is_void, cilTree, $"\"({parserRule.Start.Line},{parserRule.Start.Column + 1}) -  Rutime Error: A case on void\"");

            //ejecucion del case
            var closestAncestor = new LocalCil($"_closestAncestor{cilTree.LocalCils.Count}");

            cilTree.LocalCils.Add(closestAncestor);

            //Inicializo el valor de numberType en 0 y closestAncestor con object
            var isNotConform = new LocalCil($"_isNotConform{cilTree.LocalCils.Count}");

            cilTree.LocalCils.Add(isNotConform);

            var branches = parserRule._branches.Concat(new List <BranchContext>()
            {
                parserRule.firstBranch
            }).OrderBy(t => - (CilAst.GetTypeCilByName(t.typeText).IndexOfPrecedence)).ToArray();
            //El tipo de la primera rama
            var End = cilTree.CreateLabel("End_");

            for (int i = 0; i < branches.Length; i++)
            {
                var branch    = branches[i];
                var nextLabel = cilTree.CreateLabel("Case_");
                //tipo de la rama
                var typeBranch = CilAst.GetTypeCilByName(branch.typeText, typeCil);
                cilTree.ThreeDirInses.Add(new IsNotConformCil(isNotConform, TypeValue, typeBranch));
                cilTree.ThreeDirInses.Add(new IfGoto(isNotConform, nextLabel));
                var valueBranch = new LocalCil(branch.idText);//preguntarle as zahuis
                cilTree.LocalCils.Add(valueBranch);
                cilTree.ThreeDirInses.Add(new AssigCil(valueBranch, expr0));
                var newContextCil = contextCil.CreateAChild();
                newContextCil.Define(branch.idText);
                var valueExpr = Visit(branch.expression, cilTree, newContextCil);
                cilTree.ThreeDirInses.Add(new AssigCil(value, valueExpr));
                cilTree.ThreeDirInses.Add(new GotoCil(End));
                cilTree.ThreeDirInses.Add(new Label(nextLabel));
            }
            Visit_Runtime_Error(cilTree, $"\"linea {parserRule.Start.Line} y columna {parserRule.Start.Column + 1} Execution of a case statement without a matching branch\"");
            cilTree.ThreeDirInses.Add(new Label(End));


            return(value);
        }
        public virtual IFunctionCil Visit(MethodContext parserRule)
        {
            IFunctionCil function;
            var          contextCil = new ContextCil();

            //El unico metodo que no pertenece a una clase es entry
            if (parserRule.Parent == null)
            {
                function = CilAst.GetFunctionCilsByName($"{parserRule.idText}");
            }
            else
            {
                // El nombre metodo en el tipo tiene siempre esta estructura (Type_CoolName)
                function = CilAst.GetFunctionCilsByName($"{(parserRule.Parent as ClassContext).type.Text}_{parserRule.idText}");
                // Como toda fucion pertenece a una clase se le agrega self como una parametro
                var self = new ArgCil("self");
                function.ArgCils.Add(self);
                contextCil.Define("self");
                foreach (var formal in parserRule._formals)
                {
                    Visit(formal, function, contextCil);
                }
            }
            var result = Visit(parserRule.exprBody, function, contextCil);

            function.ThreeDirInses.Add(new ReturnCil(result));
            return(function);
        }
 public virtual void Visit(ProgramContext parserRule)
 {
     Visit(basicTypes.entry);
     foreach (var _class in parserRule._classes)
     {
         typeCil = CilAst.GetTypeCilByName(_class.type.Text);
         typeC   = GlobalContext.GetType(_class.type.Text);
         Visit(_class);
     }
 }
        public IHolderCil Visit(IsvoidExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil)
        {
            var value = new LocalCil($"_value{cilTree.LocalCils.Count}");

            cilTree.LocalCils.Add(value);
            var valueExpr = Visit(parserRule.expresion, cilTree, contextCil);
            var TypeValue = new LocalCil($"_TypeValue{cilTree.LocalCils.Count}");

            cilTree.LocalCils.Add(TypeValue);
            cilTree.ThreeDirInses.Add(new TypeOf(TypeValue, valueExpr));
            cilTree.ThreeDirInses.Add(new EqualCil(value, TypeValue, CilAst.GetTypeCilByName("void")));
            return(CreateABasicTypeWhitVal(cilTree, CilAst.Bool, value));
        }
Beispiel #5
0
 public void Visit(MethodContext parserRule, ITypeCil cilTree)
 {
     if (cilTree == null)
     {
         CilAst.CreateFunctionCil(null, parserRule.idText);
     }
     else
     {
         //Creo la funcion e cil y la se anade al CilAst
         var function = CilAst.CreateFunctionCil(type.type.Text, parserRule.idText);
         //Le hago referencia al tipo correspondiente
         //La al anadirla ya hay una funcion definida con el mismo nombre se le cambia el nombre de la funcionCil por el nuevo
         cilTree.AddFunc(new FunctionTypeCil(type.type.Text, parserRule.idText, function));
     }
 }
        public IHolderCil Visit(NewTypeExprContext parserRule, IFunctionCil cilTree, IContextCil contextCil)
        {
            var value = new LocalCil($"_value{cilTree.LocalCils.Count}");

            cilTree.LocalCils.Add(value);
            if (parserRule.type.Text == "SELF_TYPE")
            {
                var varType = new LocalCil($"_Type{cilTree.ThreeDirInses.Count}");
                cilTree.LocalCils.Add(varType);
                cilTree.ThreeDirInses.Add(new TypeOf(varType, new ValuelCil("self")));
                cilTree.ThreeDirInses.Add(new VCallCil(value, varType, new ValuelCil("Init")));
            }
            else
            {
                var varType = CilAst.GetTypeCilByName(parserRule.type.Text, typeCil);
                cilTree.ThreeDirInses.Add(new CallCil(value, varType.Init.Function));
            }
            return(value);
        }
Beispiel #7
0
 public void Visit(ProgramContext parserRule)
 {
     Visit(basicTypes.entry, null);
     foreach (var _class in parserRule._classes)
     {
         var typeCil = new TypeCil(_class.type.Text, CilAst);
         typeCil.inherit = CilAst.GetTypeCilByName(_class.father?.type.Text);
         if (typeCil.inherit != null)
         {
             typeCil.IndexOfPrecedence = 1 + typeCil.inherit.IndexOfPrecedence;
         }
         CilAst.TypeCils.Add(typeCil);
     }
     foreach (var _class in parserRule._classes)
     {
         var typeCil = CilAst.GetTypeCilByName(_class.type.Text);
         Visit(_class, typeCil);
     }
 }
        public IHolderCil Visit(IFunctionCil cilTree)
        {
            switch (cilTree.Name)
            {
            case "String_lenght":
                var value = new LocalCil("value");
                cilTree.LocalCils.Add(value);
                cilTree.ThreeDirInses.Add(new LenghtCil(value, GetValue(cilTree.self, cilTree, CilAst.GetTypeCilByName("String"))));
                return(CreateABasicTypeWhitVal(cilTree, CilAst.GetTypeCilByName("Int"), value));

            case "String_concat":
                value = new LocalCil("value");
                cilTree.LocalCils.Add(value);
                cilTree.ThreeDirInses.Add(new ConcatCil(value, GetValue(cilTree.self, cilTree, CilAst.GetTypeCilByName("String")), GetValue(cilTree.ArgCils.SingleOrDefault(t => t.Name != "self"), cilTree, CilAst.GetTypeCilByName("String"))));
                return(CreateABasicTypeWhitVal(cilTree, CilAst.GetTypeCilByName("String"), value));

            case "String_substr":
                value = new LocalCil("value");
                cilTree.LocalCils.Add(value);
                var self = GetValue(cilTree.self, cilTree, CilAst.GetTypeCilByName("String"));
                //tomamos los valores de los argumentos
                var param1 = GetValue(cilTree.ArgCils.ElementAt(1), cilTree, CilAst.Int);
                var param2 = GetValue(cilTree.ArgCils.ElementAt(2), cilTree, CilAst.Int);
                cilTree.ThreeDirInses.Add(new SubStringCil(value, self, param1, param2));
                return(CreateABasicTypeWhitVal(cilTree, CilAst.String, value));

            case "Object_abort":
                cilTree.ThreeDirInses.Add(new Halt());
                return(null);

            case "Object_type_name":
                var x_type_name = new LocalCil("x");
                cilTree.LocalCils.Add(x_type_name);
                cilTree.ThreeDirInses.Add(new Type_Name(x_type_name, cilTree.self));
                return(CreateABasicTypeWhitVal(cilTree, CilAst.GetTypeCilByName("String"), x_type_name));

            case "Object_copy":
                var x_Object_copy = new LocalCil("x");
                cilTree.LocalCils.Add(x_Object_copy);
                cilTree.ThreeDirInses.Add(new Copy(x_Object_copy, cilTree.self));
                return(x_Object_copy);

            case "IO_out_string":
                cilTree.ThreeDirInses.Add(new Out_strCil(GetValue(cilTree.ArgCils.SingleOrDefault(t => t.Name != "self"), cilTree, CilAst.GetTypeCilByName("String"))));
                return(cilTree.self);

            case "IO_out_int":
                cilTree.ThreeDirInses.Add(new Out_intCil(GetValue(cilTree.ArgCils.SingleOrDefault(t => t.Name != "self"), cilTree, CilAst.GetTypeCilByName("Int"))));
                return(cilTree.self);

            case "IO_in_string":
                var x_in_string = new LocalCil("x");
                cilTree.LocalCils.Add(x_in_string);
                cilTree.ThreeDirInses.Add(new In_strCil(x_in_string));
                return(CreateABasicTypeWhitVal(cilTree, CilAst.GetTypeCilByName("String"), x_in_string));

            case "IO_in_int":
                var x_in_int = new LocalCil("x");
                cilTree.LocalCils.Add(x_in_int);
                cilTree.ThreeDirInses.Add(new In_intCil(x_in_int));
                return(CreateABasicTypeWhitVal(cilTree, CilAst.GetTypeCilByName("Int"), x_in_int));

            default:
                return(null);
            }
        }
        public void Visit()
        {
            IFunctionCil init  = typeCil.Init.Function;
            var          value = new LocalCil("self");

            init.LocalCils.Add(value);
            var typeCilNew = CilAst.GetTypeCilByName(typeCil.Name, typeCil);

            init.ThreeDirInses.Add(new Allocate(value, typeCilNew));
            var typeCool   = GlobalContext.GetType(typeCil.Name);
            var contextCil = new ContextCil();

            contextCil.Define("self");
            foreach (var typeTemp in typeCool.Hierachty)
            {
                foreach (var attributeTemp in typeTemp.Attributes)
                {
                    //Inicializamos los atributos
                    if (attributeTemp.initializacion != null)
                    {
                        var valueAttribute = Visit(attributeTemp.initializacion, init, contextCil);
                        //No siempre los tipos de Cil estan para eso eso habria que hacer 2 pasadas al AST
                        init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), valueAttribute));
                    }
                    else
                    {
                        if (typeTemp == GlobalContext.Int || typeTemp == GlobalContext.Bool)
                        {
                            init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), new ValuelCil("0")));
                        }
                        else if (typeTemp == GlobalContext.String)
                        {
                            var valueS = new LocalCil($"_value{init.LocalCils.Count}");
                            init.LocalCils.Add(valueS);

                            var stringCool    = "";
                            var varDataString = new VarCil($"s{CilAst.dataStringCils.Count}");
                            CilAst.dataStringCils.Add(new DataStringCil(varDataString, new StringCil(stringCool)));
                            init.ThreeDirInses.Add(new LoadCil(valueS, varDataString));
                            init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), valueS));
                        }
                        else if (attributeTemp.Type == GlobalContext.String)
                        {
                            init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), CreateABasicType(init, CilAst.String)));
                        }
                        else if (attributeTemp.Type == GlobalContext.Int)
                        {
                            init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), CreateABasicType(init, CilAst.Int)));
                        }
                        else if (attributeTemp.Type == GlobalContext.Bool)
                        {
                            init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), CreateABasicType(init, CilAst.Bool)));
                        }
                        else
                        {
                            init.ThreeDirInses.Add(new SetAttrCil(value, typeCilNew.GetAttributeCilsByCoolName(attributeTemp.ID), Visit_void(init)));
                        }
                    }
                }
            }
            init.ThreeDirInses.Add(new ReturnCil(value));
        }
        public virtual IHolderCil Visit(DispatchContext parserRule, IFunctionCil cilTree, IContextCil contextCil)
        {
            var Params = new List <IHolderCil>();
            var expr0  = Visit(parserRule.expresion, cilTree, contextCil);

            foreach (var expr in parserRule._expresions)
            {
                //genera el codigo de cada parametro que le paso a los metodos
                var param = Visit(expr, cilTree, contextCil);
                Params.Add(param);
            }
            //Averiguo el tipo dinamico de self es decir( el de la clase que esta usando la funcion en ese momento)
            var varType = new LocalCil($"_Type{cilTree.ThreeDirInses.Count}");

            cilTree.LocalCils.Add(varType);
            cilTree.ThreeDirInses.Add(new TypeOf(varType, expr0));
            //Verifico si el tipo del objeto que le voy hacer el dispatch es void
            if (parserRule.id.Text == "substr")
            {
                VisitString(parserRule, cilTree, new List <IHolderCil>()
                {
                    expr0
                }.Concat(Params).ToList());
            }
            if (cilTree.Name != "entry")
            {
                var isVoid = new LocalCil($"_isVoid{cilTree.ThreeDirInses.Count}");
                cilTree.LocalCils.Add(isVoid);
                cilTree.ThreeDirInses.Add(new NotEqualCil(isVoid, varType, CilAst.GetTypeCilByName("void")));
                Visit_Runtime_Error_whit_Cond(isVoid, cilTree, $"\"({parserRule.id.Line},{parserRule.id.Column+1}) -  Rutime Error: A dispatch on void\"");
                cilTree.ThreeDirInses.Add(new ArgExprCil(expr0));
            }
            //cada parametro los anado al metodo puede que tenga sentido pasarlos al revez


            foreach (var param in Params)
            {
                cilTree.ThreeDirInses.Add(new ArgExprCil(param));
            }
            ////nueva variable donde se almacena el valor que retorna el metodo
            var value = new LocalCil($"_value{cilTree.LocalCils.Count}");

            cilTree.LocalCils.Add(value);

            if (parserRule.type == null)
            {
                //Se resuleve el tipo de la expr0 a partir de su tipo estatico calculado por el checkeo semantico
                var typeExpr0 = CilAst.GetTypeCilByName(parserRule.expresion.computedType.Name, typeCil);
                ////resuelve el metodo en cil de ese tipo estatico
                var functionCil = typeExpr0.GetFunctionCilsByCoolName(parserRule.id.Text);
                //como ningun tipo puede redefinir a string entonces llamo directamente al metodo
                if (parserRule.expresion.computedType == GlobalContext.String)
                {
                    cilTree.ThreeDirInses.Add(new CallCil(value, functionCil.Function));
                }
                else
                {
                    cilTree.ThreeDirInses.Add(new VCallCil(value, varType, functionCil));
                }
            }
            else
            {
                //Se resuelve el tipo de la type
                var typeT       = CilAst.GetTypeCilByName(parserRule.type.Text, typeCil);
                var functionCil = typeT.GetFunctionCilsByCoolName(parserRule.id.Text).Function;
                cilTree.ThreeDirInses.Add(new CallCil(value, functionCil));
            }
            return(value);
        }
Beispiel #11
0
 public GenerateToCilTypes(CheckSemanticVisitor visitor)
 {
     basicTypes    = visitor.basicTypes;
     GlobalContext = visitor.globalContext;
     CilAst        = new CilAst();
 }