mir: implement proper short-circuit lowering (&&/||) via branch+phi; vm: add NYASH_VM_TRACE exec/phi logs and reg_load diagnostics; vm-fallback: minimal Void guards (push/get_position/line/column), MapBox.birth no-op; smokes: filter builtin Array/Map plugin notices; docs: CURRENT_TASK updated

This commit is contained in:
Selfhosting Dev
2025-09-26 03:30:59 +09:00
parent 041cef875a
commit fd56b8049a
45 changed files with 3022 additions and 204 deletions

View File

@ -50,8 +50,12 @@ filter_noise() {
grep -v "^\[UnifiedBoxRegistry\]" \
| grep -v "^\[FileBox\]" \
| grep -v "^Net plugin:" \
| grep -v "^\[.*\] Plugin" \
| grep -v "^\[.*\] Plugin" \
| grep -v "Using builtin StringBox" \
| grep -v "Using builtin ArrayBox" \
| grep -v "Using builtin MapBox" \
| grep -v "plugins/nyash-array-plugin" \
| grep -v "plugins/nyash-map-plugin" \
| grep -v "Phase 15.5: Everything is Plugin" \
| grep -v "cargo build -p nyash-string-plugin" \
| grep -v "^\[plugin-loader\] backend=" \
@ -140,13 +144,13 @@ run_nyash_vm() {
local tmpfile="/tmp/nyash_test_$$.nyash"
echo "$code" > "$tmpfile"
# プラグイン初期化メッセージを除外
NYASH_VM_USE_PY="$USE_PYVM" NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN=1 "$NYASH_BIN" "$tmpfile" "$@" 2>&1 | filter_noise
NYASH_VM_USE_PY="$USE_PYVM" NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN=1 "$NYASH_BIN" --backend vm "$tmpfile" "$@" 2>&1 | filter_noise
local exit_code=${PIPESTATUS[0]}
rm -f "$tmpfile"
return $exit_code
else
# プラグイン初期化メッセージを除外
NYASH_VM_USE_PY="$USE_PYVM" NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN=1 "$NYASH_BIN" "$program" "$@" 2>&1 | filter_noise
NYASH_VM_USE_PY="$USE_PYVM" NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN=1 "$NYASH_BIN" --backend vm "$program" "$@" 2>&1 | filter_noise
return ${PIPESTATUS[0]}
fi
}

View File

@ -0,0 +1,45 @@
#!/bin/bash
# forward_refs_2pass.sh - Forward references resolved via declaration indexing (2-pass)
source "$(dirname "$0")/../../../lib/test_runner.sh"
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/forward_refs_2pass_$$"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
cat > main.nyash << 'EOF'
static box Main {
main() {
// Bare function call to a static method declared later
print(id())
// new to a user-defined box declared later
local p = new Parser()
print(p.ok())
return 0
}
}
static box Util {
id() { return 7 }
}
box Parser {
ok() { return true }
}
EOF
expected=$(cat << 'TXT'
7
true
TXT
)
output=$(run_nyash_vm main.nyash)
compare_outputs "$expected" "$output" "forward_refs_2pass" || exit 1
cd /
rm -rf "$TEST_DIR"

View File

@ -0,0 +1,61 @@
#!/bin/bash
# forward_refs_using_ast_vm.sh - Forward references across using (AST prelude, VM backend)
source "$(dirname "$0")/../../../lib/test_runner.sh"
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/forward_refs_using_ast_vm_$$"
mkdir -p "$TEST_DIR/lib/u"
cd "$TEST_DIR"
# nyash.toml with a package + alias
cat > nyash.toml << EOF
[using.u]
path = "lib/u"
[using.aliases]
util = "u"
EOF
# Library package: lib/u/u.nyash
cat > lib/u/u.nyash << 'EOF'
static box Util {
id() { return 13 }
}
box Parser {
ok() { return true }
}
EOF
# Main uses the package alias and exercises forward refs (bare id, new Parser)
cat > main.nyash << 'EOF'
using util
static box Main {
main() {
print(id()) // bare call to static method in prelude
local p = new Parser() // instance box declared in prelude
print(p.ok())
return 0
}
}
EOF
expected=$(cat << 'TXT'
13
true
TXT
)
# Enable AST prelude in dev profile and run on VM (override NYASH_ROOT for local lib)
export NYASH_USING_PROFILE=dev
export NYASH_USING_AST=1
export NYASH_ROOT="$TEST_DIR"
output=$(run_nyash_vm main.nyash)
compare_outputs "$expected" "$output" "forward_refs_using_ast_vm" || exit 1
cd /
rm -rf "$TEST_DIR"

View File

@ -0,0 +1,66 @@
#!/bin/bash
# json_deep_nesting_ast.sh - Deeply nested arrays/objects roundtrip via AST using
source "$(dirname "$0")/../../../lib/test_runner.sh"
export SMOKES_USE_PYVM=1
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/json_deep_nesting_ast_$$"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
cat > nyash.toml << EOF
[using.json_native]
path = "$NYASH_ROOT/apps/lib/json_native/"
main = "parser/parser.nyash"
[using.aliases]
json = "json_native"
EOF
cat > driver.nyash << 'EOF'
using json_native as JsonParserModule
static box Main {
main() {
// Build a 20-level nested array: [[[[...0...]]]]
local open = "[[[[[[[[[[[[[[[[[[[" // 20 '['
local close = "]]]]]]]]]]]]]]]]]]]" // 20 ']'
local arr = open + "0" + close
// Build a 10-level nested object: {"a":{"a":{..."a":0...}}}
local i = 0
local obj = "0"
loop(i < 10) {
obj = "{\\"a\\":" + obj + "}"
i = i + 1
}
local samples = new ArrayBox()
samples.push(arr)
samples.push(obj)
local k = 0
loop(k < samples.length()) {
local s = samples.get(k)
local r = JsonParserModule.roundtrip_test(s)
print(r)
k = k + 1
}
return 0
}
}
EOF
expected=$(cat << 'TXT'
[[[[[[[[[[[[[[[[[[[0]]]]]]]]]]]]]]]]]]
{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":{"a":0}}}}}}}}}}
TXT
)
output=$(NYASH_LLVM_USE_HARNESS=1 run_nyash_llvm driver.nyash)
compare_outputs "$expected" "$output" "json_deep_nesting_ast"
cd /
rm -rf "$TEST_DIR"

View File

@ -0,0 +1,47 @@
#!/bin/bash
# json_error_messages_ast.sh - JSON error messages (line/column) via AST using
source "$(dirname "$0")/../../../lib/test_runner.sh"
export SMOKES_USE_PYVM=1
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/json_error_messages_ast_$$"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
cat > nyash.toml << EOF
[using.json_native]
path = "$NYASH_ROOT/apps/lib/json_native/"
main = "parser/parser.nyash"
[using.aliases]
json = "json_native"
EOF
cat > driver.nyash << 'EOF'
using json_native as JsonParserModule
static box Main {
main() {
local parser = JsonParserModule.create_parser()
// Single-character object start, triggers EOF then key error at pos 2
local res = parser.parse("{")
if parser.has_errors() {
local msgs = parser.get_error_messages()
// Print first message only
print(msgs.get(0))
} else {
print("NO_ERROR")
}
return 0
}
}
EOF
expected='Error at line 1, column 2: Expected string key in object'
output=$(NYASH_LLVM_USE_HARNESS=1 run_nyash_llvm driver.nyash)
compare_outputs "$expected" "$output" "json_error_messages_ast"
cd /
rm -rf "$TEST_DIR"

View File

@ -0,0 +1,58 @@
#!/bin/bash
# json_error_positions_ast.sh - Error UX (line/column) checks via AST using
source "$(dirname "$0")/../../../lib/test_runner.sh"
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/json_error_positions_ast_$$"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
cat > nyash.toml << EOF
[using.json_native]
path = "$NYASH_ROOT/apps/lib/json_native/"
main = "parser/parser.nyash"
[using.aliases]
json = "json_native"
EOF
cat > driver.nyash << 'EOF'
using json_native as JsonParserModule
static box Main {
main() {
// Case 1: missing comma in array
local p1 = JsonParserModule.create_parser()
local r1 = p1.parse("[1 2]")
if p1.has_errors() { print(p1.get_error_messages().get(0)) } else { print("NO_ERROR") }
// Case 2: unexpected character in literal
local p2 = JsonParserModule.create_parser()
local r2 = p2.parse("truX")
if p2.has_errors() { print(p2.get_error_messages().get(0)) } else { print("NO_ERROR") }
// Case 3: object missing comma (multi-line)
local json3 = "{\n\"a\": 1\n 2\n}"
local p3 = JsonParserModule.create_parser()
local r3 = p3.parse(json3)
if p3.has_errors() { print(p3.get_error_messages().get(0)) } else { print("NO_ERROR") }
return 0
}
}
EOF
expected=$(cat << 'TXT'
Error at line 1, column 4: Expected ',' or ']' in array
Error at line 1, column 1: Lexer error: Unknown keyword: truX
Error at line 3, column 3: Expected ',' or '}' in object
TXT
)
output=$("$NYASH_BIN" --backend vm driver.nyash 2>&1 | filter_noise)
compare_outputs "$expected" "$output" "json_error_positions_ast"
cd /
rm -rf "$TEST_DIR"

View File

@ -2,6 +2,7 @@
# json_errors_ast.sh - JSON error cases via AST using
source "$(dirname "$0")/../../../lib/test_runner.sh"
export SMOKES_USE_PYVM=1
require_env || exit 2
preflight_plugins || exit 2
@ -54,7 +55,7 @@ ERR
TXT
)
output=$("$NYASH_BIN" --backend vm driver.nyash 2>&1 | filter_noise)
output=$(NYASH_LLVM_USE_HARNESS=1 run_nyash_llvm driver.nyash)
compare_outputs "$expected" "$output" "json_errors_ast"
cd /

View File

@ -0,0 +1,40 @@
#!/bin/bash
# json_large_array_ast.sh - Large array roundtrip via AST using
source "$(dirname "$0")/../../../lib/test_runner.sh"
export SMOKES_USE_PYVM=1
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/json_large_array_ast_$$"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
cat > nyash.toml << EOF
[using.json_native]
path = "$NYASH_ROOT/apps/lib/json_native/"
main = "parser/parser.nyash"
[using.aliases]
json = "json_native"
EOF
cat > driver.nyash << 'EOF'
using json_native as JsonParserModule
static box Main {
main() {
local arr = "[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]"
local out = JsonParserUtils.roundtrip_test(arr)
print(out)
return 0
}
}
EOF
expected='[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]'
output=$(NYASH_LLVM_USE_HARNESS=1 run_nyash_llvm driver.nyash)
compare_outputs "$expected" "$output" "json_large_array_ast"
cd /
rm -rf "$TEST_DIR"

View File

@ -0,0 +1,47 @@
#!/bin/bash
# json_long_string_ast.sh - Long JSON string roundtrip via AST using
source "$(dirname "$0")/../../../lib/test_runner.sh"
export SMOKES_USE_PYVM=1
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/json_long_string_ast_$$"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
cat > nyash.toml << EOF
[using.json_native]
path = "$NYASH_ROOT/apps/lib/json_native/"
main = "parser/parser.nyash"
[using.aliases]
json = "json_native"
EOF
cat > driver.nyash << 'EOF'
using json_native as JsonParserModule
static box Main {
main() {
// Long ASCII string with common escapes; repeated to increase size
local payload = "A long string with quote \" and backslash \\ and newline \\n and tab \\t. "
local s = "\"" + payload + payload + payload + payload + "\"" // JSON string literal
local out = JsonParserModule.roundtrip_test(s)
print(out)
return 0
}
}
EOF
# Expected is the exact JSON string used (payload repeated 4x inside quotes)
expected=$(cat << 'TXT'
"A long string with quote \" and backslash \\ and newline \n and tab \t. A long string with quote \" and backslash \\ and newline \n and tab \t. A long string with quote \" and backslash \\ and newline \n and tab \t. A long string with quote \" and backslash \\ and newline \n and tab \t. "
TXT
)
output=$(run_nyash_vm driver.nyash)
compare_outputs "$expected" "$output" "json_long_string_ast"
cd /
rm -rf "$TEST_DIR"

View File

@ -2,6 +2,7 @@
# json_nested_ast.sh - Nested arrays/objects roundtrip via AST using
source "$(dirname "$0")/../../../lib/test_runner.sh"
export SMOKES_USE_PYVM=1
require_env || exit 2
preflight_plugins || exit 2
@ -31,7 +32,7 @@ static box Main {
local i = 0
loop(i < samples.length()) {
local s = samples.get(i)
local r = JsonParserModule.roundtrip_test(s)
local r = JsonParserUtils.roundtrip_test(s)
print(r)
i = i + 1
}
@ -47,7 +48,7 @@ expected=$(cat << 'TXT'
TXT
)
output=$("$NYASH_BIN" --backend vm driver.nyash 2>&1 | filter_noise)
output=$(NYASH_LLVM_USE_HARNESS=1 run_nyash_llvm driver.nyash)
compare_outputs "$expected" "$output" "json_nested_ast"
cd /

View File

@ -0,0 +1,56 @@
#!/bin/bash
# json_nested_vm.sh - Nested arrays/objects via AST using on VM backend
source "$(dirname "$0")/../../../lib/test_runner.sh"
export SMOKES_USE_PYVM=0
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/json_nested_vm_$$"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
cat > nyash.toml << EOF
[using.json_native]
path = "$NYASH_ROOT/apps/lib/json_native/"
main = "parser/parser.nyash"
[using.aliases]
json = "json_native"
EOF
cat > driver.nyash << 'EOF'
using json as JsonParserModule
static box Main {
main() {
local samples = new ArrayBox()
samples.push("[1,[2,3],{\"x\":[4]}]")
samples.push("{\"a\":{\"b\":[1,2]},\"c\":\"d\"}")
samples.push("{\"n\":-1e-3,\"z\":0.0}")
local i = 0
loop(i < samples.length()) {
local s = samples.get(i)
local p = JsonParserModule.create_parser()
local r = p.parse(s)
if (r == null) { print("null"); } else { print(r.toString()) }
i = i + 1
}
return 0
}
}
EOF
expected=$(cat << 'TXT'
[1,[2,3],{"x":[4]}]
{"a":{"b":[1,2]},"c":"d"}
{"n":-1e-3,"z":0.0}
TXT
)
output=$(NYASH_USING_PROFILE=dev NYASH_USING_AST=1 run_nyash_vm driver.nyash)
compare_outputs "$expected" "$output" "json_nested_vm" || exit 1
cd /
rm -rf "$TEST_DIR"

View File

@ -2,6 +2,7 @@
# json_roundtrip_ast.sh - JSON parse/stringify roundtrip via AST using
source "$(dirname "$0")/../../../lib/test_runner.sh"
export SMOKES_USE_PYVM=1
require_env || exit 2
preflight_plugins || exit 2
@ -42,7 +43,7 @@ static box Main {
local i = 0
loop(i < samples.length()) {
local s = samples.get(i)
local r = JsonParserModule.roundtrip_test(s)
local r = JsonParserUtils.roundtrip_test(s)
// Print each roundtrip result on its own line
print(r)
i = i + 1
@ -70,7 +71,7 @@ false
TXT
)
output=$("$NYASH_BIN" --backend vm driver.nyash 2>&1 | filter_noise)
output=$(NYASH_LLVM_USE_HARNESS=1 run_nyash_llvm driver.nyash)
compare_outputs "$expected" "$output" "json_roundtrip_ast"
cd /

View File

@ -0,0 +1,78 @@
#!/bin/bash
# json_roundtrip_vm.sh - JSON parse/stringify roundtrip via AST using on VM backend
source "$(dirname "$0")/../../../lib/test_runner.sh"
export SMOKES_USE_PYVM=0
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/json_roundtrip_vm_$$"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
cat > nyash.toml << EOF
[using.json_native]
path = "$NYASH_ROOT/apps/lib/json_native/"
main = "parser/parser.nyash"
[using.aliases]
json = "json_native"
EOF
cat > driver.nyash << 'EOF'
using json as JsonParserModule
static box Main {
main() {
local samples = new ArrayBox()
samples.push("null")
samples.push("true")
samples.push("false")
samples.push("42")
samples.push("-0")
samples.push("0")
samples.push("3.14")
samples.push("-2.5")
samples.push("6.02e23")
samples.push("-1e-9")
samples.push("\"hello\"")
samples.push("[]")
samples.push("{}")
samples.push("{\"a\":1}")
local i = 0
loop(i < samples.length()) {
local s = samples.get(i)
local p = JsonParserModule.create_parser()
local r = p.parse(s)
if (r == null) { print("null") } else { print(r.toString()) }
i = i + 1
}
return 0
}
}
EOF
expected=$(cat << 'TXT'
null
true
false
42
"hello"
[]
{}
{"a":1}
0
0
3.14
-2.5
6.02e23
-1e-9
TXT
)
output=$(NYASH_USING_PROFILE=dev NYASH_USING_AST=1 run_nyash_vm driver.nyash)
compare_outputs "$expected" "$output" "json_roundtrip_vm" || exit 1
cd /
rm -rf "$TEST_DIR"

View File

@ -1,63 +0,0 @@
#!/bin/bash
# json_string_escapes_ast.sh - JSON string escapes roundtrip via AST using
source "$(dirname "$0")/../../../lib/test_runner.sh"
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/json_string_escapes_ast_$$"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
cat > nyash.toml << EOF
[using.json_native]
path = "$NYASH_ROOT/apps/lib/json_native/"
main = "parser/parser.nyash"
[using.aliases]
json = "json_native"
EOF
cat > driver.nyash << 'EOF'
using json_native as JsonParserModule
static box Main {
main() {
// input → expected stringify
local inputs = new ArrayBox()
local expect = new ArrayBox()
inputs.push("\"A\""); expect.push("\"A\"")
inputs.push("\"\\n\" "); expect.push("\"\\n\"")
inputs.push("\"\\t\""); expect.push("\"\\t\"")
inputs.push("\"\\\\\""); expect.push("\"\\\\\"")
inputs.push("\"\\\"\""); expect.push("\"\\\"\"")
inputs.push("\"\\u0041\""); expect.push("\"A\"")
local i = 0
loop(i < inputs.length()) {
local s = inputs.get(i)
local r = JsonParserModule.roundtrip_test(s)
print(r)
i = i + 1
}
return 0
}
}
EOF
expected=$(cat << 'TXT'
"A"
"\n"
"\t"
"\\"
"\""
"A"
TXT
)
output=$("$NYASH_BIN" --backend vm driver.nyash 2>&1 | filter_noise)
compare_outputs "$expected" "$output" "json_string_escapes_ast"
cd /
rm -rf "$TEST_DIR"

View File

@ -0,0 +1,50 @@
#!/bin/bash
# json_unicode_basic_ast.sh - Basic \uXXXX handling via AST using
source "$(dirname "$0")/../../../lib/test_runner.sh"
export SMOKES_USE_PYVM=1
require_env || exit 2
preflight_plugins || exit 2
TEST_DIR="/tmp/json_unicode_basic_ast_$$"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
cat > nyash.toml << EOF
[using.json_native]
path = "$NYASH_ROOT/apps/lib/json_native/"
main = "parser/parser.nyash"
[using.aliases]
json = "json_native"
EOF
cat > driver.nyash << 'EOF'
using json_native as JsonParserModule
static box Main {
main() {
// Case 1: ASCII via \uXXXX becomes plain letters after roundtrip
local s1 = "\"A\\u0041\\u005A\"" // => "AAZ"
print(JsonParserUtils.roundtrip_test(s1))
// Case 2: control via \u000A becomes newline, stringifier emits \n
local s2 = "\"line\\u000Aend\""
print(JsonParserUtils.roundtrip_test(s2))
return 0
}
}
EOF
expected=$(cat << 'TXT'
"AAZ"
"line\nend"
TXT
)
output=$(NYASH_LLVM_USE_HARNESS=1 run_nyash_llvm driver.nyash)
compare_outputs "$expected" "$output" "json_unicode_basic_ast"
cd /
rm -rf "$TEST_DIR"