def test_numeric_enumeration_operand(self):
        with pkg_resources.path(config_files,
                                'test_operand_features.yaml') as fp:
            isa_model = AssemblerModel(str(fp), 0)
        lineid = LineIdentifier(33, 'test_numeric_enumeration_operand')

        t1 = InstructionLine.factory(lineid, 'num my_val+7', 'comment',
                                     isa_model)
        t1.set_start_address(1)
        t1.label_scope = TestInstructionParsing.label_values
        self.assertIsInstance(t1, InstructionLine)
        self.assertEqual(t1.byte_size, 1, 'has 1 bytes')
        t1.generate_bytes()
        self.assertEqual(list(t1.get_bytes()), [0b10101000],
                         'instruction byte should match')

        t2 = InstructionLine.factory(lineid, 'sftl a, 1', 'comment', isa_model)
        t2.set_start_address(1)
        t2.label_scope = TestInstructionParsing.label_values
        self.assertIsInstance(t2, InstructionLine)
        self.assertEqual(t2.byte_size, 1, 'has 1 bytes')
        t2.generate_bytes()
        self.assertEqual(list(t2.get_bytes()), [0b10001001],
                         'instruction byte should match')

        with self.assertRaises(SystemExit,
                               msg='test invalid enumeration values'):
            e1 = InstructionLine.factory(lineid, 'num 7',
                                         'number 7 is not allowed', isa_model)
            e1.label_scope = TestInstructionParsing.label_values
            e1.generate_bytes()
    def test_deferred_operands(self):
        with pkg_resources.path(config_files,
                                'test_operand_features.yaml') as fp:
            isa_model = AssemblerModel(str(fp), 0)
        lineid = LineIdentifier(13, 'test_deferred_operands')

        t1 = InstructionLine.factory(lineid, '  ld a, [[$F0]]', 'comment',
                                     isa_model)
        t1.set_start_address(1)
        t1.label_scope = TestInstructionParsing.label_values
        self.assertIsInstance(t1, InstructionLine)
        self.assertEqual(t1.byte_size, 2, 'has 2 bytes')
        t1.generate_bytes()
        self.assertEqual(list(t1.get_bytes()), [0b00010101, 0xF0],
                         'instruction byte should match')

        t2 = InstructionLine.factory(lineid, '  ld [[my_val]],x', 'comment',
                                     isa_model)
        t2.set_start_address(1)
        t2.label_scope = TestInstructionParsing.label_values
        self.assertIsInstance(t2, InstructionLine)
        self.assertEqual(t2.byte_size, 2, 'has 2 bytes')
        t2.generate_bytes()
        self.assertEqual(list(t2.get_bytes()), [0b10011101, 0x08],
                         'instruction byte should match')
Esempio n. 3
0
    def test_predefined_entities(self):
        with pkg_resources.path(config_files,
                                'test_compiler_features.yaml') as fp:
            model = AssemblerModel(str(fp), 0)

        self.assertSetEqual(set(model.predefined_labels),
                            set(['CONST1', 'CONST2', 'buffer']),
                            'label set should equal')
