Skip to content

Commit

Permalink
Add public_labels, test of labels
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jepler committed Sep 20, 2024
1 parent 5e7678e commit b746aec
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
18 changes: 16 additions & 2 deletions adafruit_pioasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"""

try:
from typing import List, MutableSequence
from typing import List, Sequence, Any
except ImportError:
pass

Expand Down Expand Up @@ -55,12 +55,20 @@ class Program: # pylint: disable=too-few-public-methods
"""

assembled: array.array
"""The assembled PIO program instructions"""
public_labels: dict[str, int]
"""The offset of any labels delcared public"""
pio_kwargs: dict[str, Any]
"""Settings from assembler directives to pass to the StateMachine constructor"""

def __init__(self, text_program: str, *, build_debuginfo: bool = False) -> None:
"""Converts pioasm text to encoded instruction bytes"""
# pylint: disable=too-many-branches,too-many-statements,too-many-locals
assembled: List[int] = []
program_name = None
labels = {}
public_labels = {}
linemap = []
instructions: List[str] = []
sideset_count = 0
Expand Down Expand Up @@ -219,6 +227,9 @@ def parse_rxfifo_brackets(arg, fifo_dir):

elif line.endswith(":"):
label = line[:-1]
if line.startswith("public "):
label = label[7:]
public_labels[label] = len(instructions)
if label in labels:
raise SyntaxError(f"Duplicate label {repr(label)}")
labels[label] = len(instructions)
Expand All @@ -227,6 +238,7 @@ def parse_rxfifo_brackets(arg, fifo_dir):
instructions.append(line)
linemap.append(i)

mov_destinations: Sequence[str | None]
if pio_version >= 1:
mov_destinations = MOV_DESTINATIONS_V1
else:
Expand Down Expand Up @@ -502,6 +514,8 @@ def parse_rxfifo_brackets(arg, fifo_dir):

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

self.public_labels = public_labels

@classmethod
def from_file(cls, filename: str, **kwargs) -> "Program":
"""Assemble a PIO program in a file"""
Expand Down Expand Up @@ -557,7 +571,7 @@ def print_c_program(self, name: str, qualifier: str = "const") -> None:
print()


def assemble(program_text: str) -> MutableSequence[int]:
def assemble(program_text: str) -> array.array:
"""Converts pioasm text to encoded instruction bytes
In new code, prefer to use the `Program` class so that the extra arguments
Expand Down
63 changes: 63 additions & 0 deletions tests/test_label.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# SPDX-FileCopyrightText: 2024 Jeff Epler for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
Tests out
"""

from pytest_helpers import assert_assembly_fails
import adafruit_pioasm


def test_label() -> None:
source = [
" jmp label1",
"label1:",
" jmp label2",
"public label2:",
" nop",
]
program = adafruit_pioasm.Program("\n".join(source))
assert program.public_labels == {"label2": 2}

# Test each combination of public/privagte label duplication
source = [
"label1:\n",
"nop\n",
"public label1:\n",
"nop\n",
]
assert_assembly_fails(
"\n".join(source), match="Duplicate label", errtype=SyntaxError
)

source = [
"label1:\n",
" nop\n",
"label1:\n",
" nop\n",
]
assert_assembly_fails(
"\n".join(source), match="Duplicate label", errtype=SyntaxError
)

source = [
"public label1:\n",
" nop\n",
"label1:\n",
" nop\n",
]
assert_assembly_fails(
"\n".join(source), match="Duplicate label", errtype=SyntaxError
)

source = [
"public label1:\n",
" nop\n",
"public label1:\n",
" nop\n",
]
assert_assembly_fails(
"\n".join(source), match="Duplicate label", errtype=SyntaxError
)

0 comments on commit b746aec

Please sign in to comment.