diff options
| author | 2026-10-14 07:28:39 +0000 | |
|---|---|---|
| committer | 2026-10-14 07:28:39 +0000 | |
| commit | 7451eb090d890fb5ea5e4d40627a1b4df15a49de (patch) | |
| tree | 357bdf4b528e860bffa688865306f656b788d2c2 /tinyvm.bat | |
| parent | analyzer: close the ownership gaps that stopped the compiler compiling itself (diff) | |
build: embed images with #embed, keep everything generated in build/
the cores take their genome in with c23 #embed through src/core/genome.h,
so images are plain little-endian word files (genome.bin) instead of
generated c headers. zc0 writes that format, mkgenome checks an image
against its map and shows a compiler's diagnostics when it gets them,
and the javascript vm and the editor's vm host read the same files.
src/tools/findcc.sh picks a compiler with #embed (clang 19 or gcc 15).
zc gets an embed declaration, embed "file" as [type] name, for globals
and locals: a byte string by default, char*, numbers read little-endian,
and arrays of numbers. the compiler and language server carry their
library and source texts through it, so embed.sh and the text it
spliced into compiler.zc are gone.
make writes executables to build/bin, the default map to build/core/map,
the web page to build/web and the extension staging to build/vsix, and
the genome now rebuilds when its sources change. the test suite lays
out its own map and bootstrap and reads nothing from build/.
also: rt.put_s of a byte string in zc0 images, retained function
sources no longer count as live objects, a missing include no longer
cascades into undefined-name errors, consecutive comment lines join
into one hover paragraph, and stale test fixtures follow the include
format.
Diffstat (limited to 'tinyvm.bat')
| -rwxr-xr-x | tinyvm.bat | 569 |
1 files changed, 297 insertions, 272 deletions
@@ -7,65 +7,83 @@ if /i "%~1"=="help" goto :show_help if /i "%~1"=="--help" goto :show_help if /i "%~1"=="-h" goto :show_help +REM everything built or generated goes under build\ (executables in build\bin); +REM the tree holds sources only. the cores take their genome in with c23 #embed, +REM so the compiler has to be clang 19 or gcc 15 or later. + REM ========================================================================= REM Compiler Detection & Environment Setup REM ========================================================================= set "CC_NAME=" - -REM preserve a compiler selected by the caller. +if not exist "build\probe" mkdir "build\probe" +> "build\probe\probe.bin" echo ab +> "build\probe\probe.c" echo static const unsigned char probe[] = { +>> "build\probe\probe.c" echo #embed "probe.bin" +>> "build\probe\probe.c" echo }; +>> "build\probe\probe.c" echo int main(void) { return sizeof probe ^> 0 ? 0 : 1; } + +REM preserve a compiler selected by the caller, if it can #embed. if defined CC ( - set "CC_NAME=Configured [%CC%]" - goto :has_compiler + call :probe_cc "%CC%" + if not errorlevel 1 ( + set "CC_NAME=Configured [%CC%]" + goto :has_compiler + ) + echo [ERROR] CC=%CC% does not support #embed; clang 19 or gcc 15 is needed. + exit /b 1 ) -REM 1. Search WinGet LLVM-MinGW portable packages first (self-contained with CRT headers) +REM 1. WinGet LLVM-MinGW portable packages (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 + call :probe_cc "%%B\bin\clang.exe" + if not errorlevel 1 ( + set "PATH=%%B\bin;!PATH!" + set "CC=clang" + set "CC_NAME=LLVM-MinGW Clang [WinGet]" + goto :has_compiler + ) ) ) ) -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 2. clang or gcc already in PATH +for %%C in (clang gcc) do ( + where %%C >nul 2>nul + if !errorlevel! equ 0 ( + call :probe_cc %%C + if not errorlevel 1 ( + set "CC=%%C" + set "CC_NAME=%%C [in PATH]" + goto :has_compiler + ) + ) ) -REM 3. Search C:\Program Files\LLVM\bin +REM 3. C:\Program Files\LLVM\bin and the x86 variant 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 + call :probe_cc "%ProgramFiles%\LLVM\bin\clang.exe" + if not errorlevel 1 ( + set "PATH=%ProgramFiles%\LLVM\bin;%PATH%" + set "CC=clang" + set "CC_NAME=LLVM Clang [Program Files]" + goto :has_compiler + ) ) - 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 + call :probe_cc "!PFX86!\LLVM\bin\clang.exe" + if not errorlevel 1 ( + set "PATH=!PFX86!\LLVM\bin;%PATH%" + set "CC=clang" + set "CC_NAME=LLVM Clang [Program Files x86]" + goto :has_compiler + ) ) -:compiler_found -if not "%CC%"=="" goto :has_compiler - -echo [ERROR] No suitable C compiler [clang or gcc] found on this system. +echo [ERROR] No C compiler with #embed support [clang 19 or gcc 15 and later] was found. echo. echo Please install LLVM / Clang: echo winget install MartinStorsjo.LLVM-MinGW.UCRT @@ -74,7 +92,14 @@ echo. pause exit /b 1 +REM :probe_cc compiler - errorlevel 0 when it compiles a file that uses #embed +:probe_cc +%1 -w --embed-dir=build\probe build\probe\probe.c -o build\probe\probe.exe >nul 2>nul +exit /b %errorlevel% + :has_compiler +REM the include and embed paths of a core that carries the compiler genome +set "COREINC=-Isrc/core -Ibuild/core/map --embed-dir=build/core" REM Handle CLI Arguments if provided if not "%~1"=="" goto :handle_cli @@ -92,29 +117,29 @@ 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 ) +if exist "build\bin\zy.exe" ( echo [X] build\bin\zy.exe - VM core interpreter ) else ( echo [ ] build\bin\zy.exe - not built ) +if exist "build\bin\zym.exe" ( echo [X] build\bin\zym.exe - portable microcore ) else ( echo [ ] build\bin\zym.exe - not built ) +if exist "build\bin\zc0.exe" ( echo [X] build\bin\zc0.exe - stage 0 bootstrap compiler ) else ( echo [ ] build\bin\zc0.exe - not built ) +if exist "build\bin\mkgenome.exe" ( echo [X] build\bin\mkgenome.exe - genome image checker ) else ( echo [ ] build\bin\mkgenome.exe - not built ) +if exist "build\bin\genmap.exe" ( echo [X] build\bin\genmap.exe - memory map generator ) else ( echo [ ] build\bin\genmap.exe - not built ) +if exist "build\bin\zclsp.exe" ( echo [X] build\bin\zclsp.exe - language server protocol ^& highlighter ) else ( echo [ ] build\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 [1] build VM core (build\bin\zy.exe) +echo [2] build microcore (build\bin\zym.exe) +echo [3] build bootstrap tools (zc0.exe, mkgenome.exe, genmap.exe) +echo [4] build LSP server ^& highlighter (build\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 build/js/tinyvm.js) +echo [7] run an example on the native VM (build\bin\zy.exe) +echo [8] run an example in the JavaScript VM (node build\js\tinyvm.js) echo [9] run a custom .zc source file -echo [L] check/highlight .zc with LSP (bin\zclsp.exe) +echo [L] check/highlight .zc with LSP (build\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 [G] rebuild the compiler genome and check the fixpoint +echo [C] clean generated output (build) echo [Q] quit echo =============================================================================== -set /p "CHOICE=select an option [1-9, L, R, B, C, Q]: " +set /p "CHOICE=select an option [1-9, L, R, G, C, Q]: " if /i "%CHOICE%"=="1" goto :menu_build_core if /i "%CHOICE%"=="2" goto :menu_build_micro @@ -127,7 +152,7 @@ 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%"=="g" goto :menu_genome if /i "%CHOICE%"=="c" goto :menu_clean if /i "%CHOICE%"=="q" exit /b 0 @@ -141,7 +166,6 @@ REM ========================================================================= :menu_build_core echo. -echo [Building zy.exe]... call :build_core echo. pause @@ -149,7 +173,6 @@ goto :main_menu :menu_build_micro echo. -echo [Building zym.exe]... call :build_micro echo. pause @@ -157,7 +180,6 @@ goto :main_menu :menu_build_tools echo. -echo [Building tools: zc0.exe, mkgenome.exe, genmap.exe]... call :build_tools echo. pause @@ -165,7 +187,6 @@ goto :main_menu :menu_build_lsp echo. -echo [Building zclsp.exe (LSP Server ^& Highlighter)]... call :build_lsp echo. pause @@ -173,14 +194,7 @@ 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 +call :build_all if errorlevel 1 goto :build_failed echo. echo [OK] Build complete. @@ -195,41 +209,23 @@ 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" +call :run_tests if errorlevel 1 echo [ERROR] Test suite failed. echo. pause goto :main_menu -:menu_bootstrap +:menu_genome echo. -echo [Running Bootstrap and Full Test Verification]... -call :build_tools +call :build_genome 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. +call :clean echo. pause goto :main_menu @@ -245,18 +241,15 @@ if not exist "%CUSTOM_FILE%" ( pause goto :main_menu ) - -if not exist "bin\zy.exe" ( - echo bin\zy.exe not found, building first... +if not exist "build\bin\zy.exe" ( call :build_core if errorlevel 1 goto :build_failed ) - echo. echo =============================================================================== echo Running: %CUSTOM_FILE% echo =============================================================================== -bin\zy.exe < "%CUSTOM_FILE%" +build\bin\zy.exe < "%CUSTOM_FILE%" echo. echo =============================================================================== pause @@ -272,18 +265,15 @@ if not exist "%LSP_FILE%" ( pause goto :main_menu ) - -if not exist "bin\zclsp.exe" ( - echo bin\zclsp.exe not found, building first... +if not exist "build\bin\zclsp.exe" ( call :build_lsp if errorlevel 1 goto :build_failed ) - echo. echo =============================================================================== -echo Analyzing with bin\zclsp.exe: %LSP_FILE% +echo Analyzing with build\bin\zclsp.exe: %LSP_FILE% echo =============================================================================== -bin\zclsp.exe < "%LSP_FILE%" +build\bin\zclsp.exe < "%LSP_FILE%" echo. echo =============================================================================== pause @@ -291,8 +281,7 @@ goto :main_menu :menu_repl echo. -if not exist "bin\zy.exe" ( - echo bin\zy.exe not found, building first... +if not exist "build\bin\zy.exe" ( call :build_core if errorlevel 1 goto :build_failed ) @@ -302,7 +291,7 @@ 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 +(type examples\repl.zc & echo ` & more) | build\bin\zy.exe echo. pause goto :main_menu @@ -316,47 +305,24 @@ 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 =============================================================================== +call :example_list 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" - +call :example_file "%EX_CHOICE%" if "%EX_FILE%"=="" ( echo Invalid choice. timeout /t 2 >nul goto :menu_examples ) - -if not exist "bin\zy.exe" ( +if not exist "build\bin\zy.exe" ( call :build_core if errorlevel 1 goto :build_failed ) - echo. echo =============================================================================== echo Running: %EX_FILE% echo =============================================================================== -bin\zy.exe < "%EX_FILE%" +build\bin\zy.exe < "%EX_FILE%" echo. echo =============================================================================== pause @@ -367,142 +333,216 @@ 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%"=="" ( +call :example_list +set /p "EX_CHOICE=Select an example [1-9, B]: " +if /i "%EX_CHOICE%"=="b" goto :main_menu +call :example_file "%EX_CHOICE%" +if "%EX_FILE%"=="" ( echo Invalid choice. timeout /t 2 >nul goto :menu_examples_js ) - +call :build_js +if errorlevel 1 goto :build_failed echo. echo =============================================================================== -echo Running in JS: %JS_EX_FILE% +echo Running in JS: %EX_FILE% echo =============================================================================== -node src\js\tinyvm.js "%JS_EX_FILE%" +node build\js\tinyvm.js "%EX_FILE%" echo. echo =============================================================================== pause goto :menu_examples_js +:example_list +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 compiler running inside TinyVM +echo [B] Back to main menu +echo =============================================================================== +exit /b 0 + +:example_file +set "EX_FILE=" +if "%~1"=="1" set "EX_FILE=examples\hello.zc" +if "%~1"=="2" set "EX_FILE=examples\fact.zc" +if "%~1"=="3" set "EX_FILE=examples\mandel.zc" +if "%~1"=="4" set "EX_FILE=examples\primes.zc" +if "%~1"=="5" set "EX_FILE=examples\life.zc" +if "%~1"=="6" set "EX_FILE=examples\lists.zc" +if "%~1"=="7" set "EX_FILE=examples\typed.zc" +if "%~1"=="8" set "EX_FILE=examples\wiring.zc" +if "%~1"=="9" set "EX_FILE=examples\bf.zc" +exit /b 0 + 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. +REM genmap needs no map; the default map comes from it and the zc sources' const blocks +:build_tools +if not exist "build\bin" mkdir build\bin +echo Compiling genmap.exe (memory map generator)... +"%CC%" -O2 -w -fwrapv src\tools\genmap.c -o build\bin\genmap.exe +if errorlevel 1 (echo [ERROR] Failed to build build\bin\genmap.exe.& exit /b 1) +if exist build\core\map rmdir /s /q build\core\map +if not exist build\core mkdir build\core +build\bin\genmap.exe --preset default --check -o build\core\map >nul +if errorlevel 1 (echo [ERROR] The default memory map does not match the sources.& exit /b 1) +echo Compiling zc0.exe (bootstrap compiler)... +"%CC%" -O1 -w -fwrapv src\tools\zc0.c -Isrc/core -Ibuild/core/map -o build\bin\zc0.exe +if errorlevel 1 (echo [ERROR] Failed to build build\bin\zc0.exe.& exit /b 1) +echo Compiling mkgenome.exe (genome image checker)... +"%CC%" -O1 -w -fwrapv src\tools\mkgenome.c -Ibuild/core/map -o build\bin\mkgenome.exe +if errorlevel 1 (echo [ERROR] Failed to build build\bin\mkgenome.exe.& exit /b 1) +echo [OK] Bootstrap tools built in build\bin. 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. +REM zc0 compiles the compiler to g0, g0 compiles it to g1, g1 to g2. g1 and g2 +REM must be identical, and g1 becomes build\core\genome.bin. +:build_genome +call :build_tools +if errorlevel 1 exit /b 1 +echo Bootstrapping the compiler genome... +if not exist build\s0 mkdir build\s0 +if not exist build\s1 mkdir build\s1 +(type src\runtime\rt.zc & type src\core\core.zc & type src\compiler\compiler.zc) | build\bin\zc0.exe > build\s0\g0.bin +if errorlevel 1 (echo [ERROR] Stage 0 failed.& exit /b 1) +build\bin\mkgenome.exe < build\s0\g0.bin > build\s0\genome.bin +if errorlevel 1 (echo [ERROR] Stage 0 did not produce a genome.& exit /b 1) +"%CC%" -O2 -w -fwrapv -DJTYPE=int src\core\core.c src\core\io_win.c -Isrc/core -Ibuild/core/map --embed-dir=build/s0 -o build\s0\zy0.exe +if errorlevel 1 (echo [ERROR] Failed to build the stage 0 core.& exit /b 1) +(type src\tools\build.zc & echo ` & type src\runtime\rt.zc & type src\core\core.zc & type src\compiler\compiler.zc) | build\s0\zy0.exe > build\s1\g1.bin +build\bin\mkgenome.exe < build\s1\g1.bin > build\s1\genome.bin +if errorlevel 1 (echo [ERROR] The compiler did not compile itself; its diagnostics are above.& exit /b 1) +"%CC%" -O2 -w -fwrapv -DJTYPE=int src\core\core.c src\core\io_win.c -Isrc/core -Ibuild/core/map --embed-dir=build/s1 -o build\s1\zy1.exe +if errorlevel 1 (echo [ERROR] Failed to build the stage 1 core.& exit /b 1) +(type src\tools\build.zc & echo ` & type src\runtime\rt.zc & type src\core\core.zc & type src\compiler\compiler.zc) | build\s1\zy1.exe > build\s1\g2.bin +fc /b build\s1\g1.bin build\s1\g2.bin >nul +if errorlevel 1 (echo [ERROR] Fixpoint failed: the compiler does not compile itself to the same image.& exit /b 1) +copy /y build\s1\genome.bin build\core\genome.bin >nul +echo [OK] Fixpoint reached; build\core\genome.bin updated. 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\. +:need_genome +if exist build\core\genome.bin if exist build\core\map\memmap.h exit /b 0 +call :build_genome +exit /b %errorlevel% + +:build_core +call :need_genome +if errorlevel 1 exit /b 1 +echo Compiling zy.exe (VM core with the compiler genome)... +"%CC%" -O2 -w -fwrapv -DJTYPE=int src\core\core.c src\core\io_win.c %COREINC% -o build\bin\zy.exe +if errorlevel 1 (echo [ERROR] Failed to build build\bin\zy.exe.& exit /b 1) +echo [OK] build\bin\zy.exe built. +exit /b 0 + +:build_micro +call :need_genome +if errorlevel 1 exit /b 1 +echo Compiling zym.exe (portable microcore)... +"%CC%" -O2 -w -fwrapv src\micro\micro.c src\micro\port_win.c %COREINC% -Isrc/micro -o build\bin\zym.exe +if errorlevel 1 (echo [ERROR] Failed to build build\bin\zym.exe.& exit /b 1) +echo [OK] build\bin\zym.exe built. exit /b 0 +REM the language server: the compiler in check mode plus src\lsp\server.zc, on a +REM map sized to the image (the steps of src/tools/automap.sh lsp with DOCS=1) :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" ( +if not exist "build\bin\genmap.exe" ( call :build_tools if errorlevel 1 exit /b 1 ) +echo Compiling zclsp.exe (language server ^& semantic highlighter)... 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 +mkdir build\lsp +call :lsp_pass "" "" image.bin +if errorlevel 1 exit /b 1 +call :words build\lsp\image.bin +set /a SLOT=(WORDS+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 +call :lsp_pass %DOCS_WORK% -DZC0DOCS image.bin +if errorlevel 1 exit /b 1 +call :words build\lsp\image.bin +set /a DOCS_SLOT=(WORDS+4095)/4096*4096 +set "DOCS_WORDS=!WORDS!" +call :lsp_pass %DOCS_SLOT% -DZC0DOCS lsp_genome.bin +if errorlevel 1 exit /b 1 +call :words build\lsp\lsp_genome.bin +if not "!WORDS!"=="!DOCS_WORDS!" (echo [ERROR] LSP genome changed length after map sizing.& exit /b 1) +copy /y build\lsp\map\memmap.h build\lsp\memmap.h >nul +"%CC%" -O2 -w -fwrapv -DJTYPE=int -DZY_SANDBOX -DUSE_LSP_GENOME src\core\core.c src\core\io_win.c -Isrc/core -Ibuild/lsp --embed-dir=build/lsp -o build\lsp\zclsp.exe +if errorlevel 1 (echo [ERROR] Failed to build zclsp.exe.& exit /b 1) +if not exist "build\bin" mkdir build\bin +copy /y build\lsp\zclsp.exe build\bin\zclsp.exe >nul +echo [OK] build\bin\zclsp.exe built with !WORDS! words. +exit /b 0 + +REM :lsp_pass genome-slot zc0-define output - lay out the lsp map (with that genome +REM slot, or the preset's own when it is empty) and compile the server image into it +:lsp_pass +if exist build\lsp\map rmdir /s /q build\lsp\map +if "%~1"=="" ( + build\bin\genmap.exe --preset lsp --grow -o build\lsp\map >nul 2>nul +) else ( + build\bin\genmap.exe --preset lsp --grow --genome %~1 -o build\lsp\map >nul 2>nul +) +if errorlevel 1 (echo [ERROR] Could not generate the LSP map.& exit /b 1) +"%CC%" -O1 -w -fwrapv %~2 src\tools\zc0.c -Ibuild/lsp/map -Isrc/core -o build\lsp\zc0.exe +if errorlevel 1 (echo [ERROR] Could not build the LSP stage 0 compiler.& exit /b 1) +"%CC%" -O1 -w -fwrapv src\tools\mkgenome.c -Ibuild/lsp/map -o build\lsp\mkgenome.exe +if errorlevel 1 (echo [ERROR] Could not build the LSP image checker.& exit /b 1) +(type build\lsp\map\rt.zc & type src\core\core.zc & type build\lsp\map\compiler.zc & type src\lsp\server.zc) | build\lsp\zc0.exe > build\lsp\raw.bin +if errorlevel 1 (echo [ERROR] Could not compile the LSP image.& exit /b 1) +build\lsp\mkgenome.exe < build\lsp\raw.bin > build\lsp\%~3 +if errorlevel 1 (echo [ERROR] The LSP image does not match its map.& exit /b 1) +exit /b 0 + +REM :words file - WORDS is the file's length in 64-bit words +:words +set /a WORDS=%~z1/8 +exit /b 0 + +REM the javascript vm: layout, genome and the compiled vm in build\js (needs node and tsc) +:build_js +call :need_genome if errorlevel 1 exit /b 1 -copy /y src\core\io_win.c build\lsp\src\ >nul +if not exist build\js mkdir build\js +node src\js\mklayout.js --map build\core\map\memmap.h --out build\js >nul +if errorlevel 1 (echo [ERROR] Could not write the javascript layout.& exit /b 1) +copy /y build\core\genome.bin build\js\genome.bin >nul +call tsc src\js\tinyvm.ts --target es2020 --lib es2020,dom --module commonjs --outDir build\js +if errorlevel 1 (echo [ERROR] Could not compile the javascript vm; tsc is needed.& exit /b 1) +exit /b 0 + +:build_all +call :build_genome if errorlevel 1 exit /b 1 -copy /y src\core\fops.h build\lsp\src\ >nul +call :build_core if errorlevel 1 exit /b 1 -copy /y src\core\bops.h build\lsp\src\ >nul +call :build_micro if errorlevel 1 exit /b 1 -copy /y src\core\stack.h build\lsp\src\ >nul +call :build_lsp +exit /b %errorlevel% + +:run_tests +call :build_core if errorlevel 1 exit /b 1 -copy /y build\lsp\map\memmap.h build\lsp\src\ >nul +call :build_micro 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. +powershell -NoProfile -ExecutionPolicy Bypass -File "tests\test_win.ps1" +exit /b %errorlevel% + +:clean +rmdir /s /q build 2>nul +echo [OK] Generated build directory removed. exit /b 0 REM ========================================================================= @@ -514,22 +554,24 @@ 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 "%ARG2%"=="" ( call :build_all & exit /b !errorlevel! ) + if /i "%ARG2%"=="all" ( call :build_all & exit /b !errorlevel! ) 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! ) + if /i "%ARG2%"=="js" ( call :build_js & exit /b !errorlevel! ) echo Unknown build target: %ARG2% exit /b 1 ) +if /i "%CMD%"=="genome" ( + call :build_genome + exit /b !errorlevel! +) + 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" + call :run_tests exit /b !errorlevel! ) @@ -539,11 +581,11 @@ if /i "%CMD%"=="run" ( echo Usage: tinyvm.bat run path\to\program.zc exit /b 1 ) - if not exist "bin\zy.exe" ( + if not exist "build\bin\zy.exe" ( call :build_core if errorlevel 1 exit /b 1 ) - bin\zy.exe < "%SOURCE_ARG%" + build\bin\zy.exe < "%SOURCE_ARG%" exit /b !errorlevel! ) @@ -553,11 +595,11 @@ if /i "%CMD%"=="run-micro" ( echo Usage: tinyvm.bat run-micro path\to\program.zc exit /b 1 ) - if not exist "bin\zym.exe" ( + if not exist "build\bin\zym.exe" ( call :build_micro if errorlevel 1 exit /b 1 ) - bin\zym.exe < "%SOURCE_ARG%" + build\bin\zym.exe < "%SOURCE_ARG%" exit /b !errorlevel! ) @@ -567,7 +609,9 @@ if /i "%CMD%"=="js" ( echo Usage: tinyvm.bat js path\to\program.zc exit /b 1 ) - node src\js\tinyvm.js "%SOURCE_ARG%" + call :build_js + if errorlevel 1 exit /b 1 + node build\js\tinyvm.js "%SOURCE_ARG%" exit /b !errorlevel! ) @@ -577,62 +621,43 @@ if /i "%CMD%"=="lsp" ( echo Usage: tinyvm.bat lsp path\to\program.zc exit /b 1 ) - if not exist "bin\zclsp.exe" ( + if not exist "build\bin\zclsp.exe" ( call :build_lsp if errorlevel 1 exit /b 1 ) - bin\zclsp.exe < "%SOURCE_ARG%" + build\bin\zclsp.exe < "%SOURCE_ARG%" exit /b !errorlevel! ) if /i "%CMD%"=="repl" ( - if not exist "bin\zy.exe" ( + if not exist "build\bin\zy.exe" ( call :build_core if errorlevel 1 exit /b 1 ) - (type examples\repl.zc & echo ` & more) | bin\zy.exe + (type examples\repl.zc & echo ` & more) | build\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. + call :clean 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 usage: tinyvm.bat [command] echo tinyvm.bat launch interactive build ^& run menu -echo tinyvm.bat build [all^|core^|micro^|tools^|lsp] -echo compile TinyVM executables +echo tinyvm.bat build [all^|core^|micro^|tools^|lsp^|js] +echo compile TinyVM executables into build\bin +echo tinyvm.bat genome rebuild build\core\genome.bin and check the fixpoint 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 test run the Windows test suite echo tinyvm.bat repl launch the resident compiler REPL -echo tinyvm.bat clean remove generated bin and build directories +echo tinyvm.bat clean remove the generated build directory +echo the compiler must support c23 #embed: clang 19 or gcc 15 and later. 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! |
