diff --git a/apps/tests/phase102_realapp_read_quoted_min.hako b/apps/tests/phase102_realapp_read_quoted_min.hako new file mode 100644 index 00000000..b6cc5714 --- /dev/null +++ b/apps/tests/phase102_realapp_read_quoted_min.hako @@ -0,0 +1,28 @@ +// Phase 102: real-app loop fixture (MiniJsonLoader.read_quoted_from) +// Goal: Fix accumulator + escape (+2) + quote-break in Pattern2/JoinIR, and keep VM/LLVM EXE parity. + +static box Main { + read_quoted_min(s, pos) { + local i = pos + if s.substring(i, i+1) != "\"" { return "" } + i = i + 1 + local out = "" + local n = s.length() + loop (i < n) { + local ch = s.substring(i, i+1) + if ch == "\"" { break } + if ch == "\\" { i = i + 1 ch = s.substring(i, i+1) } + out = out + ch + i = i + 1 + } + return out + } + + main() { + local s = "\"ab\\\"c\"" + local out = me.read_quoted_min(s, 0) + print(out.length()) + return "OK" + } +} + diff --git a/tools/smokes/v2/profiles/integration/apps/phase102_realapp_read_quoted_llvm_exe.sh b/tools/smokes/v2/profiles/integration/apps/phase102_realapp_read_quoted_llvm_exe.sh new file mode 100644 index 00000000..52d668ab --- /dev/null +++ b/tools/smokes/v2/profiles/integration/apps/phase102_realapp_read_quoted_llvm_exe.sh @@ -0,0 +1,120 @@ +#!/bin/bash +# Phase 102: real-app read_quoted loop (LLVM EXE parity) + +source "$(dirname "$0")/../../../lib/test_runner.sh" +export SMOKES_USE_PYVM=0 +require_env || exit 2 + +# LLVM availability checks (graceful SKIP) +if ! command -v llvm-config-18 &> /dev/null; then + test_skip "llvm-config-18 not found"; exit 0 +fi + +if ! "$NYASH_BIN" --help 2>&1 | grep -q "llvm"; then + test_skip "hakorune --backend llvm not available"; exit 0 +fi + +if ! python3 -c "import llvmlite" 2>/dev/null; then + test_skip "Python llvmlite not found"; exit 0 +fi + +# Phase 97/98/100 SSOT: plugin dlopen check → build only if needed → dlopen recheck. +FILEBOX_SO="$NYASH_ROOT/plugins/nyash-filebox-plugin/libnyash_filebox_plugin.so" +MAPBOX_SO="$NYASH_ROOT/plugins/nyash-map-plugin/libnyash_map_plugin.so" +STRINGBOX_SO="$NYASH_ROOT/plugins/nyash-string-plugin/libnyash_string_plugin.so" +CONSOLEBOX_SO="$NYASH_ROOT/plugins/nyash-console-plugin/libnyash_console_plugin.so" +INTEGERBOX_SO="$NYASH_ROOT/plugins/nyash-integer-plugin/libnyash_integer_plugin.so" + +check_plugins() { + python3 - "$FILEBOX_SO" "$MAPBOX_SO" "$STRINGBOX_SO" "$CONSOLEBOX_SO" "$INTEGERBOX_SO" <<'PY' +import ctypes +import os +import sys +names = ["FileBox", "MapBox", "StringBox", "ConsoleBox", "IntegerBox"] +paths = sys.argv[1:] +failures = [] +for name, path in zip(names, paths): + if not os.path.isfile(path): + failures.append(f"[plugin/missing] {name}: {path}") + continue + try: + ctypes.CDLL(path) + except Exception as e: # noqa: BLE001 + failures.append(f"[plugin/dlopen] {name}: {path} ({e})") +if failures: + print("\n".join(failures)) + sys.exit(1) +print("OK") +PY +} + +echo "[INFO] Checking plugin artifacts (FileBox/MapBox/StringBox/ConsoleBox/IntegerBox)" +if ! CHECK_OUTPUT=$(check_plugins 2>&1); then + echo "$CHECK_OUTPUT" + echo "[INFO] Missing/broken plugin detected, running build-all (core plugins)" + BUILD_LOG="/tmp/phase102_realapp_read_quoted_plugin_build.log" + if ! bash "$NYASH_ROOT/tools/plugins/build-all.sh" \ + nyash-filebox-plugin nyash-map-plugin nyash-string-plugin nyash-console-plugin nyash-integer-plugin \ + >"$BUILD_LOG" 2>&1; then + echo "[FAIL] tools/plugins/build-all.sh failed for core plugins" + tail -n 80 "$BUILD_LOG" + exit 1 + fi + if ! CHECK_OUTPUT=$(check_plugins 2>&1); then + echo "$CHECK_OUTPUT" + echo "[FAIL] Plugin artifacts still missing or unloadable after build-all" + tail -n 80 "$BUILD_LOG" + exit 1 + fi +fi + +mkdir -p "$NYASH_ROOT/tmp" + +INPUT_HAKO="$NYASH_ROOT/apps/tests/phase102_realapp_read_quoted_min.hako" +OUTPUT_EXE="$NYASH_ROOT/tmp/phase102_realapp_read_quoted_min" + +echo "[INFO] Building: $INPUT_HAKO → $OUTPUT_EXE" + +BUILD_LOG="/tmp/phase102_realapp_read_quoted_build.log" +if ! env NYASH_DISABLE_PLUGINS=0 "$NYASH_ROOT/tools/build_llvm.sh" "$INPUT_HAKO" -o "$OUTPUT_EXE" 2>&1 | tee "$BUILD_LOG"; then + echo "[FAIL] build_llvm.sh failed" + tail -n 80 "$BUILD_LOG" + exit 1 +fi + +if [ ! -x "$OUTPUT_EXE" ]; then + echo "[FAIL] Executable not created or not executable: $OUTPUT_EXE" + ls -la "$OUTPUT_EXE" 2>/dev/null || echo "File does not exist" + exit 1 +fi + +echo "[INFO] Executing: $OUTPUT_EXE" + +set +e +OUTPUT=$(timeout "${RUN_TIMEOUT_SECS:-10}" env NYASH_DISABLE_PLUGINS=0 "$OUTPUT_EXE" 2>&1) +EXIT_CODE=$? +set -e + +if [ "$EXIT_CODE" -ne 0 ]; then + echo "[FAIL] Execution failed with exit code $EXIT_CODE" + echo "$OUTPUT" | tail -n 80 + exit 1 +fi + +CLEAN=$(printf "%s\n" "$OUTPUT" | grep -E '^-?[0-9]+$' | head -n 1 | tr -d '\r') +EXPECTED="4" + +echo "[INFO] CLEAN output:" +echo "$CLEAN" + +if [ "$CLEAN" = "$EXPECTED" ]; then + test_pass "phase102_realapp_read_quoted_llvm_exe: output matches expected (4)" +else + echo "[FAIL] Output mismatch" + echo "[INFO] Raw output (tail):" + echo "$OUTPUT" | tail -n 80 + echo "[INFO] Expected:" + printf "%s\n" "$EXPECTED" + exit 1 +fi + diff --git a/tools/smokes/v2/profiles/integration/apps/phase102_realapp_read_quoted_vm.sh b/tools/smokes/v2/profiles/integration/apps/phase102_realapp_read_quoted_vm.sh new file mode 100644 index 00000000..20928e28 --- /dev/null +++ b/tools/smokes/v2/profiles/integration/apps/phase102_realapp_read_quoted_vm.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Phase 102: real-app read_quoted loop (VM) +# +# Fixture extracted from MiniJsonLoader.read_quoted_from: +# - out = out + ch (string accumulator) +# - escape branch consumes 2 chars (\X) +# - quote terminator breaks + +source "$(dirname "$0")/../../../lib/test_runner.sh" +export SMOKES_USE_PYVM=0 +require_env || exit 2 + +PASS_COUNT=0 +FAIL_COUNT=0 +RUN_TIMEOUT_SECS=${RUN_TIMEOUT_SECS:-10} + +INPUT="$NYASH_ROOT/apps/tests/phase102_realapp_read_quoted_min.hako" + +echo "[INFO] Phase 102: real-app read_quoted loop (VM) - $INPUT" + +set +e +OUTPUT=$(timeout "$RUN_TIMEOUT_SECS" env \ + NYASH_DISABLE_PLUGINS=1 \ + HAKO_JOINIR_STRICT=1 \ + "$NYASH_BIN" --backend vm "$INPUT" 2>&1) +EXIT_CODE=$? +set -e + +if [ "$EXIT_CODE" -eq 124 ]; then + echo "[FAIL] hakorune timed out (>${RUN_TIMEOUT_SECS}s)" + FAIL_COUNT=$((FAIL_COUNT + 1)) +elif [ "$EXIT_CODE" -eq 0 ]; then + EXPECTED="4" + CLEAN=$(printf "%s\n" "$OUTPUT" | grep -E '^-?[0-9]+$' | head -n 1 | tr -d '\r') + if [ "$CLEAN" = "$EXPECTED" ]; then + echo "[PASS] Output verified: 4" + PASS_COUNT=$((PASS_COUNT + 1)) + else + echo "[FAIL] Unexpected output (expected: 4)" + echo "[INFO] output (tail):" + echo "$OUTPUT" | tail -n 50 || true + FAIL_COUNT=$((FAIL_COUNT + 1)) + fi +else + echo "[FAIL] hakorune failed with exit code $EXIT_CODE" + echo "[INFO] output (tail):" + echo "$OUTPUT" | tail -n 50 || true + FAIL_COUNT=$((FAIL_COUNT + 1)) +fi + +echo "[INFO] PASS: $PASS_COUNT, FAIL: $FAIL_COUNT" + +if [ "$FAIL_COUNT" -eq 0 ]; then + test_pass "phase102_realapp_read_quoted_vm: All tests passed" + exit 0 +else + test_fail "phase102_realapp_read_quoted_vm: $FAIL_COUNT test(s) failed" + exit 1 +fi +