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('! - > '))
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 :).