Skip to main content

robinpath/
lib.rs

1pub mod ast;
2pub mod error;
3pub mod executor;
4pub mod lexer;
5pub mod modules;
6pub mod parser;
7pub mod stream;
8pub mod value;
9
10pub use error::RobinPathError;
11pub use executor::{BuiltinCallback, BuiltinFn, Environment};
12pub use value::Value;
13
14use executor::Executor;
15use lexer::Lexer;
16use parser::Parser;
17
18pub struct RobinPath {
19    executor: Executor,
20}
21
22impl RobinPath {
23    pub fn new() -> Self {
24        let mut env = Environment::new();
25        modules::register_all_modules(&mut env);
26        Self {
27            executor: Executor::new(env),
28        }
29    }
30
31    pub fn with_environment(env: Environment) -> Self {
32        Self {
33            executor: Executor::new(env),
34        }
35    }
36
37    /// Parse source code into AST
38    pub fn parse(source: &str) -> Result<Vec<ast::Stmt>, RobinPathError> {
39        let tokens = Lexer::new(source).tokenize()?;
40        let stmts = Parser::new(tokens).parse()?;
41        Ok(stmts)
42    }
43
44    /// Execute source code and return the final value
45    pub fn execute(&mut self, source: &str) -> Result<Value, RobinPathError> {
46        let stmts = Self::parse(source)?;
47        self.executor.execute(&stmts)
48    }
49
50    /// Execute pre-parsed AST
51    pub fn execute_ast(&mut self, stmts: &[ast::Stmt]) -> Result<Value, RobinPathError> {
52        self.executor.execute(stmts)
53    }
54
55    /// Get captured output lines
56    pub fn output(&self) -> &[String] {
57        &self.executor.environment.output
58    }
59
60    /// Clear captured output
61    pub fn clear_output(&mut self) {
62        self.executor.environment.output.clear();
63    }
64
65    /// Get a variable value
66    pub fn get_variable(&self, name: &str) -> Option<&Value> {
67        self.executor.environment.variables.get(name)
68    }
69
70    /// Set a variable
71    pub fn set_variable(&mut self, name: &str, value: Value) {
72        self.executor.environment.variables.insert(name.to_string(), value);
73    }
74
75    /// Register an external builtin function (for use by extension crates)
76    pub fn register_builtin(
77        &mut self,
78        name: &str,
79        func: impl Fn(&[Value], Option<&BuiltinCallback>) -> Result<Value, String> + Send + Sync + 'static,
80    ) {
81        self.executor.environment.register_builtin(name, func);
82    }
83}
84
85impl Default for RobinPath {
86    fn default() -> Self {
87        Self::new()
88    }
89}