-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmatacerebros
116 lines (100 loc) · 4.53 KB
/
matacerebros
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
import argparse
import pila
import errores
import sys
import time
ARREGLO_MAX = 30000
class Cinta(object):
"......."
def __init__(self,comandos,modo):
self.cinta = [0]*ARREGLO_MAX
self.cinta_posicion_actual = 0
self.comandos = comandos
self.comando_actual = 0
self.modo = modo
def avanzar(self):
if self.cinta_posicion_actual == ARREGLO_MAX:
self.cinta_posicion_actual = 0
return
self.cinta_posicion_actual+=1
def retroceder(self):
if self.cinta_posicion_actual == -ARREGLO_MAX:
self.cinta_posicion_actual = ARREGLO_MAX
return
self.cinta_posicion_actual-=1
def imprimir_actual(self):
sys.stdout.write(chr(self.cinta[self.cinta_posicion_actual]))
sys.stdout.flush()
time.sleep(0.01)
def incrementar(self):
if self.cinta[self.cinta_posicion_actual] == 256:
self.cinta[self.cinta_posicion_actual] = 0
return
self.cinta[self.cinta_posicion_actual]+=1
def decrementar(self):
if self.cinta[self.cinta_posicion_actual] == 0:
self.cinta[self.cinta_posicion_actual] = 256
return
self.cinta[self.cinta_posicion_actual]-=1
def interpretar(self):
dic_funciones = {"<":Cinta.retroceder,">":Cinta.avanzar,
".":Cinta.imprimir_actual,"-":Cinta.decrementar,
"+":Cinta.incrementar}
while self.comando_actual < len(self.comandos):
if isinstance(self.comandos[self.comando_actual],list):
if self.comandos[self.comando_actual][0] == "[" and self.cinta[self.cinta_posicion_actual] == 0:
self.comando_actual = self.comandos[self.comando_actual][1]+1
continue
elif self.comandos[self.comando_actual][0] == "]" and self.cinta[self.cinta_posicion_actual] != 0:
self.comando_actual = self.comandos[self.comando_actual][1]+1
continue
else:
self.comando_actual+=1
else:
dic_funciones[self.comandos[self.comando_actual]](self)
self.comando_actual+=1
def cargar_codigo(archivo):
""" Pre: El archivo debe existir y se tiene que poder leer
Post: Devuelve una lista con los comandos que reconoce
un interprete de matacerebros
"""
with open(archivo) as archivo_matacerebros:
comandos_matacerebro = "<>+-[]."
comandos_archivo = []
pila_saltos = pila.Pila()
pos_actual = 0
for linea in archivo_matacerebros:
for caracter in linea:
if caracter in comandos_matacerebro:
if caracter == "[":
pila_saltos.apilar([caracter,pos_actual])
comandos_archivo.append([caracter,pos_actual])
pos_actual+=1
continue
elif caracter == "]":
try:
if pila_saltos.ver_tope()[0] == "[":
posicion_anterior = pila_saltos.desapilar()[1]
comandos_archivo[posicion_anterior][1] = pos_actual
comandos_archivo.append([caracter,posicion_anterior])
pos_actual+=1
continue
except pila.PilaVaciaError:
raise errores.MCSyntaxError
comandos_archivo.append(caracter)
pos_actual+=1
if pila_saltos.esta_vacia():
return comandos_archivo
else: raise errores.MCSyntaxError
#Este codigo devuelve la lista de cada comando pero en cada corchete "[" o "]" guarda la posicion del corchete asociado
def main():
parser = argparse.ArgumentParser(description='Interprete de codigo MataCerebros')
parser.add_argument('archivo', metavar='archivo', help='archivo con codigo a interpretar')
parser.add_argument('-d', '--debug', action='store_true', help='modo debug')
args = parser.parse_args()
nombre_archivo = args.archivo #Esto es un string, que vendria a tener
modo_debug = args.debug #si en la linea de comandos le pasas aparte del nombre, "-d", esto guarda True
lista_comandos = cargar_codigo(nombre_archivo)
interprete = Cinta(lista_comandos,modo_debug)
interprete.interpretar()
main()