summaryrefslogtreecommitdiff
path: root/src/parser.rs
blob: fe414b0a5da7963e3d40041152472e1e94c8879a (plain)
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
extern crate core;
use core::str::Chars;

#[derive(Debug, PartialEq)]
pub enum Token {
    Number(i32),
    Plus,
    Minus,
    Multiply,
    Divide,
}

pub struct Lexer<'a> {
    chars: Chars<'a>,
}

impl<'a> Lexer<'a> {
	// Constructor
    pub fn new(input: &'a str) -> Self {
        Lexer { chars: input.chars() }
}

	fn next_token(&mut self) -> Option<Token> {
	        let next_char = self.chars.next()?;

	        match next_char {
	            '+' => Some(Token::Plus),
	            '-' => Some(Token::Minus),
	            '*' => Some(Token::Multiply),
	            '/' => Some(Token::Divide),
	            '1'..='9' => {
	                let mut number = next_char.to_digit(10)? as i32;
	                while let Some(next_char) = self.chars.clone().next() {
	                    if let Some(digit) = next_char.to_digit(10) {
	                        number = number * 10 + digit as i32;
	                        self.chars.next();
	                    } else {
	                        break;
	                    }
	                }
	                Some(Token::Number(number))
	            }
	            '0' => {
	            	let base = match self.chars.next().unwrap() {
	            		'b' => Some(2),
	            		'o' => Some(8),
	            		'x' => Some(16),
	            		_   => None,
	            	};
	            	if base.is_none() {
	            		return None;
	            	}

	            	let mut number = next_char.to_digit(base.clone().unwrap())?;
	            	while let Some(next_char) = self.chars.clone().next() {
	            		if let Some(digit) = next_char.to_digit(base.clone().unwrap()) {
	            			number = number * base.clone().unwrap() + digit;
	            			self.chars.next();
	            		} else {
	            			break;
	            		}
	            	}
	            	Some(Token::Number(number as i32))
	            }
	            _ => None,
	        }
    }
    
    pub fn tokenize(&mut self) -> Vec<Token> {
        let mut tokens = Vec::new();
        while let Some(token) = self.next_token() {
            tokens.push(token);
        }
        tokens
    }
}

fn main() {
    let mut lexer = Lexer::new("0x6A+0b001101*0o13");
    let tokens = lexer.tokenize();
    assert_eq!(
    tokens,
    vec![
        Token::Number(106),
        Token::Plus,
        Token::Number(13),
        Token::Multiply,
        Token::Number(11),
    ]
    );
}