Files
rust-interpreter/src/lexer/mod.rs
T
2026-05-10 12:13:16 +02:00

93 lines
2.4 KiB
Rust

use super::token::ASSIGN;
use super::token::COMMA;
use super::token::EOF;
use super::token::FUNCTION;
use super::token::IDENT;
use super::token::ILLEGAL;
use super::token::INT;
use super::token::LBRACE;
use super::token::LET;
use super::token::LPAREN;
use super::token::PLUS;
use super::token::RBRACE;
use super::token::RPAREN;
use super::token::SEMICOLON;
use super::token::Token;
struct Lexer {
input: String,
position: Option<i32>,
read_pos: Option<i32>,
ch: Option<u8>,
}
trait LexerTraits {
fn read_char(&mut self);
fn next_token(&mut self) -> Token;
}
fn new(input_str: String) -> Lexer {
let mut l: Lexer = Lexer {
input: input_str,
position: Some(0),
read_pos: Some(1),
ch: Some(0),
};
l.read_char();
l
}
impl LexerTraits for Lexer {
fn read_char(&mut self) {
let read_pos = usize::try_from(self.read_pos.unwrap());
if read_pos.unwrap() >= self.input.len() {
self.ch = Some(0);
} else {
let bytes = self.input.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if i == read_pos.unwrap() {
self.ch = Some(item);
}
}
}
self.position = self.read_pos;
let new_read_pos = self.read_pos.unwrap() + 1;
self.read_pos = Some(new_read_pos);
}
fn next_token(&mut self) -> Token {
#[allow(unused_assignments)]
let mut tok = Token::default();
let lit = self.ch.unwrap();
let c = char::from(lit);
match c {
'=' => tok = new_token(ASSIGN, lit),
';' => tok = new_token(SEMICOLON, lit),
'(' => tok = new_token(LPAREN, lit),
')' => tok = new_token(RPAREN, lit),
',' => tok = new_token(COMMA, lit),
'+' => tok = new_token(PLUS, lit),
'{' => tok = new_token(LBRACE, lit),
'}' => tok = new_token(RBRACE, lit),
_ => {
tok = Token {
type_: String::from(EOF),
literal: String::from(""),
}
}
}
self.read_char();
tok
}
}
fn new_token(token_type: &str, ch: u8) -> Token {
let lit = ch.to_string();
let token_type = String::from(token_type);
Token {
type_: token_type,
literal: lit,
}
}