aboutsummaryrefslogtreecommitdiff
path: root/tinyvm.bat
diff options
context:
space:
mode:
Diffstat (limited to 'tinyvm.bat')
-rwxr-xr-xtinyvm.bat569
1 files changed, 297 insertions, 272 deletions
diff --git a/tinyvm.bat b/tinyvm.bat
index 9a457eb..7d0676d 100755
--- a/tinyvm.bat
+++ b/tinyvm.bat
@@ -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!