Skip to content

Commit f7dfddc

Browse files
committed
move parse_int to util module
remove duplication
1 parent 23f8ab4 commit f7dfddc

File tree

6 files changed

+62
-91
lines changed

6 files changed

+62
-91
lines changed

esp32_ulp/opcodes.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from uctypes import struct, addressof, LITTLE_ENDIAN, UINT32, BFUINT32, BF_POS, BF_LEN
1414

1515
from .soc import *
16-
from .util import split_tokens, validate_expression
16+
from .util import split_tokens, validate_expression, parse_int
1717

1818
# XXX dirty hack: use a global for the symbol table
1919
symbols = None
@@ -297,26 +297,6 @@ def eval_arg(arg):
297297
return eval(parts)
298298

299299

300-
def parse_int(literal):
301-
"""
302-
Parses string literals into integers, using base prefixes
303-
0x (hex), 0b (binary), and 0o or legacy 0NNN (octal).
304-
Without prefix will be treated as decimal.
305-
"""
306-
if len(literal) > 2:
307-
prefix_start = 1 if literal[0] == '-' else 0 # skip negative sign if present
308-
309-
if literal[prefix_start] == "0":
310-
prefix = literal[prefix_start + 1]
311-
if prefix == "x":
312-
return int(literal, 16)
313-
elif prefix == "b":
314-
return int(literal, 2)
315-
return int(literal, 8) # legacy octal (e.g. 077)
316-
317-
return int(literal) # implicit base10
318-
319-
320300
def arg_qualify(arg):
321301
"""
322302
look at arg and qualify its type:

esp32_ulp/opcodes_s2.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from ucollections import namedtuple
1313
from uctypes import struct, addressof, LITTLE_ENDIAN, UINT32, BFUINT32, BF_POS, BF_LEN
1414

15-
from .util import split_tokens, validate_expression
15+
from .util import split_tokens, validate_expression, parse_int
1616

1717
# XXX dirty hack: use a global for the symbol table
1818
symbols = None
@@ -313,26 +313,6 @@ def eval_arg(arg):
313313
return eval(parts)
314314

315315

316-
def parse_int(literal):
317-
"""
318-
Parses string literals into integers, using base prefixes
319-
0x (hex), 0b (binary), and 0o or legacy 0NNN (octal).
320-
Without prefix will be treated as decimal.
321-
"""
322-
if len(literal) > 2:
323-
prefix_start = 1 if literal[0] == '-' else 0 # skip negative sign if present
324-
325-
if literal[prefix_start] == "0":
326-
prefix = literal[prefix_start + 1]
327-
if prefix == "x":
328-
return int(literal, 16)
329-
elif prefix == "b":
330-
return int(literal, 2)
331-
return int(literal, 8) # legacy octal (e.g. 077)
332-
333-
return int(literal) # implicit base10
334-
335-
336316
def arg_qualify(arg):
337317
"""
338318
look at arg and qualify its type:

esp32_ulp/util.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,28 @@ def validate_expression(param):
7777
return True
7878

7979

80+
def parse_int(literal):
81+
"""
82+
Parses string literals into integers, using base prefixes
83+
0xNNN (hex), 0bNNN (binary), and 0oNNN or 0NNN (octal).
84+
Without prefix will be treated as decimal.
85+
"""
86+
if len(literal) > 2:
87+
prefix_start = 1 if literal[0] == '-' else 0 # skip negative sign if present
88+
89+
if literal[prefix_start] == "0":
90+
prefix = literal[prefix_start + 1]
91+
if prefix == "x": # Hex
92+
return int(literal, 16)
93+
elif prefix == "b": # Binary
94+
return int(literal, 2)
95+
elif prefix == "o": # Octal, Python style (0bNNN)
96+
return int(literal, 8)
97+
return int(literal, 8) # Octal, GNU as style (0NNN)
98+
99+
return int(literal) # implicit decimal (base10)
100+
101+
80102
def file_exists(filename):
81103
try:
82104
os.stat(filename)

tests/opcodes.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,6 @@ def test_make_ins():
3939
assert _delay.all == 0x40000023
4040

4141

42-
def test_parse_int():
43-
# decimal
44-
assert parse_int("5") == 5, "5 == 5"
45-
assert parse_int("-5") == -5, "-5 == -5"
46-
# hex
47-
assert parse_int("0x5") == 5, "0x5 == 5"
48-
assert parse_int("0x5a") == 90, "0x5a == 90"
49-
assert parse_int("-0x5a") == -90, "-0x5a == -90"
50-
# binary
51-
assert parse_int("0b1001") == 9, "0b1001 == 9"
52-
assert parse_int("-0b1001") == -9, "-0b1001 == 9"
53-
# octal
54-
assert parse_int("0100") == 64, "0100 == 64"
55-
assert parse_int("0o210") == 136, "0o210 == 136"
56-
assert parse_int("-0100") == -64, "-0100 == -64"
57-
assert parse_int("-0o210") == -136, "-0o210 == -136"
58-
# negative cases
59-
assert_raises(ValueError, parse_int, '0b123', message="invalid syntax for integer with base 2: '123'")
60-
assert_raises(ValueError, parse_int, '0900', message="invalid syntax for integer with base 8: '0900'")
61-
assert_raises(ValueError, parse_int, '0o900', message="invalid syntax for integer with base 8: '900'")
62-
assert_raises(ValueError, parse_int, '0xg', message="invalid syntax for integer with base 16: 'g'")
63-
64-
6542
def test_arg_qualify():
6643
assert arg_qualify('r0') == ARG(REG, 0, 'r0')
6744
assert arg_qualify('R3') == ARG(REG, 3, 'R3')
@@ -240,7 +217,6 @@ def test_reg_address_translations_sens():
240217

