diff --git a/rust/nasl-interpreter/src/fork_interpreter.rs b/rust/nasl-interpreter/src/fork_interpreter.rs index 1c50e0464..38ddcdfc1 100644 --- a/rust/nasl-interpreter/src/fork_interpreter.rs +++ b/rust/nasl-interpreter/src/fork_interpreter.rs @@ -64,7 +64,7 @@ where self.first = false; Some( self.interpreter - .retry_resolve(&self.statement, self.retries), + .retry_resolve_next(&self.statement, self.retries), ) } else { self.interpreter @@ -73,3 +73,98 @@ where } } } + +/// Uses given code to return results based on that. +pub struct CodeInterpreter<'a, 'b, K> { + lexer: nasl_syntax::Lexer<'b>, + interpreter: crate::interpreter::Interpreter<'a, K>, + statement: Option, +} + +impl<'a, 'b, K> CodeInterpreter<'a, 'b, K> +where + K: AsRef, +{ + /// Creates a new code interpreter + /// + /// Example: + /// ``` + /// use nasl_syntax::NaslValue; + /// use nasl_interpreter::{Register, ContextBuilder, CodeInterpreter}; + /// let register = Register::default(); + /// let context_builder = ContextBuilder::default(); + /// let context = context_builder.build(); + /// let code = r#" + /// set_kb_item(name: "test", value: 1); + /// set_kb_item(name: "test", value: 2); + /// display(get_kb_item("test")); + /// "#; + /// let interpreter = CodeInterpreter::new(code, register, &context); + /// let results = interpreter.filter_map(|x|x.ok()).collect::>(); + /// assert_eq!(results, vec![NaslValue::Null; 4]); + /// ``` + pub fn new( + code: &'b str, + register: crate::Register, + context: &'a crate::Context<'a, K>, + ) -> CodeInterpreter<'a, 'b, K> { + let token = nasl_syntax::Tokenizer::new(code); + let lexer = nasl_syntax::Lexer::new(token); + let interpreter = crate::interpreter::Interpreter::new(register, context); + Self { + lexer, + interpreter, + statement: None, + } + } + fn next_statement(&mut self) -> Option { + self.statement = None; + match self.lexer.next() { + Some(Ok(nstmt)) => { + let results = Some(self.interpreter.retry_resolve_next(&nstmt, 5)); + self.statement = Some(nstmt); + results + } + Some(Err(err)) => Some(Err(err.into())), + None => None, + } + } +} + +impl<'a, 'b, K> Iterator for CodeInterpreter<'a, 'b, K> +where + K: AsRef, +{ + type Item = InterpretResult; + + fn next(&mut self) -> Option { + if let Some(stmt) = self.statement.as_ref() { + match self.interpreter.next_interpreter() { + Some(inter) => Some(inter.retry_resolve(stmt, 5)), + None => self.next_statement(), + } + } else { + self.next_statement() + } + } +} + +#[cfg(test)] +mod rests { + #[test] + fn code_interpreter() { + use crate::{CodeInterpreter, ContextBuilder, Register}; + use nasl_syntax::NaslValue; + let register = Register::default(); + let context_builder = ContextBuilder::default(); + let context = context_builder.build(); + let code = r#" + set_kb_item(name: "test", value: 1); + set_kb_item(name: "test", value: 2); + display(get_kb_item("test")); + "#; + let interpreter = CodeInterpreter::new(code, register, &context); + let results = interpreter.filter_map(|x| x.ok()).collect::>(); + assert_eq!(results, vec![NaslValue::Null; 4]); + } +} diff --git a/rust/nasl-syntax/src/lexer.rs b/rust/nasl-syntax/src/lexer.rs index 55ee56f9d..5ac8aab62 100644 --- a/rust/nasl-syntax/src/lexer.rs +++ b/rust/nasl-syntax/src/lexer.rs @@ -44,12 +44,6 @@ impl End { } } - // pub fn category(&self) -> &Option { - // match self { - // End::Done(t) => &Some(t.category), - // End::Continue => &None, - // } - // } } impl Not for End {