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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
pub mod token; pub use token::*;
#[derive(Debug, PartialEq, Eq, Clone)] pub struct Interpreter { text: String, pos: usize, current_token: Option<Token>, current_char: Option<char>, }
impl Interpreter { pub fn new() -> Self { Interpreter { text: String::new(), pos: 0, current_token: None, current_char: None, } }
pub fn error(&self, message: &str) -> ! { panic!("Error parsing input: {}", message); }
pub fn advance(&mut self) { self.pos += 1; if self.pos > self.text.len() { self.current_char = None; return; } self.current_char = self.text.chars().nth(self.pos); }
pub fn integer(&mut self) -> String { let mut result = String::new(); while let Some(c) = self.current_char { if c.is_digit(10) { result.push(c); self.advance(); } else { break; } } result }
pub fn get_next_token(&mut self) -> Token { if self.pos >= self.text.len() { return Token::new(TokenType::Eof, None); }
if self.current_char.unwrap().is_whitespace() { self.advance(); return self.get_next_token(); }
if self.current_char.unwrap().is_digit(10) { return Token::new(TokenType::Integer, Some(self.integer())); }
if self.current_char == Some('+') { self.advance(); return Token::new( TokenType::Plus, Some(self.current_char.unwrap().to_string()), ); } if self.current_char == Some('-') { self.advance(); return Token::new( TokenType::Minus, Some(self.current_char.unwrap().to_string()), ); } self.error("Unexpected character"); }
pub fn eat(&mut self, token_type: TokenType) { if let Some(ref current_token) = self.current_token { if current_token.token_type == token_type { self.current_token = Some(self.get_next_token()); } else { self.error("Unexpected token"); } } else { self.error("Unexpected end of input"); } }
pub fn term(&mut self) -> i32 { let token = self.current_token.clone().unwrap(); self.eat(TokenType::Integer); return token.value.unwrap().parse::<i32>().unwrap(); }
pub fn expr(&mut self, text: String) -> i32 { self.text = text; self.pos = 0; self.current_char = self.text.chars().nth(self.pos); self.current_token = Some(self.get_next_token());
let mut result = self.term();
while let Some(ref token) = self.current_token.clone() { if token.token_type == TokenType::Plus { self.eat(TokenType::Plus); result += self.term(); } else if token.token_type == TokenType::Minus { self.eat(TokenType::Minus); result -= self.term(); } else { break; } } result } }
|