aboutsummaryrefslogtreecommitdiff
path: root/tinyvm.bat
diff options
context:
space:
mode:
authorGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
committerGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
commitecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch)
tree70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /tinyvm.bat
a
Diffstat (limited to 'tinyvm.bat')
-rwxr-xr-xtinyvm.bat635
1 files changed, 635 insertions, 0 deletions
diff --git a/tinyvm.bat b/tinyvm.bat
new file mode 100755
index 0000000..0807eb9
--- /dev/null
+++ b/tinyvm.bat
@@ -0,0 +1,635 @@
+@echo off
+setlocal enabledelayedexpansion
+set "SOURCE_ARG=%~f2"
+cd /d "%~dp0"
+title TinyVM - Windows Interactive Build ^& Run
+
+REM =========================================================================
+REM Compiler Detection & Environment Setup
+REM =========================================================================
+
+set "CC_NAME="
+
+REM preserve a compiler selected by the caller.
+if defined CC (
+ set "CC_NAME=Configured [%CC%]"
+ goto :has_compiler
+)
+
+REM 1. Search WinGet LLVM-MinGW portable packages first (self-contained with CRT headers)
+for /d %%D in ("%LOCALAPPDATA%\Microsoft\WinGet\Packages\MartinStorsjo.LLVM-MinGW*") do (
+ for /d %%B in ("%%D\llvm-mingw*") do (
+ if exist "%%B\bin\clang.exe" (
+ set "PATH=%%B\bin;!PATH!"
+ set "CC=clang"
+ set "CC_NAME=LLVM-MinGW Clang [WinGet]"
+ goto :compiler_found
+ )
+ )
+)
+
+REM 2. Check if clang or gcc is already in PATH
+where clang >nul 2>nul
+if %errorlevel% equ 0 (
+ set "CC=clang"
+ set "CC_NAME=Clang [in PATH]"
+ goto :compiler_found
+)
+
+where gcc >nul 2>nul
+if %errorlevel% equ 0 (
+ set "CC=gcc"
+ set "CC_NAME=GCC [in PATH]"
+ goto :compiler_found
+)
+
+REM 3. Search C:\Program Files\LLVM\bin
+if exist "%ProgramFiles%\LLVM\bin\clang.exe" (
+ set "PATH=%ProgramFiles%\LLVM\bin;%PATH%"
+ set "CC=clang"
+ set "CC_NAME=LLVM Clang [Program Files]"
+ goto :compiler_found
+)
+
+set "PFX86=%ProgramFiles(x86)%"
+if defined PFX86 if exist "!PFX86!\LLVM\bin\clang.exe" (
+ set "PATH=!PFX86!\LLVM\bin;%PATH%"
+ set "CC=clang"
+ set "CC_NAME=LLVM Clang [Program Files x86]"
+ goto :compiler_found
+)
+
+:compiler_found
+if not "%CC%"=="" goto :has_compiler
+
+echo [ERROR] No suitable C compiler [clang or gcc] found on this system.
+echo.
+echo Please install LLVM / Clang:
+echo winget install MartinStorsjo.LLVM-MinGW.UCRT
+echo or: winget install LLVM.LLVM
+echo.
+pause
+exit /b 1
+
+:has_compiler
+
+REM Handle CLI Arguments if provided
+if not "%~1"=="" goto :handle_cli
+
+REM =========================================================================
+REM Interactive Main Menu
+REM =========================================================================
+
+:main_menu
+cls
+echo ===============================================================================
+echo TinyVM - Windows Toolchain
+echo ===============================================================================
+echo Compiler : %CC_NAME%
+echo Working : %CD%
+echo -------------------------------------------------------------------------------
+echo executable status:
+if exist "bin\zy.exe" ( echo [X] bin\zy.exe - VM core interpreter ) else ( echo [ ] bin\zy.exe - not built )
+if exist "bin\zym.exe" ( echo [X] bin\zym.exe - portable microcore ) else ( echo [ ] bin\zym.exe - not built )
+if exist "bin\zc0.exe" ( echo [X] bin\zc0.exe - stage 0 bootstrap compiler ) else ( echo [ ] bin\zc0.exe - not built )
+if exist "bin\mkgenome.exe" ( echo [X] bin\mkgenome.exe - genome header generator ) else ( echo [ ] bin\mkgenome.exe - not built )
+if exist "bin\genmap.exe" ( echo [X] bin\genmap.exe - memory map generator ) else ( echo [ ] bin\genmap.exe - not built )
+if exist "bin\zclsp.exe" ( echo [X] bin\zclsp.exe - language server protocol ^& highlighter ) else ( echo [ ] bin\zclsp.exe - not built )
+echo ===============================================================================
+echo [1] build VM core (bin\zy.exe)
+echo [2] build microcore (bin\zym.exe)
+echo [3] build bootstrap tools (bin\zc0.exe, bin\mkgenome.exe, bin\genmap.exe)
+echo [4] build LSP server ^& highlighter (bin\zclsp.exe)
+echo [5] build everything
+echo [6] run Windows test suite (native, LSP, JS, bootstrap)
+echo [7] run an example on the native VM (bin\zy.exe)
+echo [8] run an example in the JavaScript VM (node src/js/tinyvm.js)
+echo [9] run a custom .zc source file
+echo [L] check/highlight .zc with LSP (bin\zclsp.exe)
+echo [R] launch the interactive REPL (resident compiler)
+echo [B] bootstrap and run the full test suite
+echo [C] clean generated build directories (bin, build)
+echo [Q] quit
+echo ===============================================================================
+set /p "CHOICE=select an option [1-9, L, R, B, C, Q]: "
+
+if /i "%CHOICE%"=="1" goto :menu_build_core
+if /i "%CHOICE%"=="2" goto :menu_build_micro
+if /i "%CHOICE%"=="3" goto :menu_build_tools
+if /i "%CHOICE%"=="4" goto :menu_build_lsp
+if /i "%CHOICE%"=="5" goto :menu_build_all
+if /i "%CHOICE%"=="6" goto :menu_test
+if /i "%CHOICE%"=="7" goto :menu_examples
+if /i "%CHOICE%"=="8" goto :menu_examples_js
+if /i "%CHOICE%"=="9" goto :menu_run_custom
+if /i "%CHOICE%"=="l" goto :menu_lsp_check
+if /i "%CHOICE%"=="r" goto :menu_repl
+if /i "%CHOICE%"=="b" goto :menu_bootstrap
+if /i "%CHOICE%"=="c" goto :menu_clean
+if /i "%CHOICE%"=="q" exit /b 0
+
+echo Invalid choice. Please try again.
+timeout /t 2 >nul
+goto :main_menu
+
+REM =========================================================================
+REM Actions
+REM =========================================================================
+
+:menu_build_core
+echo.
+echo [Building zy.exe]...
+call :build_core
+echo.
+pause
+goto :main_menu
+
+:menu_build_micro
+echo.
+echo [Building zym.exe]...
+call :build_micro
+echo.
+pause
+goto :main_menu
+
+:menu_build_tools
+echo.
+echo [Building tools: zc0.exe, mkgenome.exe, genmap.exe]...
+call :build_tools
+echo.
+pause
+goto :main_menu
+
+:menu_build_lsp
+echo.
+echo [Building zclsp.exe (LSP Server ^& Highlighter)]...
+call :build_lsp
+echo.
+pause
+goto :main_menu
+
+:menu_build_all
+echo.
+echo [Building all components]...
+call :build_core
+if errorlevel 1 goto :build_failed
+call :build_micro
+if errorlevel 1 goto :build_failed
+call :build_tools
+if errorlevel 1 goto :build_failed
+call :build_lsp
+if errorlevel 1 goto :build_failed
+echo.
+echo [OK] Build complete.
+pause
+goto :main_menu
+
+:build_failed
+echo.
+echo [ERROR] Build failed. See the messages above.
+pause
+goto :main_menu
+
+:menu_test
+echo.
+if not exist "bin\zy.exe" (
+ call :build_core
+ if errorlevel 1 goto :build_failed
+)
+if not exist "bin\zym.exe" (
+ call :build_micro
+ if errorlevel 1 goto :build_failed
+)
+echo [Running test suite]...
+powershell -NoProfile -ExecutionPolicy Bypass -File "tests\test_win.ps1"
+if errorlevel 1 echo [ERROR] Test suite failed.
+echo.
+pause
+goto :main_menu
+
+:menu_bootstrap
+echo.
+echo [Running Bootstrap and Full Test Verification]...
+call :build_tools
+if errorlevel 1 goto :build_failed
+if not exist "bin\zy.exe" (
+ call :build_core
+ if errorlevel 1 goto :build_failed
+)
+powershell -NoProfile -ExecutionPolicy Bypass -File "tests\test_win.ps1"
+if errorlevel 1 echo [ERROR] Test suite failed.
+echo.
+pause
+goto :main_menu
+
+:menu_clean
+echo.
+echo [Cleaning build artifacts]...
+rmdir /s /q build bin 2>nul
+echo [OK] Generated bin and build directories removed.
+echo.
+pause
+goto :main_menu
+
+:menu_run_custom
+echo.
+set /p "CUSTOM_FILE=Enter path to .zc file (or drag & drop here): "
+REM Remove quotes if user dragged & dropped
+set "CUSTOM_FILE=%CUSTOM_FILE:"=%"
+if not exist "%CUSTOM_FILE%" (
+ echo [ERROR] File not found: %CUSTOM_FILE%
+ echo.
+ pause
+ goto :main_menu
+)
+
+if not exist "bin\zy.exe" (
+ echo bin\zy.exe not found, building first...
+ call :build_core
+ if errorlevel 1 goto :build_failed
+)
+
+echo.
+echo ===============================================================================
+echo Running: %CUSTOM_FILE%
+echo ===============================================================================
+bin\zy.exe < "%CUSTOM_FILE%"
+echo.
+echo ===============================================================================
+pause
+goto :main_menu
+
+:menu_lsp_check
+echo.
+set /p "LSP_FILE=Enter path to .zc file to check/highlight (or drag & drop here): "
+set "LSP_FILE=%LSP_FILE:"=%"
+if not exist "%LSP_FILE%" (
+ echo [ERROR] File not found: %LSP_FILE%
+ echo.
+ pause
+ goto :main_menu
+)
+
+if not exist "bin\zclsp.exe" (
+ echo bin\zclsp.exe not found, building first...
+ call :build_lsp
+ if errorlevel 1 goto :build_failed
+)
+
+echo.
+echo ===============================================================================
+echo Analyzing with bin\zclsp.exe: %LSP_FILE%
+echo ===============================================================================
+bin\zclsp.exe < "%LSP_FILE%"
+echo.
+echo ===============================================================================
+pause
+goto :main_menu
+
+:menu_repl
+echo.
+if not exist "bin\zy.exe" (
+ echo bin\zy.exe not found, building first...
+ call :build_core
+ if errorlevel 1 goto :build_failed
+)
+echo ===============================================================================
+echo TinyVM Interactive REPL (resident compiler)
+echo Each input chunk separated by backtick (`) is compiled and run.
+echo Type expression or function, terminate with ` (or EOF / Ctrl+Z).
+echo Type 'quit;' then backtick or press Ctrl+C to exit.
+echo ===============================================================================
+(type examples\repl.zc & echo ` & more) | bin\zy.exe
+echo.
+pause
+goto :main_menu
+
+REM =========================================================================
+REM Example Selection Sub-menu
+REM =========================================================================
+
+:menu_examples
+cls
+echo ===============================================================================
+echo Run TinyVM Examples on Native VM (zy.exe)
+echo ===============================================================================
+echo [1] hello.zc - Classic "hello, world!"
+echo [2] fact.zc - Recursive & iterative factorial computation
+echo [3] mandel.zc - Mandelbrot ASCII set using custom enhancement opcode
+echo [4] primes.zc - Sieve of Eratosthenes with o3 region compilation
+echo [5] life.zc - Conway's Game of Life on a typed torus board
+echo [6] lists.zc - Dynamic array with ownership tracking (u, m, d tags)
+echo [7] typed.zc - Structs, generic vectors, and reflection
+echo [8] wiring.zc - Runtime custom enhancement opcodes demo
+echo [9] bf.zc - Brainfuck JIT compiler running inside TinyVM
+echo [B] Back to main menu
+echo ===============================================================================
+set /p "EX_CHOICE=Select an example [1-9, B]: "
+
+if /i "%EX_CHOICE%"=="b" goto :main_menu
+set "EX_FILE="
+if "%EX_CHOICE%"=="1" set "EX_FILE=examples\hello.zc"
+if "%EX_CHOICE%"=="2" set "EX_FILE=examples\fact.zc"
+if "%EX_CHOICE%"=="3" set "EX_FILE=examples\mandel.zc"
+if "%EX_CHOICE%"=="4" set "EX_FILE=examples\primes.zc"
+if "%EX_CHOICE%"=="5" set "EX_FILE=examples\life.zc"
+if "%EX_CHOICE%"=="6" set "EX_FILE=examples\lists.zc"
+if "%EX_CHOICE%"=="7" set "EX_FILE=examples\typed.zc"
+if "%EX_CHOICE%"=="8" set "EX_FILE=examples\wiring.zc"
+if "%EX_CHOICE%"=="9" set "EX_FILE=examples\bf.zc"
+
+if "%EX_FILE%"=="" (
+ echo Invalid choice.
+ timeout /t 2 >nul
+ goto :menu_examples
+)
+
+if not exist "bin\zy.exe" (
+ call :build_core
+ if errorlevel 1 goto :build_failed
+)
+
+echo.
+echo ===============================================================================
+echo Running: %EX_FILE%
+echo ===============================================================================
+bin\zy.exe < "%EX_FILE%"
+echo.
+echo ===============================================================================
+pause
+goto :menu_examples
+
+:menu_examples_js
+cls
+echo ===============================================================================
+echo Run TinyVM Examples in JavaScript VM (Node.js)
+echo ===============================================================================
+echo [1] hello.zc - Classic "hello, world!"
+echo [2] fact.zc - Recursive & iterative factorial computation
+echo [3] mandel.zc - Mandelbrot ASCII set using custom enhancement opcode
+echo [4] primes.zc - Sieve of Eratosthenes with o3 region compilation
+echo [5] life.zc - Conway's Game of Life on a typed torus board
+echo [6] lists.zc - Dynamic array with ownership tracking (u, m, d tags)
+echo [7] typed.zc - Structs, generic vectors, and reflection
+echo [8] wiring.zc - Runtime custom enhancement opcodes demo
+echo [9] bf.zc - Brainfuck JIT compiler running inside TinyVM
+echo [B] Back to main menu
+echo ===============================================================================
+set /p "JS_EX_CHOICE=Select an example [1-9, B]: "
+
+if /i "%JS_EX_CHOICE%"=="b" goto :main_menu
+set "JS_EX_FILE="
+if "%JS_EX_CHOICE%"=="1" set "JS_EX_FILE=examples\hello.zc"
+if "%JS_EX_CHOICE%"=="2" set "JS_EX_FILE=examples\fact.zc"
+if "%JS_EX_CHOICE%"=="3" set "JS_EX_FILE=examples\mandel.zc"
+if "%JS_EX_CHOICE%"=="4" set "JS_EX_FILE=examples\primes.zc"
+if "%JS_EX_CHOICE%"=="5" set "JS_EX_FILE=examples\life.zc"
+if "%JS_EX_CHOICE%"=="6" set "JS_EX_FILE=examples\lists.zc"
+if "%JS_EX_CHOICE%"=="7" set "JS_EX_FILE=examples\typed.zc"
+if "%JS_EX_CHOICE%"=="8" set "JS_EX_FILE=examples\wiring.zc"
+if "%JS_EX_CHOICE%"=="9" set "JS_EX_FILE=examples\bf.zc"
+
+if "%JS_EX_FILE%"=="" (
+ echo Invalid choice.
+ timeout /t 2 >nul
+ goto :menu_examples_js
+)
+
+echo.
+echo ===============================================================================
+echo Running in JS: %JS_EX_FILE%
+echo ===============================================================================
+node src\js\tinyvm.js "%JS_EX_FILE%"
+echo.
+echo ===============================================================================
+pause
+goto :menu_examples_js
+
+REM =========================================================================
+REM Build Routines
+REM =========================================================================
+
+:build_core
+echo Compiling zy.exe (VM Core with JIT/Interpreter and Enhancements)...
+if not exist "bin" mkdir bin
+"%CC%" -O2 -w -fwrapv -DJTYPE=int src\core\core.c src\core\io_win.c -Isrc/core -o bin\zy.exe
+if errorlevel 1 (echo [ERROR] Failed to build bin\zy.exe.& exit /b 1)
+echo [OK] bin\zy.exe built successfully.
+exit /b 0
+
+:build_micro
+echo Compiling zym.exe (Portable Microcore)...
+if not exist "bin" mkdir bin
+"%CC%" -O2 -w -fwrapv src\micro\micro.c src\micro\port_win.c -Isrc/core -Isrc/micro -o bin\zym.exe
+if errorlevel 1 (echo [ERROR] Failed to build bin\zym.exe.& exit /b 1)
+echo [OK] bin\zym.exe built successfully.
+exit /b 0
+
+:build_tools
+if not exist "bin" mkdir bin
+echo Compiling zc0.exe (Bootstrap compiler)...
+"%CC%" -O1 -w -fwrapv src\tools\zc0.c -Isrc/core -o bin\zc0.exe
+if errorlevel 1 (echo [ERROR] Failed to build bin\zc0.exe.& exit /b 1)
+echo Compiling mkgenome.exe (Genome generator)...
+"%CC%" -O1 -w -fwrapv src\tools\mkgenome.c -Isrc/core -o bin\mkgenome.exe
+if errorlevel 1 (echo [ERROR] Failed to build bin\mkgenome.exe.& exit /b 1)
+echo Compiling genmap.exe (Memory map generator)...
+"%CC%" -O2 -w -fwrapv src\tools\genmap.c -Isrc/core -o bin\genmap.exe
+if errorlevel 1 (echo [ERROR] Failed to build bin\genmap.exe.& exit /b 1)
+echo [OK] Bootstrap tools built successfully in bin\.
+exit /b 0
+
+:build_lsp
+echo Compiling zclsp.exe (LSP Server ^& Semantic Highlighter in zc)...
+if not exist "bin" mkdir bin
+if not exist "bin\zc0.exe" (
+ call :build_tools
+ if errorlevel 1 exit /b 1
+)
+if not exist "bin\genmap.exe" (
+ call :build_tools
+ if errorlevel 1 exit /b 1
+)
+if exist build\lsp rmdir /s /q build\lsp
+mkdir build\lsp\src
+if errorlevel 1 (echo [ERROR] Could not create build\lsp.& exit /b 1)
+bin\genmap.exe --preset lsp --grow -o build\lsp\map >nul 2>nul
+if errorlevel 1 (echo [ERROR] Could not generate the initial LSP map.& exit /b 1)
+"%CC%" -O1 -w -fwrapv src\tools\zc0.c -Ibuild\lsp\map -Isrc/core -o build\lsp\zc0.exe
+if errorlevel 1 (echo [ERROR] Could not build the LSP sizing compiler.& exit /b 1)
+(type build\lsp\map\rt.zc & type build\lsp\map\compiler.zc & type src\lsp\server.zc) | build\lsp\zc0.exe > build\lsp\plain.h
+if errorlevel 1 (echo [ERROR] Could not size the LSP genome.& exit /b 1)
+set "GLEN="
+for /f "tokens=3" %%G in ('findstr /b /c:"#define GLEN" build\lsp\plain.h') do set "GLEN=%%G"
+if not defined GLEN (echo [ERROR] Could not read the LSP genome size.& exit /b 1)
+set /a SLOT=(GLEN+4095)/4096*4096
+set /a DOCS_WORK=SLOT+65536
+rmdir /s /q build\lsp\map
+bin\genmap.exe --preset lsp --grow --genome %DOCS_WORK% -o build\lsp\map >nul 2>nul
+if errorlevel 1 (echo [ERROR] Could not generate the documentation build map.& exit /b 1)
+"%CC%" -O1 -w -fwrapv -DZC0DOCS src\tools\zc0.c -Ibuild\lsp\map -Isrc/core -o build\lsp\zc0docs.exe
+if errorlevel 1 (echo [ERROR] Could not build the documentation compiler.& exit /b 1)
+(type build\lsp\map\rt.zc & type build\lsp\map\compiler.zc & type src\lsp\server.zc) | build\lsp\zc0docs.exe > build\lsp\docs-first.h
+if errorlevel 1 (echo [ERROR] Could not build the first documentation genome.& exit /b 1)
+set "DOCS_GLEN="
+for /f "tokens=3" %%G in ('findstr /b /c:"#define GLEN" build\lsp\docs-first.h') do set "DOCS_GLEN=%%G"
+if not defined DOCS_GLEN (echo [ERROR] Could not read the documentation genome size.& exit /b 1)
+set /a DOCS_SLOT=(DOCS_GLEN+4095)/4096*4096
+rmdir /s /q build\lsp\map
+bin\genmap.exe --preset lsp --grow --genome %DOCS_SLOT% -o build\lsp\map >nul 2>nul
+if errorlevel 1 (echo [ERROR] Could not generate the sized LSP map.& exit /b 1)
+"%CC%" -O1 -w -fwrapv -DZC0DOCS src\tools\zc0.c -Ibuild\lsp\map -Isrc/core -o build\lsp\zc0docs.exe
+if errorlevel 1 (echo [ERROR] Could not rebuild the documentation compiler.& exit /b 1)
+(type build\lsp\map\rt.zc & type build\lsp\map\compiler.zc & type src\lsp\server.zc) | build\lsp\zc0docs.exe > build\lsp\src\lsp_genome.h
+if errorlevel 1 (echo [ERROR] Could not build the sized documentation genome.& exit /b 1)
+set "FINAL_GLEN="
+for /f "tokens=3" %%G in ('findstr /b /c:"#define GLEN" build\lsp\src\lsp_genome.h') do set "FINAL_GLEN=%%G"
+if not "!FINAL_GLEN!"=="!DOCS_GLEN!" (echo [ERROR] LSP genome changed length after map sizing.& exit /b 1)
+copy /y src\core\core.c build\lsp\src\ >nul
+if errorlevel 1 exit /b 1
+copy /y src\core\io_win.c build\lsp\src\ >nul
+if errorlevel 1 exit /b 1
+copy /y src\core\fops.h build\lsp\src\ >nul
+if errorlevel 1 exit /b 1
+copy /y src\core\bops.h build\lsp\src\ >nul
+if errorlevel 1 exit /b 1
+copy /y src\core\stack.h build\lsp\src\ >nul
+if errorlevel 1 exit /b 1
+copy /y build\lsp\map\memmap.h build\lsp\src\ >nul
+if errorlevel 1 exit /b 1
+"%CC%" -O2 -w -fwrapv -DJTYPE=int -DZY_SANDBOX -DUSE_LSP_GENOME -Ibuild\lsp\src build\lsp\src\core.c build\lsp\src\io_win.c -o bin\zclsp.exe
+if errorlevel 1 (echo [ERROR] Failed to build bin\zclsp.exe.& exit /b 1)
+echo [OK] bin\zclsp.exe built successfully with %FINAL_GLEN% words.
+exit /b 0
+
+REM =========================================================================
+REM CLI Command Handler
+REM =========================================================================
+
+:handle_cli
+set "CMD=%~1"
+set "ARG2=%~2"
+
+if /i "%CMD%"=="build" (
+ if "%ARG2%"=="" goto :cli_build_all
+ if /i "%ARG2%"=="all" goto :cli_build_all
+ if /i "%ARG2%"=="core" ( call :build_core & exit /b !errorlevel! )
+ if /i "%ARG2%"=="micro" ( call :build_micro & exit /b !errorlevel! )
+ if /i "%ARG2%"=="tools" ( call :build_tools & exit /b !errorlevel! )
+ if /i "%ARG2%"=="lsp" ( call :build_lsp & exit /b !errorlevel! )
+ echo Unknown build target: %ARG2%
+ exit /b 1
+)
+
+if /i "%CMD%"=="test" (
+ call :build_core
+ if errorlevel 1 exit /b 1
+ call :build_micro
+ if errorlevel 1 exit /b 1
+ powershell -NoProfile -ExecutionPolicy Bypass -File "tests\test_win.ps1"
+ exit /b !errorlevel!
+)
+
+if /i "%CMD%"=="run" (
+ if "%ARG2%"=="" (
+ echo Error: Missing .zc file to run.
+ echo Usage: tinyvm.bat run path\to\program.zc
+ exit /b 1
+ )
+ if not exist "bin\zy.exe" (
+ call :build_core
+ if errorlevel 1 exit /b 1
+ )
+ bin\zy.exe < "%SOURCE_ARG%"
+ exit /b !errorlevel!
+)
+
+if /i "%CMD%"=="run-micro" (
+ if "%ARG2%"=="" (
+ echo Error: Missing .zc file to run.
+ echo Usage: tinyvm.bat run-micro path\to\program.zc
+ exit /b 1
+ )
+ if not exist "bin\zym.exe" (
+ call :build_micro
+ if errorlevel 1 exit /b 1
+ )
+ bin\zym.exe < "%SOURCE_ARG%"
+ exit /b !errorlevel!
+)
+
+if /i "%CMD%"=="js" (
+ if "%ARG2%"=="" (
+ echo Error: Missing .zc file to run.
+ echo Usage: tinyvm.bat js path\to\program.zc
+ exit /b 1
+ )
+ node src\js\tinyvm.js "%SOURCE_ARG%"
+ exit /b !errorlevel!
+)
+
+if /i "%CMD%"=="lsp" (
+ if "%ARG2%"=="" (
+ echo Error: Missing .zc file to check.
+ echo Usage: tinyvm.bat lsp path\to\program.zc
+ exit /b 1
+ )
+ if not exist "bin\zclsp.exe" (
+ call :build_lsp
+ if errorlevel 1 exit /b 1
+ )
+ bin\zclsp.exe < "%SOURCE_ARG%"
+ exit /b !errorlevel!
+)
+
+if /i "%CMD%"=="repl" (
+ if not exist "bin\zy.exe" (
+ call :build_core
+ if errorlevel 1 exit /b 1
+ )
+ (type examples\repl.zc & echo ` & more) | bin\zy.exe
+ exit /b !errorlevel!
+)
+
+if /i "%CMD%"=="clean" (
+ rmdir /s /q build bin 2>nul
+ echo [OK] Generated bin and build directories removed.
+ exit /b 0
+)
+
+if /i "%CMD%"=="help" (
+ goto :show_help
+)
+if /i "%CMD%"=="-h" (
+ goto :show_help
+)
+if /i "%CMD%"=="--help" (
+ goto :show_help
+)
+
+echo Unknown command: %CMD%
+echo.
+exit /b 1
+:show_help
+echo TinyVM Windows CLI usage:
+echo tinyvm.bat launch interactive build ^& run menu
+echo tinyvm.bat build [all^|core^|micro^|tools^|lsp]
+echo compile TinyVM executables
+echo tinyvm.bat run ^<file.zc^> run a .zc program on VM core (zy.exe)
+echo tinyvm.bat run-micro ^<file.zc^> run a .zc program on microcore (zym.exe)
+echo tinyvm.bat js ^<file.zc^> run a .zc program on the JavaScript VM (node)
+echo tinyvm.bat lsp ^<file.zc^> check/highlight a .zc program with zclsp.exe
+echo tinyvm.bat test run the full Windows test suite
+echo tinyvm.bat repl launch the resident compiler REPL
+echo tinyvm.bat clean remove generated bin and build directories
+exit /b 0
+
+:cli_build_all
+call :build_core
+if errorlevel 1 exit /b 1
+call :build_micro
+if errorlevel 1 exit /b 1
+call :build_tools
+if errorlevel 1 exit /b 1
+call :build_lsp
+exit /b !errorlevel!