Skip to main content

walker_stash/
walker_stash.rs

1//! North-star example #2a for Step 2 (`docs/plan/README.md` §4
2//! Step 2.3): enumerate every named sub in the package tree via
3//! [`StashWalker`], then dump the OP tree (tree order, with statement
4//! line numbers) of the subs defined in the main script file.
5//!
6//! ```text
7//! cargo run --example walker_stash -- -e 'sub hello { my ($who) = @_; print "hi $who\n" }'
8//! ```
9//!
10//! Port of libperl-proto0's `105_scan_stash.rs` /
11//! `106_scan_allpackage.rs` onto the new newtype layer.
12
13use std::env;
14
15use libperl_rs::{Op, Perl, StashWalker};
16
17fn print_tree(perl: &Perl, op: Op, level: usize) {
18    let name = op.name().unwrap_or("<custom>");
19    let loc = op
20        .as_cop(perl)
21        .map(|cop| format!(" (line {})", cop.line()))
22        .unwrap_or_default();
23    println!("{}{name}{loc}", "  ".repeat(level));
24    for kid in op.kids() {
25        print_tree(perl, kid, level + 1);
26    }
27}
28
29fn main() {
30    let mut perl = Perl::new();
31    perl.parse_env_args(env::args(), env::vars());
32
33    let sv0 = perl.get_sv("0", 0).expect("$0 is always set");
34    let main_file = String::from_utf8_lossy(sv0.pv(&perl)).into_owned();
35    println!("$0 = {main_file:?}");
36
37    let mut walker = StashWalker::new(&perl);
38    walker.walk("main", &mut |e| {
39        let file = e.cv.file();
40        println!("sub {}::{} file {:?}", e.package, e.name, file);
41        if file.as_deref() == Some(main_file.as_str()) {
42            if let Some(root) = e.cv.root_op() {
43                print_tree(&perl, root, 1);
44            }
45        }
46    });
47}