241218
test_make_ins_struct_def()
242219
test_make_ins()
243-
test_parse_int()
244220
test_arg_qualify()
245221
test_get_reg()
246222
test_get_imm()

tests/opcodes_s2.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,6 @@ def test_make_ins():
3939
assert _delay.all == 0x40000023
4040

4141

42-
def test_parse_int():
43-
# decimal
44-
assert parse_int("5") == 5, "5 == 5"
45-
assert parse_int("-5") == -5, "-5 == -5"
46-
# hex
47-
assert parse_int("0x5") == 5, "0x5 == 5"
48-
assert parse_int("0x5a") == 90, "0x5a == 90"
49-
assert parse_int("-0x5a") == -90, "-0x5a == -90"
50-
# binary
51-
assert parse_int("0b1001") == 9, "0b1001 == 9"
52-
assert parse_int("-0b1001") == -9, "-0b1001 == 9"
53-
# octal
54-
assert parse_int("0100") == 64, "0100 == 64"
55-
assert parse_int("0o210") == 136, "0o210 == 136"
56-
assert parse_int("-0100") == -64, "-0100 == -64"
57-
assert parse_int("-0o210") == -136, "-0o210 == -136"
58-
# negative cases
59-
assert_raises(ValueError, parse_int, '0b123', message="invalid syntax for integer with base 2: '123'")
60-
assert_raises(ValueError, parse_int, '0900', message="invalid syntax for integer with base 8: '0900'")
61-
assert_raises(ValueError, parse_int, '0o900', message="invalid syntax for integer with base 8: '900'")
62-
assert_raises(ValueError, parse_int, '0xg', message="invalid syntax for integer with base 16: 'g'")
63-
64-
6542
def test_arg_qualify():
6643
assert arg_qualify('r0') == ARG(REG, 0, 'r0')
6744
assert arg_qualify('R3') == ARG(REG, 3, 'R3')
@@ -290,7 +267,6 @@ def test_reg_address_translations_s3_sens():
290267

291268
test_make_ins_struct_def()
292269
test_make_ins()
293-
test_parse_int()
294270
test_arg_qualify()
295271
test_get_reg()
296272
test_get_imm()

tests/util.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# SPDX-License-Identifier: MIT
77

88
import os
9-
from esp32_ulp.util import split_tokens, validate_expression, file_exists
9+
from esp32_ulp.util import split_tokens, validate_expression, parse_int, file_exists
1010

1111
tests = []
1212

@@ -18,6 +18,19 @@ def test(param):
1818
tests.append(param)
1919

2020

21+
def assert_raises(exception, func, *args, message=None):
22+
try:
23+
func(*args)
24+
except exception as e:
25+
raised = True
26+
actual_message = e.args[0]
27+
else:
28+
raised = False
29+
assert raised
30+
if message:
31+
assert actual_message == message, '%s == %s' % (actual_message, message)
32+
33+
2134
@test
2235
def test_split_tokens():
2336
assert split_tokens("") == []
@@ -69,6 +82,30 @@ def test_validate_expression():
6982
assert validate_expression('def CAFE()') is False
7083

7184

85+
@test
86+
def test_parse_int():
87+
# decimal
88+
assert parse_int("5") == 5, "5 == 5"
89+
assert parse_int("-5") == -5, "-5 == -5"
90+
# hex
91+
assert parse_int("0x5") == 5, "0x5 == 5"
92+
assert parse_int("0x5a") == 90, "0x5a == 90"
93+
assert parse_int("-0x5a") == -90, "-0x5a == -90"
94+
# binary
95+
assert parse_int("0b1001") == 9, "0b1001 == 9"
96+
assert parse_int("-0b1001") == -9, "-0b1001 == 9"
97+
# octal
98+
assert parse_int("0100") == 64, "0100 == 64"
99+
assert parse_int("0o210") == 136, "0o210 == 136"
100+
assert parse_int("-0100") == -64, "-0100 == -64"
101+
assert parse_int("-0o210") == -136, "-0o210 == -136"
102+
# negative cases
103+
assert_raises(ValueError, parse_int, '0b123', message="invalid syntax for integer with base 2: '123'")
104+
assert_raises(ValueError, parse_int, '0900', message="invalid syntax for integer with base 8: '0900'")
105+
assert_raises(ValueError, parse_int, '0o900', message="invalid syntax for integer with base 8: '900'")
106+
assert_raises(ValueError, parse_int, '0xg', message="invalid syntax for integer with base 16: 'g'")
107+
108+
72109
@test
73110
def test_file_exists():
74111
testfile = '.testfile'

0 commit comments

Comments
 (0)