23 Commits

Author SHA1 Message Date
Eremey Valetov
cabd93caea Release 0.18.0 + automated FreeDOS QEMU smoke (#2)
* tests: automated headless FreeDOS QEMU smoke

Fully-automated counterpart to the manual run_freedos_qemu.sh: overlays the
FreeDOS image (no mutation), stages the interpreter and a SYSTEM-terminated
smoke on C:, injects the run plus poweroff into the image's startup batch,
boots headless, and diffs OUT.TXT against the golden file. Local-dev only
(needs qemu, a FreeDOS qcow2, mtools, nbd, and passwordless sudo); CI keeps
using the DOSBox-X path. Exercises the binary on a real FreeDOS install
rather than DOSBox-X emulation.

* Release 0.18.0

Cross-language linking (link BASIC into C/Fortran, call C from BASIC via
'$EXTERN), the v0.18 codegen/perf batch (paren string-comparison fix,
--no-gc-check/--fast-math, larger 32-bit caps, process-local DATE$/TIME$),
and the automated FreeDOS QEMU smoke. Bumps GW_VERSION and updates the
banners, CHANGES.TXT, and the development history table.

---------

Co-authored-by: Eremey Valetov <evvaletov@users.noreply.github.com>
2026-06-13 15:37:45 +03:00
Eremey Valetov
c317d683fb Compiler: accept unnumbered programs, fix string concat in PRINT
Three fixes that lift seven test programs from skipped to passing,
bringing the AOT compiler harness from 56/56 to 63/63.

- Unnumbered programs (compiler_main.c): src/compiler_main.c skipped
  any line that didn't start with a digit, so direct-mode .bas files
  like hello.bas, math_ops.bas, string_ops.bas (no line numbers)
  failed with "No program lines found".  load_file now auto-assigns
  line numbers (last_num + 10) to unnumbered lines, with overflow
  protection at line 65520.

- String concatenation in PRINT (codegen.c): emit_str_atom had a
  broken concat loop that emitted "; _cat = gw_str_concat(&...
  _cat.sval ...)" — _cat was never declared, so any program with a
  string-literal concat in PRINT (like PRINT "ABC" + "DEF") failed
  to link.  Concat is properly handled by emit_str_expr's outer
  loop; remove the dead/broken code in the atom.  Fixes
  string_ops.bas.

- Transcendental result type (codegen.c): peek_expr_type returned
  VT_DBL for ATN/LOG/EXP/VAL, so PRINT formatted them with 15-digit
  double precision (e.g. 3.141592653589793) while real GW-BASIC and
  the interpreter format the single-precision result as 3.141593.
  Real GW-BASIC's transcendentals are single-precision; only CDBL
  forces double.  Demote ATN/LOG/EXP/VAL to VT_SNG; CDBL stays
  VT_DBL.  Fixes math_ops.bas.

Also: tests/run_compiler_tests.sh now runs the compiled binary from
the project root rather than the tempdir where it was built, so
test programs that reference tests/programs/ via relative paths
(chain_test, common_test, run_file, misc_stmts) resolve their
targets.  Earlier I'd misdiagnosed those failures as ON ERROR
divergence — they were just CWD-dependent path lookups.

Doc/test counts: 56 → 63 in README, docs/index.md, docs/development.md,
docs/roadmap.md.  Roadmap updated to note the compiler now accepts
unnumbered programs.
2026-05-04 16:32:09 -04:00
Eremey Valetov
70ffd39562 v0.17.0: BIOS-routed TUI on DOS, version banner, compiler PulseAudio link
QA findings from a multi-round review of the FreeDOS submission prep work:

- TUI rendering refactor: src/tui.c emitted ANSI escape sequences via
  printf, which displays as raw text on bare FreeDOS (no ANSI.SYS).
  Add four HAL ops (tui_enter, tui_leave, render_run, set_cursor_shape)
  and route per-cell rendering through them.  POSIX backend keeps the
  ANSI path; DOS backend drives BIOS INT 10h via the existing
  bios_set_cursor / bios_write_char helpers.  The TUI's logical cursor
  goes through the saved orig_locate to avoid recursing through the
  swapped-in gw_hal->locate.

- DOS extended-key mapping: dos_getch returns 0x100 | scancode for
  arrows / F-keys; tui_read_key wasn't translating those to its TK_*
  constants, so the editor never saw arrow keys or F1-F10 on DOS.
  Add a __MSDOS__-conditional translation table in tui_read_key.

