Пример #1
0
class memory_manager():
    def __init__(self):
        """ Inicializa los scopes de las variables : Temporales, Globales,
		Locales y Constantes.
		"""
        self.tmp = Temporal()
        self.glob = Globs()
        self.loc = Local()
        self.const = Constant()
        self.max_memory = 20000
        self.current_used_memory = 0

    def increment_address_pointer(self, var_type, var_dir, offset):
        """ Almacenar y manejar direcciones de arreglos.
		Args:
			var_dir: Diccionario del tipo de dato.
			var_type: Tipo de dato de la variable.
			offset: Tamanio del arreglo.
			"""
        # Checar la direccion y si cabe dentro de los limites de la memoria entonces
        # incrementar el contador de ese scope en la cantidad de casillas del arreglo.
        if var_dir >= self.tmp.l_limit and var_dir <= self.tmp.u_limit:
            self.tmp.increment_address_pointer(var_dir, var_type, offset)
        elif var_dir >= self.glob.l_limit and var_dir <= self.glob.u_limit:
            self.glob.increment_address_pointer(var_dir, var_type, offset)
        elif var_dir >= self.loc.l_limit and var_dir <= self.loc.u_limit:
            self.loc.increment_address_pointer(var_dir, var_type, offset)
        elif var_dir >= self.const.l_limit and var_dir <= self.const.u_limit:
            self.const.increment_address_pointer(var_dir, var_type, offset)

    def set_val(self, var_dir, val, var_type):
        """ Asignar valor a las direcciones de cada scope.
		Args:
		    var_dir: Direccion de la variable.
			val: Valor de la variable.
			var_type: Tipo de dato de la variable.
			"""
        # Checar la direccion y dependiendo del mismo asignarle el valor a la
        # direccion de la variable.
        if var_dir >= self.tmp.l_limit and var_dir <= self.tmp.u_limit:
            self.tmp.set_val(var_dir, val, var_type)
        elif var_dir >= self.glob.l_limit and var_dir <= self.glob.u_limit:
            self.glob.set_val(var_dir, val, var_type)
        elif var_dir >= self.loc.l_limit and var_dir <= self.loc.u_limit:
            self.loc.set_val(var_dir, val, var_type)
        elif var_dir >= self.const.l_limit and var_dir <= self.const.u_limit:
            self.const.set_val(var_dir, val, var_type)

    def free_memory(self, no_vars):
        """ Libera la memoria que ha sido utilizada por una llamada a funcion.
		Args:
			no_vars: Cantidad de variables de una funcion. """
        self.current_used_memory -= no_vars

    def check_available_memory(self, no_vars):
        """ Pide la memoria que sera utilizada por una llamada a funcion.
		Args:
			no_vars: Cantidad de variables de una funcion. """
        if self.current_used_memory + no_vars <= self.max_memory:
            self.current_used_memory += no_vars
        else:
            # muestra un error en caso de que ya no haya mas memoria.
            raise MemoryError("ERROR: ya no hay espacio en memoria.")

    def get_val_from_dir(self, address):
        """ Obtener el valor de una direccion.
		Args:
		    address: Direccion de la cual se quiere obtener el valor.
		Return:
		    Valor de la direccion	
			"""
        # Checar si la direccion esta dentro de los limites para ver el scope
        # de dato que es para posteriormente obtener la direccion.

        # Usar en arreglos (numero)
        if str(address)[len(str(address)) - 1] == '_':
            return int(address[:len(str(address)) - 1])
        # Apuntador a una direccion
        if str(address)[0] == '_':
            meta_address = self.get_val_from_dir(int(address[1:]))
            return self.get_val_from_dir(meta_address)
        if address >= self.tmp.l_limit and address <= self.tmp.u_limit:
            return self.tmp.get_val_from_dir(address)
        elif address >= self.glob.l_limit and address <= self.glob.u_limit:
            return self.glob.get_val_from_dir(address)
        elif address >= self.loc.l_limit and address <= self.loc.u_limit:
            return self.loc.get_val_from_dir(address)
        elif address >= self.const.l_limit and address <= self.const.u_limit:
            return self.const.get_val_from_dir(address)

    def set_val_from_dir(self, address, val):
        """ Asignar el valor a una direccion. Si no se encuentra la 
		direccion entonces mostrar un error.
		Args:
		    address: Direccion de la cual se quiere asignar el valor.
			val: Valor a asignar.
			"""
        # Checar si la direccion esta dentro de los limites para ver el scope
        # del dato que es para posteriormente asignarle un valor a la direccion.

        # Apuntador a una direccion
        if str(address)[0] == '_':
            address = self.get_val_from_dir(int(address[1:]))
        if address >= self.tmp.l_limit and address <= self.tmp.u_limit:
            self.tmp.set_val_from_dir(address, val)
        elif address >= self.glob.l_limit and address <= self.glob.u_limit:
            self.glob.set_val_from_dir(address, val)
        elif address >= self.loc.l_limit and address <= self.loc.u_limit:
            self.loc.set_val_from_dir(address, val)
        elif address >= self.const.l_limit and address <= self.const.u_limit:
            self.const.set_val_from_dir(address, val)

    def insert_variable(self, var_type, var_id, var_scope, var_val):
        """ Funcion exclusiva para agregar variables locales/globales
		Args:
			var_type: El tipo de la variable.
			var_id: Id de la variable.
			var_scope: Scope de la variable.
			var_val: Valor de la variable.
		"""
        global debug
        segment = self.check_variable_functionality(var_scope, var_id)
        if debug:
            print("llego la variable", var_id, "de tipo", var_type,
                  "para el segmento de", segment)
        if var_type == "entero":
            return segment.insert_integer(var_val)
        elif var_type == "flotante":
            return segment.insert_float(var_val, var_id)
        elif var_type == "bool":
            return segment.insert_boolean(var_val)
        elif var_type == "caracter":
            return segment.insert_character(var_val)
        elif var_type == "cadena":
            return segment.insert_string(var_val)

    def check_variable_functionality(self, var_scope, var_id):
        """" Revisa si la variable es temporal, global o local
		Args:
			var_scope: Scope de la variable.
			var_id: id de la variable
		Regreso:
			El objeto correspondiente a la funcionalidad de la variable."""
        if var_id == "const":
            return self.const
        elif var_id[0:2] == "t_":
            return self.tmp
        elif var_scope == "global":
            return self.glob
        else:
            return self.loc

    """