all lex errors have a position now

main
Jordan Orelli 7 months ago
parent 1d504ff36d
commit 965cb45437

@ -207,7 +207,7 @@ impl Editor {
/// reads one command from the editor. This function blocks until the user has entered an /// reads one command from the editor. This function blocks until the user has entered an
/// entire command. /// entire command.
pub fn read_command(&mut self, _history: &mut History) -> Result<Option<String>> { pub fn read_command(&mut self, history: &mut History) -> Result<Option<String>> {
use input::Event::*; use input::Event::*;
loop { loop {
@ -266,6 +266,7 @@ impl Editor {
match esc { match esc {
Left => self.back(1)?, Left => self.back(1)?,
Right => self.forward(1)?, Right => self.forward(1)?,
Up => self.prev_history()?,
Home => self.seek_left()?, Home => self.seek_left()?,
End => self.seek_right()?, End => self.seek_right()?,
esc => debug!(" Ignored escape: {esc:?}"), esc => debug!(" Ignored escape: {esc:?}"),
@ -422,4 +423,8 @@ impl Editor {
self.display.reset()?; self.display.reset()?;
Ok(()) Ok(())
} }
fn prev_history(&mut self) -> Result<()> {
Ok(())
}
} }

@ -1,4 +1,7 @@
use crate::{lex::Token, topo::Glyph}; use crate::{
lex::Token,
topo::{Glyph, Position},
};
use std::io; use std::io;
use thiserror::Error; use thiserror::Error;
use windows::Win32::Foundation::{GetLastError, BOOL}; use windows::Win32::Foundation::{GetLastError, BOOL};
@ -36,21 +39,32 @@ pub enum LexError {
UnexpectedCharacterInGlob(Glyph), UnexpectedCharacterInGlob(Glyph),
#[error("unexpected eof")] #[error("unexpected eof")]
UnexpectedEOF, UnexpectedEOF(Position),
#[error("not yet supported: {0}")] #[error("not yet supported: {1}")]
NotYetSupported(String), NotYetSupported(Position, String),
} }
impl LexError { impl LexError {
pub fn not_yet(msg: &str) -> Self { pub fn not_yet(p: Position, msg: &str) -> Self {
LexError::NotYetSupported(msg.to_string()) LexError::NotYetSupported(p, msg.to_string())
}
fn position(&self) -> Position {
use LexError::*;
match self {
UnexpectedCharacter(g) => g.position,
UnexpectedCharacterInBareString(g) => g.position,
UnexpectedCharacterInGlob(g) => g.position,
UnexpectedEOF(p) => *p,
NotYetSupported(p, _) => *p,
}
} }
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum ParseError { pub enum ParseError {
#[error("lex error")] #[error("lex error at line {line}, column {col}", line=.0.position().line, col=.0.position().column)]
LexError(#[from] LexError), LexError(#[from] LexError),
#[error("Unexpected Token: {0:?}")] #[error("Unexpected Token: {0:?}")]

@ -1,7 +1,13 @@
pub struct History {} pub struct History {
events: Vec<String>,
}
impl History { impl History {
pub fn new() -> Self { pub fn new() -> Self {
Self {} Self { events: Vec::new() }
}
pub fn add<S: Into<String>>(&mut self, event: S) {
self.events.push(event.into());
} }
} }

@ -154,7 +154,7 @@ impl<'text> Tokenizer<'text> {
} }
if progress.is_empty() { if progress.is_empty() {
Err(LexError::UnexpectedEOF) Err(LexError::UnexpectedEOF(self.source.next_position))
} else { } else {
Ok(Token::Word(progress.into())) Ok(Token::Word(progress.into()))
} }
@ -175,22 +175,31 @@ impl<'text> Tokenizer<'text> {
} }
if progress.is_empty() { if progress.is_empty() {
Err(LexError::UnexpectedEOF) Err(LexError::UnexpectedEOF(self.source.next_position))
} else { } else {
Ok(Token::Glob(progress.into())) Ok(Token::Glob(progress.into()))
} }
} }
fn lex_raw_string(&mut self, _progress: Vec<Glyph>) -> Result<Token, LexError> { fn lex_raw_string(&mut self, _progress: Vec<Glyph>) -> Result<Token, LexError> {
Err(LexError::not_yet("raw strings not done yet")) Err(LexError::not_yet(
self.source.next_position,
"raw strings not done yet",
))
} }
fn lex_interp_string(&mut self, _progress: Vec<Glyph>) -> Result<Token, LexError> { fn lex_interp_string(&mut self, _progress: Vec<Glyph>) -> Result<Token, LexError> {
Err(LexError::not_yet("interpreted strings not done yet")) Err(LexError::not_yet(
self.source.next_position,
"interpreted strings not done yet",
))
} }
fn lex_var(&mut self, _progress: Vec<Glyph>) -> Result<Token, LexError> { fn lex_var(&mut self, _progress: Vec<Glyph>) -> Result<Token, LexError> {
Err(LexError::not_yet("variables are not done yet")) Err(LexError::not_yet(
self.source.next_position,
"variables are not done yet",
))
} }
} }

@ -47,6 +47,12 @@ impl fmt::Debug for Position {
} }
} }
impl fmt::Display for Position {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
(self as &dyn fmt::Debug).fmt(f)
}
}
/// A Glyph represents a character occurring at some specific position in some input text. /// A Glyph represents a character occurring at some specific position in some input text.
#[derive(PartialEq, Clone)] #[derive(PartialEq, Clone)]
pub struct Glyph { pub struct Glyph {
@ -97,7 +103,7 @@ pub struct Glyphs<'text> {
source: Chars<'text>, source: Chars<'text>,
/// the position of the next character in the source text /// the position of the next character in the source text
next_position: Position, pub(crate) next_position: Position,
/// the number of bytes we've read from our input document so far /// the number of bytes we've read from our input document so far
bytes_read: u64, bytes_read: u64,
@ -153,7 +159,8 @@ impl<'text> Glyphs<'text> {
/// takes the next character from our input text /// takes the next character from our input text
pub fn pop(&mut self) -> Result<Glyph, LexError> { pub fn pop(&mut self) -> Result<Glyph, LexError> {
self.next().ok_or(LexError::UnexpectedEOF) self.next()
.ok_or(LexError::UnexpectedEOF(self.next_position))
} }
/// returns a reference to a character in our lookahead buffer at a given position. This allows /// returns a reference to a character in our lookahead buffer at a given position. This allows

Loading…
Cancel
Save