diff --git a/c/src/metta.rs b/c/src/metta.rs index 35c8c3aec..c94511a5d 100644 --- a/c/src/metta.rs +++ b/c/src/metta.rs @@ -1093,7 +1093,7 @@ impl runner_state_t { pub extern "C" fn runner_state_new_with_parser(metta: *const metta_t, parser: sexpr_parser_t) -> runner_state_t { let metta = unsafe{ &*metta }.borrow(); let parser = parser.into_inner(); - let state = RunnerState::new_with_parser(metta, parser); + let state = RunnerState::new_with_parser(metta, Box::new(parser)); state.into() } diff --git a/lib/src/metta/runner/mod.rs b/lib/src/metta/runner/mod.rs index 0ad3b24e5..59291afcc 100644 --- a/lib/src/metta/runner/mod.rs +++ b/lib/src/metta/runner/mod.rs @@ -3,7 +3,7 @@ use crate::common::shared::Shared; use super::*; use super::space::*; -use super::text::{Tokenizer, SExprParser}; +use super::text::{Tokenizer, Parser, SExprParser}; use super::types::validate_atom; use std::rc::Rc; @@ -60,7 +60,7 @@ enum MettaRunnerMode { pub struct RunnerState<'m, 'i> { mode: MettaRunnerMode, metta: &'m Metta, - parser: Option>, + parser: Option>, atoms: Option<&'i [Atom]>, interpreter_state: Option>, results: Vec>, @@ -245,8 +245,8 @@ impl Metta { self.0.settings.borrow().get(key.into()).map(|a| a.to_string()) } - pub fn run(&self, parser: SExprParser) -> Result>, String> { - let state = RunnerState::new_with_parser(self, parser); + pub fn run(&self, parser: impl Parser) -> Result>, String> { + let state = RunnerState::new_with_parser(self, Box::new(parser)); state.run_to_completion() } @@ -297,8 +297,8 @@ impl<'m, 'i> RunnerState<'m, 'i> { results: vec![], } } - /// Returns a new RunnerState, for running code from the [SExprParser] with the specified [Metta] runner - pub fn new_with_parser(metta: &'m Metta, parser: SExprParser<'i>) -> Self { + /// Returns a new RunnerState, for running code from the [Parser] with the specified [Metta] runner + pub fn new_with_parser(metta: &'m Metta, parser: Box) -> Self { let mut state = Self::new(metta); state.parser = Some(parser); state @@ -345,7 +345,7 @@ impl<'m, 'i> RunnerState<'m, 'i> { // Get the next atom, and start a new intperpreter let next_atom = if let Some(parser) = self.parser.as_mut() { - match parser.parse(&self.metta.0.tokenizer.borrow()) { + match parser.next_atom(&self.metta.0.tokenizer.borrow()) { Ok(atom) => atom, Err(err) => { self.mode = MettaRunnerMode::TERMINATE; diff --git a/lib/src/metta/text.rs b/lib/src/metta/text.rs index 6c0f1d007..bf0bcf560 100644 --- a/lib/src/metta/text.rs +++ b/lib/src/metta/text.rs @@ -217,6 +217,22 @@ impl SyntaxNode { } } +/// Implemented on a type that yields atoms to be interpreted as MeTTa code. Typically +/// by parsing source text +pub trait Parser { + fn next_atom(&mut self, tokenizer: &Tokenizer) -> Result, String>; +} + +impl Parser for SExprParser<'_> { + fn next_atom(&mut self, tokenizer: &Tokenizer) -> Result, String> { + self.parse(tokenizer) + } +} + +/// Provides a parser for MeTTa code written in S-Expression Syntax +/// +/// NOTE: The SExprParser type is short-lived, and can be created cheaply to evaluate a specific block +/// of MeTTa source code. #[derive(Clone)] pub struct SExprParser<'a> { text: &'a str,