rawk_core/awk.rs
1use crate::{Evaluator, Lexer, Parser, Program};
2
3/// High-level wrapper for compiling and running an AWK script.
4///
5/// This type parses the script once and can be run with different input.
6///
7/// # Example
8/// ```
9/// use rawk_core::awk::Awk;
10///
11/// let awk = Awk::new("{ print }");
12/// let output = awk.run(vec!["hello world".into()], None);
13/// assert_eq!(output, vec!["hello world".to_string()]);
14/// ```
15pub struct Awk {
16 program: Program<'static>,
17}
18
19impl Awk {
20 /// Parse an AWK script into an executable program.
21 ///
22 /// The script is stored with a static lifetime to keep the AST valid.
23 pub fn new(script: impl Into<String>) -> Self {
24 let script: String = script.into();
25 let script: &'static str = Box::leak(script.into_boxed_str());
26
27 let lexer = Lexer::new(script);
28 let parser: &'static mut Parser<'static> = Box::leak(Box::new(Parser::new(lexer)));
29 let program = parser.parse_program();
30
31 Self { program }
32 }
33
34 /// Execute the compiled program against the given input lines.
35 ///
36 /// When `filename` is `None`, `FILENAME` defaults to `"-"`.
37 pub fn run(&self, input: Vec<String>, filename: Option<String>) -> Vec<String> {
38 let filename = filename.unwrap_or_else(|| "-".to_string());
39 let mut evaluator = Evaluator::new(self.program.clone(), input, filename);
40
41 evaluator.eval()
42 }
43}