- Version banner: GW_VERSION was still 0.16.0 even though the v0.17.0
  release prep was already in CHANGES.TXT.  Bump.

- Compiler PulseAudio link: gwbasic-compile -c hardcoded
  '-lgwrt -lm -lpthread' on the gcc command line.  When libgwrt was
  built against libpulse-simple (the default on any host with the
  PulseAudio dev headers installed), the compile workflow failed with
  'undefined reference to pa_simple_drain'.  CMake now passes
  GWRT_HAS_PULSEAUDIO to gwbasic-compile when libpulse is present, and
  the compiler appends -lpulse-simple to the link line.

- FRE("") garbage collection: the interpreter skipped strpool_gc with a
  comment 'unsafe during expression eval', but that's exactly what real
  GW-BASIC's FRE("") does (and the AOT compiler path already did).  Add
  the GC call; strpool_pin/unpin is the existing escape hatch if a
  caller has live pool pointers on the C stack.  Fixes the string_gc
  compat test.

- Test harness normalization: run_tests.sh stripped trailing whitespace
  on the actual output but not the expected file, causing spurious
  mismatches against golden files captured from real GWBASIC.EXE.
  Normalize both sides identically.  Fixes the peek_gfx mismatch.

- Print_using: snprintf into mantissa[32] with %.*f and an unbounded
  dec triggered a -Wformat-truncation warning.  Clamp dec to 20 (IEEE
  double has at most ~17 significant decimal digits).

- Doc/version consistency: 16-bit binary size reported as 127KB in one
  place and 128KB in three; standardize on 128KB.  HAL backend count
  said '1 file' but is now 2.  CI test count said 'all 66 test
  programs' but is 72.  Add a v0.17.0 row to the development.md table.
  Update getting-started.md DOS section to match the BIOS-rendering
  reality and add a manual TUI verification checklist.

- dos_init now writes back BIOS-reported cols/rows to dos_hal struct
  fields (forward-declared so dos_init can reference it).

After these changes: 72/72 interpreter tests pass, compat 68/68
matched, no warnings on the Linux build.
2026-05-03 12:25:41 -04:00
Eremey Valetov
b22ccccf88 Update all public docs for v0.16.0 release
README.md: rewrite with v0.16.0 version, compiler section, Jupyter
kernel section, hardware I/O in statement table, accurate test counts
(72 interpreter + 14 kernel + 69 compiler), build instructions for
all three targets.

docs/roadmap.md: clean up Phase 2 accumulation into single coherent
compiler description. List all language coverage, operators, functions,
and optimizations. Remove stale intermediate progress markers.

docs/development.md: update test counts (72 programs, 68 golden files),
add kernel and compiler test commands.
2026-03-30 16:45:41 -04:00
Eremey Valetov
4be33ff180 Update docs: compiler 69/69 tests pass (100%) — all tests green 2026-03-29 20:48:58 -04:00
Eremey Valetov
8ee17b9e2a Update docs: compiler 67/72 tests (93%), CHAIN/COMMON/RUN supported 2026-03-29 19:41:49 -04:00
Eremey Valetov
a21f60cd89 Release v0.16.0: AOT compiler (89%), Jupyter kernel, Hardware I/O, string GC
Version 0.16.0 consolidates the major features added since v0.14.0:

Ahead-of-time compiler (gwbasic-compile):
  - Translates .bas programs to C source → GCC → native executables
  - 64 of 72 test programs produce correct output (89%)
  - Zero compile errors — all 72 programs compile successfully
  - Token embedding for complex statements (PRINT USING, DEF FN,
    graphics, file I/O, MID$ assignment)
  - String comparison, division-by-zero detection, ON ERROR GOTO/RESUME
  - libgwrt.a runtime library from existing interpreter modules

Jupyter kernel (gwbasickernel):
  - Persistent subprocess with sentinel protocol
  - Inline Sixel graphics rendering (pure-Python decoder → PNG)
  - INPUT statement support via Jupyter stdin protocol
  - Pygments GW-BASIC syntax highlighter

Hardware I/O simulator (portio.c):
  - 8253 PIT, PPI speaker, CGA mode/color, COM1, game port
  - Continuous tone via PulseAudio pthread worker

