// File: pranavmodx[P]modlang/test/parser_test.cpp
// Function: TestLetStatement()
void TestLetStatement()
{
	std::string input =
		"let x = 5;"
		"let y = 10;"
		"let foobar = 838383;";

	std::vector<std::string> expectedIdent{"x", "y", "foobar"};

	// struct LetTest {
	// 	std::string input;
	// 	std::string expectedIdent;
	// 	Expression *value;
	// };

	// std::vector<LetTest> tests {
	// 	{"let x = 5;", "x", 5},
	// 	{"let y = true;", "y", true},
	// 	{"let foobar = y;", "foobar", "y"},
	// }

	Lexer lexer;
	lexer.New(input);

	Parser parser;
	parser.New(lexer);

	Program *program = parser.ParseProgram();

	checkParserErrors(parser);

	if (program == nullptr)
		std::cout << "ParseProgram() returned null" << std::endl;

	if (program->statements.size() != 3)
		std::cout << "program->statements does not contain 3 statements, got " << program->statements.size() << std::endl;

	Statement *stmt;
	for (int i = 0; i < program->statements.size(); i++)
	{
		stmt = program->statements[i];

		if (!testLetStatement((LetStatement *)stmt, expectedIdent[i]))
			return;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x370, %rsp            # imm = 0x370
leaq -0x21(%rbp), %rdi
movq %rdi, -0x2b8(%rbp)
callq 0x5470
movq -0x2b8(%rbp), %rdx
leaq 0x19b7b(%rip), %rsi     # 0x260c4
leaq -0x20(%rbp), %rdi
callq 0xdb60
jmp 0xc554
leaq -0x21(%rbp), %rdi
callq 0x52c0
movb $0x1, -0xcc(%rbp)
leaq -0xc0(%rbp), %rax
movq %rax, -0x2c8(%rbp)
movq %rax, -0xc8(%rbp)
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x2c0(%rbp)
callq 0x5470
movq -0x2c8(%rbp), %rdi
movq -0x2c0(%rbp), %rdx
leaq 0x19b4d(%rip), %rsi     # 0x260ee
callq 0xdb60
jmp 0xc5a8
leaq -0xa0(%rbp), %rax
movq %rax, -0x2d8(%rbp)
movq %rax, -0xc8(%rbp)
leaq -0xca(%rbp), %rdi
movq %rdi, -0x2d0(%rbp)
callq 0x5470
movq -0x2d8(%rbp), %rdi
movq -0x2d0(%rbp), %rdx
leaq 0x19b0b(%rip), %rsi     # 0x260f0
callq 0xdb60
jmp 0xc5ec
leaq -0x80(%rbp), %rax
movq %rax, -0x2e8(%rbp)
movq %rax, -0xc8(%rbp)
leaq -0xcb(%rbp), %rdi
movq %rdi, -0x2e0(%rbp)
callq 0x5470
movq -0x2e8(%rbp), %rdi
movq -0x2e0(%rbp), %rdx
leaq 0x19acc(%rip), %rsi     # 0x260f2
callq 0xdb60
jmp 0xc62d
movb $0x0, -0xcc(%rbp)
leaq -0xc0(%rbp), %rax
movq %rax, -0x60(%rbp)
movq $0x3, -0x58(%rbp)
leaq -0xcd(%rbp), %rdi
movq %rdi, -0x2f0(%rbp)
callq 0xddb0
movq -0x2f0(%rbp), %rcx
movq -0x60(%rbp), %rsi
movq -0x58(%rbp), %rdx
leaq -0x50(%rbp), %rdi
callq 0xddd0
jmp 0xc674
leaq -0xcd(%rbp), %rdi
callq 0xde50
leaq -0xc0(%rbp), %rax
movq %rax, -0x300(%rbp)
addq $0x60, %rax
movq %rax, -0x2f8(%rbp)
movq -0x2f8(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x308(%rbp)
callq 0x54d8
movq -0x300(%rbp), %rcx
movq -0x308(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x2f8(%rbp)
jne 0xc699
leaq -0xcb(%rbp), %rdi
callq 0x52c0
leaq -0xca(%rbp), %rdi
callq 0x52c0
leaq -0xc9(%rbp), %rdi
callq 0x52c0
leaq -0x100(%rbp), %rdi
movq %rdi, -0x310(%rbp)
callq 0xde70
movq -0x310(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x12480
jmp 0xc713
leaq -0x270(%rbp), %rdi
callq 0x197b0
jmp 0xc721
leaq -0x270(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x19c70
jmp 0xc736
leaq -0x270(%rbp), %rdi
callq 0x1c280
movq %rax, -0x318(%rbp)
jmp 0xc74b
movq -0x318(%rbp), %rax
movq %rax, -0x278(%rbp)
leaq -0x270(%rbp), %rdi
callq 0xd720
jmp 0xc767
cmpq $0x0, -0x278(%rbp)
jne 0xc8f9
movq 0x2b854(%rip), %rdi     # 0x37fd0
leaq 0x19976(%rip), %rsi     # 0x260f9
callq 0x5260
movq %rax, -0x320(%rbp)
jmp 0xc791
movq -0x320(%rbp), %rdi
movq 0x2b809(%rip), %rsi     # 0x37fa8
callq 0x52a0
jmp 0xc7a6
jmp 0xc8f9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x21(%rbp), %rdi
callq 0x52c0
jmp 0xcad9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0xc86e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0xc862
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0xc856
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0xcd(%rbp), %rdi
callq 0xde50
leaq -0xc0(%rbp), %rax
movq %rax, -0x330(%rbp)
addq $0x60, %rax
movq %rax, -0x328(%rbp)
movq -0x328(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x338(%rbp)
callq 0x54d8
movq -0x330(%rbp), %rcx
movq -0x338(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x328(%rbp)
jne 0xc823
jmp 0xc856
leaq -0xcb(%rbp), %rdi
callq 0x52c0
leaq -0xca(%rbp), %rdi
callq 0x52c0
leaq -0xc9(%rbp), %rdi
callq 0x52c0
testb $0x1, -0xcc(%rbp)
jne 0xc885
jmp 0xc8d2
movq -0xc8(%rbp), %rax
leaq -0xc0(%rbp), %rcx
cmpq %rax, %rcx
movq %rax, -0x340(%rbp)
je 0xc8d0
movq -0x340(%rbp), %rdi
addq $-0x20, %rdi
movq %rdi, -0x348(%rbp)
callq 0x54d8
movq -0x348(%rbp), %rax
leaq -0xc0(%rbp), %rcx
cmpq %rcx, %rax
movq %rax, -0x340(%rbp)
jne 0xc89f
jmp 0xc8d2
jmp 0xcad0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0xcabb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0xcaaf
movq -0x278(%rbp), %rdi
addq $0x8, %rdi
callq 0xde90
cmpq $0x3, %rax
je 0xc96a
movq 0x2b6ba(%rip), %rdi     # 0x37fd0
leaq 0x197f9(%rip), %rsi     # 0x26116
callq 0x5260
movq %rax, -0x350(%rbp)
jmp 0xc92b
movq -0x278(%rbp), %rdi
addq $0x8, %rdi
callq 0xde90
movq -0x350(%rbp), %rdi
movq %rax, %rsi
callq 0x50a0
movq %rax, -0x358(%rbp)
jmp 0xc953
movq -0x358(%rbp), %rdi
movq 0x2b647(%rip), %rsi     # 0x37fa8
callq 0x52a0
jmp 0xc968
jmp 0xc96a
movl $0x0, -0x284(%rbp)
movslq -0x284(%rbp), %rax
movq %rax, -0x360(%rbp)
movq -0x278(%rbp), %rdi
addq $0x8, %rdi
callq 0xde90
movq %rax, %rcx
movq -0x360(%rbp), %rax
cmpq %rcx, %rax
jae 0xca72
movq -0x278(%rbp), %rdi
addq $0x8, %rdi
movslq -0x284(%rbp), %rsi
callq 0xdeb0
movq (%rax), %rax
movq %rax, -0x280(%rbp)
movq -0x280(%rbp), %rax
movq %rax, -0x368(%rbp)
movslq -0x284(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0xded0
movq %rax, %rsi
leaq -0x2a8(%rbp), %rdi
callq 0x5120
jmp 0xc9f5
movq -0x368(%rbp), %rdi
leaq -0x2a8(%rbp), %rsi
callq 0xd8b0
movb %al, -0x369(%rbp)
jmp 0xca10
movb -0x369(%rbp), %al
xorb $-0x1, %al
movb %al, -0x36a(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x54d8
movb -0x36a(%rbp), %al
testb $0x1, %al
jne 0xca36
jmp 0xca5c
movl $0x1, -0x2ac(%rbp)
jmp 0xca7c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x54d8
jmp 0xcaaf
jmp 0xca5e
movl -0x284(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x284(%rbp)
jmp 0xc974
movl $0x0, -0x2ac(%rbp)
leaq -0x270(%rbp), %rdi
callq 0xdef0
leaq -0x100(%rbp), %rdi
callq 0xdf70
leaq -0x50(%rbp), %rdi
callq 0xdd50
leaq -0x20(%rbp), %rdi
callq 0x54d8
addq $0x370, %rsp            # imm = 0x370
popq %rbp
retq
leaq -0x270(%rbp), %rdi
callq 0xdef0
leaq -0x100(%rbp), %rdi
callq 0xdf70
leaq -0x50(%rbp), %rdi
callq 0xdd50
leaq -0x20(%rbp), %rdi
callq 0x54d8
movq -0x30(%rbp), %rdi
callq 0x5460
nopw %cs:(%rax,%rax)