1mod identifier_parselet;
4mod literal_parselet;
5mod assignment_parselet;
6mod binop_parselet;
7mod paren_parselet;
8mod matrix_parselet;
9mod func_parselet;
10mod prime_parselet;
11
12use std::collections::HashMap;
13
14use crate::{
15 Expression,
16 Token,
17 TokenClass,
18 Tokenizer,
19};
20
21use identifier_parselet::IdentifierParselet;
22use literal_parselet::LiteralParselet;
23use assignment_parselet::AssignmentParselet;
24use binop_parselet::BinOpParselet;
25use paren_parselet::ParenParselet;
26use matrix_parselet::MatrixParselet;
27use func_parselet::FuncParselet;
28use prime_parselet::PrimeParselet;
29
30
31impl From<TokenClass> for u8 {
33 fn from(t: TokenClass) -> u8 {
34 match t {
35 TokenClass::Assignment => 1,
36 TokenClass::Plus => 3,
37 TokenClass::Minus => 3,
38 TokenClass::Multiply => 4,
39 TokenClass::Divide => 4,
40 TokenClass::OpenParen => 6,
41 TokenClass::OpenBracket => 7,
42 TokenClass::Prime => 8,
43 _ => 0,
44 }
45 }
46}
47
48
49pub trait PrefixParselet {
51 fn parse(&self, parser: &Parser, tokenizer: &mut Tokenizer, token: Token) -> Expression;
52}
53
54pub trait InfixParselet {
56 fn parse(&self, parser: &Parser, tokenizer: &mut Tokenizer, token: Token, left: Expression) -> Expression;
57}
58
59
60pub struct Parser {
62 prefix_parselets: HashMap<TokenClass, Box<dyn PrefixParselet>>,
63 infix_parselets: HashMap<TokenClass, Box<dyn InfixParselet>>,
64}
65
66impl Parser {
67 pub fn new() -> Self {
69 let mut prefix_parselets: HashMap<TokenClass, Box<dyn PrefixParselet>> = HashMap::new();
70 let mut infix_parselets: HashMap<TokenClass, Box<dyn InfixParselet>> = HashMap::new();
71
72 prefix_parselets.insert(TokenClass::Identifier, Box::new(IdentifierParselet {}));
74 prefix_parselets.insert(TokenClass::Int, Box::new(LiteralParselet {}));
75 prefix_parselets.insert(TokenClass::Float, Box::new(LiteralParselet {}));
76 prefix_parselets.insert(TokenClass::OpenParen, Box::new(ParenParselet {}));
77 prefix_parselets.insert(TokenClass::OpenBracket, Box::new(MatrixParselet {}));
78 infix_parselets.insert(TokenClass::Assignment, Box::new(AssignmentParselet {}));
79 infix_parselets.insert(TokenClass::Plus, Box::new(BinOpParselet {}));
80 infix_parselets.insert(TokenClass::Minus, Box::new(BinOpParselet {}));
81 infix_parselets.insert(TokenClass::Multiply, Box::new(BinOpParselet {}));
82 infix_parselets.insert(TokenClass::Divide, Box::new(BinOpParselet {}));
83 infix_parselets.insert(TokenClass::OpenParen, Box::new(FuncParselet {}));
84 infix_parselets.insert(TokenClass::Prime, Box::new(PrimeParselet {}));
85
86 Self {
87 prefix_parselets,
88 infix_parselets,
89 }
90 }
91
92 pub fn parse(&self, tokenizer: &mut Tokenizer, precedence: u8) -> Expression {
94 let token = match tokenizer.next() {
95 Some(t) => t,
96 None => return Expression::Nil,
97 };
98
99 let parselet: &Box<dyn PrefixParselet> = match self.prefix_parselets.get(&token.get_class()) {
100 Some(p) => p,
101 None => return Expression::Nil,
102 };
103 let mut left = parselet.parse(self, tokenizer, token);
104
105 while precedence < tokenizer.get_next_precedence() {
106 let next = match tokenizer.peek() {
107 Some(t) => t,
108 None => break,
109 };
110
111 let parselet: &Box<dyn InfixParselet> = match self.infix_parselets.get(&next.get_class()) {
112 Some(p) => p,
113 None => break,
114 };
115 tokenizer.next();
116
117 left = parselet.parse(self, tokenizer, next, left);
118 }
119
120 left
121 }
122}