예제 #1
0
 def __init__(self,
              name: str = None,
              local_id: int = None,
              temp: 'Temp' = None,
              position: Position = Position(0, 0),
              unique_id: int = -1):
     IExp.__init__(self, position)
     if local_id is None and temp is None:
         self.id = Temp.counter
         Temp.counter += 1
         self.local_id = 0
         self.name = name
         self.info_enum = InfoEnum.NAME
         self.unique = unique_id != -1
         if self.unique:
             self.id = unique_id
             self.local_id = unique_id
     elif name is None and temp is None:
         self.id = Temp.counter
         Temp.counter += 1
         self.local_id = local_id
         self.name = ''
         self.info_enum = InfoEnum.ID
         self.unique = False
     elif name is None and local_id is None:
         self.id = temp.id
         self.local_id = temp.local_id
         self.name = temp.name
         self.info_enum = temp.info_enum
         self.position = temp.position
         self.unique = temp.unique
예제 #2
0
 def __init__(self,
              func_expr: IExp,
              args: ExpList,
              position: Position = Position(0, 0)):
     IExp.__init__(self, position)
     self.func_expr = func_expr
     self.args = args
예제 #3
0
 def __init__(self,
              operation,
              expression: IExp,
              position: Position = Position(0, 0)):
     IExp.__init__(self, position)
     self.operation = operation
     self.expression = expression
예제 #4
0
 def __init__(self,
              destination: IExp,
              source: IExp,
              position: Position = Position(0, 0)):
     IStm.__init__(self, position)
     self.source = source
     self.destination = destination
예제 #5
0
 def __init__(self,
              head: IExp = None,
              tail: IExp = None,
              position=Position(0, 0)):
     IExp.__init__(self, position)
     self.head = head
     self.tail = tail
예제 #6
0
 def add_method_to_scope(self, method_name: str, position: Position = Position(0, 0)):
     """
     Отвечает за добавление метода в текущий Scope по его названию
     :param method_name: название метода
     :param position: расположение метода
     :return:
     """
     self._add_method_to_scope(self.get_method(method_name, position))
예제 #7
0
 def fill_table(self, program: Program):
     """
     Отвечает за обход AST и заполнение таблицы
     :param program: корень AST (class Program)
     :return:
     """
     program.accept(self)
     if self.verbose:
         for class_name in self.table.classes_names:
             try:
                 class_info = self.table.get_class(class_name,
                                                   Position(0, 0))
                 self.table.add_class_to_scope(class_name, Position(0, 0))
                 if self.verbose:
                     self._print_class_info(class_info)
                 self.table.free_last_scope()
                 print()
             except SyntaxError as error:
                 print(error)
예제 #8
0
 def get_class(self, class_name: str, position: Position = Position(0, 0)) -> ClassInfo:
     """
     Отвечает за получение информации о классе по его названию и расположению
     :param class_name: название класса
     :param position: расположение класса
     :return:
     """
     class_info = self.classes_block.get(class_name)
     if class_info is not None:
         return class_info
     raise SyntaxError(f'Not declared class {class_name} requested! Position {position}')
예제 #9
0
    def __init__(self,
                 head: IStm = None,
                 tail: IStm = None,
                 position=Position(0, 0)):
        IStm.__init__(self, position)
        self.head = head
        self.tail = tail


#ExpList: List[IExp] = list
#StmList: List[IStm] = list
예제 #10
0
    def __init__(self,
                 jump_type_enum: JumpTypeEnum,
                 condition_left_expression: IExp,
                 condition_right_expression: IExp,
                 true_label: Label,
                 position: Position = Position(0, 0)):
        IStm.__init__(self, position)

        self.true_label = true_label
        self.condition_left_expression = condition_left_expression
        self.condition_right_expression = condition_right_expression
        self.jump_type_enum = jump_type_enum
