// File: philpoore[P]Math/./src/Lexer.cpp
// Function: Lexer::tokenize()
vector<Token> Lexer::tokenize() {
    vector<Token> tokens;

    while (i < size) {
        char a = peek();
        if (a == 'i' && peek(1) == 'f') {  // if
            Token t = createToken(TOKEN_IF);
            t.source = "if";
            tokens.push_back(t);
            advance(2);
            continue;
        } else if (peekStr(0, 4) == "else") {  // else
            Token t = createToken(TOKEN_ELSE);
            t.source = "else";
            tokens.push_back(t);
            advance(4);
            continue;
        } else if (isalpha(a)) {
            // idents
            string ident = "";
            Token t = createToken(TOKEN_IDENT);
            while (isalpha(a) || isdigit(a)) {
                ident += a;
                advance();
                a = peek();
            }
            t.source = ident;
            tokens.push_back(t);
            continue;
        } else if (isdigit(a)) {
            Token t = createToken(TOKEN_NUMBER_LITERAL);
            // number literal
            string number = "";
            while (isdigit(a)) {
                number += a;
                advance();
                a = peek();
            }

            // decimal point
            if (a == '.') {
                number += a;
                advance();
                a = peek();
                while (isdigit(a)) {
                    number += a;
                    advance();
                    a = peek();
                }
            }

            t.source = number;
            tokens.push_back(t);
            continue;
        } else if (isspace(a)) {
            string whitespace;

            Token t = createToken(TOKEN_WHITESPACE);
            while (isspace(a)) {
                whitespace += a;
                if (a == '\n') {
                    advanceRow();
                }
                advance();
                a = peek();
            }
            t.source = whitespace;
            tokens.push_back(t);
            continue;
        } else if (a == '*' && peek(1) == '*') {
            Token t = createToken(TOKEN_EXP);
            t.source = "**";
            tokens.push_back(t);
            advance(2);
            continue;
        } else {
            TokenType tt =
                tokenTypeMap.count(a) ? tokenTypeMap.at(a) : (TokenType)a;
            Token t = createToken(tt);
            t.source = a;
            tokens.push_back(t);
            advance();
        }
    }

    Token t = createToken(TOKEN_EOF);
    tokens.push_back(t);

    return tokens;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2a0, %rsp            # imm = 0x2A0
movq %rdi, -0x258(%rbp)
movq %rdi, %rax
movq %rax, -0x250(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x248(%rbp)
movb $0x0, -0x11(%rbp)
callq 0xc9e0
movq -0x248(%rbp), %rcx
movl 0x20(%rcx), %eax
cmpl 0x24(%rcx), %eax
jge 0x87a7
movq -0x248(%rbp), %rdi
xorl %esi, %esi
callq 0xca00
movb %al, -0x259(%rbp)
jmp 0x7f91
movb -0x259(%rbp), %al
movb %al, -0x12(%rbp)
movsbl -0x12(%rbp), %eax
cmpl $0x69, %eax
jne 0x8059
movq -0x248(%rbp), %rdi
movl $0x1, %esi
callq 0xca00
movb %al, -0x25a(%rbp)
jmp 0x7fc0
movb -0x25a(%rbp), %al
movsbl %al, %eax
cmpl $0x66, %eax
jne 0x8059
movq -0x248(%rbp), %rsi
leaq -0x58(%rbp), %rdi
movl $0x10e, %edx            # imm = 0x10E
callq 0xca30
jmp 0x7fe9
leaq -0x50(%rbp), %rdi
leaq 0xe396(%rip), %rsi      # 0x1638a
callq 0x43e0
jmp 0x7ffb
movq -0x258(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0xcad0
jmp 0x800d
movq -0x248(%rbp), %rdi
movl $0x2, %esi
callq 0xcb40
jmp 0x8020
leaq -0x58(%rbp), %rdi
callq 0xcb70
jmp 0x7f68
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x8824
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x58(%rbp), %rdi
callq 0xcb70
jmp 0x8824
movq -0x248(%rbp), %rsi
leaq -0x78(%rbp), %rdi
xorl %edx, %edx
movl $0x4, %ecx
callq 0xcbc0
jmp 0x8072
leaq 0xe314(%rip), %rsi      # 0x1638d
leaq -0x78(%rbp), %rdi
callq 0xcb90
movb %al, -0x25b(%rbp)
jmp 0x808a
leaq -0x78(%rbp), %rdi
callq 0x4200
movb -0x25b(%rbp), %al
testb $0x1, %al
jne 0x80a2
jmp 0x8141
movq -0x248(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
movl $0x10f, %edx            # imm = 0x10F
callq 0xca30
jmp 0x80bc
leaq -0xa0(%rbp), %rdi
leaq 0xe2c3(%rip), %rsi      # 0x1638d
callq 0x43e0
jmp 0x80d1
movq -0x258(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0xcad0
jmp 0x80e6
movq -0x248(%rbp), %rdi
movl $0x4, %esi
callq 0xcb40
jmp 0x80f9
leaq -0xa8(%rbp), %rdi
callq 0xcb70
jmp 0x7f68
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x4200
jmp 0x8824
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0xcb70
jmp 0x8824
movsbl -0x12(%rbp), %edi
callq 0x4470
cmpl $0x0, %eax
je 0x82cc
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x268(%rbp)
callq 0x4500
movq -0x268(%rbp), %rdx
leaq 0xe37f(%rip), %rsi      # 0x164f3
leaq -0xc8(%rbp), %rdi
callq 0xbcf0
jmp 0x8182
leaq -0xc9(%rbp), %rdi
callq 0x4340
movq -0x248(%rbp), %rsi
leaq -0x100(%rbp), %rdi
movl $0x101, %edx            # imm = 0x101
callq 0xca30
jmp 0x81a8
jmp 0x81aa
movsbl -0x12(%rbp), %edi
callq 0x4470
movl %eax, %ecx
movb $0x1, %al
cmpl $0x0, %ecx
movb %al, -0x269(%rbp)
jne 0x81d7
movsbl -0x12(%rbp), %edi
callq 0x42c0
cmpl $0x0, %eax
setne %al
movb %al, -0x269(%rbp)
movb -0x269(%rbp), %al
testb $0x1, %al
jne 0x81e6
jmp 0x8274
movsbl -0x12(%rbp), %esi
leaq -0xc8(%rbp), %rdi
callq 0x4210
jmp 0x81f8
movq -0x248(%rbp), %rdi
movl $0x1, %esi
callq 0xcb40
jmp 0x820b
movq -0x248(%rbp), %rdi
xorl %esi, %esi
callq 0xca00
movb %al, -0x26a(%rbp)
jmp 0x8221
movb -0x26a(%rbp), %al
movb %al, -0x12(%rbp)
jmp 0x81aa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0xc9(%rbp), %rdi
callq 0x4340
jmp 0x8824
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x82bb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x100(%rbp), %rdi
callq 0xcb70
jmp 0x82bb
leaq -0xf8(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x4050
jmp 0x8289
movq -0x258(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0xcad0
jmp 0x829e
leaq -0x100(%rbp), %rdi
callq 0xcb70
leaq -0xc8(%rbp), %rdi
callq 0x4200
jmp 0x7f68
leaq -0xc8(%rbp), %rdi
callq 0x4200
jmp 0x8824
movsbl -0x12(%rbp), %edi
callq 0x42c0
cmpl $0x0, %eax
je 0x84c4
movq -0x248(%rbp), %rsi
leaq -0x130(%rbp), %rdi
movl $0x102, %edx            # imm = 0x102
callq 0xca30
jmp 0x82f8
leaq -0x151(%rbp), %rdi
movq %rdi, -0x278(%rbp)
callq 0x4500
movq -0x278(%rbp), %rdx
leaq 0xe1da(%rip), %rsi      # 0x164f3
leaq -0x150(%rbp), %rdi
callq 0xbcf0
jmp 0x8327
leaq -0x151(%rbp), %rdi
callq 0x4340
movsbl -0x12(%rbp), %edi
callq 0x42c0
cmpl $0x0, %eax
je 0x83c5
movsbl -0x12(%rbp), %esi
leaq -0x150(%rbp), %rdi
callq 0x4210
jmp 0x8357
movq -0x248(%rbp), %rdi
movl $0x1, %esi
callq 0xcb40
jmp 0x836a
movq -0x248(%rbp), %rdi
xorl %esi, %esi
callq 0xca00
movb %al, -0x279(%rbp)
jmp 0x8380
movb -0x279(%rbp), %al
movb %al, -0x12(%rbp)
jmp 0x8333
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x151(%rbp), %rdi
callq 0x4340
jmp 0x84b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x150(%rbp), %rdi
callq 0x4200
jmp 0x84b3
movsbl -0x12(%rbp), %eax
cmpl $0x2e, %eax
jne 0x846c
movsbl -0x12(%rbp), %esi
leaq -0x150(%rbp), %rdi
callq 0x4210
jmp 0x83e4
movq -0x248(%rbp), %rdi
movl $0x1, %esi
callq 0xcb40
jmp 0x83f7
movq -0x248(%rbp), %rdi
xorl %esi, %esi
callq 0xca00
movb %al, -0x27a(%rbp)
jmp 0x840d
movb -0x27a(%rbp), %al
movb %al, -0x12(%rbp)
movsbl -0x12(%rbp), %edi
callq 0x42c0
cmpl $0x0, %eax
je 0x846a
movsbl -0x12(%rbp), %esi
leaq -0x150(%rbp), %rdi
callq 0x4210
jmp 0x8436
movq -0x248(%rbp), %rdi
movl $0x1, %esi
callq 0xcb40
jmp 0x8449
movq -0x248(%rbp), %rdi
xorl %esi, %esi
callq 0xca00
movb %al, -0x27b(%rbp)
jmp 0x845f
movb -0x27b(%rbp), %al
movb %al, -0x12(%rbp)
jmp 0x8416
jmp 0x846c
leaq -0x128(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x4050
jmp 0x8481
movq -0x258(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0xcad0
jmp 0x8496
leaq -0x150(%rbp), %rdi
callq 0x4200
leaq -0x130(%rbp), %rdi
callq 0xcb70
jmp 0x7f68
leaq -0x130(%rbp), %rdi
callq 0xcb70
jmp 0x8824
movsbl -0x12(%rbp), %edi
callq 0x4080
cmpl $0x0, %eax
je 0x85f5
leaq -0x178(%rbp), %rdi
callq 0x43f0
movq -0x248(%rbp), %rsi
leaq -0x1a8(%rbp), %rdi
movl $0x111, %edx            # imm = 0x111
callq 0xca30
jmp 0x84fc
jmp 0x84fe
movsbl -0x12(%rbp), %edi
callq 0x4080
cmpl $0x0, %eax
je 0x859d
movsbl -0x12(%rbp), %esi
leaq -0x178(%rbp), %rdi
callq 0x4210
jmp 0x8522
movsbl -0x12(%rbp), %eax
cmpl $0xa, %eax
jne 0x8566
movq -0x248(%rbp), %rdi
callq 0xcc60
jmp 0x8539
jmp 0x8566
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x85e4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x1a8(%rbp), %rdi
callq 0xcb70
jmp 0x85e4
movq -0x248(%rbp), %rdi
movl $0x1, %esi
callq 0xcb40
jmp 0x8579
movq -0x248(%rbp), %rdi
xorl %esi, %esi
callq 0xca00
movb %al, -0x27c(%rbp)
jmp 0x858f
movb -0x27c(%rbp), %al
movb %al, -0x12(%rbp)
jmp 0x84fe
leaq -0x1a0(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x4050
jmp 0x85b2
movq -0x258(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0xcad0
jmp 0x85c7
leaq -0x1a8(%rbp), %rdi
callq 0xcb70
leaq -0x178(%rbp), %rdi
callq 0x4200
jmp 0x7f68
leaq -0x178(%rbp), %rdi
callq 0x4200
jmp 0x8824
movsbl -0x12(%rbp), %eax
cmpl $0x2a, %eax
jne 0x86b2
movq -0x248(%rbp), %rdi
movl $0x1, %esi
callq 0xca00
movb %al, -0x27d(%rbp)
jmp 0x861b
movb -0x27d(%rbp), %al
movsbl %al, %eax
cmpl $0x2a, %eax
jne 0x86b2
movq -0x248(%rbp), %rsi
leaq -0x1d8(%rbp), %rdi
movl $0x109, %edx            # imm = 0x109
callq 0xca30
jmp 0x8647
leaq -0x1d0(%rbp), %rdi
leaq 0xdc55(%rip), %rsi      # 0x162aa
callq 0x43e0
jmp 0x865c
movq -0x258(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0xcad0
jmp 0x8671
movq -0x248(%rbp), %rdi
movl $0x2, %esi
callq 0xcb40
jmp 0x8684
leaq -0x1d8(%rbp), %rdi
callq 0xcb70
jmp 0x7f68
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0xcb70
jmp 0x8824
leaq 0x17c57(%rip), %rdi     # 0x20310
leaq -0x12(%rbp), %rsi
callq 0xcc80
movq %rax, -0x288(%rbp)
jmp 0x86cb
movq -0x288(%rbp), %rax
cmpq $0x0, %rax
je 0x8702
leaq 0x17c31(%rip), %rdi     # 0x20310
leaq -0x12(%rbp), %rsi
callq 0xcce0
movq %rax, -0x290(%rbp)
jmp 0x86f1
movq -0x290(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x294(%rbp)
jmp 0x870c
movsbl -0x12(%rbp), %eax
movl %eax, -0x294(%rbp)
movq -0x248(%rbp), %rsi
movl -0x294(%rbp), %eax
movl %eax, -0x1dc(%rbp)
movl -0x1dc(%rbp), %edx
leaq -0x210(%rbp), %rdi
callq 0xca30
jmp 0x8733
movsbl -0x12(%rbp), %esi
leaq -0x208(%rbp), %rdi
callq 0x44b0
jmp 0x8745
movq -0x258(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0xcad0
jmp 0x875a
movq -0x248(%rbp), %rdi
movl $0x1, %esi
callq 0xcb40
jmp 0x876d
leaq -0x210(%rbp), %rdi
callq 0xcb70
jmp 0x8798
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x210(%rbp), %rdi
callq 0xcb70
jmp 0x8824
jmp 0x879a
jmp 0x879c
jmp 0x879e
jmp 0x87a0
jmp 0x87a2
jmp 0x7f68
movq -0x248(%rbp), %rsi
leaq -0x240(%rbp), %rdi
movl $0x112, %edx            # imm = 0x112
callq 0xca30
jmp 0x87c1
movq -0x258(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0xcad0
jmp 0x87d6
movb $0x1, -0x11(%rbp)
leaq -0x240(%rbp), %rdi
callq 0xcb70
testb $0x1, -0x11(%rbp)
jne 0x8814
jmp 0x8808
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x240(%rbp), %rdi
callq 0xcb70
jmp 0x8824
movq -0x258(%rbp), %rdi
callq 0xcd80
movq -0x250(%rbp), %rax
addq $0x2a0, %rsp            # imm = 0x2A0
popq %rbp
retq
movq -0x258(%rbp), %rdi
callq 0xcd80
movq -0x20(%rbp), %rdi
callq 0x44f0
nopl (%rax)