add lexer

This commit is contained in:
Raptorox 2026-05-20 21:04:14 +02:00
parent 05ad6afe72
commit ad7a8ad879
No known key found for this signature in database
GPG key ID: 8B3556FC3ED1F6D8
3 changed files with 120 additions and 2 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/target
/res

96
src/lexer.rs Normal file
View file

@ -0,0 +1,96 @@
#[derive(Debug, PartialEq)]
pub enum Token {
Number(i64),
Ident(String),
// Operators
Add,
Sub,
Mul,
Div,
Mod,
// Parentheses
LParen,
RParen,
LBrace,
RBrace,
LBracket,
RBracket,
Semicolon
}
pub struct Lexer {
source: Vec<u8>,
pos: usize
}
impl Lexer {
pub fn new(source: &str) -> Self {
Self {
source: source.as_bytes().to_vec(),
pos: 0
}
}
fn skip_whitespace(&mut self) {
while matches!(self.peek(), Some(c) if c.is_ascii_whitespace()) {
self.advance();
}
}
fn advance(&mut self) {
self.pos += 1;
}
fn peek(&self) -> Option<u8> {
self.source.get(self.pos).copied()
}
fn number(&mut self) -> Option<Token> {
let mut num = String::new();
while matches!(self.peek(), Some(b'0' ..= b'9')) {
num.push(self.peek().unwrap() as char);
self.advance();
}
Some(Token::Number(num.parse().unwrap()))
}
fn ident(&mut self) -> Option<Token> {
let mut ident = String::new();
while matches!(self.peek(), Some(b'a' ..= b'z' | b'A' ..= b'Z')) {
ident.push(self.peek().unwrap() as char);
}
Some(Token::Ident(ident))
}
pub fn next(&mut self) -> Option<Token> {
self.skip_whitespace();
match self.peek() {
Some(b'0' ..= b'9') => self.number(),
Some(b'a' ..= b'z' | b'A' ..= b'Z') => self.ident(),
Some(b'+') => {self.advance(); Some(Token::Add)},
Some(b'-') => {self.advance(); Some(Token::Sub)},
Some(b'*') => {self.advance(); Some(Token::Mul)},
Some(b'/') => {self.advance(); Some(Token::Div)},
Some(b'%') => {self.advance(); Some(Token::Mod)},
Some(b'(') => {self.advance(); Some(Token::LParen)},
Some(b')') => {self.advance(); Some(Token::RParen)},
Some(b'[') => {self.advance(); Some(Token::LBracket)},
Some(b']') => {self.advance(); Some(Token::RBracket)},
Some(b'{') => {self.advance(); Some(Token::LBrace)},
Some(b'}') => {self.advance(); Some(Token::RBrace)},
Some(b';') => {self.advance(); Some(Token::Semicolon)}
_ => None
}
}
}

View file

@ -1,3 +1,24 @@
fn main() {
println!("Hello, world!");
use std::{fs::File, io::Read};
mod lexer;
use lexer::Lexer;
fn main() -> std::io::Result<()> {
let args = std::env::args().collect::<Vec<String>>();
let mut source = String::new();
File::open(&args[1])?.read_to_string(&mut source)?;
println!("{:?}", source);
let mut lexer = Lexer::new(&source);
loop {
match lexer.next() {
Some(tok) => print!("{tok:?}, "),
None => break
}
}
Ok(())
}