def visitDefinirShortVar(self, shortVar):
     #print('visitShortVarDecl')
     variaveis = shortVar.IdentifierList.accept(self)
     tipos = shortVar.ExpressionList.accept(self)
     if (type(variaveis) is list and type(tipos) is list):
         if (len(variaveis) == len(tipos)):
             for k in range(len(variaveis)):
                 if (variaveis[k] in lex.reserved):
                     shortVar.accept(self.printer)
                     print('\n\t[Erro]: Declaracao invalida')
                 else:
                     for k in range(len(variaveis)):
                         if (tipos[k] in st.TiposPrimitivos):
                             st.addVar(variaveis[k], tipos[k])
                         else:
                             shortVar.accept(self.printer)
                             print('\n\t[Erro]: Declaracao invalida')
         else:
             shortVar.accept(self.printer)
             print('\n\t[Erro]: Declaracao invalida')
     elif (type(variaveis) is list):
         shortVar.accept(self.printer)
         print('\n\t[Erro]: Declaracao invalida')
     elif (variaveis in lex.reserved):
         shortVar.accept(self.printer)
         print('\n\t[Erro]: Declaracao invalida')
     elif (tipos in st.TiposPrimitivos):
         st.addVar(variaveis, tipos)
     else:
         shortVar.accept(self.printer)
         print('\n\t[Erro]: Declaracao invalida')
    def visitClassicVarSpec(self, classicVarSpec):
        #print('visitClassicVarSpec')
        variaveis = classicVarSpec.IdentifierList.accept(self)
        tipo = classicVarSpec.Type

        tipo = st.getNewType(tipo)
        if (tipo == None):
            classicVarSpec.accept(self.printer)
            print('\n\t[ERRO] Tipo indefinido')

        for k in range(len(variaveis)):
            if (st.getBindable(variaveis[k]) == None):
                st.addVar(variaveis[k], tipo)
            else:
                classicVarSpec.accept(self.printer)
                print('\n\t[Erro]:', variaveis[k], 'redefinida neste bloco')

        expressao = classicVarSpec.ExpressionList.accept(self)

        if (type(expressao) != type([])):
            if (expressao != tipo):
                classicVarSpec.accept(self.printer)
                print(
                    '\n\t[Erro]: Atribuicao nao compativel com o tipo declarado'
                )
        else:
            for i in range(len(expressao)):
                if (expressao[i] != tipo):
                    classicVarSpec.accept(self.printer)
                    print(
                        '\n\t[Erro]: Atribuicao nao compativel com o tipo declarado'
                    )
                    break
    def visitSimpleVarSpec(self, simpleVarSpec):
        #print('visitSimpleVarSpec')
        variavel = simpleVarSpec.IdentifierList.accept(self)
        tipo = simpleVarSpec.ExpressionList.accept(self)

        if (type(tipo) is not list):
            tipo = [tipo]
        if (len(variavel) != len(tipo)):
            simpleVarSpec.accept(self.printer)
            print('\n\t[Erro]:', len(variavel), 'variaveis mas', len(tipo),
                  'valores')
        else:
            for x in range(len(variavel)):
                if (st.getBindable(variavel[x]) == None):
                    if (tipo[x] not in st.TiposPrimitivos):
                        tipoAux = st.getBindable(tipo[x])
                        if (tipoAux == None):
                            simpleVarSpec.accept(self.printer)
                            print('\n\t[ERRO]: Atribuicao nao compativel')
                        else:
                            st.addVar(variavel[x], tipoAux[st.TYPE])
                    else:
                        st.addVar(variavel[x], tipo[x])
                else:
                    simpleVarSpec.accept(self.printer)
                    print('\n\t[Erro]:', variavel[x], 'redefinida neste bloco')
    def visitListTypeExp(self, listTypeExp):
        #print('visitListTypeExp')
        variaveis = listTypeExp.IdentifierList.accept(self)
        tipo = st.getNewType(listTypeExp.Type)

        for indice in range(len(variaveis)):
            if (st.getBindable(variaveis[indice]) == None):
                st.addVar(variaveis[indice], tipo)
            else:
                listTypeExp.accept(self.printer)
                print('\n\t[ERRO]:', variaveis[indice],
                      'redefinida neste bloco')

        expressao = listTypeExp.ExpressionList.accept(self)

        if (type(expressao) is not list):
            if (expressao in st.TiposPrimitivos and expressao != tipo):
                listTypeExp.accept(self.printer)
                print(
                    '\n\t[ERRO]: Atribuicao nao compativel com o tipo declarado'
                )
            elif (expressao != tipo):
                expressao = st.getBindable(expressao)
                if (None == expressao or expressao[st.TYPE] != tipo):
                    listTypeExp.accept(self.printer)
                    print(
                        '\n\t[ERRO]: Atribuicao nao compativel com o tipo declarado'
                    )
        else:
            for ind in range(len(expressao)):
                if (expressao[ind] != tipo):
                    listTypeExp.accept(self.printer)
                    print('\n\t[ERRO]: Atribuicao nao compativel')
                    break
    def visitListIdExp(self, listIdExp):
        #print('visitListIdExp')
        idList = listIdExp.IdentifierList.accept(self)
        expList = listIdExp.ExpressionList.accept(self)

        if (type(expList) is not list):
            expList = [expList]

        if (len(idList) != len(expList)):
            listIdExp.accept(self.printer)
            print('[Erro]: ', len(idList), 'constantes mas', len(expList),
                  'valores')
        else:
            for i in range(len(idList)):
                if (st.getBindable(idList[i]) == None):
                    if (expList[i] not in st.TiposPrimitivos):
                        expAux = st.getBindable(expList[i])
                        if (expAux == None):
                            listIdExp.accept(self.printer)
                            print('\n\t[ERRO]: Atribuicao nao compativel')
                        else:
                            st.addVar(idList[i], expList[st.TYPE])
                            st.symbolTable[-1][idList[i]][st.CONST] = 'const'
                    else:
                        st.addVar(idList[i], expList[i])
                        st.symbolTable[-1][idList[i]][st.CONST] = 'const'
                else:
                    listIdExp.accept(self.printer)
                    print('\n\t[Erro]:', idList[i], 'redefinida neste bloco')
    def visitSpecVar(self, specVar):
        #print('visitSpecVar')
        variaveis = specVar.IdentifierList.accept(self)
        tipo = st.getNewType(specVar.Type)

        if (tipo == None):
            specVar.accept(self.printer)
            print('\n\t[ERRO] Tipo indefinido')

        for k in range(len(variaveis)):
            st.addVar(variaveis[k], tipo)
    def visitDefinirFuncBody(self, definirFuncBody):
        parametrosRetorno = definirFuncBody.Signature.accept(self)
        st.addFunction(definirFuncBody.ID, parametrosRetorno[0:-1],
                       parametrosRetorno[-1])
        st.beginScope(definirFuncBody.ID)
        if (parametrosRetorno[0] != None):
            for k in range(0, len(parametrosRetorno[0:-1]), 2):
                st.addVar(parametrosRetorno[0:-1][k],
                          parametrosRetorno[0:-1][k + 1])

        definirFuncBody.FunctionBody.accept(self)
    def visitRangeExpList(self, rangeExpList):
        #print('visitRangeExpList')
        left = rangeExpList.ExpressionList.accept(self)
        right = rangeExpList.Expression.accept(self)

        if (type(left) is list):
            if (left[0] in st.TiposPrimitivos and left[0] != st.INT):
                rangeExpList.accept(self.printer)
                print(
                    '\n\t [ERRO] O tipo da primeira variavel precisa ser inteiro.'
                )
            elif (left[0] != st.INT):
                st.addVar(left[0], st.INT)

            if (left[1] in st.TiposPrimitivos and left[1] != st.STRING):
                rangeExpList.accept(self.printer)
                print(
                    '\n\t [ERRO] O tipo da segunda variavel precisa ser string.'
                )
            elif (left[1] != st.STRING):
                st.addVar(left[1], st.STRING)

        elif (left in lex.reserved and left != st.STRING):
            rangeExpList.accept(self.printer)
            print('\n\t[ERRO] Variavel precisa ser do tipo string.')
        elif (left != st.STRING):
            st.addVar(left, st.STRING)

        if (right != st.STRING):
            rangeExpList.accept(self.printer)
            print('\n\t[ERRO] Declaracao range precisa ser do tipo string')