コード例 #1
0
 def parse_while(self, pos: int):
     '''
     Логика обработки директивы while
     '''
     return_pos = pos + 1
     
     if len(self.all_file[pos].arguments) != 1:
         raise Exception('invalid num params')
     
     expr_str = ParserTool.parse_assembly_string(self.__check_defines(pos)).arguments[0][:]
     expr_result = bool(eval_expr(expr_str))
     
     cycle_pred = True # устанавливается в True при первом проходе по тексту 
     
     
     while cycle_pred == True:
         while return_pos < len(self.all_file) and self.all_file[return_pos].code != ENDW_TOKEN:
             if expr_result:
                 return_pos = MacroAssembly.statement(self, return_pos)
             else: 
                 return_pos += 1
                 
         if return_pos == len(self.all_file):
             raise Exception('endw not found')
         
         if expr_result == False:
             cycle_pred = expr_result
         else:
             expr_str = ParserTool.parse_assembly_string(self.__check_defines(pos)).arguments[0][:]
             cycle_pred = expr_result = bool(eval_expr(expr_str))
     
             if expr_result != False:
                 return_pos = pos + 1
   
     return return_pos
コード例 #2
0
 def parse_include(self, pos: int):
     '''
     Логика обработки include -- удаляем
     '''
     if len(self.all_file[pos].arguments) != 1:
         raise Exception('invalid num params')
         
     filename = str(eval_expr(ParserTool.parse_assembly_string(self.__check_defines(pos)).arguments[0]))
     
     self.all_file = self.all_file[:pos] + [ParserTool.parse_assembly_string(s) for s in open(filename).readlines()] + self.all_file[pos + 1:]
     
     return pos - 1
コード例 #3
0
 def parse_rept(self, pos: int):
     '''
     Логика обработки директивы rept
     rept (целое значение) -- выполнение n раз
     '''
     return_pos = pos + 1
     
     if len(self.all_file[pos].arguments) != 1:
         raise Exception('invalid num params')
         
     expr_str = ParserTool.parse_assembly_string(self.__check_defines(pos)).arguments[0][:]
     n = int(eval_expr(expr_str))
     
     while n:
         while return_pos < len(self.all_file) and self.all_file[return_pos].code != ENDR_TOKEN:
             return_pos = MacroAssembly.statement(self, return_pos)
                 
         if return_pos == len(self.all_file):
             raise Exception('endr not found')
         
         n -= 1
         
         if n: # переходим только если не прошли n раз
             return_pos = pos + 1
   
     return return_pos
コード例 #4
0
 def parse_if(self, pos: int):
     '''
     Обработка конструкции if
     грамматика вида ifndef <expr> <statements> <else> <statements> endif
     ветка else не обязательна
     
     '''
     return_pos = pos + 1
     
     if len(self.all_file[pos].arguments) != 1:
         raise Exception('invalid num params')
     expr_result = bool(eval_expr(ParserTool.parse_assembly_string(self.__check_defines(pos)).arguments[0]))
 
     while return_pos < len(self.all_file) and self.all_file[return_pos].code != ENDIF_TOKEN:
         if self.all_file[return_pos].code == ELSE_TOKEN:
             expr_result = not expr_result
             return_pos += 1
             continue
         
         if expr_result: # если true -- то обрабатываем
             return_pos = MacroAssembly.statement(self, return_pos)
         else: # иначе обходим
             return_pos += 1
     
     if return_pos == len(self.all_file):
         raise Exception('endif not found')
             
     return return_pos
コード例 #5
0
 def statement(self, pos: int):
     '''
     Обработка конструкции statement
     
     '''
     
     # обработка подстановок для строк (переменных)
     # обработка макроподстановок
     
     #print(self.variables)
     #print(self.all_file[pos].source)
     
     work_str = copy.deepcopy(self.all_file[pos])
     
     work_str.source = self.__check_defines(pos)
     work_str = ParserTool.parse_assembly_string(work_str.source)
     
     return_pos = pos
     
     if work_str.code == IFDEF_TOKEN:
         return_pos = self.parse_ifdef(pos)
     elif work_str.code == IF_TOKEN:
         return_pos = self.parse_if(pos)
     elif work_str.code == IFNDEF_TOKEN:
         return_pos = self.parse_ifndef(pos)
     elif work_str.code == MACRO_TOKEN:
         return_pos = self.parse_macro(pos)
     elif work_str.code == DEFINE_TOKEN:
         return_pos = self.parse_define(pos)
     elif work_str.code == SET_TOKEN:
         return_pos = self.parse_set(pos)
     elif work_str.code == WHILE_TOKEN:
         return_pos = self.parse_while(pos)
     elif work_str.code == REPT_TOKEN:
         return_pos = self.parse_rept(pos)
     elif work_str.code == INCLUDE_TOKEN:
         return_pos = self.parse_include(pos)
     elif work_str.code in self.macro_table.keys():
         self.output_file += MacroAssembly.evaluate([ParserTool.parse_assembly_string(asm_op) 
                                                     for asm_op in self.macro_table[work_str.code]
                                                     .execute(work_str.arguments)],
                                                     self.macro_table, self.variables)
     else:
         
         self.output_file.append(work_str.source)
     return return_pos + 1
コード例 #6
0
 def parse_set(self, pos: int):
     '''
     Логика обработки директивы set
     '''
     label: str = self.all_file[pos].label
     if label in self.variables.keys():
         if len(self.all_file[pos].arguments) == 1:
             self.variables[label] = eval_expr(ParserTool.parse_assembly_string(self.__check_defines(pos)).arguments[0])
         else:
             raise Exception("Invalid number of params")
     else:
         raise Exception(f"variable {label} has never defined")
     return pos
コード例 #7
0
 def __open_file(self):
     '''
     Инициализация файла с кодом
     '''
     with open(self.filename, 'r') as fs:
         self.all_file = [ParserTool.parse_assembly_string(asm_str) for asm_str in fs.readlines()]