use super::token::Token;
use super::types::Type;
use super::value::Value;
pub struct Lexer {
text: String,
position: usize,
current_char: Option<char>,
}
impl Lexer {
pub fn new(text: String) -> Self {
Self {
current_char: Some(
text.chars()
.nth(0)
.expect("Input to Lexer should have length > 0 "),
),
text: text,
position: 0,
}
}
fn peek(&mut self) -> Option<char> {
self.text.chars().nth(self.position + 1)
}
fn advance(&mut self) {
self.position = self.position + 1;
if self.position > (self.text.chars().count() - 2) {
self.current_char = None
} else {
self.current_char = Some(
self.text
.chars()
.nth(self.position)
.expect("Input to Interpreter should have length > 0 "),
)
}
}
fn id(&mut self) -> Token {
let mut _id = String::new();
while let Some(_char) = self.current_char {
if !_char.is_alphabetic() {
break;
}
_id.push(_char);
self.advance();
}
if _id == "BYRJAFARR" {
return Token::new(Type::BEGIN, None);
}
if _id == "SLUTTADÅ" {
return Token::new(Type::END, None);
}
return Token::new(Type::VARIABLE, Some(Box::new(Value::STRING(_id))));
}
fn skip_whitespace(&mut self) {
while self.current_char.is_some() && self.current_char.unwrap().is_whitespace() {
self.advance();
}
}
fn integer(&mut self) -> i32 {
let mut result = String::new();
while self.current_char.is_some() && self.current_char.unwrap().is_numeric() {
result.push(self.current_char.unwrap());
self.advance();
}
return result.parse::<i32>().unwrap();
}
pub fn get_next_token(&mut self) -> Token {
while let Some(_char) = self.current_char {
if _char.is_whitespace() {
self.skip_whitespace();
continue;
}
if _char.is_numeric() {
return Token::new(
Type::INTEGER,
Some(Box::new(Value::INTEGER(self.integer()))),
);
}
if _char == ':' && self.peek() == Some('=') {
self.advance();
self.advance();
return Token::new(Type::ASSIGN, None);
}
if _char == ';' {
self.advance();
return Token::new(Type::SEMI, None);
}
if _char == '.' {
self.advance();
return Token::new(Type::DOT, None);
}
if _char == ';' {
self.advance();
return Token::new(Type::SEMI, None);
}
if _char == '+' {
self.advance();
return Token::new(Type::PLUS, None);
}
if _char == '-' {
self.advance();
return Token::new(Type::MINUS, None);
}
if _char == '/' {
self.advance();
return Token::new(Type::DIVIDE, None);
}
if _char == '*' {
self.advance();
return Token::new(Type::MULTIPLY, None);
}
if _char == '(' {
self.advance();
return Token::new(Type::LPAREN, None);
}
if _char == ')' {
self.advance();
return Token::new(Type::RPAREN, None);
}
if _char.is_alphabetic() {
return self.id();
}
self.error(_char);
}
Token::empty()
}
fn error(&self, _char: char) {
panic!("Intepreter crashed due to invalid input, {}.", _char);
}
}