1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
use crate::ast::Position; use crate::lexer::{Token, TokenKind}; use serde::{Deserialize, Serialize}; use std::fmt; #[derive(Debug, Deserialize, Serialize)] pub struct Error { pub message: String, pub position: Position, } impl Error { pub fn new(message: String, position: Position) -> Self { Self { message, position } } pub fn expect(expect_toks: &[TokenKind], tok: Token, context: String) -> Self { let info = format!( "expected {}, got '{}' in {}", if expect_toks.len() == 1 { format!( "token '{}'", expect_toks.first().map(TokenKind::to_string).unwrap() ) } else { format!( "one of {}", expect_toks .iter() .enumerate() .map(|(i, t)| { format!( "{}'{}'", if i == 0 { "" } else if i == expect_toks.len() - 1 { " or " } else { ", " }, t ) }) .collect::<String>() ) }, tok, context, ); Self::new(info, tok.position) } pub fn unexpect(tok: Token, context: Option<String>) -> Self { let info = match context { Some(ctx) => format!("unexpected token '{}' in {}", tok, ctx), None => format!("unexpected token '{}'", tok,), }; Self::new(info, tok.position) } pub fn abort() -> Self { Self { message: String::from("abort"), position: Position::default(), } } } impl fmt::Display for Error { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { if self.position.index == 0 { write!(formatter, "{}", self.message,) } else { write!( formatter, "{} at line {} column {}", self.message, self.position.line, self.position.col, ) } } }