diff options
| author | Sophie Forrest <git@sophieforrest.com> | 2024-08-30 23:35:45 +1200 |
|---|---|---|
| committer | Sophie Forrest <git@sophieforrest.com> | 2024-08-30 23:35:45 +1200 |
| commit | 3c163eabc78ddbd26bb250ef5ad6da28cd61adc6 (patch) | |
| tree | 58e17534e1db18813554d4fb6e67020f898b655d /crates/brainf_lexer/src/lexer.rs | |
| parent | 17b78f8cb127817b93f7e6ced7e55d8748806a80 (diff) | |
feat: split engine into crates
Diffstat (limited to 'crates/brainf_lexer/src/lexer.rs')
| -rw-r--r-- | crates/brainf_lexer/src/lexer.rs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/crates/brainf_lexer/src/lexer.rs b/crates/brainf_lexer/src/lexer.rs new file mode 100644 index 0000000..b95cd87 --- /dev/null +++ b/crates/brainf_lexer/src/lexer.rs @@ -0,0 +1,75 @@ +//! Lexer implementation using logos. + +#![expect(clippy::indexing_slicing)] + +use logos::{Lexer, Logos}; + +/// List of operator codes for the lexer +/// Note: Any input symbol that is not in this list is a comment + +fn loop_callback(lex: &Lexer<Token>) -> (usize, usize) { + let span = lex.span(); + + (span.start, span.len()) +} + +/// List of Tokens for the lexer +/// Note: Any input symbol that is not in this list is a comment +#[derive(Clone, Copy, Debug, Logos, PartialEq, Eq)] +#[logos(skip r"[^<>+\-.,\[\]]+")] +pub enum Token { + /// `>` + /// + /// Increment the data pointer by one (to point to the next cell to the + /// right). + #[token(">")] + IncrementPointer, + + /// `<` + /// + /// Decrement the data pointer by one (to point to the next cell to the + /// left). + #[token("<")] + DecrementPointer, + + /// `+` + /// + /// Increment the byte at the data pointer by one. + #[token("+")] + IncrementByte, + + /// `-` + /// + /// Decrement the byte at the data pointer by one. + #[token("-")] + DecrementByte, + + /// `.` + /// + /// Output the byte at the data pointer. + #[token(".")] + OutputByte, + + /// `,` + /// + /// Accept one byte of input, storing its value in the byte at the data + /// pointer. + #[token(",")] + InputByte, + + /// `[` + /// + /// If the byte at the data pointer is zero, then instead of moving the + /// instruction pointer forward to the next command, jump it forward to the + /// command after the matching ] command. + #[token("[", loop_callback)] + StartLoop((usize, usize)), + + /// `]` + /// + /// If the byte at the data pointer is nonzero, then instead of moving the + /// instruction pointer forward to the next command, jump it back to the + /// command after the matching [ command. + #[token("]", loop_callback)] + EndLoop((usize, usize)), +} |