## Phase 71-SSA: StageBDriverBox birth warning 解消 - Fixed false-positive dev verify warning for static boxes - StageBDriverBox is a static box, so it doesn't follow NewBox→birth pattern - Modified lifecycle.rs to skip StageBDriverBox from birth() requirement ## Phase 73-A: Stage-3 legacy ENV 統一化 - Consolidated NYASH_PARSER_STAGE3 and HAKO_PARSER_STAGE3 → NYASH_FEATURES=stage3 - Updated 20 test files (46 direct replacements) - Special handling for parser_stage3.rs compat layer and mir_static_main_args_loop.rs - All test files now use unified NYASH_FEATURES=stage3 ## Phase 72-73: ENV inventory documented - Created phase72-73-env-inventory.md with complete usage analysis - Identified 113 direct ENV reads requiring SSOT consolidation - Prioritized Phase 72 (JoinIR EXPERIMENT SSOT) and Phase 73 (Stage-3 cleanup) ## Phase 74-SSA: Minimal reproduction for static box delegation - Created parser_box_minimal.hako and ssa_static_delegation_min.hako - Investigated spawn failure in selfhost compiler (arguments too long) - Root cause: NYASH_NY_COMPILER_EMIT_ONLY=1 defaults to emit-only mode 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
86 lines
2.1 KiB
Rust
86 lines
2.1 KiB
Rust
use crate::parser::NyashParser;
|
||
|
||
fn enable_stage3() {
|
||
std::env::set_var("NYASH_FEATURES", "stage3");
|
||
// Accept block‑postfix under Stage‑3 gate
|
||
std::env::set_var("NYASH_BLOCK_CATCH", "1");
|
||
}
|
||
|
||
#[test]
|
||
fn block_postfix_catch_basic() {
|
||
enable_stage3();
|
||
let src = r#"
|
||
{
|
||
print("x")
|
||
throw "IO"
|
||
} catch (e) {
|
||
print(e)
|
||
}
|
||
"#;
|
||
let ast = NyashParser::parse_from_string(src).expect("parse ok");
|
||
fn has_try(ast: &crate::ast::ASTNode) -> bool {
|
||
match ast {
|
||
crate::ast::ASTNode::TryCatch { .. } => true,
|
||
crate::ast::ASTNode::Program { statements, .. } => statements.iter().any(has_try),
|
||
_ => false,
|
||
}
|
||
}
|
||
assert!(has_try(&ast), "expected TryCatch from block‑postfix catch");
|
||
}
|
||
|
||
#[test]
|
||
fn block_postfix_cleanup_only() {
|
||
enable_stage3();
|
||
let src = r#"
|
||
{
|
||
print("ok")
|
||
} cleanup {
|
||
print("done")
|
||
}
|
||
"#;
|
||
let ast = NyashParser::parse_from_string(src).expect("parse ok");
|
||
// Ensure TryCatch with empty catches and Some(cleanup)
|
||
fn check(ast: &crate::ast::ASTNode) -> bool {
|
||
match ast {
|
||
crate::ast::ASTNode::TryCatch {
|
||
catch_clauses,
|
||
finally_body,
|
||
..
|
||
} => catch_clauses.is_empty() && finally_body.is_some(),
|
||
crate::ast::ASTNode::Program { statements, .. } => statements.iter().any(check),
|
||
_ => false,
|
||
}
|
||
}
|
||
assert!(check(&ast), "expected TryCatch with cleanup only");
|
||
}
|
||
|
||
#[test]
|
||
fn block_without_catch_with_direct_throw_should_error() {
|
||
enable_stage3();
|
||
let src = r#"
|
||
{ throw "Oops" }
|
||
"#;
|
||
assert!(NyashParser::parse_from_string(src).is_err());
|
||
}
|
||
|
||
#[test]
|
||
fn multiple_catch_after_block_should_error() {
|
||
enable_stage3();
|
||
let src = r#"
|
||
{ print("x") }
|
||
catch (e) { print(e) }
|
||
catch (e2) { print(e2) }
|
||
"#;
|
||
assert!(NyashParser::parse_from_string(src).is_err());
|
||
}
|
||
|
||
#[test]
|
||
fn cannot_attach_catch_to_if_block() {
|
||
enable_stage3();
|
||
let src = r#"
|
||
if true { print("x") }
|
||
catch (e) { print(e) }
|
||
"#;
|
||
assert!(NyashParser::parse_from_string(src).is_err());
|
||
}
|