Tags: avwohl/mbasic
Tags
Clarify --compile-c failure output (exit code was already correct)
Investigated the report that --compile-c exits 1 despite writing the C
file. The exit code is NOT wrong: when z88dk fails, no .com is produced,
so a non-zero exit is the correct signal. Returning 0 would tell scripts
a binary exists when it does not. Left as is.
Two real defects did make that outcome look like a bug, and both are
fixed:
- Output order was reversed. stdout is block buffered when redirected
while stderr is not, so 'z88dk compilation failed' appeared BEFORE
'Generated C: <file>', making it look as though the C file was never
written. The success line is now flushed.
- The failure message was just z88dk's raw stderr, which can read as
nonsense: it reports "file 'x.c' not found" for a file that plainly
exists when it cannot reach the directory - the snap package cannot
read /tmp or hidden directories, which is exactly how this was hit.
The message now states that the .com was not created, gives the path
of the C source that WAS generated, and then quotes z88dk.
Before:
z88dk compilation failed:
file 'e.c' not found
Generated C: e.c
After:
Generated C: f1.c
z88dk compilation failed - f1.com was not created.
The generated C source is at f1.c.
z88dk reported:
file 'f1.c' not found
Verified all three paths: success exits 0 with the .com present; z88dk
failure exits 1 with the message above; z88dk absent exits 1 and says so.
Regression suite and utils/run_tests.py unchanged (9/13/2/24 and 36/2).
Version: 1.0.1005
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix --compile-js loading the analyzer under two module names compile_to_javascript() imported lexer/parser/semantic_analyzer flat while src/codegen_js_backend.py imports them as src.*, so Python loaded them twice under two names with two distinct VarType enum classes. All 12 VarType comparisons in the JS backend were silently false - the same root cause fixed for --compile-c in d927cf1, still latent on the JS path. The generated JavaScript was wrong for 235 of the 291 corpus programs that compile (81%), in three distinct ways: - String variables were initialised to the number 0 instead of "". '10 PRINT "[";A$;"]" / 20 A$ = A$ + "X" / 30 PRINT "[";A$;"]"' generated code printing [0] then [0X]; the interpreter prints [] then [X]. Now matches. - Single-precision coercion was absent (coerce: null). Numeric variables and INPUT results are now wrapped in _toSingle, so arithmetic rounds the way MBASIC does. - INPUT into a string variable called the NUMERIC input helper: 'dummy_str = _input_num("PRESS RETURN TO CONTINUE...")'. It now calls _input_str. Measured by generating JS for all 541 corpus programs before and after: 291 programs generate JS in both, 235 produce different output, 0 newly broken and 0 newly working. Sampling 30 changed programs and classifying every added line found 27 string-INPUT fixes, 198 coercion additions and 113 string initialisations, and zero cases of a non-string variable being given the string input helper - i.e. no change goes the wrong way. Regression suite and utils/run_tests.py unchanged (9/13/2/24 and 36/2). JavaScript output could not be executed to confirm at runtime: node is not installed in this environment, so correctness is established by comparing generated code against interpreter output. Version: 1.0.1003 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Sanitize dots in variable names for the C backend MBASIC allows '.' in variable names (REC.NUM, OLD.FILE), which is not a valid C identifier character. _mangle_variable_name passed it through, so a program using such a name emitted 'int rec.num_int, old.file_int;' and z88dk stopped with 'Missing token, expecting ; got .'. Non-alphanumeric characters now map to '_', the same substitution _mangle_string_name already applied (which is why STR_ ids were fine while plain variables were not). BASIC names cannot contain '_', so the mapping cannot collide with another BASIC variable. Scope, measured rather than assumed: of the 311 corpus programs that generate C, exactly ONE (basic/business/diary.bas) emitted a dotted declaration, and that file has no line numbers so it is not valid MBASIC 5.21 input and still fails for unrelated reasons. My earlier claim that this was the most common remaining compile failure was wrong - it came from a sample of 8 where it accounted for 1 case. Verified with a synthetic program exercising all three types (REC.NUM, OLD.FILE$, END.FLAG%): declarations and references now agree and it compiles and links to .com with the real z88dk. C generation across the corpus unchanged at 311 OK with 0 newly broken; no generated declaration contains a dot. Regression suite and utils/run_tests.py unchanged (9/13/2/24 and 36/2). Version: 1.0.1002 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Migrate to PEP 639 SPDX license metadata setuptools warned that both `project.license` as a TOML table and `License ::` classifiers are deprecated and stop working after 2027-02-18. Switched to the SPDX string form plus `license-files`, and dropped the now-redundant classifier. The SPDX form needs setuptools>=77.0, so build-system.requires is bumped from 61.0. That is a build-time requirement only - the wheel is pure Python and still installs anywhere requires-python allows. Build now emits zero SetuptoolsDeprecationWarnings, metadata carries License-Expression: GPL-3.0-or-later with the LICENSE file shipped in dist-info/licenses/, and twine check passes for both wheel and sdist. Caveat worth knowing: setuptools has required Python >=3.9 since 75.8.2, so building from the SDIST on Python 3.8 can no longer resolve a usable setuptools. Wheel installs on 3.8 are unaffected (no build step), so requires-python is left at >=3.8 rather than silently dropping support. Version: 1.0.998 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Keep publish smoke test log clean on success grep -q closed the pipe early, so a passing run still logged a BrokenPipeError from mbasic flushing stdout. Redirect to a file and grep that instead. No version bump: this is CI-only and 1.0.996 is the release being published. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>