Skip to content

Add public_labels, test of labels #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
)