// File: pranavmodx[P]modlang/src/parser.cpp
// Function: Parser::parseExpression(Precedence)
Expression *Parser::parseExpression(Precedence precedence)
{
	if (prefixParseFns.find(curToken.type) == prefixParseFns.end())
	{
		noPrefixParseFnError(curToken.type);
		return nullptr;
	}

	PrefixParseFn prefix = prefixParseFns[curToken.type];

	Expression *leftExp = (this->*prefix)(); // ->* operator is used to invoke method pointer

	while (peekToken.type != SEMICOLON && precedence < peekPrecedence())
	{
		if (infixParseFns.find(peekToken.type) == infixParseFns.end())
			return leftExp;

		InfixParseFn infix = infixParseFns[peekToken.type];
		if (infix == nullptr)
			return leftExp;

		nextToken();

		leftExp = (this->*infix)(leftExp);
	}

	return leftExp;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rsi
movq %rsi, -0x98(%rbp)
movq %rsi, %rdi
addq $0x100, %rdi            # imm = 0x100
addq $0x30, %rsi
callq 0x231e0
movq -0x98(%rbp), %rdi
movq %rax, -0x20(%rbp)
addq $0x100, %rdi            # imm = 0x100
callq 0x23210
movq %rax, -0x28(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x231b0
testb $0x1, %al
jne 0x21dbe
jmp 0x21e1e
movq -0x98(%rbp), %rsi
addq $0x30, %rsi
leaq -0x48(%rbp), %rdi
movq %rdi, -0xa0(%rbp)
callq 0x5130
movq -0x98(%rbp), %rdi
movq -0xa0(%rbp), %rsi
callq 0x221d0
jmp 0x21dee
leaq -0x48(%rbp), %rdi
callq 0x5518
movq $0x0, -0x8(%rbp)
jmp 0x22069
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x5518
jmp 0x22076
movq -0x98(%rbp), %rsi
movq %rsi, %rdi
addq $0x100, %rdi            # imm = 0x100
addq $0x30, %rsi
callq 0x22b70
movq -0x98(%rbp), %rcx
movq %rax, %rdx
movq (%rdx), %rax
movq 0x8(%rdx), %rdx
movq %rdx, -0x60(%rbp)
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x60(%rbp), %rdx
addq %rdx, %rcx
movq %rcx, -0xa8(%rbp)
andq $0x1, %rax
cmpq $0x0, %rax
je 0x21e96
movq -0xb0(%rbp), %rcx
movq -0xa8(%rbp), %rax
movq (%rax), %rax
subq $0x1, %rcx
movq (%rax,%rcx), %rax
movq %rax, -0xb8(%rbp)
jmp 0x21ea4
movq -0xb0(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xa8(%rbp), %rdi
movq -0xb8(%rbp), %rax
callq *%rax
movq %rax, -0x70(%rbp)
movq -0x98(%rbp), %rdi
addq $0x70, %rdi
leaq 0x43d16(%rip), %rsi     # 0x65be0
callq 0x22d80
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xb9(%rbp)
jne 0x21ee0
jmp 0x21f08
movq -0x98(%rbp), %rdi
movl -0x14(%rbp), %eax
movl %eax, -0xc0(%rbp)
callq 0x224c0
movl %eax, %ecx
movl -0xc0(%rbp), %eax
cmpl %ecx, %eax
setl %al
movb %al, -0xb9(%rbp)
movb -0xb9(%rbp), %al
testb $0x1, %al
jne 0x21f17
jmp 0x22061
movq -0x98(%rbp), %rsi
movq %rsi, %rdi
addq $0x138, %rdi            # imm = 0x138
addq $0x70, %rsi
callq 0x23270
movq -0x98(%rbp), %rdi
movq %rax, -0x78(%rbp)
addq $0x138, %rdi            # imm = 0x138
callq 0x232a0
movq %rax, -0x80(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x23240
testb $0x1, %al
jne 0x21f5f
jmp 0x21f6c
movq -0x70(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x22069
movq -0x98(%rbp), %rsi
movq %rsi, %rdi
addq $0x138, %rdi            # imm = 0x138
addq $0x70, %rsi
callq 0x22ba0
movq %rax, %rcx
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
movq %rcx, -0x88(%rbp)
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rcx
movq -0x88(%rbp), %rdx
cmpq $0x0, %rcx
sete %al
cmpq $0x0, %rcx
sete %cl
cmpq $0x0, %rdx
sete %dl
orb %dl, %cl
andb %cl, %al
testb $0x1, %al
jne 0x21fcb
jmp 0x21fd8
movq -0x70(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x22069
movq -0x98(%rbp), %rdi
callq 0x1f390
movq -0x98(%rbp), %rcx
movq -0x90(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0x88(%rbp), %rdx
addq %rdx, %rcx
movq %rcx, -0xc8(%rbp)
andq $0x1, %rax
cmpq $0x0, %rax
je 0x22036
movq -0xd0(%rbp), %rcx
movq -0xc8(%rbp), %rax
movq (%rax), %rax
subq $0x1, %rcx
movq (%rax,%rcx), %rax
movq %rax, -0xd8(%rbp)
jmp 0x22044
movq -0xd0(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xc8(%rbp), %rdi
movq -0xd8(%rbp), %rax
movq -0x70(%rbp), %rsi
callq *%rax
movq %rax, -0x70(%rbp)
jmp 0x21eb8
movq -0x70(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xe0, %rsp
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x5490
nop