mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-15 09:55:03 +01:00
started lexer
This commit is contained in:
parent
3eeafb574c
commit
0f7999cc0f
4 changed files with 295 additions and 0 deletions
145
src/lex.rs
Normal file
145
src/lex.rs
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use std::iter::Peekable;
|
||||
use std::str::CharIndices;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)]
|
||||
struct Span(usize);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Token<'code> {
|
||||
span: Span,
|
||||
kind: TokenType<'code>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum TokenType<'code> {
|
||||
// keywords
|
||||
Let,
|
||||
Fn,
|
||||
If,
|
||||
Else,
|
||||
Loop,
|
||||
While,
|
||||
For,
|
||||
True,
|
||||
False,
|
||||
Null,
|
||||
And,
|
||||
Or,
|
||||
Not,
|
||||
// literals
|
||||
String(&'code str),
|
||||
Number(f64),
|
||||
// ident
|
||||
Ident(&'code str),
|
||||
// punctuation
|
||||
/// +
|
||||
Plus,
|
||||
/// -
|
||||
Minus,
|
||||
/// *
|
||||
Asterisk,
|
||||
/// /
|
||||
Slash,
|
||||
/// %
|
||||
Percent,
|
||||
/// {
|
||||
BraceO,
|
||||
/// }
|
||||
BraceC,
|
||||
/// [
|
||||
BracketO,
|
||||
/// ]
|
||||
BracketC,
|
||||
/// (
|
||||
ParenO,
|
||||
/// )
|
||||
ParenC,
|
||||
/// .
|
||||
Dot,
|
||||
/// ,
|
||||
Comma,
|
||||
// =
|
||||
Equal,
|
||||
/// ==
|
||||
EqualEqual,
|
||||
/// !=
|
||||
BangEqual,
|
||||
/// >
|
||||
GreaterThan,
|
||||
/// <
|
||||
LessThan,
|
||||
/// >=
|
||||
GreaterThanEqual,
|
||||
/// <=
|
||||
LessThanEqual,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Lexer<'code> {
|
||||
code: Peekable<CharIndices<'code>>,
|
||||
state: LexState,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum LexState {
|
||||
Init,
|
||||
StrLit(usize),
|
||||
NumLit(usize),
|
||||
Ident(usize),
|
||||
Equal(usize),
|
||||
Bang(usize),
|
||||
GreaterThan(usize),
|
||||
LessThan(usize),
|
||||
}
|
||||
|
||||
impl<'code> Lexer<'code> {
|
||||
pub fn lex(code: &'code str) -> Self {
|
||||
Self {
|
||||
code: code.char_indices().peekable(),
|
||||
state: LexState::Init,
|
||||
}
|
||||
}
|
||||
|
||||
fn expect(&mut self, expected: char) -> bool {
|
||||
self.code
|
||||
.peek()
|
||||
.map(|(_, char)| *char == expected)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'code> Iterator for Lexer<'code> {
|
||||
type Item = Result<Token<'code>, LexError>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
match self.state {
|
||||
LexState::Init => match self.code.next() {
|
||||
_ => {}
|
||||
},
|
||||
LexState::StrLit(_) => {}
|
||||
LexState::NumLit(_) => {}
|
||||
LexState::Ident(_) => {}
|
||||
LexState::Equal(_) => {}
|
||||
LexState::Bang(start) => {
|
||||
return if self.expect('=') {
|
||||
let _ = self.code.next();
|
||||
Some(Ok(Token {
|
||||
span: Span(start),
|
||||
kind: TokenType::BangEqual,
|
||||
}))
|
||||
} else {
|
||||
Some(Err(LexError))
|
||||
}
|
||||
}
|
||||
LexState::GreaterThan(_) => {}
|
||||
LexState::LessThan(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LexError;
|
||||
8
src/lib.rs
Normal file
8
src/lib.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
mod lex;
|
||||
mod parse;
|
||||
|
||||
pub fn run_program(program: &str) {
|
||||
let lexer = lex::Lexer::lex(program);
|
||||
let tokens: Result<Vec<_>, _> = lexer.collect();
|
||||
println!("{:#?}", tokens);
|
||||
}
|
||||
0
src/parse.rs
Normal file
0
src/parse.rs
Normal file
Loading…
Add table
Add a link
Reference in a new issue