able-script/ablescript/src/lexer.rs

183 lines
3.1 KiB
Rust
Raw Normal View History

use logos::{Lexer, Logos};
#[derive(Logos, Debug, PartialEq, Clone)]
pub enum Token {
// Symbols
#[token("(")]
LeftParen,
#[token(")")]
RightParen,
#[token("[")]
LeftBracket,
#[token("]")]
RightBracket,
#[token("{")]
LeftCurly,
#[token("}")]
RightCurly,
#[token(";")]
Semicolon,
#[token(",")]
Comma,
// Operators
#[token("+")]
Plus,
#[token("-")]
Minus,
#[token("*")]
Star,
#[token("/")]
FwdSlash,
#[token("=:")]
Assign,
2021-07-27 04:52:43 -05:00
#[token("<=")]
Arrow,
// Logical operators
#[token("<")]
LessThan,
#[token(">")]
GreaterThan,
#[token("=")]
Equals,
2022-04-08 10:39:14 -05:00
#[token("ain't")]
Aint,
// Keywords
2021-04-27 06:48:56 -05:00
#[token("functio")]
Functio,
2021-04-27 06:48:56 -05:00
/// Brain fuck FFI
#[token("bff")]
Bff,
2021-04-27 06:48:56 -05:00
/// Variable bro
#[token("dim")]
Dim,
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,
// 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,
/// HopBack hops on the back of loop - like `continue`
2021-05-02 11:12:51 -05:00
#[token("hopback")]
HopBack,
/// Crash with random error (see discussion #17)
#[token("rlyeh")]
Rlyeh,
2021-06-13 00:11:02 -05:00
#[token("rickroll")]
Rickroll,
// Literals
/// String
2022-03-13 07:18:51 -05:00
#[token("/*", get_string)]
String(String),
/// 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),
/// An identifier
2022-04-16 15:06:37 -05:00
#[regex(r"\p{XID_Start}[\p{XID_Continue}]*", get_ident)]
Identifier(String),
#[regex(r"owo .*")]
Comment,
#[regex(r"[ \t\n\f]+", logos::skip)]
#[error]
Error,
2021-04-11 17:22:06 -05:00
}
2021-10-04 16:03:23 -05:00
fn get_value<T: std::str::FromStr>(lexer: &mut Lexer<Token>) -> Option<T> {
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-10-04 16:00:18 -05:00
fn get_ident(lexer: &mut Lexer<Token>) -> String {
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() { dim var 3; if (var = 3) { var print } }";
let expected = &[
Functio,
Identifier("test".to_owned()),
LeftParen,
RightParen,
LeftCurly,
Dim,
Identifier("var".to_owned()),
Integer(3),
Semicolon,
If,
LeftParen,
Identifier("var".to_owned()),
Equals,
Integer(3),
RightParen,
LeftCurly,
Identifier("var".to_owned()),
Print,
RightCurly,
RightCurly,
];
let lexer = Token::lexer(code);
let result: Vec<Token> = lexer.collect();
assert_eq!(result, expected);
}
2021-04-27 06:48:56 -05:00
}