associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

InterpretadorHq9

  • HQ9+ é uma linguagem "esotérica" criada por Cliff L. Biffle. Ela tem esse nome por causa de seus quatro(e únicos) operadores(H, Q, 9 e +). A idéia é criar uma linguagem perfeita para iniciantes, que possa executar os exemplos/exercícios mais típicos para eles sem muito sofrimento. Mais sobre isso em http://www.cliff.biffle.org/esoterica/hq9plus.html.

Os quatro operadores

  • H - "Hello, world!" na stdout.
  • Q - mostra todo o código digitado desde o início do interpretador.
  • 9 - Letra de "99 garrafas de cerveja no muro".
  • + - incrementa em um o contador iniciado em 0 junto do interpretador.

Numa tarde, com excesso de tempo livre, eu tive uma idéia: eu ia escrever um interpretador. Essa é a primeira versão, estruturada:

   1 #! /usr/bin/env python
   2 
   3 """Interpretador HQ9+
   4 
   5 HQ9+ e uma linguagem de programacao "esoterica", criada por Cliff L. Biffle
   6 (http://www.cliff.biffle.org/esoterica/hq9plus.html)
   7 Essa e uma versao python do interpretador."""
   8 
   9 __author__ = "Carlos KNIGHTSTALKER M. dos Santos (knightslayer@gmail.com)"
  10 __coauthor__ = "Eduardo 'EdCrypt' de Oliveira Padoan (eduardo.padoan@gmail.com)"
  11 
  12 def main():
  13     counter = 0
  14     end = False
  15     
  16     def inccounter(): counter += 1 # nested scopes
  17     
  18     def finalize(): end = True
  19     
  20     while not end:
  21         comm = raw_input('! - >')
  22 
  23         runtime.append(comm)
  24         
  25         for c in comm:
  26             try:
  27                 {'H': H,
  28                  'Q': Q,
  29                  '9': nine,
  30                  '+': inccounter,
  31                  '!': finalize}[c.upper()]() # dictionary dispatch
  32             except KeyError:
  33                 print u'\tComando não reconhecido: "%s"' %(c)
  34             else:
  35                 if c == '+':
  36                     print counter
  37                 elif c == '!':
  38                     break
  39 
  40 def H():
  41     print "Hello, world!!" # eu me recuso a traduzir isso!!!
  42 
  43 
  44 def Q():
  45     print '\n'.join([elem for elem in runtime])
  46 
  47 
  48 def nine(n=99):
  49     '''Yeah, I always do the things in "the hardest way", so
  50        why can't I put it in verbose mode ?) '''
  51     
  52     def bottles(n):
  53         if n > 99:
  54             return '%s garrafas de cerveja' %(str(n))
  55         elif n > 19:
  56             if n%10 != 0:
  57                 return "%s e %s garrafas de cerveja" %(tenths[str(n)[0]], ones[str(n)[1]].lower())
  58             else:
  59                 return "%s garrafas de cerveja" %(tenths[str(n)[0]])
  60         elif n > 9:
  61             return "%s garrafas de cerveja" %(tenths['1'][int(str(n)[1])])
  62         elif n > 1:
  63             return "%s garrafas de cerveja" %(ones[str(n)])
  64         else:
  65             return "Uma garrafa de cerveja"
  66 
  67     for x in range(n):
  68         print "%s no muro, " %(bottles(n-x))
  69         print "%s no muro, " %(bottles(n-x))
  70         print "%s." %(bottles(n-x))
  71         print "Derrube uma, comece de novo, "
  72     print "Nao sobrou nenhuma garrafa de cerveja no muro..."
  73 
  74 
  75 if __name__ == "__main__":
  76     runtime = []
  77     tenths = {'1': ['Dez', 
  78                     'Onze', 
  79                     'Doze', 
  80                     'Treze', 
  81                     'Quatorze',
  82                     'Quinze', 
  83                     'Dezesseis', 
  84                     'Dezessete', 
  85                     'Dezoito',
  86                     'Dezenove'],
  87             '2': 'Vinte',
  88             '3': 'Trinta',
  89             '4': 'Quarenta',
  90             '5': 'Cinquenta',
  91             '6': 'Sessenta',
  92             '7': 'Setenta',
  93             '8': 'Oitenta',
  94             '9': 'Noventa'}
  95     
  96     ones={'1': 'Uma',
  97           '2': 'Duas',
  98           '3': 'Tres',
  99           '4': 'Quatro',
 100           '5': 'Cinco',
 101           '6': 'Seis',
 102           '7': 'Sete',
 103           '8': 'Oito',
 104           '9': 'Nove'}
 105 
 106     print "\tInterpretador HQ9+\nPython powered(http://www.python.org)" 
 107     main()

Um amigo, EduardoDeOliveiraPadoan, fez a modificação para por as rotinas numa hash.

