2021-06-06 13:28:13 -05:00
|
|
|
use logos::{Lexer, Logos};
|
2021-04-12 13:20:45 -05:00
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
#[derive(Logos, Debug, PartialEq, Clone)]
|
|
|
|
pub enum Token {
|
|
|
|
// Symbols
|
|
|
|
#[token("(")]
|
2021-06-06 17:09:45 -05:00
|
|
|
LeftParen,
|
2021-04-28 15:52:19 -05:00
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
#[token(")")]
|
2021-06-06 17:09:45 -05:00
|
|
|
RightParen,
|
2021-04-28 15:52:19 -05:00
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
#[token("[")]
|
|
|
|
LeftBracket,
|
2021-04-28 15:52:19 -05:00
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
#[token("]")]
|
|
|
|
RightBracket,
|
2021-04-28 15:52:19 -05:00
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
#[token("{")]
|
|
|
|
LeftCurly,
|
2021-04-28 15:52:19 -05:00
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
#[token("}")]
|
|
|
|
RightCurly,
|
2021-04-28 15:52:19 -05:00
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
#[token(";")]
|
|
|
|
Semicolon,
|
2021-04-28 15:52:19 -05:00
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
#[token(",")]
|
|
|
|
Comma,
|
|
|
|
|
|
|
|
// Operators
|
|
|
|
#[token("+")]
|
|
|
|
Plus,
|
|
|
|
|
|
|
|
#[token("-")]
|
|
|
|
Minus,
|
|
|
|
|
|
|
|
#[token("*")]
|
|
|
|
Star,
|
|
|
|
|
|
|
|
#[token("/")]
|
|
|
|
FwdSlash,
|
|
|
|
|
|
|
|
#[token("=")]
|
|
|
|
Equal,
|
|
|
|
|
2021-07-27 04:52:43 -05:00
|
|
|
#[token("<=")]
|
|
|
|
Arrow,
|
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
// Logical operators
|
|
|
|
#[token("<")]
|
|
|
|
LessThan,
|
|
|
|
|
|
|
|
#[token(">")]
|
|
|
|
GreaterThan,
|
|
|
|
|
|
|
|
#[token("==")]
|
|
|
|
EqualEqual,
|
|
|
|
|
|
|
|
#[token("!=")]
|
|
|
|
NotEqual,
|
|
|
|
|
2022-03-02 04:36:08 -06:00
|
|
|
#[regex("!|ain't")]
|
2021-06-06 13:28:13 -05:00
|
|
|
Not,
|
|
|
|
|
|
|
|
// Keywords
|
2021-04-27 06:48:56 -05:00
|
|
|
#[token("functio")]
|
2021-06-06 13:28:13 -05:00
|
|
|
Functio,
|
2021-04-27 06:48:56 -05:00
|
|
|
|
|
|
|
/// Brain fuck FFI
|
|
|
|
#[token("bff")]
|
2021-06-07 04:00:06 -05:00
|
|
|
Bff,
|
2021-04-27 06:48:56 -05:00
|
|
|
|
|
|
|
/// Variable bro
|
|
|
|
#[token("var")]
|
2021-06-07 04:00:06 -05:00
|
|
|
Var,
|
2021-04-27 06:48:56 -05:00
|
|
|
|
|
|
|
/// Prints the preceding things
|
|
|
|
#[token("print")]
|
|
|
|
Print,
|
|
|
|
|
2021-06-18 13:28:53 -05:00
|
|
|
/// Read input into preceding variable
|
|
|
|
#[token("read")]
|
|
|
|
Read,
|
|
|
|
|
2021-04-27 06:48:56 -05:00
|
|
|
/// Ban the following variable from ever being used again
|
|
|
|
#[token("melo")]
|
|
|
|
Melo,
|
|
|
|
|
|
|
|
#[token("T-Dark")]
|
|
|
|
TDark,
|
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
// Control flow keywords
|
2021-04-27 06:48:56 -05:00
|
|
|
#[token("if")]
|
|
|
|
If,
|
|
|
|
|
|
|
|
#[token("loop")]
|
|
|
|
Loop,
|
|
|
|
|
2021-05-02 11:12:51 -05:00
|
|
|
#[token("break")]
|
|
|
|
Break,
|
|
|
|
|
2021-06-06 13:28:13 -05:00
|
|
|
/// HopBack hops on the back of loop - like `continue`
|
2021-05-02 11:12:51 -05:00
|
|
|
#[token("hopback")]
|
|
|
|
HopBack,
|
|
|
|
|
2021-06-06 16:15:11 -05:00
|
|
|
/// Crash with random error (see discussion #17)
|
|
|
|
#[token("rlyeh")]
|
|
|
|
Rlyeh,
|
|
|
|
|
2021-06-13 00:11:02 -05:00
|
|
|
#[token("rickroll")]
|
|
|
|
Rickroll,
|
|
|
|
|
2021-04-18 15:33:55 -05:00
|
|
|
// Literals
|
|
|
|
/// String
|
2022-03-13 07:18:51 -05:00
|
|
|
#[token("/*", get_string)]
|
2021-04-27 03:51:39 -05:00
|
|
|
String(String),
|
2021-04-18 15:33:55 -05:00
|
|
|
|
|
|
|
/// Integer
|
2021-10-04 16:03:23 -05:00
|
|
|
#[regex(r"-?[0-9]+", get_value)]
|
2022-02-12 17:55:19 -06:00
|
|
|
Integer(isize),
|
2021-04-18 15:33:55 -05:00
|
|
|
|
2022-03-01 14:53:58 -06:00
|
|
|
/// An identifier
|
2022-04-02 13:39:48 -05:00
|
|
|
#[regex(r"[\p{XID_Start}|_][\p{XID_Continue}]*", get_ident)]
|
2021-04-27 04:09:19 -05:00
|
|
|
Identifier(String),
|
2021-04-12 13:20:45 -05:00
|
|
|
|
2021-08-23 11:58:28 -05:00
|
|
|
#[regex(r"owo .*")]
|
2021-04-12 13:20:45 -05:00
|
|
|
Comment,
|
|
|
|
|
|
|
|
#[regex(r"[ \t\n\f]+", logos::skip)]
|
|
|
|
#[error]
|
|
|
|
Error,
|
2021-04-11 17:22:06 -05:00
|
|
|
}
|
2021-04-27 03:51:39 -05:00
|
|
|
|
2021-10-04 16:03:23 -05:00
|
|
|
fn get_value<T: std::str::FromStr>(lexer: &mut Lexer<Token>) -> Option<T> {
|
2021-04-27 03:51:39 -05:00
|
|
|
lexer.slice().parse().ok()
|
|
|
|
}
|
|
|
|
|
2022-03-13 07:18:51 -05:00
|
|
|
fn get_string(lexer: &mut Lexer<Token>) -> Option<String> {
|
|
|
|
lexer.bump(lexer.remainder().find("*/")?);
|
|
|
|
let string = lexer.slice()[2..].to_owned();
|
|
|
|
lexer.bump(2);
|
2022-04-02 13:41:59 -05:00
|
|
|
|
2022-03-13 07:18:51 -05:00
|
|
|
Some(string)
|
2021-04-27 03:51:39 -05:00
|
|
|
}
|
|
|
|
|
2021-10-04 16:00:18 -05:00
|
|
|
fn get_ident(lexer: &mut Lexer<Token>) -> String {
|
2021-04-27 04:09:19 -05:00
|
|
|
lexer.slice().to_owned()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::Token;
|
|
|
|
use super::Token::*;
|
|
|
|
use logos::Logos;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn simple_fn() {
|
|
|
|
let code = "functio test() { var a = 3; if a == 3 { a print } }";
|
|
|
|
let expected = &[
|
2021-06-06 13:28:13 -05:00
|
|
|
Functio,
|
2021-04-27 04:09:19 -05:00
|
|
|
Identifier("test".to_owned()),
|
2021-06-06 17:09:45 -05:00
|
|
|
LeftParen,
|
|
|
|
RightParen,
|
2021-06-06 13:28:13 -05:00
|
|
|
LeftCurly,
|
2021-06-07 04:00:06 -05:00
|
|
|
Var,
|
2021-04-27 04:09:19 -05:00
|
|
|
Identifier("a".to_owned()),
|
2021-06-06 13:28:13 -05:00
|
|
|
Equal,
|
2021-04-27 04:09:19 -05:00
|
|
|
Integer(3),
|
|
|
|
Semicolon,
|
|
|
|
If,
|
|
|
|
Identifier("a".to_owned()),
|
2021-06-06 13:28:13 -05:00
|
|
|
EqualEqual,
|
2021-04-27 04:09:19 -05:00
|
|
|
Integer(3),
|
2021-06-06 13:28:13 -05:00
|
|
|
LeftCurly,
|
2021-04-27 04:09:19 -05:00
|
|
|
Identifier("a".to_owned()),
|
|
|
|
Print,
|
2021-06-06 13:28:13 -05:00
|
|
|
RightCurly,
|
|
|
|
RightCurly,
|
2021-04-27 04:09:19 -05:00
|
|
|
];
|
|
|
|
let lexer = Token::lexer(code);
|
|
|
|
let result: Vec<Token> = lexer.collect();
|
|
|
|
assert_eq!(result, expected);
|
|
|
|
}
|
2021-04-27 06:48:56 -05:00
|
|
|
}
|