fix string parsing and error output

This commit is contained in:
2024-10-28 18:44:05 -04:00
parent 4c614c1937
commit 48d2c009fb
4 changed files with 20 additions and 17 deletions

View File

@@ -54,7 +54,7 @@ impl fmt::Display for Error {
if let Some(code) = &self.code { if let Some(code) = &self.code {
let mut lines = code.lines(); let mut lines = code.lines();
let linect = match lines.nth(*line) { let linect = match lines.nth(*line - 1) {
Some(l) => l, Some(l) => l,
None => return Ok(()), // there should probably be an error if the line number is somehow out of range None => return Ok(()), // there should probably be an error if the line number is somehow out of range
}; };

View File

@@ -196,7 +196,7 @@ impl<R: BufRead> CodeIter<R> {
reader, reader,
code: String::new(), code: String::new(),
pos: 0, pos: 0,
line: 0, line: 1,
column: 0, column: 0,
} }
} }

View File

@@ -69,13 +69,13 @@ impl Parser {
items.into_iter().fold(self, |acc, (k, v)| acc.add_global(k, v)) items.into_iter().fold(self, |acc, (k, v)| acc.add_global(k, v))
} }
pub(crate) fn add_local(mut self, k: String, v: Type) -> Self { pub(crate) fn _add_local(mut self, k: String, v: Type) -> Self {
self.locals.insert(k, v); self.locals.insert(k, v);
self self
} }
pub(crate) fn add_locals<Items: Iterator<Item = (String, Type)>>(self, items: Items) -> Self { pub(crate) fn _add_locals<Items: Iterator<Item = (String, Type)>>(self, items: Items) -> Self {
items.fold(self, |acc, (key, value)| acc.add_local(key, value)) items.fold(self, |acc, (key, value)| acc._add_local(key, value))
} }
fn add_local_mut(&mut self, k: String, v: Type) -> &mut Self { fn add_local_mut(&mut self, k: String, v: Type) -> &mut Self {

View File

@@ -240,10 +240,15 @@ impl<R: BufRead> Tokenizer<R> {
while let Some(c) = self.next_char() { while let Some(c) = self.next_char() {
match c { match c {
'"' => break, '"' => {
let (line, col) = self.getpos();
return Ok(Some(Token::new(TokenType::Constant(
Value::String(token.clone())), token, line, col)));
}
'\n' => return Err( '\n' => return Err(
Error::new("Unclosed string literal".into()) Error::new("Unclosed string literal".into())
.location(line, col..self.getpos().1) .location(line, col..col+token.len()+1)
.note("newlines are not allowed in string literals (try \\n)".into())), .note("newlines are not allowed in string literals (try \\n)".into())),
'\\' => match self.next_char() { '\\' => match self.next_char() {
Some('\\') => token.push('\\'), Some('\\') => token.push('\\'),
@@ -254,17 +259,16 @@ impl<R: BufRead> Tokenizer<R> {
Some(c) => token.push(c), Some(c) => token.push(c),
None => return Err( None => return Err(
Error::new("Unclosed string literal".into()) Error::new("Unclosed string literal".into())
.location(line, col..self.getpos().1) .location(line, col..token.len()+1)
.note("end of file found before \"".into())), .note("end of file found before \"".into())),
} }
_ => token.push(c), _ => token.push(c),
} };
} }
let (line, col) = self.getpos(); Err(Error::new("Unclosed string literal".into())
.location(line, col..self.getpos().1+1)
Ok(Some(Token::new(TokenType::Constant( .note("end of file found before \"".into()))
Value::String(token.clone())), token, line, col)))
} else if operators.keys().any(|x| x.starts_with(c)) { } else if operators.keys().any(|x| x.starts_with(c)) {
let mut token = String::from(c); let mut token = String::from(c);
@@ -349,9 +353,8 @@ impl<R: BufRead> Tokenizer<R> {
} else { } else {
let (line, col) = self.getpos(); let (line, col) = self.getpos();
return Err( Err(Error::new(format!("an unidentified character {c} was found"))
Error::new(format!("an unidentified character {c} was found")) .location(line, col..col+1))
.location(line, col - 1..col));
} }
} }
} }