Skip to main content

mate_rs/
monitor.rs

1//
2// Copyright 2022-present theiskaa. All rights reserved.
3// Use of this source code is governed by MIT license
4// that can be found in the LICENSE file.
5//
6
7use crate::token::{Sub, SubMethod, Token, TokenType};
8
9pub trait Monitor {
10    // Converts the [&self] object to the
11    // right String representing value.
12    fn to_string(&self, n: usize) -> String;
13}
14
15// A monitor debugger implementation for [Token].
16impl Monitor for Token {
17    fn to_string(&self, n: usize) -> String {
18        let mut lit: String;
19        let mut space: String = String::new();
20
21        let nest: usize = n;
22        if self.typ != TokenType::SUBEXP {
23            lit = format!("({})", self.literal);
24        } else {
25            lit = String::new();
26            for t in self.sub.tokens.iter().map(|t| t.to_string(nest + 1)) {
27                lit.push_str(format!("\n{t}").as_str())
28            }
29        }
30
31        for _ in 0..nest {
32            space.push_str("  ");
33        }
34
35        let mut typstr = self.typ.to_string(0);
36        if self.is_sub_exp() {
37            typstr.push_str(format!(" -> {{{}}}", self.sub.to_string(0)).as_str());
38        }
39
40        format!("{}{}{}", space.as_str(), typstr, lit)
41    }
42}
43
44// A monitor debugger implementation for [TokenType].
45impl Monitor for TokenType {
46    fn to_string(&self, _n: usize) -> String {
47        let data = match self {
48            TokenType::NUMBER => "NUMBER",
49            TokenType::ILLEGAL => "ILLEGAL",
50            TokenType::SUBEXP => "SUB-EXPRESSION",
51            TokenType::LPAREN => "LEFT-PARENTHESES",
52            TokenType::RPAREN => "RIGHT-PARENTHESES",
53            TokenType::POINTER => "POINTER",
54            TokenType::PLUS => "PLUS",
55            TokenType::MINUS => "MINUS",
56            TokenType::PRODUCT => "PRODUCT",
57            TokenType::DIVIDE => "DIVIDE",
58            TokenType::PERCENTAGE => "PERCENTAGE",
59            TokenType::POWER => "POWER",
60            TokenType::FACTORIAL => "FACTORIAL",
61            TokenType::LABS => "LEFT-ABS",
62            TokenType::RABS => "RIGHT-ABS",
63            TokenType::SQRT => "SQRT",
64            TokenType::SIN => "SIN",
65            TokenType::COS => "COS",
66            TokenType::TAN => "TAN",
67            TokenType::LOG => "LOG",
68            TokenType::LN => "LN",
69            TokenType::EXP => "EXP",
70            TokenType::FLOOR => "FLOOR",
71            TokenType::CEIL => "CEIL",
72            TokenType::ROUND => "ROUND",
73        };
74
75        String::from(data)
76    }
77}
78
79// A monitor debugger implementation for [Sub].
80impl Monitor for Sub {
81    fn to_string(&self, _n: usize) -> String {
82        let data = match &self.method {
83            SubMethod::ABS => "ABSOLUTE-VALUE",
84            SubMethod::PAREN => "PARENTHESES",
85        };
86
87        String::from(data)
88    }
89}
90
91// A monitor debugger implementation for [SubMethod].
92impl Monitor for SubMethod {
93    fn to_string(&self, _n: usize) -> String {
94        let data = match self {
95            SubMethod::ABS => "ABSOLUTE-VALUE",
96            SubMethod::PAREN => "PARENTHESES",
97        };
98
99        String::from(data)
100    }
101}
102
103#[cfg(test)]
104mod tests {
105    use super::*;
106    use std::collections::HashMap;
107
108    #[test]
109    fn token_to_string() {
110        let test_data: HashMap<String, String> = HashMap::from([
111            (
112                Token::from(String::from("-25"), (0, 1)).to_string(0),
113                String::from("NUMBER(-25)"),
114            ),
115            (
116                Token::from(String::from("/"), (0, 0)).to_string(0),
117                String::from("DIVIDE(/)"),
118            ),
119        ]);
120
121        for (t, expected) in test_data {
122            assert_eq!(t, expected);
123        }
124    }
125
126    #[test]
127    fn token_type_to_string() {
128        let test_data: HashMap<String, &str> = HashMap::from([
129            (TokenType::NUMBER.to_string(0), "NUMBER"),
130            (TokenType::ILLEGAL.to_string(0), "ILLEGAL"),
131            (TokenType::SUBEXP.to_string(0), "SUB-EXPRESSION"),
132            (TokenType::LPAREN.to_string(0), "LEFT-PARENTHESES"),
133            (TokenType::RPAREN.to_string(0), "RIGHT-PARENTHESES"),
134            (TokenType::POINTER.to_string(0), "POINTER"),
135            (TokenType::PLUS.to_string(0), "PLUS"),
136            (TokenType::MINUS.to_string(0), "MINUS"),
137            (TokenType::PRODUCT.to_string(0), "PRODUCT"),
138            (TokenType::DIVIDE.to_string(0), "DIVIDE"),
139            (TokenType::PERCENTAGE.to_string(0), "PERCENTAGE"),
140            (TokenType::POWER.to_string(0), "POWER"),
141            (TokenType::LABS.to_string(0), "LEFT-ABS"),
142            (TokenType::RABS.to_string(0), "RIGHT-ABS"),
143        ]);
144
145        for (tt, expected) in test_data {
146            assert_eq!(tt, expected);
147        }
148    }
149
150    #[test]
151    fn sub_to_string() {
152        let test_data: HashMap<String, &str> = HashMap::from([
153            (
154                Sub::new(Vec::new(), SubMethod::PAREN).to_string(0),
155                "PARENTHESES",
156            ),
157            (
158                Sub::new(Vec::new(), SubMethod::ABS).to_string(0),
159                "ABSOLUTE-VALUE",
160            ),
161        ]);
162
163        for (s, expected) in test_data {
164            assert_eq!(s, expected);
165        }
166    }
167
168    #[test]
169    fn sub_type_to_string() {
170        let test_data: HashMap<String, &str> = HashMap::from([
171            (SubMethod::PAREN.to_string(0), "PARENTHESES"),
172            (SubMethod::ABS.to_string(0), "ABSOLUTE-VALUE"),
173        ]);
174
175        for (s, expected) in test_data {
176            assert_eq!(s, expected);
177        }
178    }
179}