Esempio n. 4
0
 def test_bad_registers_in_configuratin(self):
     with pkg_resources.path(
             config_files, 'test_bad_registers_in_configuratin.yaml') as fp:
         with self.assertRaises(
                 SystemExit,
                 msg=
                 'model configuration should not specify prohibited register names'
         ):
             model = AssemblerModel(str(fp), 0)
 def test_label_parsing(self):
     with pkg_resources.path(config_files,
                             'test_instructions_with_variants.yaml') as fp:
         isa_model = AssemblerModel(str(fp), 0)
     lineid = LineIdentifier(42, 'test_label_parsing')
     l1: LineObject = LineOjectFactory.parse_line(lineid,
                                                  "LABEL = %00001111",
                                                  isa_model)[0]
     self.assertIsInstance(l1, LabelLine)
     self.assertTrue(l1.is_constant, )
     self.assertEqual(l1.get_value(), 0x0F, 'value should be right')
    def test_indirect_indexed_regsiter_operands(self):
        with pkg_resources.path(
                config_files,
                'test_indirect_indexed_register_operands.yaml') as fp:
            isa_model = AssemblerModel(str(fp), 0)

        ins0 = InstructionLine.factory(22, 'mov a, [hl+i]', 'some comment!',
                                       isa_model)
        ins0.set_start_address(1212)
        self.assertIsInstance(ins0, InstructionLine)
        self.assertEqual(ins0.byte_size, 1, 'has 1 bytes')
        ins0.label_scope = TestInstructionParsing.label_values
        ins0.generate_bytes()
        self.assertEqual(list(ins0.get_bytes()), [0x81],
                         'instruction byte should match')

        ins1 = InstructionLine.factory(22, 'mov [$2000], [hl+i]',
                                       'some comment!', isa_model)
        ins1.set_start_address(1212)
        self.assertIsInstance(ins1, InstructionLine)
        self.assertEqual(ins1.byte_size, 3, 'has 3 bytes')
        ins1.label_scope = TestInstructionParsing.label_values
        ins1.generate_bytes()
        self.assertEqual(list(ins1.get_bytes()), [0xB1, 0x00, 0x20],
                         'instruction byte should match')

        ins2 = InstructionLine.factory(22, 'mov [$2000], [hl+[sp+2]]',
                                       'some comment!', isa_model)
        ins2.set_start_address(1212)
        self.assertIsInstance(ins2, InstructionLine)
        self.assertEqual(ins2.byte_size, 4, 'has 4 bytes')
        ins2.label_scope = TestInstructionParsing.label_values
        ins2.generate_bytes()
        self.assertEqual(list(ins2.get_bytes()), [0xB3, 0x00, 0x20, 0x02],
                         'instruction byte should match')

        ins2 = InstructionLine.factory(22, 'mov [mar + $44], [$8020]',
                                       'some comment!', isa_model)
        ins2.set_start_address(1212)
        self.assertIsInstance(ins2, InstructionLine)
        self.assertEqual(ins2.byte_size, 4, 'has 4 bytes')
        ins2.label_scope = TestInstructionParsing.label_values
        ins2.generate_bytes()
        self.assertEqual(list(ins2.get_bytes()), [0xFE, 0x20, 0x80, 0x44],
                         'instruction byte should match, operands reversed')

        with self.assertRaises(SystemExit,
                               msg='no instruction  should match here'):
            bad1 = InstructionLine.factory(22, '  mov a, [sp+i]',
                                           'some comment!', isa_model)
            bad1.set_start_address(666)
            bad1.label_scope = TestInstructionParsing.label_values
            bad1.generate_bytes()
    def test_enumeration_operand(self):
        with pkg_resources.path(config_files,
                                'test_operand_features.yaml') as fp:
            isa_model = AssemblerModel(str(fp), 0)
        lineid = LineIdentifier(21, 'test_enumeration_operand')

        t1 = InstructionLine.factory(lineid, '  tst bee', 'comment', isa_model)
        t1.set_start_address(1)
        t1.label_scope = TestInstructionParsing.label_values
        self.assertIsInstance(t1, InstructionLine)
        self.assertEqual(t1.byte_size, 2, 'has 2 bytes')
        t1.generate_bytes()
        self.assertEqual(list(t1.get_bytes()), [0b00111001, 0xBB],
                         'instruction byte should match')
Esempio n. 8
0
 def __init__(
     self,
     config_file_path: str,
     is_verbose: int,
     export_dir: str,
     language_name: str,
     language_version: str,
     code_extension: str,
 ) -> None:
     self._model = AssemblerModel(config_file_path, is_verbose)
     self._verbose = is_verbose
     self._export_dir = export_dir
     self._language_name = self.model.isa_name if language_name is None else language_name
     self._language_version = self.model.isa_version if language_version is None else language_version
     self._extension = code_extension if code_extension is not None else self.model.assembly_file_extenions
    def test_numeric_bytecode_operand(self):
        with pkg_resources.path(config_files,
                                'test_operand_features.yaml') as fp:
            isa_model = AssemblerModel(str(fp), 0)
        lineid = LineIdentifier(33, 'test_numeric_bytecode_operand')

        t1 = InstructionLine.factory(lineid, '  tstb x, the_two+1', 'comment',
                                     isa_model)
        t1.set_start_address(1)
        t1.label_scope = TestInstructionParsing.label_values
        self.assertIsInstance(t1, InstructionLine)
        self.assertEqual(t1.byte_size, 1, 'has 1 bytes')
        t1.generate_bytes()
        self.assertEqual(list(t1.get_bytes()), [0b10011011],
                         'instruction byte should match')

        t2 = InstructionLine.factory(lineid, '  tstb a, 7', 'comment',
                                     isa_model)
        t2.set_start_address(1)
        t2.label_scope = TestInstructionParsing.label_values
        self.assertIsInstance(t2, InstructionLine)
        self.assertEqual(t2.byte_size, 1, 'has 1 bytes')
        t2.generate_bytes()
        self.assertEqual(list(t2.get_bytes()), [0b00011111],
                         'instruction byte should match')

        t3 = InstructionLine.factory(lineid, '  enumarg 6', 'comment',
                                     isa_model)
        t3.set_start_address(1)
        t3.label_scope = TestInstructionParsing.label_values
        self.assertIsInstance(t3, InstructionLine)
        self.assertEqual(t3.byte_size, 2, 'has 2 bytes')
        t3.generate_bytes()
        self.assertEqual(list(t3.get_bytes()), [254, 64],
                         'instruction byte should match')

        with self.assertRaises(SystemExit, msg='test bounds'):
            e1 = InstructionLine.factory(lineid, '  tstb b, 14',
                                         'second argument is too large',
                                         isa_model)
            e1.label_scope = TestInstructionParsing.label_values
            e1.generate_bytes()

        with self.assertRaises(SystemExit, msg='test invalid enumerations'):
            e2 = InstructionLine.factory(lineid, '  enumarg 12', 'comment',
                                         isa_model)
            e2.label_scope = TestInstructionParsing.label_values
            e2.generate_bytes()
Esempio n. 10
0
    def test_bad_instruction_lines(self):
        with pkg_resources.path(config_files,
                                'register_argument_exmaple_config.yaml') as fp:
            isa_model = AssemblerModel(str(fp), 0)
        label_values = GlobalLabelScope(isa_model.registers)

        # this instruction should fail because register A is not configured to be an
        # indirect register, so the parser assumes this is a indirect numeric expression
        # and then sees a register used there.
        with self.assertRaises(SystemExit, msg='this instruction should fail'):
            InstructionLine.factory(22, '  mov [a+2],5', 'move it', isa_model)

        # this instruction should fail because register i is being used in a numeric
        # expression
        with self.assertRaises(SystemExit, msg='this instruction should fail'):
            InstructionLine.factory(22, '  add i+5', 'add it', isa_model)
Esempio n. 11
0
    def test_specifc_configured_operands(self):
        with pkg_resources.path(config_files,
                                'register_argument_exmaple_config.yaml') as fp:
            isa_model = AssemblerModel(str(fp), 0)

        label_values = GlobalLabelScope(isa_model.registers)
        label_values.set_label_value('test1', 0xABCD, 1)

        ins1 = InstructionLine.factory(22, 'mov i,[mar]', 'specific operands',
                                       isa_model)
        ins1.set_start_address(1234)
        self.assertIsInstance(ins1, InstructionLine)
        self.assertEqual(ins1.byte_size, 1, 'has 1 byte')
        ins1.label_scope = label_values
        ins1.generate_bytes()
        self.assertEqual(ins1.get_bytes(), bytearray([0x52]),
                         'instruction should match')

        ins2 = InstructionLine.factory(22, 'mov [sp+8],[mar]',
                                       'specific operands', isa_model)
        ins2.set_start_address(1234)
        self.assertIsInstance(ins2, InstructionLine)
        self.assertEqual(ins2.byte_size, 2, 'has 2 byte')
        ins2.label_scope = label_values
        ins2.generate_bytes()
        self.assertEqual(ins2.get_bytes(), bytearray([0x6D, 0x08]),
                         'instruction should match')

        # ensure operand sets operands still work when instruction has specific operands configured
        ins3 = InstructionLine.factory(22, 'mov a,[sp+8]', 'specific operands',
                                       isa_model)
        ins3.set_start_address(1234)
        self.assertIsInstance(ins3, InstructionLine)
        self.assertEqual(ins3.byte_size, 2, 'has 2 byte')
        ins3.label_scope = label_values
        ins3.generate_bytes()
        self.assertEqual(ins3.get_bytes(), bytearray([0x45, 0x08]),
                         'instruction should match')
Esempio n. 12
0
 def __init__(
     self,
     source_file: str,
     config_file: str,
     output_file: str,
     binary_start: int,
     binary_end: int,
     binary_fill_value: int,
     enable_pretty_print: bool,
     pretty_print_output: str,
     is_verbose: int,
     include_paths: list[str],
 ):
     self.source_file = source_file
     self._output_file = output_file
     self._config_file = config_file
     self._enable_pretty_print = enable_pretty_print
     self._pretty_print_output = pretty_print_output
     self._binary_fill_value = binary_fill_value & 0xff
     self._verbose = is_verbose
     self._binary_start = binary_start
     self._binary_end = binary_end
     self._model = AssemblerModel(self._config_file, self._verbose)
     self._include_paths = include_paths
Esempio n. 13
0
    def test_instruction_line_creation_little_endian(self):
        with pkg_resources.path(
                config_files,
                'test_instruction_line_creation_little_endian.yaml') as fp:
            isa_model = AssemblerModel(str(fp), 0)

        label_values = GlobalLabelScope(isa_model.registers)
        label_values.set_label_value('test1', 0xABCD, 1)

        ins1 = InstructionLine.factory(22, '  lda test1', 'some comment!',
                                       isa_model)
        ins1.set_start_address(1212)
        self.assertIsInstance(ins1, InstructionLine)
        self.assertEqual(ins1.byte_size, 3, 'has 3 byte')
        ins1.label_scope = label_values
        ins1.generate_bytes()
        self.assertEqual(ins1.get_bytes(), bytearray([0x10, 0xCD, 0xAB]),
                         'instruction should match')

        ins2 = InstructionLine.factory(22, 'set test1', 'set it!', isa_model)
        ins2.set_start_address(1212)
        self.assertIsInstance(ins2, InstructionLine)
        self.assertEqual(ins2.byte_size, 3, 'has 3 byte')
        ins2.label_scope = label_values
        ins2.generate_bytes()
        self.assertEqual(ins2.get_bytes(), bytearray([0x30, 0xAB, 0xCD]),
                         'instruction should match')

        ins3 = InstructionLine.factory(22, 'big $f', 'big money', isa_model)
        ins3.set_start_address(1212)
        self.assertIsInstance(ins3, InstructionLine)
        self.assertEqual(ins3.byte_size, 2, 'has 2 byte')
        ins3.label_scope = label_values
        ins3.generate_bytes()
        self.assertEqual(ins3.get_bytes(), bytearray([0xFF, 0x3C]),
                         'instruction should match')
Esempio n. 14
0
    def test_instruction_line_creation(self):
        with pkg_resources.path(
                config_files, 'test_instruction_list_creation_isa.json') as fp:
            isa_model = AssemblerModel(str(fp), 0)

        label_values = GlobalLabelScope(isa_model.registers)
        label_values.set_label_value('test1', 0xA, 1)
        label_values.set_label_value('high_de', 0xde00, 1)

        ins1 = InstructionLine.factory(22, '  lda test1', 'some comment!',
                                       isa_model)
        ins1.set_start_address(1212)
        self.assertIsInstance(ins1, InstructionLine)
        self.assertEqual(ins1.byte_size, 1, 'has 1 byte')
        ins1.label_scope = label_values
        ins1.generate_bytes()
        self.assertEqual(ins1.get_bytes(), bytearray([0x1a]),
                         'instruction should match')

        ins2 = InstructionLine.factory(22, '  hlt', 'stop it!', isa_model)
        ins2.set_start_address(1212)
        self.assertIsInstance(ins2, InstructionLine)
        self.assertEqual(ins2.byte_size, 1, 'has 1 byte')
        ins2.label_scope = label_values
        ins2.generate_bytes()
        self.assertEqual(ins2.get_bytes(), bytearray([0xF0]),
                         'instruction should match')

        ins3 = InstructionLine.factory(22, '  seta (high_de + $00AD)',
                                       'is it alive?', isa_model)
        ins3.set_start_address(1313)
        self.assertIsInstance(ins3, InstructionLine)
        self.assertEqual(ins3.byte_size, 3, 'has 3 bytes')
        ins3.label_scope = label_values
        ins3.generate_bytes()
        self.assertEqual(ins3.get_bytes(), bytearray([0x30, 0xAD, 0xDE]),
                         'instruction should match')

        ins4 = InstructionLine.factory(22, '  lda test1+2', 'load it',
                                       isa_model)
        ins4.set_start_address(1313)
        self.assertIsInstance(ins4, InstructionLine)
        self.assertEqual(ins4.byte_size, 1, 'has 1 byte')
        ins4.label_scope = label_values
        ins4.generate_bytes()
        self.assertEqual(ins4.get_bytes(), bytearray([0x1c]),
                         'instruction should match')

        ins5 = InstructionLine.factory(22, '  plus 8', 'plus it', isa_model)
        ins5.set_start_address(888)
        self.assertIsInstance(ins5, InstructionLine)
        self.assertEqual(ins5.byte_size, 2, 'has 2 bytes')
        ins5.label_scope = label_values
        ins5.generate_bytes()
        self.assertEqual(ins5.get_bytes(), bytearray([0x40, 0x08]),
                         'instruction should match')

        ins6 = InstructionLine.factory(22, '  lda test1-2', 'load it',
                                       isa_model)
        ins6.set_start_address(888)
        self.assertIsInstance(ins6, InstructionLine)
        self.assertEqual(ins6.byte_size, 1, 'has 1 byte1')
        ins6.label_scope = label_values
        ins6.generate_bytes()
        self.assertEqual(ins6.get_bytes(), bytearray([0x18]),
                         'instruction should match')
Esempio n. 15
0
    def test_label_line_with_instruction(self):
        with pkg_resources.path(config_files,
                                'test_instructions_with_variants.yaml') as fp:
            isa_model = AssemblerModel(str(fp), 0)

        label_values = GlobalLabelScope(isa_model.registers)
        label_values.set_label_value('a_const', 40, 1)

        lineid = LineIdentifier(123, 'test_label_line_with_instruction')

        # test data line on label line
        objs1: list[LineObject] = LineOjectFactory.parse_line(
            lineid, 'the_byte: .byte 0x88 ; label and instruction', isa_model)
        self.assertEqual(len(objs1), 2, 'there should be two instructions')
        self.assertIsInstance(objs1[0], LabelLine,
                              'the first line object should be a label')
        self.assertIsInstance(objs1[1], DataLine,
                              'the first line object should be a data line')
        self.assertEqual(objs1[0].get_label(), 'the_byte',
                         'the label string should match')
        objs1[1].label_scope = label_values
        objs1[1].generate_bytes()
        self.assertEqual(objs1[1].byte_size, 1,
                         'the data value should have 1 byte')
        self.assertEqual(list(objs1[1].get_bytes()), [0x88],
                         'the data value should be [0x88]')

        # test instruction on label line
        objs2: list[LineObject] = LineOjectFactory.parse_line(
            lineid, 'the_instr: mov a, a_const ; label and instruction',
            isa_model)
        self.assertEqual(len(objs2), 2, 'there should be two instructions')
        self.assertIsInstance(objs2[0], LabelLine,
                              'the first line object should be a label')
        self.assertIsInstance(
            objs2[1], InstructionLine,
            'the first line object should be an Instruction line')
        self.assertEqual(objs2[0].get_label(), 'the_instr',
                         'the label string should match')
        objs2[1].label_scope = label_values
        objs2[1].generate_bytes()
        self.assertEqual(objs2[1].byte_size, 2,
                         'the instruction value should have 2 bytes')
        self.assertEqual(list(objs2[1].get_bytes()), [0b01000111, 40],
                         'the instruction bytes should match')

        # labels with no inline instruction should also work
        objs3: list[LineObject] = LineOjectFactory.parse_line(
            lineid, 'the_label: ;just a label', isa_model)
        self.assertEqual(len(objs3), 1, 'there should be two instructions')
        self.assertIsInstance(objs3[0], LabelLine,
                              'the first line object should be a label')
        self.assertEqual(objs3[0].get_label(), 'the_label',
                         'the label string should match')

        # labels with constants should not work
        with self.assertRaises(SystemExit, msg='this instruction should fail'):
            LineOjectFactory.parse_line(
                lineid, 'the_label: const = 3 ; label with constant',
                isa_model)
        # labels with other labels should not work
        with self.assertRaises(SystemExit, msg='this instruction should fail'):
            LineOjectFactory.parse_line(
                lineid,
                'the_label: the_second_label: ; label with another label',
                isa_model)
Esempio n. 16
0
    def test_instruction_parsing(self):
        with pkg_resources.path(config_files, 'eater-sap1-isa.yaml') as fp:
            model1 = AssemblerModel(str(fp), 0)

        test_line_id = LineIdentifier(1212, 'test_instruction_parsing')

        pi1 = model1.parse_instruction(test_line_id, 'LDA $f')
        self.assertEqual(pi1.byte_size, 1, 'assembled instruciton is 1 byte')
        self.assertEqual(pi1.get_bytes(TestConfigObject.label_values),
                         bytearray([0x1F]), 'assembled instruction')

        pi2 = model1.parse_instruction(test_line_id, 'add label1+5')
        self.assertEqual(pi2.byte_size, 1, 'assembled instruciton is 1 byte')
        self.assertEqual(pi2.get_bytes(TestConfigObject.label_values),
                         bytearray([0x27]), 'assembled instruction')

        pi3 = model1.parse_instruction(test_line_id, 'out')
        self.assertEqual(pi3.byte_size, 1, 'assembled instruciton is 1 byte')
        self.assertEqual(pi3.get_bytes(TestConfigObject.label_values),
                         bytearray([0xE0]), 'assembled instruction')

        with pkg_resources.path(config_files,
                                'register_argument_exmaple_config.yaml') as fp:
            model2 = AssemblerModel(str(fp), 0)

        piA = model2.parse_instruction(LineIdentifier(1, 'test_mov_a_i'),
                                       'mov a, i')
        self.assertEqual(piA.byte_size, 1, 'assembled instruciton is 1 byte')
        self.assertEqual(list(piA.get_bytes(TestConfigObject.label_values)),
                         [0b01000010], 'assembled instruction')

        piB = model2.parse_instruction(test_line_id, 'mov a,[$1120 + label1]')
        self.assertEqual(piB.byte_size, 3, 'assembled instruciton is 3 byte')
        self.assertEqual(piB.get_bytes(TestConfigObject.label_values),
                         bytearray([0b01000110, 0x22, 0x11]),
                         'assembled instruction')

        piC = model2.parse_instruction(test_line_id, 'add i')
        self.assertEqual(piC.byte_size, 1, 'assembled instruciton is 1 byte')
        self.assertEqual(piC.get_bytes(TestConfigObject.label_values),
                         bytearray([0b10111010]), 'assembled instruction')

        piD = model2.parse_instruction(
            test_line_id, 'mov [$110D + (label1 + LABEL2)] , 0x88')
        self.assertEqual(piD.byte_size, 4, 'assembled instruciton is 4 byte')
        self.assertEqual(piD.get_bytes(TestConfigObject.label_values),
                         bytearray([0b01110111, 0x88, 0xFF, 0x11]),
                         'arguments should be in reverse order')

        piE = model2.parse_instruction(test_line_id,
                                       'mov [sp - label1] , 0x88')
        self.assertEqual(piE.byte_size, 3, 'assembled instruciton is 3 byte')
        self.assertEqual(piE.get_bytes(TestConfigObject.label_values),
                         bytearray([0b01101111, 0x88, 0b11111110]),
                         'arguments should be in reverse order')

        piF = model2.parse_instruction(test_line_id, 'mov [sp+label1] , 0x88')
        self.assertEqual(piF.byte_size, 3, 'assembled instruciton is 3 byte')
        self.assertEqual(piF.get_bytes(TestConfigObject.label_values),
                         bytearray([0b01101111, 0x88, 2]),
                         'arguments should be in reverse order')

        piG = model2.parse_instruction(test_line_id, 'mov [sp] , 0x88')
        self.assertEqual(piG.byte_size, 3, 'assembled instruciton is 3 byte')
        self.assertEqual(piG.get_bytes(TestConfigObject.label_values),
                         bytearray([0b01101111, 0x88, 0]),
                         'arguments should be in reverse order')

        piH = model2.parse_instruction(test_line_id, 'mov [$8000], [label1]')
        self.assertEqual(piH.byte_size, 5, 'assembled instruciton is 5 byte')
        self.assertEqual(piH.get_bytes(TestConfigObject.label_values),
                         bytearray([0b01110110, 2, 0, 0, 0x80]),
                         'arguments should be in reverse order')

        piI = model2.parse_instruction(test_line_id, 'mov [mar], [label1]')
        self.assertEqual(piI.byte_size, 3, 'assembled instruciton is 3 byte')
        self.assertEqual(piI.get_bytes(TestConfigObject.label_values),
                         bytearray([0b01100110, 2, 0]),
                         'no offset should be emitted for [mar]')

        piJ = model2.parse_instruction(test_line_id, 'swap [$8000], [label1]')
        self.assertEqual(piJ.byte_size, 5, 'assembled instruciton is 3 byte')
        self.assertEqual(piJ.get_bytes(TestConfigObject.label_values),
                         bytearray([0b11110110, 0, 0x80, 2, 0]),
                         'arguments should NOT be in reverse order')

        piK = model2.parse_instruction(test_line_id, 'mov [sp+2], [sp+4]')
        self.assertEqual(piK.byte_size, 3, 'assembled instruciton is 3 byte')
        self.assertEqual(piK.get_bytes(TestConfigObject.label_values),
                         bytearray([0b01101101, 4, 2]),
                         'arguments should be in reverse order')

        piL = model2.parse_instruction(test_line_id, 'pop i')
        self.assertEqual(piL.byte_size, 1, 'assembled instruciton is 1 byte')
        self.assertEqual(list(piL.get_bytes(TestConfigObject.label_values)),
                         [0b00001010], 'pop to i')

        piM = model2.parse_instruction(
            LineIdentifier(158, 'test_pop_empty_arg'), 'pop')
        self.assertEqual(piM.byte_size, 1, 'assembled instruciton is 1 byte')
        self.assertEqual(piM.get_bytes(TestConfigObject.label_values),
                         bytearray([0b00001111]), 'just pop')

        piN = model2.parse_instruction(test_line_id, 'mov a, [sp+2]')
        self.assertEqual(piN.byte_size, 2, 'assembled instruciton is 2 byte')
        self.assertEqual(piN.get_bytes(TestConfigObject.label_values),
                         bytearray([0b01000101, 2]), 'just move [sp+2] into a')

        with self.assertRaises(
                SystemExit,
                msg='should error on unallowed operand combinations'):
            model2.parse_instruction(test_line_id, 'mov a, a')
        with self.assertRaises(SystemExit, msg='[mar] should have no offset'):
            model2.parse_instruction(test_line_id, 'mov [mar+2], [label1]')
        with self.assertRaises(SystemExit,
                               msg='should error due to too many operands'):
            model2.parse_instruction(test_line_id, 'mov a, i, j')
        with self.assertRaises(SystemExit,
                               msg='should error due to too many operands'):
            model2.parse_instruction(test_line_id, 'nop 123')
        with self.assertRaises(SystemExit,
                               msg='should error due to too few operands'):
            model2.parse_instruction(test_line_id, 'mov a')
Esempio n. 17
0
 def test_min_required_version(self):
     with pkg_resources.path(config_files,
                             'test_min_required_version_config.yaml') as fp:
         with self.assertRaises(SystemExit,
                                msg='the min version check should fail'):
             model = AssemblerModel(str(fp), 0)
    def test_instruction_variant_matching(self):
        with pkg_resources.path(config_files,
                                'test_instructions_with_variants.yaml') as fp:
            isa_model = AssemblerModel(str(fp), 0)

        # start simple
        ins1 = InstructionLine.factory(22, '  nop', 'some comment!', isa_model)
        ins1.set_start_address(1212)
        self.assertIsInstance(ins1, InstructionLine)
        self.assertEqual(ins1.byte_size, 1, 'has 1 byte')
        ins1.label_scope = TestInstructionParsing.label_values
        ins1.generate_bytes()
        self.assertEqual(ins1.get_bytes(), bytearray([0x00]),
                         'instruction should match')

        # match default variant operand sets
        ins2 = InstructionLine.factory(22, '  mov a, [sp+2]', 'some comment!',
                                       isa_model)
        ins2.set_start_address(1212)
        self.assertIsInstance(ins2, InstructionLine)
        self.assertEqual(ins2.byte_size, 2, 'has 2 byte')
        ins2.label_scope = TestInstructionParsing.label_values
        ins2.generate_bytes()
        self.assertEqual(ins2.get_bytes(), bytearray([0x44, 0x02]),
                         'instruction should match')

        # match default variant specific operand
        ins3 = InstructionLine.factory(22, '  mov a, [hl+6]', 'some comment!',
                                       isa_model)
        ins3.set_start_address(1212)
        self.assertIsInstance(ins3, InstructionLine)
        self.assertEqual(ins3.byte_size, 2, 'has 2 byte')
        ins3.label_scope = TestInstructionParsing.label_values
        ins3.generate_bytes()
        self.assertEqual(ins3.get_bytes(), bytearray([0x45, 0x06]),
                         'instruction should match')

        # match first variant
        ins4 = InstructionLine.factory(22, '  mov a, h', 'some comment!',
                                       isa_model)
        ins4.set_start_address(1212)
        self.assertIsInstance(ins4, InstructionLine)
        self.assertEqual(ins4.byte_size, 1, 'has 1 byte')
        ins4.label_scope = TestInstructionParsing.label_values
        ins4.generate_bytes()
        self.assertEqual(ins4.get_bytes(), bytearray([0x81]),
                         'instruction should match')

        # match second variant
        ins5 = InstructionLine.factory(22, '  mov h, $88', 'some comment!',
                                       isa_model)
        ins5.set_start_address(1212)
        self.assertIsInstance(ins5, InstructionLine)
        self.assertEqual(ins5.byte_size, 2, 'has 2 byte')
        ins5.label_scope = TestInstructionParsing.label_values
        ins5.generate_bytes()
        self.assertEqual(ins5.get_bytes(), bytearray([0x9F, 0x88]),
                         'instruction should match')

        # match no variant
        with self.assertRaises(SystemExit,
                               msg='no instruction variant should match here'):
            InstructionLine.factory(22, '  mov h, l', 'some comment!',
                                    isa_model)

        with self.assertRaises(SystemExit,
                               msg='no instruction variant should match here'):
            InstructionLine.factory(22, '  mov 27', 'some comment!', isa_model)