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::IDENTIFIER => "IDENTIFIER",
50            TokenType::ASSIGN => "ASSIGN",
51            TokenType::ILLEGAL => "ILLEGAL",
52            TokenType::SUBEXP => "SUB-EXPRESSION",
53            TokenType::LPAREN => "LEFT-PARENTHESES",
54            TokenType::RPAREN => "RIGHT-PARENTHESES",
55            TokenType::POINTER => "POINTER",
56            TokenType::PLUS => "PLUS",
57            TokenType::MINUS => "MINUS",
58            TokenType::PRODUCT => "PRODUCT",
59            TokenType::DIVIDE => "DIVIDE",
60            TokenType::PERCENTAGE => "PERCENTAGE",
61            TokenType::POWER => "POWER",
62            TokenType::FACTORIAL => "FACTORIAL",
63            TokenType::LABS => "LEFT-ABS",
64            TokenType::RABS => "RIGHT-ABS",
65            TokenType::SQRT => "SQRT",
66            TokenType::SIN => "SIN",
67            TokenType::COS => "COS",
68            TokenType::TAN => "TAN",
69            TokenType::LOG => "LOG",
70            TokenType::LN => "LN",
71            TokenType::EXP => "EXP",
72            TokenType::FLOOR => "FLOOR",
73            TokenType::CEIL => "CEIL",
74            TokenType::ROUND => "ROUND",
75        };
76
77        String::from(data)
78    }
79}
80
81// A monitor debugger implementation for [Sub].
82impl Monitor for Sub {
83    fn to_string(&self, _n: usize) -> String {
84        let data = match &self.method {
85            SubMethod::ABS => "ABSOLUTE-VALUE",
86            SubMethod::PAREN => "PARENTHESES",
87        };
88
89        String::from(data)
90    }
91}
92
93// A monitor debugger implementation for [SubMethod].
94impl Monitor for SubMethod {
95    fn to_string(&self, _n: usize) -> String {
96        let data = match self {
97            SubMethod::ABS => "ABSOLUTE-VALUE",
98            SubMethod::PAREN => "PARENTHESES",
99        };
100
101        String::from(data)
102    }
103}
104
105#[cfg(test)]
106mod tests {
107    use super::*;
108    use std::collections::HashMap;
109
110    #[test]
111    fn token_to_string() {
112        let test_data: HashMap<String, String> = HashMap::from([
113            (
114                Token::from(String::from("-25"), (0, 1)).to_string(0),
115                String::from("NUMBER(-25)"),
116            ),
117            (
118                Token::from(String::from("/"), (0, 0)).to_string(0),
119                String::from("DIVIDE(/)"),
120            ),
121        ]);
122
123        for (t, expected) in test_data {
124            assert_eq!(t, expected);
125        }
126    }
127
128    #[test]
129    fn token_type_to_string() {
130        let test_data: HashMap<String, &str> = HashMap::from([
131            (TokenType::NUMBER.to_string(0), "NUMBER"),
132            (TokenType::ILLEGAL.to_string(0), "ILLEGAL"),
133            (TokenType::SUBEXP.to_string(0), "SUB-EXPRESSION"),
134            (TokenType::LPAREN.to_string(0), "LEFT-PARENTHESES"),
135            (TokenType::RPAREN.to_string(0), "RIGHT-PARENTHESES"),
136            (TokenType::POINTER.to_string(0), "POINTER"),
137            (TokenType::PLUS.to_string(0), "PLUS"),
138            (TokenType::MINUS.to_string(0), "MINUS"),
139            (TokenType::PRODUCT.to_string(0), "PRODUCT"),
140            (TokenType::DIVIDE.to_string(0), "DIVIDE"),
141            (TokenType::PERCENTAGE.to_string(0), "PERCENTAGE"),
142            (TokenType::POWER.to_string(0), "POWER"),
143            (TokenType::LABS.to_string(0), "LEFT-ABS"),
144            (TokenType::RABS.to_string(0), "RIGHT-ABS"),
145        ]);
146
147        for (tt, expected) in test_data {
148            assert_eq!(tt, expected);
149        }
150    }
151
152    #[test]
153    fn sub_to_string() {
154        let test_data: HashMap<String, &str> = HashMap::from([
155            (
156                Sub::new(Vec::new(), SubMethod::PAREN).to_string(0),
157                "PARENTHESES",
158            ),
159            (
160                Sub::new(Vec::new(), SubMethod::ABS).to_string(0),
161                "ABSOLUTE-VALUE",
162            ),
163        ]);
164
165        for (s, expected) in test_data {
166            assert_eq!(s, expected);
167        }
168    }
169
170    #[test]
171    fn sub_type_to_string() {
172        let test_data: HashMap<String, &str> = HashMap::from([
173            (SubMethod::PAREN.to_string(0), "PARENTHESES"),
174            (SubMethod::ABS.to_string(0), "ABSOLUTE-VALUE"),
175        ]);
176
177        for (s, expected) in test_data {
178            assert_eq!(s, expected);
179        }
180    }
181}