Advertisement
Korotkodul

my_code_7

Apr 4th, 2025 (edited)
318
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.84 KB | None | 0 0
  1. import pyparsing as pp
  2.  
  3.  
  4. # Улучшенные определения элементов
  5. identifier = pp.Word(pp.alphas, pp.alphanums + "_")
  6. mnemonic = pp.oneOf("mov add sub halt", caseless=True)  # Список команд
  7. command_name = mnemonic("command")
  8.  
  9. # Числа: #10 или 10 (целые)
  10. number = pp.Combine(pp.Optional('#') + pp.Word(pp.nums))
  11. # Регистры: r0, r1, ..., r15
  12. register = pp.Combine(pp.CaselessLiteral('r') + pp.Word(pp.nums, max=2))
  13. argument = number | register | identifier
  14. arguments = pp.Group(pp.delimitedList(argument, delim=pp.Suppress(',')))("args")
  15.  
  16. label = (identifier + pp.Suppress(":"))("label")
  17. comment = (pp.Suppress(';') + pp.restOfLine.setParseAction(lambda t: t[0].strip()))("comment")
  18.  
  19. # Основное правило
  20. rule = (
  21.     pp.Optional(label, default='')
  22.     + pp.Optional(command_name, default='')
  23.     + pp.Optional(arguments, default=[])
  24.     + pp.Optional(comment, default='')
  25. )
  26.  
  27. debug_mode = True
  28.  
  29. def parse(s):
  30.     s = s.lower().strip()
  31.     if s[0] == '.':
  32.         s = s.replace(" ", "")
  33.         return {'label': '', 'command_name': 'start_from_address', 'arguments': [ s[2:] ], 'comment': ''}
  34.     parsed = rule.parseString(s, parseAll=True)
  35.     args = []
  36.     if len(parsed.args) != 0:
  37.         args = parsed.args.asList()
  38.     comment = ''
  39.     if parsed.comment  != '':
  40.         comment = parsed.comment[0]
  41.     label = ''
  42.     if  parsed.label != '':
  43.         label = parsed.label[0]
  44.     result = {
  45.         'label': label,
  46.         'command_name': parsed.command if 'command' in parsed else '',
  47.         'arguments': args,
  48.         'comment': comment
  49.     }
  50.  
  51.     """if debug_mode:
  52.        print("s:", s)
  53.        #print([parsed.label, parsed.command_name, parsed.arguments, parsed.comment])
  54.        print("return:", result)
  55.        print()"""
  56.  
  57.     return result
  58.  
  59.  
  60. dict_machine_code = {'start': '', 'data': []}
  61.  
  62. assembler_code = []
  63. filename = 'asm_code.txt'
  64. #filename = 'pdp11_code.txt'
  65. with open(filename, 'r', encoding='utf-8') as file:
  66.     for line in file:
  67.         line = line.lower().strip()
  68.         assembler_code.append(parse(line))
  69.  
  70. if debug_mode:
  71.     print("assembler_code")
  72.     for line in assembler_code:
  73.         print(line)
  74.     print()
  75.  
  76. opcode = {
  77.     'mov': '0001',
  78.     'add': '0110',
  79.     'halt': '0000'
  80. }
  81.  
  82. def to3bit(x):
  83.     res = str(bin(int(x))[2:])
  84.     while len(res) < 3:
  85.         res = '0' + res
  86.     return res
  87.  
  88. #print(to3bit('3'))
  89.  
  90. def to_four_digit_hex_number(x):
  91.     res = str(hex(int(x)))[2:]
  92.     while len(res) < 4:
  93.         res = '0' + res
  94.     return res
  95.  
  96. #print(to_four_digit_hex_number('10'))
  97.  
  98. #для начала считаем, что сначала идёт команда. то есть без label
  99. #считаем, что у нас могут быть только 3 команды: move/add/halt
  100. #у этих 3х команд аргументы - это SSDD
  101. #вырианты: cmd R, R; cmd #, R;
  102.  
  103. #на случай # у нас есть переменные additional...
  104. def to_raw_machine_code(command):
  105.  
  106.     if command['command_name'] == 'halt':
  107.         dict_machine_code['data'].append('0' * 16)
  108.         return '0' * 16, ''
  109.     if command['command_name'] == 'start_from_address':
  110.         dict_machine_code['start'] = to_four_digit_hex_number(int(command['arguments'][0], 8))
  111.         return [to_four_digit_hex_number(int(command['arguments'][0], 8)), 'number of bytes in the resulting file']
  112.  
  113.     command_code = opcode[command['command_name']]
  114.  
  115.     source = command['arguments'][0]
  116.     source_mode = ''
  117.     source_R_num = ''
  118.     if source[0] == 'r':
  119.         source_mode = '000'
  120.         source_R_num = to3bit(source[1])
  121.     source_additional_word = ''
  122.     if source[0] == '#':
  123.         source_mode = '010'
  124.         source_R_num = '111'
  125.         source_additional_word = to_four_digit_hex_number(source[1:])
  126.  
  127.     destination = command['arguments'][1]
  128.     destination_mode = ''
  129.     destination_R_num = ''
  130.     if destination[0] == 'r':
  131.         destination_mode = '000'
  132.         destination_R_num = to3bit(destination[1])
  133.  
  134.     raw_machine_command = command_code + source_mode + source_R_num + destination_mode + destination_R_num
  135.     dict_machine_code['data'].append(raw_machine_command)
  136.     if source_additional_word != '':
  137.         dict_machine_code['data'].append(source_additional_word)
  138.     return raw_machine_command, source_additional_word
  139.  
  140. raw_machine_code = []
  141. for cmd in assembler_code:
  142.     raw_machine_code.append(to_raw_machine_code(cmd))
  143.  
  144. print("raw_machine_code",  raw_machine_code)
  145.  
  146. machine_code = []
  147. def to_machine_code(raw_machine_command):
  148.     #print("raw_machine_command", raw_machine_command)
  149.     if len(raw_machine_command[0]) != 16:
  150.         return raw_machine_command
  151.  
  152.     raw_command_code = raw_machine_command[0]
  153.     piece1 = raw_command_code[:4]
  154.     piece2 = raw_command_code[4:8]
  155.     piece3 = raw_command_code[8:12]
  156.     piece4 = raw_command_code[12:]
  157.     #print("pieces", piece1, piece2, piece3, piece4)
  158.     num1 = hex(int(piece1,  2))[2:] + hex(int(piece2, 2))[2:]
  159.     num2 = hex(int(piece3,  2))[2:] + hex(int(piece4, 2))[2:]
  160.     machine_command = [num2, num1]
  161.  
  162.     additional_num1 = ''
  163.     additional_num2 = ''
  164.     if len(raw_machine_command[1]) == 4:
  165.         additional_num1 = raw_machine_command[1][:2]
  166.         additional_num2 = raw_machine_command[1][2:]
  167.         machine_command.append(additional_num2)
  168.         machine_command.append(additional_num1)
  169.  
  170.     return machine_command
  171.  
  172.  
  173.  
  174. for cmd in raw_machine_code:
  175.     cmd = to_machine_code(cmd)
  176.     machine_code.append(cmd)
  177.  
  178. print("machine_code:", machine_code)
  179. print("dict_machine_code:", dict_machine_code)
  180.  
  181. with open("machine_code.txt", "w", encoding="utf-8") as file:
  182.     for cmd in machine_code:
  183.         for line in cmd:
  184.             file.write(line + "\n")
  185.  
  186.  
  187.  
  188. print("Файл успешно создан и записан.")
  189.  
  190.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement