aboutsummaryrefslogtreecommitdiffstats
path: root/subx.py
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-05-28 12:42:14 +0000
committers-ol <s-ol@users.noreply.github.com>2020-05-28 12:42:14 +0000
commit95d8b69c68a17cf3fbcfb6d9f4752c9a90e9da69 (patch)
tree2083ed2af86124e9ddbf4811a5b7650d0a43f893 /subx.py
parentdisassembly helper (diff)
downloadsubv-95d8b69c68a17cf3fbcfb6d9f4752c9a90e9da69.tar.gz
subv-95d8b69c68a17cf3fbcfb6d9f4752c9a90e9da69.zip
tests, cleanup, verify.py
Diffstat (limited to 'subx.py')
-rw-r--r--subx.py102
1 files changed, 78 insertions, 24 deletions
diff --git a/subx.py b/subx.py
index 53f72ce..ed3b184 100644
--- a/subx.py
+++ b/subx.py
@@ -1,40 +1,94 @@
import re
white = re.compile('[ \t\.\n]+')
-hex = re.compile('^(0x)?[0-9a-f]+$')
+hex = re.compile(r'^\-?(0x)?[0-9a-f]+$')
def parse_part(part):
- part = part.split('/')
- if hex.match(part[0]):
- part[0] = int(part[0], 16)
- return tuple(part)
+ part = part.split('/')
+ if hex.match(part[0]):
+ part[0] = int(part[0], 16)
+ return tuple(part)
def parse_instr(line):
- parts = white.split(line)
- parts = [parse_part(part) for part in parts if part != '']
- return parts
+ parts = white.split(line)
+ parts = [parse_part(part) for part in parts if part != '']
+ return parts
def parse_segment(line):
- parts = white.split(line)
- return (parts[1], int(parts[2], 16))
+ parts = white.split(line)
+ return (parts[1], int(parts[2], 16))
+
+def is_lref(part):
+ return isinstance(part[0], str)
+
+def unlabel(part, expect=None):
+ if expect and part[1] != expect:
+ raise ValueError("expected {} to be labelled {}", part, expect)
+ return part[0]
def format_part(part):
- if not isinstance(part[0], str):
- part = ('{:02x}'.format(part[0]),) + part[1:]
- return '/'.join(part)
+ if not is_lref(part):
+ first = '{:02x}'.format(part[0])
+ part = (first,) + part[1:]
+ return '/'.join([str(p) for p in part])
def format_instr(inst, comment=None):
- packed = ' '.join(format_part(part) for part in inst)
- if comment:
- packed = packed + ' # ' + comment
- return packed
+ packed = ' '.join(format_part(part) for part in inst)
+ if comment:
+ packed = packed + ' # ' + comment
+ return packed
def clean(line):
- return line.strip().split('#')[0]
+ return line.strip().split('#')[0]
def classify(line):
- if line.startswith('=='): # segment
- return 'segment'
- elif line.endswith(':'): # label
- return 'label'
- else:
- return 'instr'
+ if line.startswith('=='): # segment
+ return 'segment'
+ elif line.endswith(':'): # label
+ return 'label'
+ else:
+ return 'instr'
+
+import unittest
+class TestParsing(unittest.TestCase):
+ def test_parse_part(self):
+ self.assertEqual(parse_part('0'), (0,))
+ self.assertEqual(parse_part('00'), (0,))
+ self.assertEqual(parse_part('0x00'), (0,))
+
+ self.assertEqual(parse_part('12'), (0x12,))
+ self.assertEqual(parse_part('0x12'), (0x12,))
+
+ self.assertEqual(parse_part('-12'), (-0x12,))
+ self.assertEqual(parse_part('-0x12'), (-0x12,))
+
+ self.assertEqual(parse_part('00/with/tag'), (0, 'with', 'tag'))
+ self.assertEqual(parse_part('-12/and<</tag*'), (-0x12, 'and<<', 'tag*'))
+
+ self.assertEqual(parse_part('label/tag*'), ('label', 'tag*'))
+ self.assertEqual(parse_part('$label/tag*'), ('$label', 'tag*'))
+ self.assertEqual(parse_part('label:suff/tag*'), ('label:suff', 'tag*'))
+ self.assertEqual(parse_part('$label:suff/tag*'), ('$label:suff', 'tag*'))
+
+class TestChecks(unittest.TestCase):
+ def test_is_lref(self):
+ self.assertTrue(is_lref(('hello',)))
+ self.assertTrue(is_lref(('hello:world',)))
+ self.assertTrue(is_lref(('$label',)))
+ self.assertTrue(is_lref(('$label:extra',)))
+ self.assertTrue(is_lref(('$label:extra','disp20u')))
+ self.assertTrue(is_lref(('plain','disp20u')))
+
+ self.assertFalse(is_lref((0,)))
+ self.assertFalse(is_lref((1,)))
+ self.assertFalse(is_lref((1,'disp20u')))
+ self.assertFalse(is_lref((0x13f,'imm12')))
+
+class TestFormatting(unittest.TestCase):
+ def test_format_part(self):
+ self.assertEqual(format_part((0,)), '00')
+ self.assertEqual(format_part((0x00,)), '00')
+
+ self.assertEqual(format_part(('label', 'tag*')), 'label/tag*')
+ self.assertEqual(format_part(('$label', 'tag*')), '$label/tag*')
+ self.assertEqual(format_part(('label:suff', 'tag')), 'label:suff/tag')
+ self.assertEqual(format_part(('$label:suff', 'tag')), '$label:suff/tag')