diff options
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! |
