109_scan_subs_intro1/
109_scan_subs_intro1.rs1#[cfg(perlapi_ver26)]
2use std::env;
3
4#[cfg(perlapi_ver26)]
5use libperl_rs::*;
6
7#[cfg(perlapi_ver26)]
8use libperl_sys::opcode;
9
10#[cfg(perlapi_ver26)]
11mod eg;
12#[cfg(perlapi_ver26)]
13use eg::{op1::*,sv0::*,cv0::*,stash_walker0::*};
14
15#[cfg(perlapi_ver26)]
16fn match_param_list(op: &Op) -> Vec<PadNameType> {
17 let mut res: Vec<PadNameType> = Vec::new();
18 if let Op::UNOP(opcode::OP_NULL, _,
19 Op::OP(opcode::OP_PUSHMARK, _, _, ref args_op), _) = op {
20 let mut args_op = args_op;
21 while let Op::OP(_, _, Some(arg), rest) = args_op {
22 res.push(arg.clone());
23 if let Op::NULL = rest {
24 break
25 }
26 args_op = rest;
27 }
28 }
29 res
30}
31
32#[cfg(perlapi_ver26)]
33fn my_test() {
34 let mut perl = Perl::new();
35 perl.parse_env_args(env::args(), env::vars());
36
37 let op_extractor = OpExtractor::new(&perl);
38
39 let main_file = sv_extract_pv(perl.get_sv("0", 0)).unwrap();
40 println!("$0 = {:?}", main_file);
41
42 let filter = |cv| CvFILE(cv).map_or(false, |s| s == main_file);
43
44 let mut emitter = |name: &String, cv: *const libperl_sys::cv| {
45 println!("sub {:?}", name);
46 let ast = op_extractor.extract(cv, CvROOT(cv));
47
48 match ast {
49 Op::UNOP(opcode::OP_LEAVESUB, _
50 , Op::LISTOP(opcode::OP_LINESEQ, _
51 , Op::COP(opcode::OP_NEXTSTATE, body), _), _) => {
52 println!("preamble!");
53 match body {
54 Op::BINOP(opcode::OP_AASSIGN, _
55 , Op::UNOP(opcode::OP_NULL, _
56 , Op::OP(opcode::OP_PADRANGE, _, _
57 , Op::UNOP(opcode::OP_RV2AV, _
58 , Op::PADOP(opcode::OP_GV, _
59 , Sv::GLOB { name: ref nm, .. })
60 , _))
61 , lvalue)
62 , _) if nm == "_" => {
63 println!("first array assignment from @_, lvalue = {:?}"
64 , match_param_list(lvalue));
65
66 }
67 _ => {
68 println!("first statement is not an array assignment");
69 }
70 }
71 }
72 _ => {
73 println!("doesn't match")
74 }
75 }
76
77 println!("");
78 };
79
80 let mut nswalker = StashWalker::new(&perl, Some(&filter), &mut emitter);
81
82 nswalker.walk("");
83}
84
85#[cfg(not(perlapi_ver26))]
86fn my_test() {
87 println!("Requires perl >= 5.26");
88}
89
90fn main() {
91 my_test();
92}