fix(joinir): wire balanced depth-scan policy through Pattern2
This commit is contained in:
@ -476,6 +476,7 @@ fn eq_int(left: ASTNode, n: i64) -> ASTNode {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ast::Span;
|
||||
use crate::parser::NyashParser;
|
||||
|
||||
fn span() -> Span {
|
||||
Span::unknown()
|
||||
@ -520,6 +521,46 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn find_first_loop<'a>(node: &'a ASTNode) -> Option<(&'a ASTNode, &'a [ASTNode])> {
|
||||
match node {
|
||||
ASTNode::Loop { condition, body, .. } => Some((condition.as_ref(), body.as_slice())),
|
||||
ASTNode::Program { statements, .. } => statements.iter().find_map(find_first_loop),
|
||||
ASTNode::BoxDeclaration {
|
||||
methods,
|
||||
constructors,
|
||||
static_init,
|
||||
..
|
||||
} => {
|
||||
for v in methods.values() {
|
||||
if let Some(found) = find_first_loop(v) {
|
||||
return Some(found);
|
||||
}
|
||||
}
|
||||
for v in constructors.values() {
|
||||
if let Some(found) = find_first_loop(v) {
|
||||
return Some(found);
|
||||
}
|
||||
}
|
||||
if let Some(init) = static_init {
|
||||
if let Some(found) = init.iter().find_map(find_first_loop) {
|
||||
return Some(found);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
ASTNode::FunctionDeclaration { body, .. } => body.iter().find_map(find_first_loop),
|
||||
ASTNode::If {
|
||||
then_body,
|
||||
else_body,
|
||||
..
|
||||
} => then_body
|
||||
.iter()
|
||||
.find_map(find_first_loop)
|
||||
.or_else(|| else_body.as_ref()?.iter().find_map(find_first_loop)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detects_balanced_array_end_min_shape() {
|
||||
// loop(i < n) {
|
||||
@ -584,4 +625,29 @@ mod tests {
|
||||
assert!(result.carrier_updates_override.contains_key("i"));
|
||||
assert!(result.carrier_updates_override.contains_key("depth"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detects_balanced_array_end_min_shape_from_parser_ast() {
|
||||
let src = r#"
|
||||
static box Main {
|
||||
f(s, idx) {
|
||||
local n = s.length()
|
||||
if s.substring(idx, idx+1) != "[" { return -1 }
|
||||
local depth = 0
|
||||
local i = idx
|
||||
loop (i < n) {
|
||||
local ch = s.substring(i, i+1)
|
||||
if ch == "[" { depth = depth + 1 }
|
||||
if ch == "]" { depth = depth - 1 if depth == 0 { return i } }
|
||||
i = i + 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
}
|
||||
"#;
|
||||
let ast = NyashParser::parse_from_string(src).expect("parse ok");
|
||||
let (condition, body) = find_first_loop(&ast).expect("find loop");
|
||||
let decision = classify_balanced_depth_scan_array_end(condition, body);
|
||||
assert!(matches!(decision, PolicyDecision::Use(_)), "got {:?}", decision);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user