public void Visit(ProgramContext parserRule)
        {
            basicTypes = new BasicTypes(parserRule, globalContext);

            parserRule._classes.Insert(0, basicTypes.Int);
            parserRule._classes.Insert(0, basicTypes.Bool);
            parserRule._classes.Insert(0, basicTypes.String);
            parserRule._classes.Insert(0, basicTypes.IO);
            parserRule._classes.Insert(0, basicTypes.Void);
            parserRule._classes.Insert(0, basicTypes.Object);
            foreach (var _class in parserRule._classes)
            {
                if (globalContext.IfDefineType(_class.type.Text))
                {
                    errorLogger.LogError($"El programa ya contiene una definicion para { _class.type.Text}, linea {_class.type.Line} y la columna {_class.type.Column}");
                }
                else
                {
                    globalContext.CreateChildContext(_class.type.Text);
                    if (_class.inherits != null)
                    {
                        _class.father = parserRule._classes.FirstOrDefault(p => p.type.Text == _class.inherits.Text);
                    }
                    else if (_class.type.Text != "Object" && _class.type.Text != "void")
                    {
                        _class.father = basicTypes.Object;
                    }
                }
            }
            if (!globalContext.IfDefineType("Main"))
            {
                errorLogger.LogError("El programa no contiene la definicion para Main");
            }
        }
 public void Visit(ClassContext parserRule)
 {
     type = globalContext.GetType(parserRule.type.Text);
     if (parserRule.inherits != null)
     {
         if (!globalContext.IfDefineType(parserRule.inherits.Text))
         {
             errorLogger.LogError($"El tipo con nombre {parserRule.inherits.Text} no ha sido encontrado");
         }
         if (globalContext.Int.Name == parserRule.inherits.Text)
         {
             errorLogger.LogError($"El tipo {parserRule.type.Text} no puede heredar de Int");
         }
         if (globalContext.String.Name == parserRule.inherits.Text)
         {
             errorLogger.LogError($"El tipo {parserRule.type.Text} no puede heredar de String");
         }
         if (globalContext.Bool.Name == parserRule.inherits.Text)
         {
             errorLogger.LogError($"El tipo {parserRule.type.Text} no puede heredar de Bool");
         }
         var inherits = globalContext.GetType(parserRule.inherits.Text);
         type.Inherits = inherits;
         if (inherits.Conform(type))
         {
             errorLogger.LogError("No se permite la herencia cíclica");
         }
     }
     foreach (var item in parserRule._features)
     {
         Visit(item);
     }
     //Verifico si la clase Main tiene el metodo main y si este no tiene parametros
     if (parserRule.type.Text == "Main")
     {
         if (type.IsDefineMethod("main"))
         {
             var main = type.GetMethod("main");
             if (main.Formals.Length > 0)
             {
                 errorLogger.LogError("El metodo main no tiene parametros");
             }
         }
         else
         {
             errorLogger.LogError("El metodo main no esta definido en la clase Main");
         }
     }
 }
 public void Visit(DeclarationContext parserRule, IObjectContext <IVar, IVar> context)
 {
     if (!globalContext.IfDefineType(parserRule.typeText))
     {
         errorLogger.LogError($"({parserRule.type.Line},{parserRule.type.Column + 1}) - Type Error: The type {parserRule.typeText} could not be found in the program");
     }
     if (parserRule.expression != null)
     {
         var TypeDec = globalContext.GetType(parserRule.typeText, type);
         //O_C[SELF_TYPE_type/self] defino la variable self con tipo SELF_TYPE_type
         context.Define("self", new SelfType(type, globalContext));
         Visit(parserRule.expression, context);
         //Despues de visitar la expresion verifico si su tipo estatico hereda del tipo declarado
         if (!parserRule.expression.computedType.Conform(TypeDec))
         {
             errorLogger.LogError($"({parserRule.Start.Line},{parserRule.Start.Column + 1}) - Type Error: The static type of the expression { parserRule.expression.computedType.Name} not conform to the declared type of the let declaration {parserRule.typeText}");
         }
     }
     //Defino la declaracion aun si el tipo no esta definido y despues de haber entrado
     context.Define(parserRule.idText, globalContext.GetType(parserRule.typeText));
 }