Skip to main content

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}