Skip to content

Releases: avwohl/uplm80

v0.3.1

Choose a tag to compare

@avwohl avwohl released this 30 Jun 19:22

Bug-fix release.

#7 — codegen crash on struct-member comparisons. _check_impossible_comparison crashed ('BinaryOpKind' object has no attribute 'kind') after the uplox typed-AST migration, and _get_expr_type typed every STRUCTURE member as BYTE — so an ADDRESS member compared to a 16-bit constant (e.g. rec.len <= 1025) crashed and otherwise mis-compiled to 8-bit ops. Both fixed; ADDRESS members now compile to 16-bit comparisons. Clears 3 of the 15 link_3.0 modules in ogdenpm/intel80tools that previously crashed.

#6 — PL/M-80 v4.0 conditional compilation. Conditionals are left-margin $ control lines ($IF/$ELSEIF/$ELSE/$ENDIF/$SET/$RESET) and no longer require a $COND; $COND/$NOCOND are accepted as listing-only no-ops. Added $ELSEIF. The /** $… **/ comment form is still accepted.

Thanks to @ogdenpm for both reports.

uplm80 0.3.0 — TokenKind migration

Choose a tag to compare

@avwohl avwohl released this 25 May 11:03

TokenKind migration (0.3.0)

Aligns uplm80 with uplox 3.2.0's per-grammar TokenKind IntEnum.
PL/M-80 codegen's hot paths now do tok.kind is K.X identity
compares instead of byte-by-byte string equality on tok.name.

Changed

  • _plm_parser.py regenerated against uplox 3.2.0's emitter.
    Picks up K = build_token_kind(_tokens) (a PlmFullTokenKind
    IntEnum) and the kind_map-stamped Scanner. K is exported
    in __all__.
  • ast_view.binop_kind / unop_kind moved off tok.op.name
    string compares onto tok.op.kind K identity. The
    _BINOP_TOKEN_TO_KIND dict is now K-keyed.
  • ast_view.proc_return_type uses K.KW_BYTE / K.KW_ADDRESS
    identity compares.
  • codegen BYTE-comparison constant-fold moves off op.name
    to op.kind; new module-level _BYTE_EQ_KINDS = {K.EQ, K.NE}
    frozenset.
  • _SynthToken carries kind: int so optimizer-built nodes
    round-trip through binop_kind / unop_kind. Fixes a regression
    where every constant-folded BinaryOp crashed binop_kind with a
    KeyError.

Migration

Bumps minimum uplox to 3.2.0. No PL/M source-level changes — the
plm_full grammar is unchanged, only the compiler internals moved
to the int-kind fast path.

v0.2.32

Choose a tag to compare

@avwohl avwohl released this 23 May 11:24

Patch release: switch parser/lexer to uplox, consume typed AST directly. Drop redundant 0100H origin from hellocpm example. Pin upeepz80>=0.2.3, uplox>=3.1.1.

v0.2.31

Choose a tag to compare

@avwohl avwohl released this 09 May 12:02

Ship the bundled data/plm_full.json JSON in the wheel.

The 0.2.30 wheel only declared py.typed in [tool.setuptools.package-data], so the JSON bundle that the plox-driven frontend loads at import time was missing from the published artifact. Fresh pip install users hit FileNotFoundError on uplm80/data/plm_full.json the moment they tried to compile anything (editable installs from a checkout were unaffected). Adds data/*.json to package-data.

Same defect existed in uc_core 0.3.1; fixed in parallel as uc_core 0.3.2.

v0.2.30

Choose a tag to compare

@avwohl avwohl released this 09 May 11:57

Changes

  • Switched frontend imports from plox.* to uplox.* (the upstream parser-generator project was renamed end-to-end; see uplox 3.0.0 release notes).
  • Declares the runtime dependency on uplox>=3.0.0 in pyproject.toml — frontend.py already imported plox at runtime, but the dep was undeclared. Fixed as part of this rename.
  • Regenerated bundled data/plm_full.json from examples/plm_full.uplox so the bundle's uplox_schema key matches the new runtime check.
  • Minor docstring text updates in compiler.py / preprocess.py mentioning the upstream by its new name.

19 pytest pass; 22/0/0 cpmemu execution suite.

v0.2.29

Choose a tag to compare

@avwohl avwohl released this 09 May 11:04

Codegen bug fixes

  • DJNZ-loop GOTO stack corruption. The DJNZ-converted loop pushed BC at the top of each iteration and popped it at the bottom — but a GOTO escaping the body jumped over the pop, stranding 2 bytes on the stack. Every subsequent CALL/RET in the same procedure then ran with a corrupted return address. Now the DJNZ optimization is gated on a body-contains-GOTO walk; loops with GOTO fall back to the non-DJNZ path that doesn't push state across iterations.
  • DE register clobbered across opaque calls in binary expressions. _gen_binary paths 2 and 3 kept one operand alive in DE across evaluation of the other operand, relying on the register allocator to spill DE if needed. That works for nested binary expressions but not for opaque callees, which mutate DE behind the allocator's back. Spill to the SP stack instead when the unevaluated subtree contains a procedure call (using _expr_preserves_de). Two execution-test cases turned green from this one fix.

Cleanup

  • Dead 8080 codegen branches removed; single-member Target enum and unused target parameter plumbing dropped from CodeGenerator / Compiler / generate / CLI.
  • Stale 8080 docs cleaned up: pyproject description, package docstrings, INSTALL.md (incl. removed bogus -t {z80,8080} flag), README_RASPBERRY_PI.md.
  • README "Project Structure" refreshed for the plox front-end + upeepz80 peephole split (no longer lists lexer.py / parser.py / peephole.py).
  • requires-python relaxed from >=3.11 to >=3.10.

Test fixes

  • test_array_bug: replaced the unresolved EXTERNAL declaration with a local stub so the test now links standalone (it was always meant as a codegen regression test, not an end-to-end run).
  • Misleading SCL/SCR expected-value comments in test_byte_shifts corrected (SCL/SCR are rotate-through-carry, not logical shifts).
  • Orphan tests/test_expected.txt removed (was producing a spurious SKIPPED line).

Test results

pytest tests/ 19/19, compile_tests.sh 30/30, run_tests.sh (cpmemu) 22 passed / 0 failed / 0 skipped.

v0.2.26

Choose a tag to compare

@avwohl avwohl released this 07 Jan 13:22

Auto-truncate BYTE comparisons with negative byte constants (-1 through -256)