From: Ben Pfaff Date: Tue, 20 Aug 2024 02:30:19 +0000 (-0700) Subject: work X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1603bfc0c9a2bdf32fcae8fd4910d5c2d60f6e3;p=pspp work --- diff --git a/rust/src/command.rs b/rust/src/command.rs index 4a5b24d10f..d337d1823a 100644 --- a/rust/src/command.rs +++ b/rust/src/command.rs @@ -40,7 +40,7 @@ struct Command { testing_only: bool, no_abbrev: bool, name: &'static str, - run: Box Result<(), Failure> + Send + Sync>, + run: Box, } fn commands() -> &'static [Command] { @@ -53,7 +53,6 @@ fn commands() -> &'static [Command] { name: "ECHO", run: Box::new(|_context| { println!("hi"); - Ok(()) }), }] } @@ -137,14 +136,7 @@ pub enum Success { Finish, } -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Failure { - Failure, - NotImplemented, - CascadingFailure, -} - -pub fn end_of_command(context: &Context) -> Result { +pub fn end_of_command(context: &Context) -> Result { match context.lexer.token() { Token::EndCommand | Token::End => Ok(Success::Success), _ => { @@ -153,61 +145,37 @@ pub fn end_of_command(context: &Context) -> Result { .lexer .error("Syntax error expecting end of command."), ); - Err(Failure::Failure) + Err(()) } } } -fn _parse_in_state( - lexer: &mut Lexer, - error: &Box, - _state: State, -) -> Result { +fn parse_in_state(lexer: &mut Lexer, error: &Box, _state: State) { match lexer.token() { - Token::End => Ok(Success::Eof), - Token::EndCommand => Ok(Success::Success), + Token::End | Token::EndCommand => (), _ => { - let (command, n_tokens) = - parse_command_name(lexer, error).map_err(|_| Failure::Failure)?; - for _ in 0..n_tokens { - lexer.get(); - } - let context = Context { - error, - lexer, - command_name: Some(command.name), - }; - match (command.run)(&context) { - Ok(()) => end_of_command(&context), - Err(error) => Err(error) + if let Ok((command, n_tokens)) = parse_command_name(lexer, error) { + for _ in 0..n_tokens { + lexer.get(); + } + let context = Context { + error, + lexer, + command_name: Some(command.name), + }; + (command.run)(&context); + end_of_command(&context); } + lexer.interactive_reset(); + lexer.discard_rest_of_command(); } } -} - -fn parse_in_state( - lexer: &mut Lexer, - error: &Box, - state: State, -) -> Result { - let result = _parse_in_state(lexer, error, state); - if result.is_err() { - lexer.interactive_reset(); + while let Token::EndCommand = lexer.token() { + lexer.get(); } - lexer.discard_rest_of_command(); - - match result { - Ok(Success::Eof) | Ok(Success::Finish) => (), - _ => { - while let Token::EndCommand = lexer.token() { - lexer.get(); - } - } - }; - result } -pub fn parse(lexer: &mut Lexer, error: &Box) -> Result { +pub fn parse(lexer: &mut Lexer, error: &Box) { parse_in_state(lexer, error, State::Initial) } diff --git a/rust/src/engine.rs b/rust/src/engine.rs index 800626e3f7..f48c1948c1 100644 --- a/rust/src/engine.rs +++ b/rust/src/engine.rs @@ -1,6 +1,6 @@ use crate::{ - command::{parse, Failure, Success}, - lex::lexer::{Lexer, Source}, + command::parse, + lex::{lexer::{Lexer, Source}, token::Token}, message::Diagnostic, }; @@ -17,29 +17,11 @@ impl Engine { fn run(&mut self, source: Source) { self.lexer.append(source); self.lexer.get(); - loop { + while self.lexer.token() != &Token::End { let error: Box = Box::new(|diagnostic| { println!("{diagnostic}"); }); - match parse(&mut self.lexer, &error) { - Ok(Success::Eof) | Ok(Success::Finish) => break, - Ok(Success::Success) => (), - Err(error) => match self.lexer.error_handling() { - crate::lex::lexer::ErrorHandling::Continue - if error == Failure::CascadingFailure => - { - println!("Stopping syntax file processing here to avoid a cascade of dependent command failures."); - self.lexer.discard_noninteractive(); - break; - } - crate::lex::lexer::ErrorHandling::Stop => { - println!("Error encountered while ERROR=STOP is effective."); - self.lexer.discard_noninteractive(); - break; - } - _ => (), - }, - } + parse(&mut self.lexer, &error); } } } @@ -59,7 +41,7 @@ mod tests { fn test_echo() { let mut engine = Engine::new(); engine.run(Source::for_file_contents( - "ECHO 'hi there'.\n".to_string(), + "ECHO 'hi there'.\nECHO 'bye there'.\n".to_string(), Some("test.sps".to_string()), UTF_8, Mode::default(), diff --git a/rust/src/lex/lexer.rs b/rust/src/lex/lexer.rs index 4bd1335595..82ef008aef 100644 --- a/rust/src/lex/lexer.rs +++ b/rust/src/lex/lexer.rs @@ -463,11 +463,12 @@ impl Source { if (1..=self.lines.len() as i32).contains(&line_number) { let line_number = line_number as usize; let start = self.lines[line_number - 1]; - let end = self - .lines - .get(line_number) - .copied() - .unwrap_or(self.buffer.len()); + let end = self.lines.get(line_number).copied().unwrap_or( + self.buffer[start..] + .find('\n') + .map(|ofs| ofs + start) + .unwrap_or(self.buffer.len()), + ); let line = &self.buffer[start..end]; line.strip_suffix("\r\n") .unwrap_or(line.strip_suffix('\n').unwrap_or(line))