// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %rbx
pushq %rax
leaq 0xabb3(%rip), %rdi      # 0xeb97
callq 0x3f0c
pushq $0x7b
popq %rdi
callq 0x3e57
movl $0x1c8, %edi            # imm = 0x1C8
callq 0x3e57
movl $0x234, %edi            # imm = 0x234
callq 0x3e57
pushq $0x1
popq %rbx
movl %ebx, %edi
callq 0x3e2b
movl %ebx, %edi
callq 0x3e2b
leaq 0xab88(%rip), %rdi      # 0xeba5
callq 0x3f0c
leaq 0xab89(%rip), %rdi      # 0xebb2
callq 0x3e8c
movl $0x1c8, %edi            # imm = 0x1C8
callq 0x3e57
movl %ebx, %edi
callq 0x3e2b
leaq 0xab75(%rip), %rdi      # 0xebbb
callq 0x3f0c
pushq $0x5
popq %rdi
callq 0x3e2b
pushq $0x16
popq %rdi
callq 0x3e2b
pushq $0xd
popq %rdi
callq 0x3e2b
pushq $0x9
popq %rdi
callq 0x3e2b
pushq $0x6
popq %rdi
callq 0x3e2b
pushq $0xe
popq %rdi
callq 0x3e2b
pushq $0xa
popq %rdi
callq 0x3e2b
pushq $0xb
popq %rdi
callq 0x3e2b
movl %ebx, %edi
callq 0x3e2b
leaq 0xa89f(%rip), %rdi      # 0xe938
callq 0x3f0c
pushq $0x1f
popq %rbp
movl %ebp, %edi
callq 0x3e2b
movl %ebx, %edi
callq 0x3e2b
movl %ebx, %edi
callq 0x3e2b
leaq 0xab38(%rip), %rdi      # 0xebf5
callq 0x3f0c
movl %ebp, %edi
callq 0x3e2b
pushq $0x3
popq %rdi
callq 0x3e2b
pushq $0x19
popq %rdi
callq 0x3e2b
pushq $0x7
popq %rdi
callq 0x3e2b
pushq $0x1a
popq %rdi
callq 0x3e2b
pushq $0x24
popq %rdi
callq 0x3e2b
pushq $0x1b
popq %rdi
callq 0x3e2b
pushq $0x1c
popq %rdi
callq 0x3e2b
pushq $0x1e
popq %rdi
callq 0x3e2b
pushq $0x4
popq %rdi
callq 0x3e2b
pushq $0x18
popq %rdi
callq 0x3e2b
pushq $0x22
popq %rdi
callq 0x3e2b
pushq $0x21
popq %rdi
callq 0x3e2b
pushq $0x23
popq %rdi
callq 0x3e2b
movl %ebx, %edi
callq 0x3e2b
leaq 0xaad4(%rip), %rdi      # 0xec13
callq 0x3f0c
xorl %edi, %edi
callq 0x3e57
leaq 0xaac2(%rip), %rdi      # 0xec14
callq 0x3e8c
movl %ebx, %edi
callq 0x3e2b
leaq 0xaab2(%rip), %rdi      # 0xec17
callq 0x3f0c
pushq $0x1d
popq %rdi
callq 0x3e2b
pushq $0x2d
popq %rdi
callq 0x3e57
movl %ebx, %edi
callq 0x3e2b
leaq 0xaa93(%rip), %rdi      # 0xec1b
callq 0x3f0c
leaq 0xaa8b(%rip), %rdi      # 0xec1f
callq 0x3f0c
leaq 0xaa8a(%rip), %rdi      # 0xec2a
callq 0x3f0c
leaq 0xaa82(%rip), %rdi      # 0xec2e
callq 0x3f0c
leaq 0xaa7a(%rip), %rdi      # 0xec32
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x3f0c