summary refs log tree commit diff
path: root/crates/brainf_lexer/src/lexer.rs
blob: 8e74d76ecfcab1be952152c26ebb7ad379bab35e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// SPDX-License-Identifier: AGPL-3.0-or-later

//! Lexer implementation using logos.

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)),
}