diff --git a/.claude/rules.md b/.claude/rules.md index d7fddd31..34ad0fc9 100644 --- a/.claude/rules.md +++ b/.claude/rules.md @@ -15,7 +15,7 @@ Before considering any feature complete, run the full self-hosting chain: 2. `npm run verify:quick` — same but skips Stage 2 (day-to-day dev) Or manually: -1. `npm test` — all tests pass (auto-uses native compiler if `.build/chadc` exists) +1. `npm test` — all tests pass (auto-uses native compiler if `.build/chad` exists) 2. `bash scripts/self-hosting.sh` — full 3-stage self-hosting 3. `bash scripts/self-hosting.sh --quick` — skip Stage 2 @@ -82,7 +82,7 @@ Run tests: `npm test` or `npm run test:full` (via `node scripts/test.js`) Run tests + self-hosting: `npm run verify` (or `npm run verify:quick` to skip Stage 2) Build: `npm run build` (TypeScript → dist/) -Tests auto-detect `.build/chadc` and use it instead of `node dist/chadc-node.js` (~10x faster per compile). +Tests auto-detect `.build/chad` and use it instead of `node dist/chad-node.js` (~10x faster per compile). `compiler.test.ts` runs at concurrency 32; `smoke.test.ts` at concurrency 8. ## Useful Patterns diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ca2f10dd..a32394b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,37 +62,18 @@ jobs: clang -c -O2 -fPIC -I $TS_SRC -I $TS_INCLUDE $TS_SRC/scanner.c -o build/tree-sitter-typescript-scanner.o clang -c -O2 -fPIC -I vendor/tree-sitter/lib/include c_bridges/treesitter-bridge.c -o build/treesitter-bridge.o - - name: Build native compiler for tests - run: node dist/chadc-node.js src/chadc-native.ts -o .build/chadc - - - name: Smoke test native compiler - run: | - .build/chadc examples/hello.ts -o /tmp/hello - /tmp/hello - - - name: Run tests - run: npm test - - - name: Rebuild native chadc (static release) - run: node dist/chadc-node.js src/chadc-native.ts -o .build/chadc --static --target-cpu=x86-64 - - - name: Build native chad (static release) - run: node dist/chadc-node.js src/chad-native.ts -o .build/chad --static --target-cpu=x86-64 + - name: Build native chad (static) + run: node dist/chad-node.js build src/chad-native.ts -o .build/chad --static --target-cpu=x86-64 - name: Verify static binary run: | file .build/chad ldd .build/chad 2>&1 && echo "WARNING: not fully static" || echo "OK: static binary" - - name: Smoke test native chadc - run: | - .build/chadc examples/hello.ts -o /tmp/hello - /tmp/hello - - name: Smoke test native chad run: | - .build/chad build examples/hello.ts -o /tmp/hello2 - /tmp/hello2 + .build/chad build examples/hello.ts -o /tmp/hello + /tmp/hello - name: Run self-hosting tests run: node --import tsx --test tests/self-hosting.test.ts @@ -102,7 +83,6 @@ jobs: run: | mkdir -p release/lib cp .build/chad release/ - cp .build/chadc release/ cp build/tree-sitter-typescript-parser.o release/lib/ cp build/tree-sitter-typescript-scanner.o release/lib/ cp build/treesitter-bridge.o release/lib/ @@ -113,7 +93,7 @@ jobs: cp vendor/libwebsockets/build/lib/libwebsockets.a release/lib/ cp c_bridges/lws-bridge.o release/lib/ cp c_bridges/regex-bridge.o release/lib/ - tar -czf chadscript-linux-musl-x64.tar.gz -C release chad chadc lib + tar -czf chadscript-linux-musl-x64.tar.gz -C release chad lib - name: Upload artifact uses: actions/upload-artifact@v4 @@ -180,32 +160,13 @@ jobs: clang -c -O2 -fPIC -I $TS_SRC -I $TS_INCLUDE $TS_SRC/scanner.c -o build/tree-sitter-typescript-scanner.o clang -c -O2 -fPIC -I vendor/tree-sitter/lib/include c_bridges/treesitter-bridge.c -o build/treesitter-bridge.o - - name: Build native compiler for tests - run: node dist/chadc-node.js src/chadc-native.ts -o .build/chadc - - - name: Smoke test native compiler - run: | - .build/chadc examples/hello.ts -o /tmp/hello - /tmp/hello - - - name: Run tests - run: npm test - - - name: Rebuild native chadc (release) - run: node dist/chadc-node.js src/chadc-native.ts -o .build/chadc --target-cpu=x86-64 - - - name: Build native chad (release) - run: node dist/chadc-node.js src/chad-native.ts -o .build/chad --target-cpu=x86-64 - - - name: Smoke test native chadc - run: | - .build/chadc examples/hello.ts -o /tmp/hello - /tmp/hello + - name: Build native chad + run: node dist/chad-node.js build src/chad-native.ts -o .build/chad --target-cpu=x86-64 - name: Smoke test native chad run: | - .build/chad build examples/hello.ts -o /tmp/hello2 - /tmp/hello2 + .build/chad build examples/hello.ts -o /tmp/hello + /tmp/hello - name: Run self-hosting tests run: node --import tsx --test tests/self-hosting.test.ts @@ -215,7 +176,6 @@ jobs: run: | mkdir -p release/lib cp .build/chad release/ - cp .build/chadc release/ cp build/tree-sitter-typescript-parser.o release/lib/ cp build/tree-sitter-typescript-scanner.o release/lib/ cp build/treesitter-bridge.o release/lib/ @@ -226,7 +186,7 @@ jobs: cp vendor/libwebsockets/build/lib/libwebsockets.a release/lib/ cp c_bridges/lws-bridge.o release/lib/ cp c_bridges/regex-bridge.o release/lib/ - tar -czf chadscript-linux-x64.tar.gz -C release chad chadc lib + tar -czf chadscript-linux-x64.tar.gz -C release chad lib - name: Upload artifact uses: actions/upload-artifact@v4 @@ -284,40 +244,17 @@ jobs: clang -c -O2 -fPIC -I $TS_SRC -I $TS_INCLUDE $TS_SRC/scanner.c -o build/tree-sitter-typescript-scanner.o clang -c -O2 -fPIC -I vendor/tree-sitter/lib/include c_bridges/treesitter-bridge.c -o build/treesitter-bridge.o - - name: Build native compiler for tests - run: node dist/chadc-node.js src/chadc-native.ts -o .build/chadc - - - name: Sign native compiler - run: codesign --sign - --force .build/chadc - - - name: Smoke test native compiler - run: | - .build/chadc examples/hello.ts -o /tmp/hello - /tmp/hello - - - name: Run tests - run: npm test - - - name: Rebuild native chadc (release) - run: node dist/chadc-node.js src/chadc-native.ts -o .build/chadc - - - name: Build native chad (release) - run: node dist/chadc-node.js src/chad-native.ts -o .build/chad + - name: Build native chad + run: node dist/chad-node.js build src/chad-native.ts -o .build/chad - name: Sign macOS binaries run: | codesign --sign - --force .build/chad - codesign --sign - --force .build/chadc - - - name: Smoke test native chadc - run: | - .build/chadc examples/hello.ts -o /tmp/hello - /tmp/hello - name: Smoke test native chad run: | - .build/chad build examples/hello.ts -o /tmp/hello2 - /tmp/hello2 + .build/chad build examples/hello.ts -o /tmp/hello + /tmp/hello - name: Run self-hosting tests run: node --import tsx --test tests/self-hosting.test.ts @@ -327,7 +264,6 @@ jobs: run: | mkdir -p release/lib cp .build/chad release/ - cp .build/chadc release/ cp build/tree-sitter-typescript-parser.o release/lib/ cp build/tree-sitter-typescript-scanner.o release/lib/ cp build/treesitter-bridge.o release/lib/ @@ -338,7 +274,7 @@ jobs: cp vendor/libwebsockets/build/lib/libwebsockets.a release/lib/ cp c_bridges/lws-bridge.o release/lib/ cp c_bridges/regex-bridge.o release/lib/ - tar -czf chadscript-macos-arm64.tar.gz -C release chad chadc lib + tar -czf chadscript-macos-arm64.tar.gz -C release chad lib - name: Upload artifact uses: actions/upload-artifact@v4 @@ -383,7 +319,6 @@ jobs: - name: Verify binary run: | file ~/.chadscript/chad.bin - file ~/.chadscript/chadc.bin ls -la ~/.chadscript/lib/ - name: Smoke test - hello world @@ -394,7 +329,7 @@ jobs: - name: Smoke test - compile to binary run: | echo 'process.exit(42);' > /tmp/exit42.ts - chadc /tmp/exit42.ts -o /tmp/exit42 + chad build /tmp/exit42.ts -o /tmp/exit42 /tmp/exit42 || [ $? -eq 42 ] release: diff --git a/.github/workflows/cross-compile.yml b/.github/workflows/cross-compile.yml index 0d11a037..0ea14a36 100644 --- a/.github/workflows/cross-compile.yml +++ b/.github/workflows/cross-compile.yml @@ -39,7 +39,7 @@ jobs: - name: Cross-compile hello.ts for macOS arm64 run: | - node dist/chadc-node.js --keep-temps --target macos-arm64 --emit-llvm examples/hello.ts -o .build/hello-macos + node dist/chad-node.js ir --keep-temps --target macos-arm64 examples/hello.ts -o .build/hello-macos llc -mtriple=aarch64-apple-darwin -filetype=obj .build/hello-macos.ll -o .build/hello-macos.o - name: Verify object file format @@ -87,7 +87,7 @@ jobs: - name: Cross-compile hello.ts for Linux x64 run: | - node dist/chadc-node.js --keep-temps --target linux-x64 --emit-llvm examples/hello.ts -o .build/hello-linux + node dist/chad-node.js ir --keep-temps --target linux-x64 examples/hello.ts -o .build/hello-linux llc -mtriple=x86_64-unknown-linux-gnu -filetype=obj .build/hello-linux.ll -o .build/hello-linux.o - name: Verify object file format diff --git a/BUILDING.md b/BUILDING.md index e72a3f27..55cee675 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -49,7 +49,7 @@ npm run verify:quick # Full: run tests + self-hosting Stage 0-1-2 in parallel npm run verify -# Tests only (uses native compiler if .build/chadc exists) +# Tests only (uses native compiler if .build/chad exists) npm test # Self-hosting only @@ -76,9 +76,9 @@ export CHADSCRIPT_TREESITTER_PATH=/path/to/tree-sitter ChadScript can compile its own compiler to a native binary: ```bash -chadc src/chadc-native.ts -o /tmp/chad-stage0 +chad build src/chad-native.ts -o /tmp/chad-stage0 -/tmp/chad-stage0 src/chadc-native.ts -o /tmp/chad-stage1 +/tmp/chad-stage0 build src/chad-native.ts -o /tmp/chad-stage1 ``` The Stage 1 binary is a standalone native compiler that needs no Node.js runtime. diff --git a/benchmarks/run.sh b/benchmarks/run.sh index ce3f0bb4..a4bd4e32 100755 --- a/benchmarks/run.sh +++ b/benchmarks/run.sh @@ -3,7 +3,7 @@ set -e DIR="$(cd "$(dirname "$0")" && pwd)" REPO="$(dirname "$DIR")" -CHAD="$REPO/.build/chadc" +CHAD="$REPO/.build/chad" STARTUP_RUNS=50 HTTP_BENCH="$DIR/tools/httpbench" WS_BENCH="$DIR/tools/wsbench" @@ -303,40 +303,40 @@ echo "" echo "--- Building ---" -$CHAD "$DIR/startup/chadscript.ts" -o /tmp/bench-startup-chad +$CHAD build "$DIR/startup/chadscript.ts" -o /tmp/bench-startup-chad echo " ChadScript startup built" -$CHAD "$DIR/sqlite/chadscript.ts" -o /tmp/bench-sqlite-chad +$CHAD build "$DIR/sqlite/chadscript.ts" -o /tmp/bench-sqlite-chad echo " ChadScript SQLite built" -$CHAD "$DIR/matmul/chadscript.ts" -o /tmp/bench-matmul-chad +$CHAD build "$DIR/matmul/chadscript.ts" -o /tmp/bench-matmul-chad echo " ChadScript Matmul built" -$CHAD "$DIR/montecarlo/chadscript.ts" -o /tmp/bench-montecarlo-chad +$CHAD build "$DIR/montecarlo/chadscript.ts" -o /tmp/bench-montecarlo-chad echo " ChadScript Monte Carlo built" -$CHAD "$DIR/fibonacci/chadscript.ts" -o /tmp/bench-fibonacci-chad +$CHAD build "$DIR/fibonacci/chadscript.ts" -o /tmp/bench-fibonacci-chad echo " ChadScript Fibonacci built" -$CHAD "$DIR/sieve/chadscript.ts" -o /tmp/bench-sieve-chad +$CHAD build "$DIR/sieve/chadscript.ts" -o /tmp/bench-sieve-chad echo " ChadScript Sieve built" -$CHAD "$DIR/sorting/chadscript.ts" -o /tmp/bench-sorting-chad +$CHAD build "$DIR/sorting/chadscript.ts" -o /tmp/bench-sorting-chad echo " ChadScript Sorting built" -$CHAD "$DIR/nbody/chadscript.ts" -o /tmp/bench-nbody-chad +$CHAD build "$DIR/nbody/chadscript.ts" -o /tmp/bench-nbody-chad echo " ChadScript N-Body built" -$CHAD "$DIR/stringops/chadscript.ts" -o /tmp/bench-stringops-chad +$CHAD build "$DIR/stringops/chadscript.ts" -o /tmp/bench-stringops-chad echo " ChadScript String Ops built" -$CHAD "$DIR/fileio/chadscript.ts" -o /tmp/bench-fileio-chad +$CHAD build "$DIR/fileio/chadscript.ts" -o /tmp/bench-fileio-chad echo " ChadScript File I/O built" -$CHAD "$DIR/binarytrees/chadscript.ts" -o /tmp/bench-binarytrees-chad +$CHAD build "$DIR/binarytrees/chadscript.ts" -o /tmp/bench-binarytrees-chad echo " ChadScript Binary Trees built" -$CHAD "$DIR/json/chadscript.ts" -o /tmp/bench-json-chad +$CHAD build "$DIR/json/chadscript.ts" -o /tmp/bench-json-chad echo " ChadScript JSON built" $CHAD "$DIR/stringsearch/chadscript.ts" -o /tmp/bench-stringsearch-chad diff --git a/docs/getting-started/cli.md b/docs/getting-started/cli.md index be36a668..17c3bc30 100644 --- a/docs/getting-started/cli.md +++ b/docs/getting-started/cli.md @@ -55,14 +55,3 @@ chad clean | `--keep-temps` | Keep intermediate files (`.ll`, `.o`) | | `-fsanitize=address` | Build with AddressSanitizer (ASAN) | | `--skip-semantic-analysis` | Skip semantic analysis | - -## Direct Compiler - -The bare compiler is also available as `chadc`: - -```bash -chadc hello.ts # same as chad build hello.ts -chadc hello.ts -o myapp # same as chad build hello.ts -o myapp -``` - -`chadc` is the compiler binary itself. The `chad` wrapper adds convenience commands like `run`, `ir`, and `clean`. diff --git a/docs/language/architecture.md b/docs/language/architecture.md index 45261e56..881b79cd 100644 --- a/docs/language/architecture.md +++ b/docs/language/architecture.md @@ -91,13 +91,14 @@ ChadScript is self-hosting — the compiler (~45k lines of TypeScript across ~70 ```bash # Stage 0: Node.js compiles the compiler to a native binary -chadc src/chadc-native.ts -o chad-stage0 +# Stage 0: Node.js compiles the compiler to a native binary +chad build src/chad-native.ts -o chad-stage0 # Stage 1: The native binary compiles itself (no Node.js needed) -./chad-stage0 src/chadc-native.ts -o chad-stage1 +./chad-stage0 build src/chad-native.ts -o chad-stage1 # Stage 2: Verify correctness (Stage 1 output == Stage 2 output) -./chad-stage1 src/chadc-native.ts -o chad-stage2 +./chad-stage1 build src/chad-native.ts -o chad-stage2 ``` The Stage 2 binary proves the compiler's output is correct enough to reproduce itself. diff --git a/install.sh b/install.sh index a687efac..b24b589d 100755 --- a/install.sh +++ b/install.sh @@ -86,7 +86,6 @@ main() { tar -xzf "$TMPDIR/$TARBALL" -C "$INSTALL_DIR" mv "$INSTALL_DIR/chad" "$INSTALL_DIR/chad.bin" - mv "$INSTALL_DIR/chadc" "$INSTALL_DIR/chadc.bin" cat > "$INSTALL_DIR/chad" << 'WRAPPER' #!/bin/sh @@ -95,19 +94,11 @@ exec "$DIR/chad.bin" "$@" WRAPPER chmod +x "$INSTALL_DIR/chad" - cat > "$INSTALL_DIR/chadc" << 'WRAPPER' -#!/bin/sh -DIR=$(cd "$(dirname "$(command -v "$0")")" && pwd) -exec "$DIR/chadc.bin" "$@" -WRAPPER - chmod +x "$INSTALL_DIR/chadc" - if [ "$OS_TAG" = "macos" ]; then xattr -d com.apple.quarantine "$INSTALL_DIR/chad.bin" 2>/dev/null || true - xattr -d com.apple.quarantine "$INSTALL_DIR/chadc.bin" 2>/dev/null || true fi - success "Installed chad and chadc" + success "Installed chad" add_to_path diff --git a/package.json b/package.json index a5342cb7..b7a862f1 100644 --- a/package.json +++ b/package.json @@ -3,13 +3,12 @@ "version": "0.1.0", "description": "A JavaScript to native code compiler using LLVM", "type": "module", - "main": "dist/chadc-node.js", + "main": "dist/chad-node.js", "bin": { - "chad": "./dist/chad-node.js", - "chadc": "./dist/chadc-node.js" + "chad": "./dist/chad-node.js" }, "scripts": { - "compile": "tsx src/chadc-node.ts", + "compile": "tsx src/chad-node.ts build", "prebuild": "node scripts/embed-dts.js", "build": "tsc", "test": "node scripts/test.js", diff --git a/scripts/benchmark-stage1.sh b/scripts/benchmark-stage1.sh index 10b8d185..d408c44e 100755 --- a/scripts/benchmark-stage1.sh +++ b/scripts/benchmark-stage1.sh @@ -1,7 +1,7 @@ #!/bin/bash set -e -NATIVE_COMPILER=".build/src/chadc-native" +NATIVE_COMPILER=".build/src/chad-native" BENCH_DIR="/tmp/chadscript-benchmarks" RESULTS_FILE="$BENCH_DIR/results.txt" ITERATIONS=5 @@ -84,7 +84,7 @@ echo "" | tee -a "$RESULTS_FILE" echo "Building native compiler WITHOUT __gc_disable()..." | tee -a "$RESULTS_FILE" python3 - << 'PYEOF' -with open('src/chadc-native.ts', 'r') as f: +with open('src/chad-native.ts', 'r') as f: content = f.read() content = content.replace(' __gc_disable();\n', ' // __gc_disable(); // BENCHMARK: removed\n') with open('src/native-compiler-no-gc-disable.ts', 'w') as f: @@ -113,7 +113,7 @@ echo "" | tee -a "$RESULTS_FILE" echo "Building native compiler with generate() instead of generateParts()..." | tee -a "$RESULTS_FILE" python3 - << 'PYEOF' -with open('src/chadc-native.ts', 'r') as f: +with open('src/chad-native.ts', 'r') as f: content = f.read() old_block = """ const irParts = generator.generateParts(); @@ -167,7 +167,7 @@ for fixture in "${FIXTURES[@]}"; do name=$(basename "$fixture" | sed 's/\.[^.]*$//') rm -f "$BENCH_DIR/tsx-$name" "$BENCH_DIR/tsx-$name.ll" "$BENCH_DIR/tsx-$name.o" start=$(date +%s%N) - if timeout 60 npx tsx src/chadc-node.ts "$fixture" -o "$BENCH_DIR/tsx-$name" --skip-semantic-analysis > /dev/null 2>&1; then + if timeout 60 npx tsx src/chad-node.ts build "$fixture" -o "$BENCH_DIR/tsx-$name" --skip-semantic-analysis > /dev/null 2>&1; then end=$(date +%s%N) elapsed_ms=$(( (end - start) / 1000000 )) echo "tsx/$name: ${elapsed_ms}ms" | tee -a "$RESULTS_FILE" diff --git a/scripts/check-progress.ts b/scripts/check-progress.ts index 9a943484..d9343e9f 100644 --- a/scripts/check-progress.ts +++ b/scripts/check-progress.ts @@ -49,7 +49,7 @@ function compileCliProgram(): { success: boolean; error?: string } { } try { - execSync(`node dist/chadc-node.js ${sourceFile}`, { + execSync(`node dist/chad-node.js build ${sourceFile}`, { cwd: PROJECT_ROOT, stdio: 'pipe', encoding: 'utf8', diff --git a/scripts/run-cli-tests.ts b/scripts/run-cli-tests.ts index 845fb919..a9d2deaf 100644 --- a/scripts/run-cli-tests.ts +++ b/scripts/run-cli-tests.ts @@ -34,7 +34,7 @@ function compileCliProgram(): { success: boolean; binaryPath: string; error?: st console.log(`Output: ${binaryPath}`); try { - execSync(`node dist/chadc-node.js ${sourceFile}`, { + execSync(`node dist/chad-node.js build ${sourceFile}`, { cwd: PROJECT_ROOT, stdio: 'pipe', encoding: 'utf8', diff --git a/scripts/run-examples.js b/scripts/run-examples.js index 1a4361e3..8fd42d45 100644 --- a/scripts/run-examples.js +++ b/scripts/run-examples.js @@ -43,7 +43,7 @@ async function runCommand(cmd, args, options = {}) { async function compileExample(file) { const sourcePath = join(EXAMPLES_DIR, file); - const result = await runCommand('node', ['dist/chadc-node.js', sourcePath], { + const result = await runCommand('node', ['dist/chad-node.js', 'build', sourcePath], { timeout: 60000, }); return result; diff --git a/scripts/self-hosting.sh b/scripts/self-hosting.sh index 83c70ea1..2ca25db1 100755 --- a/scripts/self-hosting.sh +++ b/scripts/self-hosting.sh @@ -23,29 +23,29 @@ npm run build --silent || fail "npm run build" pass "tsc" step "Stage 0: Node.js builds native compiler" -node dist/chadc-node.js src/chadc-native.ts -o .build/chadc || fail "stage 0 build" -pass "built .build/chadc" +node dist/chad-node.js build src/chad-native.ts -o .build/chad || fail "stage 0 build" +pass "built .build/chad" -.build/chadc examples/hello.ts -o "$TMPDIR/hello0" || fail "stage 0 compile hello" +.build/chad build examples/hello.ts -o "$TMPDIR/hello0" || fail "stage 0 compile hello" OUTPUT=$("$TMPDIR/hello0" 2>&1) [[ "$OUTPUT" == *"Hello from ChadScript"* ]] || fail "stage 0 smoke test" pass "smoke test" step "Stage 1: Native compiler compiles itself" -.build/chadc src/chadc-native.ts -o "$TMPDIR/chad-stage1" || fail "stage 1 build" +.build/chad build src/chad-native.ts -o "$TMPDIR/chad-stage1" || fail "stage 1 build" pass "built stage1" -"$TMPDIR/chad-stage1" examples/hello.ts -o "$TMPDIR/hello1" || fail "stage 1 compile hello" +"$TMPDIR/chad-stage1" build examples/hello.ts -o "$TMPDIR/hello1" || fail "stage 1 compile hello" OUTPUT=$("$TMPDIR/hello1" 2>&1) [[ "$OUTPUT" == *"Hello from ChadScript"* ]] || fail "stage 1 smoke test" pass "smoke test" if [[ "$QUICK" == "false" ]]; then step "Stage 2: Stage 1 compiles itself" -"$TMPDIR/chad-stage1" src/chadc-native.ts -o "$TMPDIR/chad-stage2" || fail "stage 2 build" +"$TMPDIR/chad-stage1" build src/chad-native.ts -o "$TMPDIR/chad-stage2" || fail "stage 2 build" pass "built stage2" -"$TMPDIR/chad-stage2" examples/hello.ts -o "$TMPDIR/hello2" || fail "stage 2 compile hello" +"$TMPDIR/chad-stage2" build examples/hello.ts -o "$TMPDIR/hello2" || fail "stage 2 compile hello" OUTPUT=$("$TMPDIR/hello2" 2>&1) [[ "$OUTPUT" == *"Hello from ChadScript"* ]] || fail "stage 2 smoke test" pass "smoke test" diff --git a/scripts/verify.sh b/scripts/verify.sh index 2af17961..7f050016 100755 --- a/scripts/verify.sh +++ b/scripts/verify.sh @@ -29,13 +29,13 @@ npm run build --silent || fail "npm run build" pass "tsc" step "Stage 0: Building native compiler" -node dist/chadc-node.js src/chadc-native.ts -o .build/chadc || fail "stage 0 build" -pass "built .build/chadc" +node dist/chad-node.js build src/chad-native.ts -o .build/chad || fail "stage 0 build" +pass "built .build/chad" TMPDIR=$(mktemp -d) trap 'rm -rf "$TMPDIR"' EXIT -.build/chadc examples/hello.ts -o "$TMPDIR/hello0" || fail "stage 0 compile hello" +.build/chad build examples/hello.ts -o "$TMPDIR/hello0" || fail "stage 0 compile hello" OUTPUT=$("$TMPDIR/hello0" 2>&1) [[ "$OUTPUT" == *"Hello from ChadScript"* ]] || fail "stage 0 smoke test" pass "stage 0 smoke test" @@ -53,20 +53,20 @@ fi if [[ "$TESTS_ONLY" == "false" ]]; then step "Self-hosting: Stage 1" - .build/chadc src/chadc-native.ts -o "$TMPDIR/chad-stage1" || fail "stage 1 build" + .build/chad build src/chad-native.ts -o "$TMPDIR/chad-stage1" || fail "stage 1 build" pass "built stage1" - "$TMPDIR/chad-stage1" examples/hello.ts -o "$TMPDIR/hello1" || fail "stage 1 compile hello" + "$TMPDIR/chad-stage1" build examples/hello.ts -o "$TMPDIR/hello1" || fail "stage 1 compile hello" OUTPUT=$("$TMPDIR/hello1" 2>&1) [[ "$OUTPUT" == *"Hello from ChadScript"* ]] || fail "stage 1 smoke test" pass "stage 1 smoke test" if [[ "$QUICK" == "false" ]]; then step "Self-hosting: Stage 2" - "$TMPDIR/chad-stage1" src/chadc-native.ts -o "$TMPDIR/chad-stage2" || fail "stage 2 build" + "$TMPDIR/chad-stage1" build src/chad-native.ts -o "$TMPDIR/chad-stage2" || fail "stage 2 build" pass "built stage2" - "$TMPDIR/chad-stage2" examples/hello.ts -o "$TMPDIR/hello2" || fail "stage 2 compile hello" + "$TMPDIR/chad-stage2" build examples/hello.ts -o "$TMPDIR/hello2" || fail "stage 2 compile hello" OUTPUT=$("$TMPDIR/hello2" 2>&1) [[ "$OUTPUT" == *"Hello from ChadScript"* ]] || fail "stage 2 smoke test" pass "stage 2 smoke test" diff --git a/src/chad-native.ts b/src/chad-native.ts index c1d1d61f..e5cd122b 100644 --- a/src/chad-native.ts +++ b/src/chad-native.ts @@ -33,6 +33,7 @@ parser.addSubcommand('clean', 'Remove the .build directory'); parser.addFlag('version', '', 'Show version'); parser.addScopedOption('output', 'o', 'Specify output file', '', 'build,run,ir'); +parser.addScopedFlag('verbose', 'v', 'Show compilation steps', 'build,run,ir'); parser.addScopedFlag('skip-semantic-analysis', '', 'Skip semantic analysis', 'build,run,ir'); parser.addScopedOption('target-cpu', '', 'Set LLVM target CPU', 'native', 'build,run,ir'); parser.addPositional('input', 'Input .ts or .js file'); diff --git a/src/chad-node.ts b/src/chad-node.ts index 2c44b91d..43517987 100644 --- a/src/chad-node.ts +++ b/src/chad-node.ts @@ -1,6 +1,6 @@ #!/usr/bin/env node -import { compile, setSkipSemanticAnalysis, setKeepTemps, setEmitLLVMOnly, setSanitize, setDebugInfo, setTarget } from './compiler.js'; +import { compile, setSkipSemanticAnalysis, setKeepTemps, setEmitLLVMOnly, setSanitize, setDebugInfo, setTarget, setTargetCpu, setStaticLink } from './compiler.js'; import { LogLevel, logger } from './utils/logger.js'; import { runInit } from './codegen/stdlib/init-templates.js'; import * as path from 'path'; @@ -41,6 +41,8 @@ function printHelp(): void { console.log(' -fsanitize=address Build with AddressSanitizer'); console.log(' -g Emit DWARF debug info for source-level debugging'); console.log(' --target Cross-compile for target (e.g., macos-arm64, linux-x64)'); + console.log(' --target-cpu Set LLVM target CPU (default: native)'); + console.log(' --static Link statically'); console.log(' -h, --help Show this help message'); console.log(' --version Show version'); console.log(''); @@ -129,6 +131,15 @@ for (let i = 0; i < subArgs.length; i++) { setTarget(subArgs[i + 1]); skipNextArg = true; } + } else if (arg.startsWith('--target-cpu=')) { + setTargetCpu(arg.split('=')[1]); + } else if (arg === '--target-cpu') { + if (i + 1 < subArgs.length) { + setTargetCpu(subArgs[i + 1]); + skipNextArg = true; + } + } else if (arg === '--static') { + setStaticLink(true); } else if (arg === '-o') { if (i + 1 < subArgs.length) { outputArg = subArgs[i + 1]; diff --git a/src/chadc-native.ts b/src/chadc-native.ts deleted file mode 100644 index 82ce1e58..00000000 --- a/src/chadc-native.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { compileNative, setSkipSemanticAnalysis, setVerbose, setTargetCpu } from './native-compiler-lib.js'; -import { ArgumentParser } from '../lib/argparse.js'; - -declare const fs: { - existsSync(filename: string): boolean; -}; - -declare const path: { - resolve(p: string): string; - dirname(p: string): string; - basename(p: string): string; -}; - -declare const process: { - exit(code: number): never; - argv: string[]; -}; - -declare const child_process: { - execSync(command: string): number; -}; - -const parser = new ArgumentParser('chadc', 'compile TypeScript to native binaries via LLVM'); -parser.addFlag('verbose', 'v', 'Show compilation steps'); -parser.addFlag('skip-semantic-analysis', '', 'Skip semantic analysis'); -parser.addOption('output', 'o', 'Specify output file', ''); -parser.addOption('target-cpu', '', 'Set LLVM target CPU (default: native)', 'native'); -parser.addPositional('input', 'Input .ts or .js file'); - -parser.parse(process.argv); - -if (parser.getFlag('verbose')) { - setVerbose(true); -} - -if (parser.getFlag('skip-semantic-analysis')) { - setSkipSemanticAnalysis(true); -} - -const cpuOpt = parser.getOption('target-cpu'); -if (cpuOpt.length > 0) { - setTargetCpu(cpuOpt); -} - -const inputFile = parser.getPositional(0); -if (inputFile.length === 0) { - console.log('Error: No input file specified'); - parser.printHelp(); - process.exit(1); -} - -if (!fs.existsSync(inputFile)) { - console.log('Error: File not found: ' + inputFile); - process.exit(1); -} - -let inputForOutput: string = inputFile; -if (inputForOutput.substr(0, 1) === '/') { - inputForOutput = path.basename(inputForOutput); -} -let outputFile: string = '.build/' + inputForOutput; -const explicitOutput = parser.getOption('output'); -if (explicitOutput.length > 0) { - outputFile = explicitOutput; -} else if (inputForOutput.substr(inputForOutput.length - 3) === '.ts') { - outputFile = '.build/' + inputForOutput.substr(0, inputForOutput.length - 3); -} else if (inputForOutput.substr(inputForOutput.length - 3) === '.js') { - outputFile = '.build/' + inputForOutput.substr(0, inputForOutput.length - 3); -} - -const outputDir = path.dirname(outputFile); -if (!fs.existsSync(outputDir)) { - child_process.execSync('mkdir -p ' + outputDir); -} - -compileNative(inputFile, outputFile); diff --git a/src/chadc-node.ts b/src/chadc-node.ts deleted file mode 100644 index 8e5df624..00000000 --- a/src/chadc-node.ts +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env node - -import { compile, setSkipSemanticAnalysis, setKeepTemps, setEmitLLVMOnly, setSanitize, setDebugInfo, setStaticLink, setTargetCpu, setTarget } from './compiler.js'; -import { LogLevel, logger } from './utils/logger.js'; -import * as path from 'path'; -import * as fs from 'fs'; - -const args = process.argv.slice(2); - -let logLevel = LogLevel.Normal; -const fileArgs: string[] = []; -let skipNextArg = false; -let outputArg: string | null = null; - -for (let i = 0; i < args.length; i++) { - const arg = args[i]; - if (skipNextArg) { - skipNextArg = false; - continue; - } - if (arg === '-v' || arg === '--verbose') { - logLevel = LogLevel.Verbose; - } else if (arg === '--debug') { - logLevel = LogLevel.Debug; - } else if (arg === '--trace') { - logLevel = LogLevel.Trace; - } else if (arg === '--skip-semantic-analysis') { - setSkipSemanticAnalysis(true); - } else if (arg === '--keep-temps' || arg === '-save-temps') { - setKeepTemps(true); - } else if (arg === '--emit-llvm' || arg === '-S') { - setEmitLLVMOnly(true); - } else if (arg === '-fsanitize=address' || arg === '--sanitize=address') { - setSanitize('address'); - } else if (arg === '-g') { - setDebugInfo(true); - } else if (arg === '--static') { - setStaticLink(true); - } else if (arg.startsWith('--target-cpu=')) { - setTargetCpu(arg.split('=')[1]); - } else if (arg === '--target') { - if (i + 1 < args.length) { - setTarget(args[i + 1]); - skipNextArg = true; - } - } else if (arg === '-o') { - if (i + 1 < args.length) { - outputArg = args[i + 1]; - skipNextArg = true; - } - } else if (arg === '-h' || arg === '--help') { - console.log('chadc - ChadScript compiler'); - console.log(''); - console.log('Usage: chadc [options] [output]'); - console.log(''); - console.log('Options:'); - console.log(' -v, --verbose Show compilation steps'); - console.log(' --debug Show internal debugging information'); - console.log(' --trace Show everything (AST, IR, variable tracking)'); - console.log(' --skip-semantic-analysis Skip semantic analysis (for self-hosting)'); - console.log(' --emit-llvm, -S Output LLVM IR only (no binary)'); - console.log(' --keep-temps Keep intermediate files (.ll, .o)'); - console.log(' -fsanitize=address Build with AddressSanitizer (ASAN)'); - console.log(' -g Emit DWARF debug info for source-level debugging'); - console.log(' --static Produce a fully static binary (Linux only)'); - console.log(' --target-cpu=CPU Set LLVM target CPU (default: native)'); - console.log(' --target Cross-compile for target (e.g., macos-arm64, linux-x64)'); - console.log(' -h, --help Show this help message'); - console.log(''); - console.log('Examples:'); - console.log(' chadc hello.ts'); - console.log(' chadc hello.ts -o myapp'); - console.log(' chadc -v hello.ts'); - process.exit(0); - } else { - fileArgs.push(arg); - } -} - -if (fileArgs.length < 1) { - logger.error('chadc: error: no input files'); - logger.error('Usage: chadc [options] [output]'); - process.exit(1); -} - -const inputFile = fileArgs[0]; -const defaultOutput = path.join('.build', inputFile.replace(/\.(js|ts)$/, '')); -const outputFile = outputArg || fileArgs[1] || defaultOutput; - -const outputDir = path.dirname(outputFile); -if (!fs.existsSync(outputDir)) { - fs.mkdirSync(outputDir, { recursive: true }); -} - -try { - compile(inputFile, outputFile, logLevel); -} catch (error) { - logger.error((error as Error).message); - process.exit(1); -} diff --git a/tests/compiler.test.ts b/tests/compiler.test.ts index 5b1dc454..cf6caa64 100644 --- a/tests/compiler.test.ts +++ b/tests/compiler.test.ts @@ -10,11 +10,8 @@ import { testCases } from './test-fixtures'; const execAsync = promisify(exec); -const compiler = process.env.CHADC_COMPILER || '.build/chadc'; -if (!process.env.CHADC_COMPILER && !fsSync.existsSync('.build/chadc')) { - throw new Error('Native compiler not found at .build/chadc — run npm test to build it first'); -} -const compilerLabel = process.env.CHADC_COMPILER ? 'node' : 'native'; +const compiler = fsSync.existsSync('.build/chad') ? '.build/chad build' : 'node dist/chad-node.js build'; +const compilerLabel = fsSync.existsSync('.build/chad') ? 'native' : 'node'; describe(`ChadScript Compiler (${compilerLabel})`, () => { describe('Compilation and Execution', { concurrency: 32 }, () => { @@ -114,7 +111,7 @@ describe(`ChadScript Compiler (${compilerLabel})`, () => { try { // Compile with --keep-temps to preserve .ll file for inspection - await execAsync(`node dist/chadc-node.js --keep-temps ${fixturePath}`); + await execAsync(`node dist/chad-node.js build --keep-temps ${fixturePath}`); // Read and verify LLVM IR const llContent = await fs.readFile(llFile, 'utf-8'); @@ -557,7 +554,7 @@ await main(); const llFile = path.join(outputDir, `${baseName}.ll`); try { - await execAsync(`node dist/chadc-node.js --emit-llvm --target linux-x64 ${fixture}`); + await execAsync(`node dist/chad-node.js ir --target linux-x64 ${fixture}`); const ir = await fs.readFile(llFile, 'utf-8'); assert.ok(ir.includes('@stderr = external global i8*'), 'Linux target should use external stderr'); assert.ok(!ir.includes('__stderrp'), 'Linux target should not use __stderrp'); @@ -573,7 +570,7 @@ await main(); const llFile = path.join(outputDir, `${baseName}.ll`); try { - await execAsync(`node dist/chadc-node.js --emit-llvm --target macos-arm64 ${fixture}`); + await execAsync(`node dist/chad-node.js ir --target macos-arm64 ${fixture}`); const ir = await fs.readFile(llFile, 'utf-8'); assert.ok(ir.includes('@__stderrp = external global i8*'), 'macOS target should use __stderrp'); assert.ok(ir.includes('@__stdoutp = external global i8*'), 'macOS target should use __stdoutp'); @@ -589,7 +586,7 @@ await main(); const llFile = path.join(outputDir, `${baseName}.ll`); try { - await execAsync(`node dist/chadc-node.js --emit-llvm --target macos-arm64 ${fixture}`); + await execAsync(`node dist/chad-node.js ir --target macos-arm64 ${fixture}`); const ir = await fs.readFile(llFile, 'utf-8'); assert.ok(ir.includes('target triple = "aarch64-apple-darwin"'), 'Should contain target triple'); assert.ok(ir.includes('target datalayout = "'), 'Should contain target datalayout'); @@ -605,7 +602,7 @@ await main(); const llFile = '/tmp/test-cross-platform.ll'; try { - await execAsync(`node dist/chadc-node.js --emit-llvm --target macos-arm64 ${fixture} -o /tmp/test-cross-platform`); + await execAsync(`node dist/chad-node.js ir --target macos-arm64 ${fixture} -o /tmp/test-cross-platform`); const ir = await fs.readFile(llFile, 'utf-8'); assert.ok(ir.includes('darwin'), 'Cross-compiled IR should contain darwin platform string'); assert.ok(ir.includes('arm64'), 'Cross-compiled IR should contain arm64 arch string'); diff --git a/tests/examples.test.ts b/tests/examples.test.ts index cb8628cb..f310855e 100644 --- a/tests/examples.test.ts +++ b/tests/examples.test.ts @@ -48,7 +48,7 @@ describe('Examples Integration', { concurrency: 1 }, () => { } catch {} try { - const compileResult = await execAsync(`node dist/chadc-node.js ${sourcePath}`, { timeout: 60000 }); + const compileResult = await execAsync(`node dist/chad-node.js build ${sourcePath}`, { timeout: 60000 }); assert.ok(fsSync.existsSync(exeFile), `binary should exist at ${exeFile}`); const args = example.args ? example.args.join(' ') : ''; @@ -86,7 +86,7 @@ describe('Examples Integration', { concurrency: 1 }, () => { } catch {} try { - await execAsync(`node dist/chadc-node.js ${sourcePath}`, { timeout: 60000 }); + await execAsync(`node dist/chad-node.js build ${sourcePath}`, { timeout: 60000 }); assert.ok(fsSync.existsSync(exeFile), `binary should exist at ${exeFile}`); } finally { try { diff --git a/tests/http-routes.test.ts b/tests/http-routes.test.ts index 62b5a84b..ac800038 100644 --- a/tests/http-routes.test.ts +++ b/tests/http-routes.test.ts @@ -115,7 +115,7 @@ describe('HTTP Route Isolation Tests', { concurrency: 1 }, () => { await fs.mkdir('tests/fixtures/network', { recursive: true }); await fs.writeFile(SERVER_SOURCE, SERVER_CODE); - await execAsync(`node dist/chadc-node.js ${SERVER_SOURCE}`, { timeout: 60000 }); + await execAsync(`node dist/chad-node.js build ${SERVER_SOURCE}`, { timeout: 60000 }); assert.ok(fsSync.existsSync(SERVER_BINARY), 'Server binary should exist'); }); diff --git a/tests/network.test.ts b/tests/network.test.ts index e91595c8..24e553ea 100644 --- a/tests/network.test.ts +++ b/tests/network.test.ts @@ -33,7 +33,7 @@ testSocket(); try { // Compile - await execAsync(`node dist/chadc-node.js ${testFile}`); + await execAsync(`node dist/chad-node.js build ${testFile}`); // Run const { stdout, stderr } = await execAsync('.build/tests/fixtures/tcp-test-socket'); @@ -93,7 +93,7 @@ testTcpClient(); await fs.writeFile(clientFile, clientCode); // Compile and run - await execAsync(`node dist/chadc-node.js ${clientFile}`); + await execAsync(`node dist/chad-node.js build ${clientFile}`); const { stdout } = await execAsync('.build/tests/fixtures/tcp-client'); assert.ok(!stdout.includes('Socket failed'), 'Socket creation should work'); @@ -135,7 +135,7 @@ testTcpClient(); try { // Compile the fetch test fixture const testFile = 'tests/fixtures/network/fetch-integration-test.ts'; - await execAsync(`node dist/chadc-node.js ${testFile}`); + await execAsync(`node dist/chad-node.js build ${testFile}`); // Run the compiled program const { stdout, stderr } = await execAsync('.build/tests/fixtures/network/fetch-integration-test'); @@ -171,7 +171,7 @@ testTcpClient(); try { const testFile = 'tests/fixtures/network/promise-all-fetch-test.ts'; - await execAsync(`node dist/chadc-node.js ${testFile}`); + await execAsync(`node dist/chad-node.js build ${testFile}`); const { stdout } = await execAsync('.build/tests/fixtures/network/promise-all-fetch-test'); assert.ok(stdout.includes('TEST_PASSED'), 'Promise.all + fetch test should pass'); } finally { @@ -191,7 +191,7 @@ testTcpClient(); try { const testFile = 'tests/fixtures/network/async-fetch-test.ts'; - await execAsync(`node dist/chadc-node.js ${testFile}`); + await execAsync(`node dist/chad-node.js build ${testFile}`); const { stdout } = await execAsync('.build/tests/fixtures/network/async-fetch-test'); assert.ok(stdout.includes('TEST_PASSED'), 'async fetch test should pass'); } finally { @@ -214,7 +214,7 @@ testTcpClient(); try { const testFile = 'tests/fixtures/network/promise-all-concurrent.ts'; - await execAsync(`node dist/chadc-node.js ${testFile}`); + await execAsync(`node dist/chad-node.js build ${testFile}`); const { stdout } = await execAsync('.build/tests/fixtures/network/promise-all-concurrent'); assert.ok(stdout.includes('TEST_PASSED'), 'Promise.all concurrent test should pass'); } finally { @@ -224,7 +224,7 @@ testTcpClient(); it('should run Promise.race with resolved promises', async () => { const testFile = 'tests/fixtures/network/promise-race-test.ts'; - await execAsync(`node dist/chadc-node.js ${testFile}`); + await execAsync(`node dist/chad-node.js build ${testFile}`); const { stdout } = await execAsync('.build/tests/fixtures/network/promise-race-test'); assert.ok(stdout.includes('TEST_PASSED'), 'Promise.race test should pass'); }); @@ -260,7 +260,7 @@ httpServe(9997, handleRequest); await fs.writeFile(testFile, testCode); try { - await execAsync(`node dist/chadc-node.js ${testFile}`); + await execAsync(`node dist/chad-node.js build ${testFile}`); const serverProcess = spawn('.build/tests/fixtures/network/http-server-test', [], { detached: true, diff --git a/tests/self-hosting.test.ts b/tests/self-hosting.test.ts index 0d335c7f..f74af978 100644 --- a/tests/self-hosting.test.ts +++ b/tests/self-hosting.test.ts @@ -9,7 +9,7 @@ import { testCases, TestCase } from './test-fixtures'; const execAsync = promisify(exec); -const CHADC = '.build/chadc'; +const CHAD = '.build/chad'; const STAGE0 = '/tmp/chad-stage0'; const STAGE1 = '/tmp/chad-stage1'; const STAGE2 = '/tmp/chad-stage2'; @@ -107,31 +107,31 @@ async function runFixture(compiler: string, tc: TestCase, outDir: string): Promi } describe('Self-Hosting', { timeout: 600000 }, () => { - describe('Stage 0 (chadc): all fixtures', { concurrency: 4 }, () => { + describe('Stage 0 (chad): all fixtures', { concurrency: 4 }, () => { const outDir = path.join(FIXTURE_OUT_DIR, 'stage0'); before(() => { assert.ok( - fsSync.existsSync(CHADC), - `Native compiler not found at ${CHADC} — build it first with: npm run build && node dist/chadc-node.js src/chadc-native.ts -o .build/chadc` + fsSync.existsSync(CHAD), + `Native compiler not found at ${CHAD} — build it first with: npm run build && node dist/chad-node.js build src/chad-native.ts -o .build/chad` ); fsSync.mkdirSync(outDir, { recursive: true }); }); for (const tc of testCases) { const todo = STAGE0_TODO.has(tc.name) ? 'Stage 0 codegen limitation' : undefined; - it(`[chadc] ${tc.name}: ${tc.description}`, { todo }, async () => { - await runFixture(CHADC, tc, outDir); + it(`[chad] ${tc.name}: ${tc.description}`, { todo }, async () => { + await runFixture(`${CHAD} build`, tc, outDir); }); } }); describe('Self-hosting chain', { timeout: 600000 }, () => { - it('Node.js → Stage 0: compile chadc-native.ts', async () => { + it('Node.js → Stage 0: compile chad-native.ts', async () => { if (fsSync.existsSync(STAGE0)) fsSync.unlinkSync(STAGE0); await execAsync( - `node dist/chadc-node.js src/chadc-native.ts -o ${STAGE0}`, + `node dist/chad-node.js build src/chad-native.ts -o ${STAGE0}`, { timeout: 180000 } ); @@ -145,7 +145,7 @@ describe('Self-Hosting', { timeout: 600000 }, () => { const outBinary = '/tmp/hello-stage0'; try { - await execAsync(`${STAGE0} examples/hello.ts -o ${outBinary}`, { timeout: 30000, env: NATIVE_ENV }); + await execAsync(`${STAGE0} build examples/hello.ts -o ${outBinary}`, { timeout: 30000, env: NATIVE_ENV }); assert.ok(fsSync.existsSync(outBinary), 'Stage 0 should produce output binary'); const { stdout } = await execAsync(outBinary, { timeout: 10000 }); @@ -160,7 +160,7 @@ describe('Self-Hosting', { timeout: 600000 }, () => { if (fsSync.existsSync(STAGE1)) fsSync.unlinkSync(STAGE1); await execWithRetry( - `${STAGE0} -v src/chadc-native.ts -o ${STAGE1}`, + `${STAGE0} build -v src/chad-native.ts -o ${STAGE1}`, { timeout: 180000, env: NATIVE_ENV } ); @@ -174,7 +174,7 @@ describe('Self-Hosting', { timeout: 600000 }, () => { const outBinary = '/tmp/hello-stage1'; try { - await execAsync(`${STAGE1} examples/hello.ts -o ${outBinary}`, { timeout: 30000, env: NATIVE_ENV }); + await execAsync(`${STAGE1} build examples/hello.ts -o ${outBinary}`, { timeout: 30000, env: NATIVE_ENV }); assert.ok(fsSync.existsSync(outBinary), 'Stage 1 should produce output binary'); const { stdout } = await execAsync(outBinary, { timeout: 10000 }); @@ -189,7 +189,7 @@ describe('Self-Hosting', { timeout: 600000 }, () => { if (fsSync.existsSync(STAGE2)) fsSync.unlinkSync(STAGE2); await execWithRetry( - `${STAGE1} -v src/chadc-native.ts -o ${STAGE2}`, + `${STAGE1} build -v src/chad-native.ts -o ${STAGE2}`, { timeout: 180000, env: NATIVE_ENV } ); @@ -203,7 +203,7 @@ describe('Self-Hosting', { timeout: 600000 }, () => { const outBinary = '/tmp/hello-stage2'; try { - await execAsync(`${STAGE2} examples/hello.ts -o ${outBinary}`, { timeout: 30000, env: NATIVE_ENV }); + await execAsync(`${STAGE2} build examples/hello.ts -o ${outBinary}`, { timeout: 30000, env: NATIVE_ENV }); assert.ok(fsSync.existsSync(outBinary), 'Stage 2 should produce output binary'); const { stdout } = await execAsync(outBinary, { timeout: 10000 }); @@ -218,7 +218,7 @@ describe('Self-Hosting', { timeout: 600000 }, () => { if (fsSync.existsSync(STAGE3)) fsSync.unlinkSync(STAGE3); await execWithRetry( - `${STAGE2} -v src/chadc-native.ts -o ${STAGE3}`, + `${STAGE2} build -v src/chad-native.ts -o ${STAGE3}`, { timeout: 180000, env: NATIVE_ENV } ); @@ -232,7 +232,7 @@ describe('Self-Hosting', { timeout: 600000 }, () => { const outBinary = '/tmp/hello-stage3'; try { - await execAsync(`${STAGE3} examples/hello.ts -o ${outBinary}`, { timeout: 30000, env: NATIVE_ENV }); + await execAsync(`${STAGE3} build examples/hello.ts -o ${outBinary}`, { timeout: 30000, env: NATIVE_ENV }); assert.ok(fsSync.existsSync(outBinary), 'Stage 3 should produce output binary'); const { stdout } = await execAsync(outBinary, { timeout: 10000 }); @@ -253,8 +253,8 @@ describe('Self-Hosting', { timeout: 600000 }, () => { const s2LL = '/tmp/bootstrap-s2.ll'; try { - await execAsync(`${STAGE1} ${testFile} -o ${s1Out}`, { timeout: 30000, env: NATIVE_ENV }); - await execAsync(`${STAGE2} ${testFile} -o ${s2Out}`, { timeout: 30000, env: NATIVE_ENV }); + await execAsync(`${STAGE1} build ${testFile} -o ${s1Out}`, { timeout: 30000, env: NATIVE_ENV }); + await execAsync(`${STAGE2} build ${testFile} -o ${s2Out}`, { timeout: 30000, env: NATIVE_ENV }); const ll1 = await fs.readFile(s1LL, 'utf-8'); const ll2 = await fs.readFile(s2LL, 'utf-8'); @@ -278,8 +278,8 @@ describe('Self-Hosting', { timeout: 600000 }, () => { const s3LL = '/tmp/bootstrap-s3.ll'; try { - await execAsync(`${STAGE2} ${testFile} -o ${s2Out}`, { timeout: 30000, env: NATIVE_ENV }); - await execAsync(`${STAGE3} ${testFile} -o ${s3Out}`, { timeout: 30000, env: NATIVE_ENV }); + await execAsync(`${STAGE2} build ${testFile} -o ${s2Out}`, { timeout: 30000, env: NATIVE_ENV }); + await execAsync(`${STAGE3} build ${testFile} -o ${s3Out}`, { timeout: 30000, env: NATIVE_ENV }); const ll2 = await fs.readFile(s2LL, 'utf-8'); const ll3 = await fs.readFile(s3LL, 'utf-8'); @@ -307,7 +307,7 @@ describe('Self-Hosting', { timeout: 600000 }, () => { for (const tc of testCases) { const todo = STAGE1_TODO.has(tc.name) ? 'Stage 1 codegen limitation' : undefined; it(`[stage1] ${tc.name}: ${tc.description}`, { todo }, async () => { - await runFixture(STAGE1, tc, outDir); + await runFixture(`${STAGE1} build`, tc, outDir); }); } }); @@ -326,7 +326,7 @@ describe('Self-Hosting', { timeout: 600000 }, () => { for (const tc of testCases) { const todo = STAGE1_TODO.has(tc.name) ? 'Stage 2 codegen limitation' : undefined; it(`[stage2] ${tc.name}: ${tc.description}`, { todo }, async () => { - await runFixture(STAGE2, tc, outDir); + await runFixture(`${STAGE2} build`, tc, outDir); }); } }); diff --git a/tests/smoke.test.ts b/tests/smoke.test.ts index e2dc8dd0..63a9a03d 100644 --- a/tests/smoke.test.ts +++ b/tests/smoke.test.ts @@ -8,7 +8,7 @@ import * as path from 'node:path'; const execAsync = promisify(exec); -const compiler = fsSync.existsSync('.build/chadc') ? '.build/chadc' : 'node dist/chadc-node.js'; +const compiler = fsSync.existsSync('.build/chad') ? '.build/chad build' : 'node dist/chad-node.js build'; interface TestCase { name: string; diff --git a/tests/tcp-server-full.test.ts b/tests/tcp-server-full.test.ts index 4b3c34fe..43b22360 100644 --- a/tests/tcp-server-full.test.ts +++ b/tests/tcp-server-full.test.ts @@ -45,7 +45,7 @@ testBind(); try { // Compile - await execAsync(`node dist/chadc-node.js ${testFile}`); + await execAsync(`node dist/chad-node.js build ${testFile}`); // Run const { stdout } = await execAsync('.build/tests/fixtures/tcp-bind-test'); @@ -118,7 +118,7 @@ testAllSyscalls(); try { // Compile - await execAsync(`node dist/chadc-node.js ${testFile}`); + await execAsync(`node dist/chad-node.js build ${testFile}`); // Run const { stdout } = await execAsync('.build/tests/fixtures/tcp-syscalls-test'); @@ -208,7 +208,7 @@ testHttpHandler(); try { // Compile - await execAsync(`node dist/chadc-node.js ${testFile}`); + await execAsync(`node dist/chad-node.js build ${testFile}`); // Run const { stdout } = await execAsync('.build/tests/fixtures/http-handler-test'); diff --git a/tsconfig.json b/tsconfig.json index c1eb17a1..d8662da6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,5 +16,5 @@ "moduleResolution": "node" }, "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "tests", "src/chadc-native.ts", "src/chad-native.ts"] + "exclude": ["node_modules", "dist", "tests", "src/chad-native.ts"] }