예제 #11
0
 def get_method(self, method_name: str, position: Position = Position(0, 0)) -> MethodInfo:
     """
     Отвечает за получение информации о методе по его названию и расположению
     :param method_name: название метода
     :param position: расположение метода
     :return:
     """
     for block in reversed(self.blocks):
         methods_block = block.methods_block
         result = methods_block.get(method_name)
         if result is not None:
             return result
     raise SyntaxError(f'Not declared method {method_name} requested! Position {position}')
예제 #12
0
 def get_variable(self, variable_name: str, position: Position = Position(0, 0)) -> VariableInfo:
     """
     Отвечает за получение информации о переменной по ее названию и расположению
     :param variable_name: название переменной
     :param position: расположение переменной
     :return:
     """
     for block in reversed(self.blocks):
         variables_block = block.variables_block
         result = variables_block.get(variable_name)
         if result is not None:
             return result
     raise SyntaxError(f'Not declared variable {variable_name} requested! Position {position}')
예제 #13
0
 def does_type_have_super(self, class_info: ClassInfo, super_class_name: str,
                          position: Position = Position(0, 0)) -> bool:
     """
     Проверяет, является ли класс наследником другого класса
     :param class_info: название класса
     :param super_class_name: название предполагаемого базового класса
     :param position: позиция, на которой произошел вызов
     :return:
     """
     while class_info.super_class_name is not None:
         if class_info.super_class_name == super_class_name:
             return True
         class_info = self.get_class(class_info.super_class_name, position)
     return False
예제 #14
0
 def verify_class(self, class_info: ClassInfo, position: Position = Position(0, 0)):
     """
     Отвечает за проверку класса на циклическую зависимость
     :param class_info: информация о проверяемом классе
     :param position: расположение проверяемого класса
     :return:
     """
     classes_in_graph = set()
     class_to_check = class_info
     while class_to_check.super_class_name is not None:
         class_to_check = self.get_class(class_to_check.super_class_name, position)
         if class_to_check in classes_in_graph:
             raise SyntaxError(f'Cyclic dependency of class {class_to_check.name}! Position {class_info.position}')
         classes_in_graph.add(class_info)
     for class_info in classes_in_graph:
         self.verified_classes.add(class_info)
예제 #15
0
 def add_class_to_scope(self, class_name: str, position: Position = Position(0, 0)):
     """
     Отвечает за добавление класса в текущий Scope по его названию
     :param class_name: название класса
     :param position: расположение класса
     :return:
     """
     class_to_add = self.get_class(class_name, position)
     if class_to_add.name not in self.verified_classes:
         self.verify_class(class_to_add, position)
     classes_stack = [class_to_add]
     while class_to_add.super_class_name is not None:
         class_to_add = self.get_class(class_to_add.super_class_name, position)
         classes_stack.append(class_to_add)
     for class_info in classes_stack:
         self._add_class_to_scope(class_info)
예제 #16
0
 def fill(self):
     """
     Отвечает за вывод задания по записям активации
     Заполняет фрейм, словно был вызов метода на пустом стеке
     :return:
     """
     assert self.filled is not True
     class_names = self.table.classes_names
     for class_name in class_names:
         position = Position(0, 0)
         self.table.add_class_to_scope(class_name, position)
         class_info = self.table.get_class(class_name, position)
         methods_names = class_info.methods_names
         for method in methods_names:
             method_info = self.table.get_method(method, position)
             frame = X86MiniJavaFrame()
             this_variable = VariableInfo(THIS_NAME, position,
                                          class_info.type_info)
             frame.add_formal(this_variable)
             for arg_info in method_info.args_block:
                 frame.add_formal(arg_info)
             for var_info in method_info.vars_block:
                 frame.add_local(var_info)
             frame.add_address_exit()
             self.print(f'Method name: {method_info.name}')
             activation = frame.find_local_or_formal(THIS_NAME)
             self.print(f'this: {activation.print(frame.FP())}')
             for arg_name in method_info.args_names:
                 activation = frame.find_local_or_formal(arg_name)
                 self.print(
                     f'{arg_name}: {activation.print(TempAddress(0))}')
                 self.print(f'FP: {frame.FP().get_address()}')
             for var_name in method_info.vars_names:
                 activation = frame.find_local_or_formal(var_name)
                 self.print(f'{var_name}: {activation.print(frame.FP())}')
             self.print(f'SP: {frame.SP().get_address()}')
             self.print(
                 f'Return address: {frame.return_address.print(TempAddress(0))}'
             )
             self.print(
                 f'Exit address: {frame.exit_address().print(TempAddress(0))}'
             )
             self.print('- - - - - - - - - - - - -')
             self.print('')
         self.table.free_last_scope()
     self.filled = True
