1use std::fmt::{self, Display};
2use std::hash::Hash;
3
4use crate::literal::Literal;
5
6#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
8pub enum Type {
9 LeftParen, RightParen, LeftBrace, RightBrace,
11 Comma, Dot, Minus, Plus, Semicolon, Slash, Star,
12
13 Bang, BangEqual,
15 Equal, EqualEqual,
16 Greater, GreaterEqual,
17 Less, LessEqual,
18
19 Identifier, String, Number,
21
22 And, Class, Else, False, Fun, For, If, Null, Or,
24 Print, Return, Break, Super, This, True, Var, While,
25
26 EOF
27}
28
29#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
31pub struct Location {
32 pub line: usize,
33 pub column: usize,
34}
35
36impl Location {
37 pub fn new(line: usize, column: usize) -> Self {
39 Location { line, column }
40 }
41}
42
43impl Display for Location {
44 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45 write!(f, "{}:{}", self.line, self.column)
46 }
47}
48
49#[derive(Debug, Eq, PartialEq, Clone)]
51pub struct Token {
52 pub r#type: Type,
54 pub lexeme: String,
56 pub literal: Option<Literal>,
58 pub location: Location,
60}
61
62impl Token {
63 pub fn new(
65 r#type: Type,
66 lexeme: String,
67 literal: Option<Literal>,
68 location: Location,
69 ) -> Token {
70 Token { r#type, lexeme, literal, location }
71 }
72}
73
74impl From<&str> for Token {
76 fn from(token: &str) -> Self {
77 Token::new(Type::Identifier, token.to_string(), None, Location::new(0, 0))
78 }
79}
80
81impl Display for Token {
82 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83 write!(f, "{:#?} {} {:#?} @ [{}]", self.r#type, self.lexeme, self.literal, self.location)
84 }
85}
86
87impl Hash for Token {
91 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
92 self.r#type.hash(state);
93 self.lexeme.hash(state);
94 self.location.hash(state);
95 }
96}