176 lines
6.9 KiB
Rust
176 lines
6.9 KiB
Rust
use super::*;
|
|
macro_rules! lex {
|
|
(type ($($t:tt)*), $expected:expr) => {
|
|
let token = Lexer::new(stringify!($($t)*)).scan().expect(stringify!($($t:tt)* should yield a valid token));
|
|
assert_eq!(token.kind, $expected);
|
|
};
|
|
(str $t:literal, $expected:expr) => {
|
|
let token = Lexer::new($t).scan().expect(stringify!($t:tt should yield a valid token));
|
|
assert_eq!(token.kind, $expected);
|
|
};
|
|
({ $($t:tt)* }) => {
|
|
Lexer::new(stringify!($($t)*))
|
|
};
|
|
}
|
|
#[test]
|
|
fn ascii_char() {
|
|
lex!(type ('A'), TokenKind::Char('A')); // 'A' should be a valid char
|
|
lex!(type ('\x1b'), TokenKind::Char('\x1b')); // '\\x1b' should be a valid char
|
|
}
|
|
#[test]
|
|
fn unicode_escape_char() {
|
|
lex!(type ('\u{1f988}'), TokenKind::Char('🦈')); // '\\u{1f988}' should be a valid 🦈
|
|
}
|
|
#[test]
|
|
fn number_with_base() {
|
|
lex!(type (0), TokenKind::Number(0, 10)); // 0 should be a 16-bit base-10 number
|
|
lex!(type (42069), TokenKind::Number(42069, 10)); // 42069 should be a 16-bit base-10 number
|
|
lex!(type (0x420), TokenKind::Number(0x420, 16)); // 0x420 should be a 16-bit base-16 number
|
|
lex!(type (0d100), TokenKind::Number(100, 10)); // 0d100 should be a 16-bit base-10 number
|
|
lex!(type (0o100), TokenKind::Number(64, 8)); // 0o100 should be a 16-bit base-8 number
|
|
lex!(type (0b100), TokenKind::Number(4, 2)); // 0b100 should be a 16-bit base-8 number
|
|
}
|
|
#[test]
|
|
fn no_operand_emulated() {
|
|
lex!(type (nop), TokenKind::NoEm(NoEm::Nop)); // nop should be a valid NoEm
|
|
lex!(type (ret), TokenKind::NoEm(NoEm::Ret)); // ret should be a valid NoEm
|
|
lex!(type (clrc), TokenKind::NoEm(NoEm::Clrc)); // clrc should be a valid NoEm
|
|
lex!(type (clrz), TokenKind::NoEm(NoEm::Clrz)); // clrz should be a valid NoEm
|
|
lex!(type (clrn), TokenKind::NoEm(NoEm::Clrn)); // clrn should be a valid NoEm
|
|
lex!(type (setc), TokenKind::NoEm(NoEm::Setc)); // setc should be a valid NoEm
|
|
lex!(type (setz), TokenKind::NoEm(NoEm::Setz)); // setz should be a valid NoEm
|
|
lex!(type (setn), TokenKind::NoEm(NoEm::Setn)); // setn should be a valid NoEm
|
|
lex!(type (dint), TokenKind::NoEm(NoEm::Dint)); // dint should be a valid NoEm
|
|
lex!(type (eint), TokenKind::NoEm(NoEm::Eint)); // eint should be a valid NoEm
|
|
}
|
|
#[test]
|
|
fn br() {
|
|
lex!(type (br), TokenKind::Special(Special::Br));
|
|
}
|
|
#[test]
|
|
fn one_operand_emulated() {
|
|
lex!(type (pop), TokenKind::OneEm(OneEm::Pop));
|
|
lex!(type (rla), TokenKind::OneEm(OneEm::Rla));
|
|
lex!(type (rlc), TokenKind::OneEm(OneEm::Rlc));
|
|
lex!(type (inv), TokenKind::OneEm(OneEm::Inv));
|
|
lex!(type (clr), TokenKind::OneEm(OneEm::Clr));
|
|
lex!(type (tst), TokenKind::OneEm(OneEm::Tst));
|
|
lex!(type (dec), TokenKind::OneEm(OneEm::Dec));
|
|
lex!(type (decd), TokenKind::OneEm(OneEm::Decd));
|
|
lex!(type (inc), TokenKind::OneEm(OneEm::Inc));
|
|
lex!(type (incd), TokenKind::OneEm(OneEm::Incd));
|
|
lex!(type (adc), TokenKind::OneEm(OneEm::Adc));
|
|
lex!(type (dadc), TokenKind::OneEm(OneEm::Dadc));
|
|
lex!(type (sbc), TokenKind::OneEm(OneEm::Sbc));
|
|
}
|
|
#[test]
|
|
fn one_operand() {
|
|
lex!(type (rrc), TokenKind::OneArg(OneArg::Rrc));
|
|
lex!(type (swpb), TokenKind::OneArg(OneArg::Swpb));
|
|
lex!(type (rra), TokenKind::OneArg(OneArg::Rra));
|
|
lex!(type (sxt), TokenKind::OneArg(OneArg::Sxt));
|
|
lex!(type (push), TokenKind::OneArg(OneArg::Push));
|
|
lex!(type (call), TokenKind::OneArg(OneArg::Call));
|
|
lex!(type (reti), TokenKind::OneArg(OneArg::Reti));
|
|
}
|
|
#[test]
|
|
fn two_operand() {
|
|
lex!(type (mov), TokenKind::TwoArg(TwoArg::Mov));
|
|
lex!(type (add), TokenKind::TwoArg(TwoArg::Add));
|
|
lex!(type (addc), TokenKind::TwoArg(TwoArg::Addc));
|
|
lex!(type (subc), TokenKind::TwoArg(TwoArg::Subc));
|
|
lex!(type (sub), TokenKind::TwoArg(TwoArg::Sub));
|
|
lex!(type (cmp), TokenKind::TwoArg(TwoArg::Cmp));
|
|
lex!(type (dadd), TokenKind::TwoArg(TwoArg::Dadd));
|
|
lex!(type (bit), TokenKind::TwoArg(TwoArg::Bit));
|
|
lex!(type (bic), TokenKind::TwoArg(TwoArg::Bic));
|
|
lex!(type (bis), TokenKind::TwoArg(TwoArg::Bis));
|
|
lex!(type (xor), TokenKind::TwoArg(TwoArg::Xor));
|
|
lex!(type (and), TokenKind::TwoArg(TwoArg::And));
|
|
}
|
|
#[test]
|
|
fn jump() {
|
|
lex!(type (jne), TokenKind::Jump(Jump::Jne));
|
|
lex!(type (jnz), TokenKind::Jump(Jump::Jnz));
|
|
lex!(type (jeq), TokenKind::Jump(Jump::Jeq));
|
|
lex!(type (jz), TokenKind::Jump(Jump::Jz));
|
|
lex!(type (jnc), TokenKind::Jump(Jump::Jnc));
|
|
lex!(type (jlo), TokenKind::Jump(Jump::Jlo));
|
|
lex!(type (jc), TokenKind::Jump(Jump::Jc));
|
|
lex!(type (jhs), TokenKind::Jump(Jump::Jhs));
|
|
lex!(type (jn), TokenKind::Jump(Jump::Jn));
|
|
lex!(type (jge), TokenKind::Jump(Jump::Jge));
|
|
lex!(type (jl), TokenKind::Jump(Jump::Jl));
|
|
lex!(type (jmp), TokenKind::Jump(Jump::Jmp));
|
|
}
|
|
#[test]
|
|
fn registers() {
|
|
lex!(type (pc), TokenKind::Reg(Reg::PC));
|
|
lex!(type (sp), TokenKind::Reg(Reg::SP));
|
|
lex!(type (sr), TokenKind::Reg(Reg::SR));
|
|
lex!(type (cg), TokenKind::Reg(Reg::CG));
|
|
lex!(type (r0), TokenKind::Reg(Reg::PC));
|
|
lex!(type (r1), TokenKind::Reg(Reg::SP));
|
|
lex!(type (r2), TokenKind::Reg(Reg::SR));
|
|
lex!(type (r3), TokenKind::Reg(Reg::CG));
|
|
lex!(type (r4), TokenKind::Reg(Reg::R4));
|
|
lex!(type (r5), TokenKind::Reg(Reg::R5));
|
|
lex!(type (r6), TokenKind::Reg(Reg::R6));
|
|
lex!(type (r7), TokenKind::Reg(Reg::R7));
|
|
lex!(type (r8), TokenKind::Reg(Reg::R8));
|
|
lex!(type (r9), TokenKind::Reg(Reg::R9));
|
|
lex!(type (r10), TokenKind::Reg(Reg::R10));
|
|
lex!(type (r11), TokenKind::Reg(Reg::R11));
|
|
lex!(type (r12), TokenKind::Reg(Reg::R12));
|
|
lex!(type (r13), TokenKind::Reg(Reg::R13));
|
|
lex!(type (r14), TokenKind::Reg(Reg::R14));
|
|
lex!(type (r15), TokenKind::Reg(Reg::R15));
|
|
}
|
|
|
|
#[test]
|
|
fn delimiters() {
|
|
lex!(str "", TokenKind::Eof);
|
|
lex!(str "\n", TokenKind::Newline);
|
|
lex!(str "(", TokenKind::OpenParen);
|
|
lex!(str ")", TokenKind::CloseParen);
|
|
lex!(str "{", TokenKind::OpenCurly);
|
|
lex!(str "}", TokenKind::CloseCurly);
|
|
lex!(str "[", TokenKind::OpenBrace);
|
|
lex!(str "]", TokenKind::CloseBrace);
|
|
}
|
|
|
|
#[test]
|
|
fn comment() {
|
|
lex!(str "; this is a comment!\n\n", TokenKind::Comment);
|
|
}
|
|
|
|
#[test]
|
|
fn other() {
|
|
// lex!(type (), TokenKind::)
|
|
lex!(type (,), TokenKind::Comma);
|
|
lex!(type (:), TokenKind::Colon);
|
|
lex!(type (!), TokenKind::Bang);
|
|
lex!(type (@), TokenKind::At);
|
|
lex!(type (&), TokenKind::Amp);
|
|
lex!(type (|), TokenKind::Bar);
|
|
lex!(type (^), TokenKind::Caret);
|
|
lex!(type (*), TokenKind::Star);
|
|
lex!(type (#), TokenKind::Hash);
|
|
lex!(type ($), TokenKind::Dollar);
|
|
lex!(type (%), TokenKind::Percent);
|
|
lex!(type (+), TokenKind::Plus);
|
|
lex!(type (-), TokenKind::Minus);
|
|
lex!(type (/), TokenKind::Slash);
|
|
lex!(type (<<), TokenKind::Lsh);
|
|
lex!(type (>>), TokenKind::Rsh);
|
|
lex!(type (.directive), TokenKind::Directive);
|
|
lex!(type (identifier), TokenKind::Identifier);
|
|
lex!(type (.b), TokenKind::Byte);
|
|
lex!(type (.w), TokenKind::Word);
|
|
}
|
|
|
|
#[test]
|
|
fn ignores_leading_whitespace() {
|
|
lex!(str " \u{a0}\t\t\t\t\t\t\t-", TokenKind::Minus);
|
|
}
|