Interpreter improvements:
  - 100% token coverage (all 144 GW-BASIC tokens handled)
  - String space pool with compacting garbage collector
  - RESET, ENVIRON/ENVIRON$, ERDEV/ERDEV$, IOCTL/IOCTL$,
    LCOPY, DATE$/TIME$ assignment, CALL, COM
2026-03-29 19:30:16 -04:00
Eremey Valetov
22206c012d Update Sphinx docs with AOT compiler Phase 1 2026-03-29 07:01:03 -04:00
Eremey Valetov
9ff3aaf104 Update Sphinx docs with Jupyter kernel, move to IDE integration next 2026-03-29 05:52:49 -04:00
Eremey Valetov
65f99da932 Update Sphinx docs with string pool GC, remove string GC from limitations 2026-03-29 04:58:29 -04:00
Eremey Valetov
724f823536 Update Sphinx docs with v0.15.0 gap-fill: ENVIRON, ERDEV, IOCTL, RESET, etc. 2026-03-28 18:50:22 -04:00
Eremey Valetov
d69c46330c Update Sphinx docs with v0.15.0 Hardware I/O Simulator, bump version 2026-03-28 18:30:04 -04:00
Eremey Valetov
0d9f29aa7a Fix DRAW M/S/A bugs, add TA rotation, =variable; substitution, X substring execution
Rewrites gfx_draw() as a recursive draw_engine() to support all DRAW
mini-language features:

Bug fixes:
- M command parsing: skip generic arg parser so M100,50 correctly
  parses both coordinates instead of consuming x as a generic arg
- S (scale) semantics: distance is now (arg ?: 1) * scale / 4, matching
  original GW-BASIC where S4 means 1 pixel per unit, not 4
- A (rotation): implements 90-degree rotation state with direction
  vector transform for all 8 direction commands

New features:
- TA n: arbitrary rotation angle (-360 to 360 degrees) via cos/sin
- =variable;: numeric variable substitution in DRAW strings
- X stringvar;: execute substring from string variable (recursive)
- Scale factor applied to relative M coordinates
2026-03-21 02:48:17 -04:00
Eremey Valetov
3f3104c385 Implement MBF binary file compatibility, fix binary loader null-byte truncation, update to v0.14.0
Binary tokenized SAVE/LOAD now stores float constants in Microsoft Binary
Format (MBF) on disk, matching original GWBASIC.EXE.  A token-walking function
(convert_floats) converts IEEE↔MBF at the save_binary()/load_binary() boundary.

Also fixes a latent bug where load_binary() scanned for 0x00 to find the end
of each token line — this fails when float bytes contain null (e.g. MBF for
100.5 is 00 00 49 87).  The loader now uses the next-line pointer to compute
token data length, matching the original's approach.
2026-03-21 01:38:53 -04:00
Eremey Valetov
000116b2a2 Fix POINT coordinate mapping, remove orphaned palette array, expand tests
Apply coordinate mapping (VIEW/WINDOW) to POINT(x,y) function so it
returns correct pixel values when WINDOW is active. Remove unused
palette[] array from graphics.c (Sixel encoder uses palette_map[]
directly). Expand view_window.bas test to cover WINDOW SCREEN mode,
VIEW+WINDOW combination, and PMAP inverse mapping. Fix CI test count
in docs.
2026-03-10 22:38:42 -04:00
Eremey Valetov
0bacfcef6c Implement VIEW/WINDOW/PALETTE, PMAP, fix MBF float format, update to v0.13.0
Graphics viewport and coordinate mapping:
- VIEW [[SCREEN] (x1,y1)-(x2,y2) [,[fill][,border]]] with clipping
- WINDOW [[SCREEN] (x1,y1)-(x2,y2)] with Cartesian/screen modes
- PALETTE [attribute, color] with CGA 16-color remapping
- PMAP(coord, func) for logical/physical coordinate conversion
- All graphics statements (PSET, LINE, CIRCLE, PAINT, GET/PUT) respect
  viewport clipping and WINDOW coordinate mapping

MBF (Microsoft Binary Format) float support:
- CVS/CVD now interpret bytes as MBF format (compatible with real GW-BASIC)
- MKS$/MKD$ now produce MBF-encoded bytes
- Fixed shift errors in MBF↔IEEE conversion routines (single: 1→0, double: 4→3)
- Random-access file I/O now byte-compatible with original GWBASIC.EXE