예제 #17
0
 def create_frame(class_info: ClassInfo, method_info: MethodInfo):
     """
     Отвечает за создание и заполнении фрейма на основании данных о классе и методе
     :param class_info:
     :param method_info:
     :return:
     """
     frame = X86MiniJavaFrame()
     this_variable = VariableInfo(THIS_NAME, Position(0, 0),
                                  class_info.type_info)
     frame.add_formal(this_variable)
     for arg_info in method_info.args_block:
         frame.add_formal(arg_info)
     for var_info in method_info.vars_block:
         frame.add_local(var_info)
     frame.add_address_exit()
     frame.add_address_return_value(method_info.return_type)
     return frame
예제 #18
0
    def _print_class_info(self, class_info: ClassInfo):
        """
        Отвечает за вывод информации о классе на экран
        :param class_info: информация о классе, который будет выведен
        :return:
        """
        print(f'class {class_info.name} {class_info.position}')

        if class_info.super_class_name is not None:
            print(f'extends {class_info.super_class_name}')
            self.table.get_class(class_info.super_class_name, Position(0, 0))

        print(f'    fields:')
        for var_name in class_info.vars_names:
            variable_info = self.table.get_variable(var_name, Position(0, 0))
            print(f'        {self._format_variable_info(variable_info)}')

        for method_name in class_info.methods_names:
            method_info = self.table.get_method(method_name, Position(0, 0))
            self.table.add_method_to_scope(method_info.name, Position(0, 0))
            access_modifier = 'public' if method_info.access_modifier == AccessModifierEnum.Public else 'private'

            print(
                f'    func {access_modifier} {method_info.name} {method_info.position}'
            )

            if method_info.get_args_count() > 0:
                print(f'        arguments:')
                for arg_name in method_info.args_names:
                    arg_info = self.table.get_variable(arg_name,
                                                       Position(0, 0))
                    print(
                        f'            {self._format_variable_info(arg_info)}')

            if method_info.get_vars_count() > 0:
                print(f'        local variables:')
                for var_name in method_info.vars_names:
                    variable_info = self.table.get_variable(
                        var_name, Position(0, 0))
                    print(
                        f'            {self._format_variable_info(variable_info)}'
                    )

            self.table.free_last_scope()
예제 #19
0
 def __init__(self, label: Label, position: Position = Position(0, 0)):
     IStm.__init__(self, position)
     self.label_name = label
예제 #20
0
 def __init__(self, value: int, position: Position = Position(0, 0)):
     IExp.__init__(self, position)
     self.value = value
예제 #21
0
 def __init__(self, operation: BinopEnum, left_expression: IExp, right_expression: IExp,
              position: Position = Position(0, 0)):
     IExp.__init__(self, position)
     self.operation = operation
     self.left_expression = left_expression
     self.right_expression = right_expression
예제 #22
0
 def __init__(self, statement: IStm, expression: IExp, position: Position = Position(0, 0)):
     IExp.__init__(self, position)
     self.statement = statement
     self.expression = expression
예제 #23
0
 def __init__(self, position: Position = Position(0, 0)):
     INode.__init__(self, position)
예제 #24
0
 def __init__(self, expression: IExp, position: Position = Position(0, 0)):
     IStm.__init__(self, position)
     self.expression = expression
예제 #25
0
 def __init__(self, name: str = None, position: Position = Position(0, 0)):
     IExp.__init__(self, position)
     if str is None:
         self.label_name = Label.get_next_enumerated_label()
     else:
         self.label_name = Label.get_label(name)