Skip to content

Commit

Permalink
Slightly improve error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
cody-quinn committed Jun 27, 2023
1 parent 29bdd10 commit 9f7f0f9
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 12 deletions.
1 change: 0 additions & 1 deletion examples/hello.sloth
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
fn main() Int {
print("Hello World\n");
var x: F = 2;
return 0;
}
81 changes: 81 additions & 0 deletions sloth/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

//! TODO: Lexing Regex Literals

use std::fmt::Display;
use std::str::Chars;

use thiserror::Error;
Expand Down Expand Up @@ -112,6 +113,86 @@ pub enum TokenType {
Error(LexerError),
}

impl Display for TokenType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
TokenType::DocComment => "##",
TokenType::Comment => "#",
TokenType::OpeningParen => "(",
TokenType::ClosingParen => ")",
TokenType::OpeningBracket => "[",
TokenType::ClosingBracket => "]",
TokenType::OpeningBrace => "{",
TokenType::ClosingBrace => "}",
TokenType::Plus => "+",
TokenType::PlusPlus => "++",
TokenType::Minus => "-",
TokenType::Star => "*",
TokenType::StarStar => "**",
TokenType::Slash => "/",
TokenType::Perc => "%",
TokenType::Tilde => "~",
TokenType::PlusEq => "+=",
TokenType::PlusPlusEq => "++=",
TokenType::MinusEq => "-=",
TokenType::StarEq => "*=",
TokenType::StarStarEq => "**=",
TokenType::SlashEq => "/=",
TokenType::PercEq => "%=",
TokenType::TildeEq => "~=",
TokenType::Amp => "&",
TokenType::AmpAmp => "&&",
TokenType::Pipe => "|",
TokenType::PipePipe => "||",
TokenType::Caret => "^",
TokenType::Eq => "=",
TokenType::EqEq => "==",
TokenType::Bang => "!",
TokenType::BangBang => "!!",
TokenType::BangEq => "!=",
TokenType::Lt => "<",
TokenType::LtLt => "<<",
TokenType::LtEq => "<=",
TokenType::LtLtEq => "<<=",
TokenType::Gt => ">",
TokenType::GtGt => ">>",
TokenType::GtEq => ">=",
TokenType::GtGtEq => ">>=",
TokenType::Comma => ",",
TokenType::Question => "?",
TokenType::QuestionDot => "?.",
TokenType::QuestionQuestion => "??",
TokenType::Dot => ".",
TokenType::DotDot => "..",
TokenType::Colon => ":",
TokenType::ColonColon => "::",
TokenType::SemiColon => ";",
TokenType::Arrow => "->",
TokenType::FatArrow => "=>",
TokenType::Const => "const",
TokenType::Val => "val",
TokenType::Var => "var",
TokenType::Fn => "fn",
TokenType::Return => "return",
TokenType::If => "if",
TokenType::Else => "else",
TokenType::While => "while",
TokenType::For => "for",
TokenType::In => "in",
TokenType::Loop => "loop",
TokenType::Break => "break",
TokenType::Continue => "continue",
TokenType::As => "as",
TokenType::Foreign => "foreign",
TokenType::Literal(_) => "literal",
TokenType::Identifier(_) => "identifier",
TokenType::Error(_) => "error",
};

write!(f, "{s}")
}
}

#[derive(Debug, Clone, PartialEq)]
pub enum Literal {
Integer(i32),
Expand Down
13 changes: 12 additions & 1 deletion sloth/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,18 @@ fn main() {
// Parsing
let tokens = Lexer::new(&source).collect_vec();
let global_symtable = mk_symtable();
let mut ast = AstParser::parse(tokens, global_symtable).unwrap();

let mut ast = match AstParser::parse(tokens, global_symtable) {
Ok(node) => node,
Err(error) => {
eprintln!(
"Error in file {} on line {}: {error}",
args[1 + (error.line() / 1_000) as usize],
error.line() % 1000 + 1,
);
return;
}
};

if let Err(error) = analyze(&mut ast) {
eprintln!(
Expand Down
2 changes: 1 addition & 1 deletion sloth/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl<'a> AstParser<'a> {
ExprKind::Grouping(Box::new(expr))
}

_ => return Err(ParsingError::UnexpectedToken),
tt => return Err(ParsingError::UnexpectedToken(self.line, tt, "")),
};

Ok(Expr::new(
Expand Down
26 changes: 19 additions & 7 deletions sloth/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,17 @@ use crate::symtable::SymbolTable;
pub enum ParsingError {
#[error("Invalid operation")]
InvalidOp,
#[error("Unexpected token")]
UnexpectedToken,
#[error("Unexpected token '{1}'. {2}")]
UnexpectedToken(u32, TokenType, &'static str),
}

impl ParsingError {
pub fn line(&self) -> u32 {
match &self {
ParsingError::InvalidOp => 0,
ParsingError::UnexpectedToken(x, _, _) => *x,
}
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -92,26 +101,29 @@ impl<'a> AstParser<'a> {
self.advance_if(|it| it.tt == *next)
}

pub fn consume(&mut self, next: TokenType, error: &str) -> Result<&Token, ParsingError> {
pub fn consume(
&mut self,
next: TokenType,
error: &'static str,
) -> Result<&Token, ParsingError> {
if std::mem::discriminant(&self.peek().tt) != std::mem::discriminant(&next) {
println!("{error} at index {:?}", self.index);
return Err(ParsingError::UnexpectedToken);
return Err(ParsingError::UnexpectedToken(self.line, next, error));
}

Ok(self.advance().unwrap())
}

pub fn consume_literal(&mut self) -> Result<Literal, ParsingError> {
let Some(TokenType::Literal(literal)) = self.advance().map(|it| it.tt.clone()) else {
return Err(ParsingError::UnexpectedToken);
return Err(ParsingError::UnexpectedToken(self.line, self.peek().tt.clone(), "Expected literal"));
};

Ok(literal.into())
}

pub fn consume_identifier(&mut self) -> Result<String, ParsingError> {
let Some(TokenType::Identifier(identifier)) = self.advance().map(|it| it.tt.clone()) else {
return Err(ParsingError::UnexpectedToken);
return Err(ParsingError::UnexpectedToken(self.line, self.peek().tt.clone(), "Expected identifier"));
};

Ok(identifier)
Expand Down
4 changes: 2 additions & 2 deletions sloth/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ impl<'a> AstParser<'a> {
// Consume the foreign token
self.consume(TokenType::Foreign, "Expected foreign")?;

match self.peek().tt {
match &self.peek().tt {
TokenType::Fn => self.define_function(true),

_ => Err(ParsingError::UnexpectedToken),
tt => Err(ParsingError::UnexpectedToken(self.line, tt.clone(), "")),
}
}

Expand Down

0 comments on commit 9f7f0f9

Please sign in to comment.