66 tests (2 new), 61 compat matches (up from 58).
2026-03-10 22:20:58 -04:00
Eremey Valetov
4551c88a50 Implement BSAVE/BLOAD, TUI color, extended PEEK/POKE, update to v0.12.0
BSAVE/BLOAD: save and load virtual memory blocks with 0xFD-header
binary format, operating on the current DEF SEG segment.

TUI color: tui_refresh emits ANSI SGR codes from cell attributes;
COLOR statement sets tui.current_attr when TUI is active.

Extended PEEK/POKE: CGA graphics framebuffer (interlaced layout) via
gfx_cga_peek/poke routed through virmem when gfx_active(); BIOS
keyboard shift flags (offset 0x17 bit 7 = insert mode).

Add bibliography to language reference. 64 tests, all passing.
2026-03-01 13:37:05 -05:00
Eremey Valetov
0743757029 Implement DEF SEG/PEEK/POKE, GET/PUT sprites, fix PRINT USING, update to v0.11.0 2026-03-01 13:07:28 -05:00
Eremey Valetov
e7f35c21ff Implement binary SAVE/LOAD, INKEY$ extended keys, golden tests, update to v0.10.0
Binary SAVE/LOAD: SAVE now writes tokenized binary by default (0xFF header
format), matching original GW-BASIC behavior. SAVE "file",A for ASCII.
LOAD auto-detects binary vs ASCII from the first byte. Command-line file
loading also auto-detects, so binary .BAS files just work.

INKEY$ extended keys: arrow keys, Home/End/PgUp/PgDn, Insert/Delete, and
F1-F10 now return the correct CHR$(0) + scan_code two-byte sequences per
the IBM PC convention. Refactored event trap key parsing to use tui_read_key()
instead of duplicating escape sequence parsing.

Golden-file regression tests: generated .expected output files for 55 of 58
test programs (3 timing-dependent tests excluded). The test runner now
reports compat match status alongside pass/fail.

Classic programs: added Hamurabi, Lunar Lander, Gunner, and Diamond from
David Ahl's BASIC Computer Games (1978) in tests/classic/ for manual
compatibility testing.

Docs updated with compiler roadmap item and hardware I/O simulator plan.
2026-03-01 12:25:47 -05:00
Eremey Valetov
3fa8c6f034 Implement EDIT statement and ON TIMER/ON KEY event trapping, update to v0.9.0
Add event-driven programming: ON TIMER(n) GOSUB with TIMER ON/OFF/STOP,
ON KEY(n) GOSUB with KEY(n) ON/OFF/STOP for F1-F10. Fix F-key escape
sequence parser (F9/F10 detection, push back consumed bytes on unmatched
sequences). Add EDIT statement for TUI line editing. Guard key trap
polling so keystrokes aren't consumed when no traps are configured.
2026-02-27 17:29:09 -05:00
Eremey Valetov
5105ecafd6 Allow RND without parentheses, update Sphinx docs to v0.8.0
RND can now be called without parentheses (equivalent to RND(1)),
matching real GW-BASIC behavior for legacy code compatibility.

Update all Sphinx documentation pages to reflect features added in
v0.6.0-0.8.0: DATE$/TIME$/TIMER, FILES/SHELL/CHDIR/MKDIR/RMDIR,
AUTO/RENUM/DELETE, COMMON, LPRINT/LLIST with --lpt, --full TUI flag,
dynamic screen buffer, 54 tests.
2026-02-22 14:09:18 -05:00
Eremey Valetov
ad21350003 Add full-screen TUI editor, DOSBox-X compat testing, rename to GW-BASIC 2026
Authentic GW-BASIC screen editor with 25x80 buffer, free cursor movement,
enter-on-any-line, F1-F10 function keys, Insert/Overwrite toggle, KEY
ON/OFF/LIST statement, and Ctrl+Break handling. HAL pointer swap routes
all PRINT/LIST/error output through the TUI automatically. Piped mode
unchanged (50/50 tests pass).

Adds automated compatibility testing infrastructure: DOSBox-X headless
config, PRINT-to-file transform script, and run_compat.sh with --generate
and --compare modes for verifying output against real GWBASIC.EXE.

Project renamed from gwbasic-c to GW-BASIC 2026.
2026-02-22 12:18:17 -05:00
Eremey Valetov
c2684712af Add Sphinx documentation site with GitHub Pages deployment
Furo theme, 6 pages split from existing docs, auto-deploys on push.
2026-02-15 16:56:02 -05:00