// File: baziotis[P]minijava-cpp/lex.cpp
// Function: lexer_test()
void lexer_test() {
    lexer_init("123 456 0x234", "test.java");
    assert_token_int(123);
    assert_token_int(456);
    assert_token_int(0x234);
    assert_token(TOK::EOI);
    assert_token(TOK::EOI);

    lexer_init("stefanos 456", "test.java");
    assert_token_id("stefanos");
    assert_token_int(456);
    assert_token(TOK::EOI);

    lexer_init("boolean class else if int return while System.out.println", "test.java");
    assert_token(TOK::BOOLEAN);
    assert_token(TOK::CLASS);
    assert_token(TOK::ELSE);
    assert_token(TOK::IF);
    assert_token(TOK::INT);
    assert_token(TOK::RETURN);
    assert_token(TOK::WHILE);
    assert_token(TOK::PRINT);
    assert_token(TOK::EOI);

    lexer_init("&& \0 another", "test.java");
    assert_token(TOK::AND_AND);
    assert_token(TOK::EOI);
    assert_token(TOK::EOI);

    lexer_init("&&  ( ) { } [ ] , ; ! = - + *", "test.java");
    assert_token(TOK::AND_AND);
    assert_token(TOK::LPAR);
    assert_token(TOK::RPAR);
    assert_token(TOK::LBRACE);
    assert_token(TOK::RBRACE);
    assert_token(TOK::LBRACKET);
    assert_token(TOK::RBRACKET);
    assert_token(TOK::COMMA);
    assert_token(TOK::SEMI);
    assert_token(TOK::NOT);
    assert_token(TOK::ASGN);
    assert_token(TOK::MINUS);
    assert_token(TOK::PLUS);
    assert_token(TOK::STAR);
    assert_token(TOK::EOI);

    // Note: No error!
    lexer_init("0r8", "test.java");
    assert_token_int(0);
    assert_token_id("r8");
    assert_token(TOK::EOI);

    // **  Warnings / Errors  ** //

    // Warning: floatings are not supported
    lexer_init(".45", "test.java");
    assert_token(TOK::DOT);
    assert_token_int(45);
    assert_token(TOK::EOI);
    // Syntax Error: Invalid hex constant
    lexer_init("0xw", "test.java");
    // Warning: Integer literal overflow
    lexer_init("0xffffffff", "test.java");
    // Warning: There's no `&` token.
    lexer_init("& +", "test.java");
    // Syntax Error: Invalid octal integer literal.
    lexer_init("085", "test.java");
    // Syntax Error: Digit `8` is out of range for base 8.
    lexer_init("058", "test.java");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
leaq 0x14934(%rip), %rdi     # 0x19def
leaq 0x1493b(%rip), %rsi     # 0x19dfd
callq 0x52b0
movl $0x7b, %edi
callq 0x5170
movl $0x1c8, %edi            # imm = 0x1C8
callq 0x5170
movl $0x234, %edi            # imm = 0x234
callq 0x5170
movl $0x1, %edi
callq 0x5120
movl $0x1, %edi
callq 0x5120
leaq 0x14907(%rip), %rdi     # 0x19e07
leaq 0x148f6(%rip), %rsi     # 0x19dfd
callq 0x52b0
leaq 0x14901(%rip), %rdi     # 0x19e14
callq 0x51d0
movl $0x1c8, %edi            # imm = 0x1C8
callq 0x5170
movl $0x1, %edi
callq 0x5120
leaq 0x148ea(%rip), %rdi     # 0x19e1d
leaq 0x148c3(%rip), %rsi     # 0x19dfd
callq 0x52b0
movl $0x5, %edi
callq 0x5120
movl $0x16, %edi
callq 0x5120
movl $0xd, %edi
callq 0x5120
movl $0x9, %edi
callq 0x5120
movl $0x6, %edi
callq 0x5120
movl $0xe, %edi
callq 0x5120
movl $0xa, %edi
callq 0x5120
movl $0xb, %edi
callq 0x5120
movl $0x1, %edi
callq 0x5120
leaq 0x145f0(%rip), %rdi     # 0x19b90
leaq 0x14856(%rip), %rsi     # 0x19dfd
callq 0x52b0
movl $0x1f, %edi
callq 0x5120
movl $0x1, %edi
callq 0x5120
movl $0x1, %edi
callq 0x5120
leaq 0x14886(%rip), %rdi     # 0x19e57
leaq 0x14825(%rip), %rsi     # 0x19dfd
callq 0x52b0
movl $0x1f, %edi
callq 0x5120
movl $0x3, %edi
callq 0x5120
movl $0x19, %edi
callq 0x5120
movl $0x7, %edi
callq 0x5120
movl $0x1a, %edi
callq 0x5120
movl $0x24, %edi
callq 0x5120
movl $0x1b, %edi
callq 0x5120
movl $0x1c, %edi
callq 0x5120
movl $0x1e, %edi
callq 0x5120
movl $0x4, %edi
callq 0x5120
movl $0x18, %edi
callq 0x5120
movl $0x22, %edi
callq 0x5120
movl $0x21, %edi
callq 0x5120
movl $0x23, %edi
callq 0x5120
movl $0x1, %edi
callq 0x5120
leaq 0x147fb(%rip), %rdi     # 0x19e75
leaq 0x1477c(%rip), %rsi     # 0x19dfd
callq 0x52b0
xorl %edi, %edi
callq 0x5170
leaq 0x147e2(%rip), %rdi     # 0x19e76
callq 0x51d0
movl $0x1, %edi
callq 0x5120
leaq 0x147cf(%rip), %rdi     # 0x19e79
leaq 0x1474c(%rip), %rsi     # 0x19dfd
callq 0x52b0
movl $0x1d, %edi
callq 0x5120
movl $0x2d, %edi
callq 0x5170
movl $0x1, %edi
callq 0x5120
leaq 0x147a2(%rip), %rdi     # 0x19e7d
leaq 0x1471b(%rip), %rsi     # 0x19dfd
callq 0x52b0
leaq 0x14793(%rip), %rdi     # 0x19e81
leaq 0x14708(%rip), %rsi     # 0x19dfd
callq 0x52b0
leaq 0x1478b(%rip), %rdi     # 0x19e8c
leaq 0x146f5(%rip), %rsi     # 0x19dfd
callq 0x52b0
leaq 0x1477c(%rip), %rdi     # 0x19e90
leaq 0x146e2(%rip), %rsi     # 0x19dfd
callq 0x52b0
leaq 0x1476d(%rip), %rdi     # 0x19e94
leaq 0x146cf(%rip), %rsi     # 0x19dfd
callq 0x52b0
popq %rbp
retq
nopw %cs:(%rax,%rax)