From 992141878227439cd517d05b68f15e57d77452a5 Mon Sep 17 00:00:00 2001 From: Akshay Date: Mon, 29 Mar 2021 10:24:49 +0530 Subject: fix: handle unterminated strings gracefully --- src/app.rs | 13 +++++++++++-- src/lisp/error.rs | 4 ++-- src/lisp/lex.rs | 8 +++++++- 3 files changed, 20 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/app.rs b/src/app.rs index 016349b..eef896d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -4,7 +4,7 @@ use crate::{ command::CommandBox, consts::{colors::*, FONT_PATH}, dither, - lisp::{eval, lex::Lexer, parse::Parser, prelude, EnvList}, + lisp::{error::LispError, eval, lex::Lexer, parse::Parser, prelude, EnvList}, message::Message, rect, symmetry::Symmetry, @@ -284,7 +284,7 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { Ok(val) => self.message.set_info(format!("{}", val)), Err(eval_err) => self.message.set_error(format!("{}", eval_err)), }, - Err(parse_err) => self.message.set_error(format!("{}", parse_err)), + Err(err) => self.message = AppState::handle_error(err, &lisp_expr), } self.command_box.hist_append(); @@ -292,6 +292,15 @@ impl<'ctx, 'file> AppState<'ctx, 'file> { self.mode = Mode::Draw; } + fn handle_error(err: LispError, src: &str) -> Message { + let mut message = Message::new(); + match err { + LispError::Parse(p) => message.set_error(p.display(&src)), + eval_err => message.set_error(eval_err.to_string()), + } + message + } + fn draw_grid(&mut self) { let cs = self.zoom as u32; let (width, height) = (self.width(), self.height()); diff --git a/src/lisp/error.rs b/src/lisp/error.rs index a360eb2..6d28c22 100644 --- a/src/lisp/error.rs +++ b/src/lisp/error.rs @@ -30,9 +30,9 @@ impl ParseError { pub fn new(span: Span, kind: ParseErrorKind) -> Self { Self { span, kind } } - pub fn fmt(&self, f: &mut fmt::Formatter<'_>, text: &str) -> fmt::Result { + pub fn display(&self, text: &str) -> String { let SpanDisplay { line, col, .. } = SpanDisplay::highlight_span(self.span, text); - write!(f, "line {}, col {}: {}", line, col, self.kind) + format!("line {}, col {}: {}", line, col, self.kind) } } diff --git a/src/lisp/lex.rs b/src/lisp/lex.rs index 1a34e53..e514d7f 100644 --- a/src/lisp/lex.rs +++ b/src/lisp/lex.rs @@ -210,6 +210,7 @@ fn parse_number<'a>(mut input: &'a str) -> Result<(usize, Token<'a>), ParseError fn parse_string<'a>(input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind> { // count opening quote let mut size = 1; + let mut closed = false; let mut chars = input.char_indices().skip(1); while let Some((ind, chr)) = chars.next() { match chr { @@ -218,12 +219,17 @@ fn parse_string<'a>(input: &'a str) -> Result<(usize, Token<'a>), ParseErrorKind } '"' => { size += ind; + closed = true; break; } _ => (), } } - return Ok((size, Token::String(&input[..size]))); + if !closed { + Err(ParseErrorKind::UnterminatedString) + } else { + Ok((size, Token::String(&input[..size]))) + } } fn is_ident(ch: char) -> bool { -- cgit v1.2.3