-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinterpretador.py
116 lines (106 loc) · 3.8 KB
/
interpretador.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import sys
def main():
codigo = ler_arquivo(sys.argv[1])
codigo = otimizar_codigo(codigo)
buffer = ConsoleBuffer()
interpretar(codigo, buffer)
def ler_arquivo(arquivo):
arquivo_lido = open(arquivo, 'r')
conteudo = arquivo_lido.read()
arquivo_lido.close()
return conteudo
def otimizar_codigo(codigo):
colchete_aberto = 0
colchete_fechado = 0
controle_colchete = []
resultado_codigo = []
for letra in codigo:
if verificar_caractere_invalido(letra):
continue
if letra == '[':
colchete_aberto = colchete_aberto + 1
controle_colchete.append(letra)
elif letra == ']':
colchete_fechado = colchete_fechado + 1
try:
if controle_colchete[-1] == '[':
controle_colchete.append(letra)
else:
return "Colchete fechado a mais."
except:
return "Colchete fechado a mais."
resultado_codigo.append(letra)
if colchete_aberto != colchete_fechado:
if colchete_aberto > colchete_fechado:
return "Colchete aberto a mais."
else:
return "Colchete fechado a mais."
return resultado_codigo
def verificar_caractere_invalido(caractere):
return caractere != '>' and caractere != '<' and caractere != '+' and caractere != '-' and caractere != ',' and caractere != '.' and caractere != '[' and caractere != ']' and caractere != ';'
def criar_memoria():
memoria = []
for i in range(0,30000):
memoria.append(0)
return memoria
def interpretar(codigo, buffer):
memoria = criar_memoria()
ponteiro = 0
controle_loop = []
indice_caractere = 0
while indice_caractere < len(codigo):
caractere = codigo[indice_caractere]
if caractere == '>':
ponteiro = (ponteiro + 1) % 30000
elif caractere == '<':
ponteiro = (ponteiro - 1) % 30000
elif caractere == '+':
memoria[ponteiro] = (memoria[ponteiro] + 1) % 256
elif caractere == '-':
memoria[ponteiro] = (memoria[ponteiro] - 1) % 256
elif caractere == '.':
buffer.write(chr(memoria[ponteiro]))
buffer.flush()
elif caractere == ';':
print(memoria[ponteiro])
elif caractere == '[':
if memoria[ponteiro] != 0:
controle_loop.append(indice_caractere)
elif memoria[ponteiro] == 0:
contador_loop = 1
while contador_loop != 0:
indice_caractere += 1
if codigo[indice_caractere] == '[':
contador_loop += 1
elif codigo[indice_caractere] == ']':
contador_loop -= 1
elif caractere == ']':
x = controle_loop.pop()
indice_caractere = x
elif caractere == ',':
proxima_tecla = buffer.read(1)
if len(proxima_tecla) == 0:
memoria[ponteiro] = 0
else:
memoria[ponteiro] = ord(proxima_tecla)
if caractere != ']':
indice_caractere = indice_caractere + 1
def server(codigo, buffer):
codigo_otimizado = otimizar_codigo(codigo)
if codigo_otimizado == "Colchete aberto a mais." or codigo_otimizado == "Colchete fechado a mais.":
buffer.buffer = codigo_otimizado
return
interpretar(codigo_otimizado, buffer)
return
class ConsoleBuffer:
# escreve no buffer do terminal
def write(self, text):
sys.stdout.write(text)
# renderiza o que esta escrito no buffer e esvazia
def flush(self):
sys.stdout.flush()
# lendo a proxima tecla e retornando ela
def read(self, size):
return sys.stdin.read(size)
if __name__ == '__main__':
main()