Skip to content

Commit b746aec

Browse files
committed
Add public_labels, test of labels
Now, a label declared with `public foo:` will be exported in the `public_labels` property of `Program` objects. Additionally, a test of this feature as well as the existing duplicate label detection feature is added. Change the return type of `assemble` so that it better reflects reality Add docstrings for the public properties of Program objects
1 parent 5e7678e commit b746aec

File tree

2 files changed

+79
-2
lines changed

2 files changed

+79
-2
lines changed

Diff for: adafruit_pioasm.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"""
1313

1414
try:
15-
from typing import List, MutableSequence
15+
from typing import List, Sequence, Any
1616
except ImportError:
1717
pass
1818

@@ -55,12 +55,20 @@ class Program: # pylint: disable=too-few-public-methods
5555
5656
"""
5757

58+
assembled: array.array
59+
"""The assembled PIO program instructions"""
60+
public_labels: dict[str, int]
61+
"""The offset of any labels delcared public"""
62+
pio_kwargs: dict[str, Any]
63+
"""Settings from assembler directives to pass to the StateMachine constructor"""
64+
5865
def __init__(self, text_program: str, *, build_debuginfo: bool = False) -> None:
5966
"""Converts pioasm text to encoded instruction bytes"""
6067
# pylint: disable=too-many-branches,too-many-statements,too-many-locals
6168
assembled: List[int] = []
6269
program_name = None
6370
labels = {}
71+
public_labels = {}
6472
linemap = []
6573
instructions: List[str] = []
6674
sideset_count = 0
@@ -219,6 +227,9 @@ def parse_rxfifo_brackets(arg, fifo_dir):
219227

220228
elif line.endswith(":"):
221229
label = line[:-1]
230+
if line.startswith("public "):
231+
label = label[7:]
232+
public_labels[label] = len(instructions)
222233
if label in labels:
223234
raise SyntaxError(f"Duplicate label {repr(label)}")
224235
labels[label] = len(instructions)
@@ -227,6 +238,7 @@ def parse_rxfifo_brackets(arg, fifo_dir):
227238
instructions.append(line)
228239
linemap.append(i)
229240

241+
mov_destinations: Sequence[str | None]
230242
if pio_version >= 1:
231243
mov_destinations = MOV_DESTINATIONS_V1
232244
else:
@@ -502,6 +514,8 @@ def parse_rxfifo_brackets(arg, fifo_dir):
502514

503515
self.debuginfo = (linemap, text_program) if build_debuginfo else None
504516

517+
self.public_labels = public_labels
518+
505519
@classmethod
506520
def from_file(cls, filename: str, **kwargs) -> "Program":
507521
"""Assemble a PIO program in a file"""
@@ -557,7 +571,7 @@ def print_c_program(self, name: str, qualifier: str = "const") -> None:
557571
print()
558572

559573

560-
def assemble(program_text: str) -> MutableSequence[int]:
574+
def assemble(program_text: str) -> array.array:
561575
"""Converts pioasm text to encoded instruction bytes
562576
563577
In new code, prefer to use the `Program` class so that the extra arguments

Diff for: tests/test_label.py

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# SPDX-FileCopyrightText: 2024 Jeff Epler for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
"""
6+
Tests out
7+
"""
8+
9+
from pytest_helpers import assert_assembly_fails
10+
import adafruit_pioasm
11+
12+
13+
def test_label() -> None:
14+
source = [
15+
" jmp label1",
16+
"label1:",
17+
" jmp label2",
18+
"public label2:",
19+
" nop",
20+
]
21+
program = adafruit_pioasm.Program("\n".join(source))
22+
assert program.public_labels == {"label2": 2}
23+
24+
# Test each combination of public/privagte label duplication
25+
source = [
26+
"label1:\n",
27+
"nop\n",
28+
"public label1:\n",
29+
"nop\n",
30+
]
31+
assert_assembly_fails(
32+
"\n".join(source), match="Duplicate label", errtype=SyntaxError
33+
)
34+
35+
source = [
36+
"label1:\n",
37+
" nop\n",
38+
"label1:\n",
39+
" nop\n",
40+
]
41+
assert_assembly_fails(
42+
"\n".join(source), match="Duplicate label", errtype=SyntaxError
43+
)
44+
45+
source = [
46+
"public label1:\n",
47+
" nop\n",
48+
"label1:\n",
49+
" nop\n",
50+
]
51+
assert_assembly_fails(
52+
"\n".join(source), match="Duplicate label", errtype=SyntaxError
53+
)
54+
55+
source = [
56+
"public label1:\n",
57+
" nop\n",
58+
"public label1:\n",
59+
" nop\n",
60+
]
61+
assert_assembly_fails(
62+
"\n".join(source), match="Duplicate label", errtype=SyntaxError
63+
)

0 commit comments

Comments
 (0)