Tempos depois, tive outra bela idéia: fazer isso orientado a objetos.

   1 #! /usr/bin/env python
   2 # -*- coding: iso-8859-1 -*-
   3 
   4 """
   5 Interpretador HQ9+
   6 
   7 HQ9+ e uma linguagem de programacao "esoterica", criada por Cliff L. Biffle
   8 (http://www.cliff.biffle.org/esoterica/hq9plus.html)
   9 Essa e uma versao orientada a objetos em python do interpretador.
  10 """
  11 
  12 __author__ = "Carlos KNIGHTSTALKER M. dos Santos ( knighslayer@gmail.com )"
  13 __licence__ = "GNU General Public Licence[http://www.opensource.org, http://www.gnu.org]"
  14 
  15 __coauthor__ = ("Eduardo de O. Padoan", "Added Hashes", "eduardo.padoan@gmail.com")
  16 
  17 import sys
  18 
  19 class HQ9Plus:
  20     '''A classe base do interpretador de comandos HQ9+'''
  21 
  22     def __init__(self):
  23         '''Isso inicia o interpretador de comandos'''
  24         self.counter = 0
  25         self.runtime = []
  26         self.tenths = {'1' : ['Dez',
  27                               'Onze',
  28                               'Doze',
  29                               'Treze',
  30                               'Quatorze',
  31                               'Quinze',
  32                               'Dezesseis',
  33                               'Dezessete',
  34                               'Dezoito',
  35                               'Dezenove'],
  36                        '2' : 'Vinte',
  37                        '3' : 'Trinta',
  38                        '4' : 'Quarenta',
  39                        '5' : 'Cinquenta',
  40                        '6' : 'Sessenta',
  41                        '7' : 'Setenta',
  42                        '8' : 'Oitenta',
  43                        '9' : 'Noventa'
  44                        }
  45         self.ones = {'1' : 'Uma',
  46                      '2' : 'Duas',
  47                      '3' : 'Tres',
  48                      '4' : 'Quatro',
  49                      '5' : 'Cinco',
  50                      '6' : 'Seis',
  51                      '7' : 'Sete',
  52                      '8' : 'Oito',
  53                      '9' : 'Nove'
  54                      }
  55                      
  56     def H(self):
  57         '''Mostra "Hello, world!" na stdout'''
  58         print "Hello, world!"  # eu me recuso a traduzir isso!!!1
  59 
  60     def Q(self):
  61         '''Faz as Quines(i.e.: mostra tudo que foi submetido
  62         ao interpretador'''
  63         print '\n'.join([elem for elem in self.runtime])
  64 
  65     def _bottles(self, n):
  66         '''Retorna o numero de garrafas.'''
  67         if n > 99:
  68             return '%s garrafas de cerveja' %(str(n))
  69         elif (n > 19) and (n < 100):
  70             if (n % 10) != 0:
  71                 return "%s e %s garrafas de cerveja" %(self.tenths[str(n)[0]], self.ones[str(n)[1]].lower())
  72             else:
  73                 return "%s garrafas de cerveja" %(self.tenths[str(n)[0]])
  74         elif (n > 9) and (n < 20):
  75             return "%s garrafas de cerveja" %(self.tenths['1'][int(str(n)[1])])
  76         elif (n > 1) and (n < 10):
  77             return "%s garrafas de cerveja" %(self.ones[str(n)])
  78         elif n == 1:
  79             return "Uma garrafa de cerveja"
  80 
  81     def nine(self, n=99):
  82         '''Mostra a letra de "99 garrafas de cerveja no muro".
  83         Por extenso, logico...'''
  84 
  85         for i in xrange(n):
  86             print ("%s no muro, " %(self._bottles(n - i))) * 2
  87             print "%s." %(self._bottles(n - i))
  88             print "Derrube uma, comece de novo, "
  89             
  90         print "Nao ha mais nenhuma garrafa de cerveja no muro..."
  91 
  92     def plus(self):
  93         '''Incrementa o contador e mostra seu valor na stdout.'''
  94         self.counter += 1
  95         print self.counter
  96 
  97     def run(self, com):
  98         '''Roda um comando
  99         'com' e uma string'''
 100         
 101         self.runtime.append(com)
 102 
 103         for c in com:
 104             if c == '!':
 105                 sys.exit(0)
 106             try:
 107                 {'H' : self.H,
 108                  'Q' : self.Q,
 109                  '9' : self.nine,
 110                  '+' : self.plus}[c.upper()]()
 111             except KeyError:
 112                 print '\tComando nao-reconhecido: %s' %(c)
 113                 
 114 
 115 
 116 if __name__ == "__main__":
 117 
 118     hq = HQ9Plus()
 119     terminate = 0
 120 
 121     print "\tInterpretador HQ9+\nPython powered(http://www.python.org)"
 122     
 123     while not terminate:
 124         hq.run(raw_input('! - > '))

CarlosMoraisDosSantos

P.S.1: Não, eu não bebo cerveja. Pelo menos não tantas.

P.S.2: Yeah, eu sei que o código tá tosco, sinta-se à vontade para alterá-lo. Inclua um atributo co-author no código também :).