// File: pranavmodx[P]modlang/test/parser_test.cpp
// Function: TestIdentifierExpression()
void TestIdentifierExpression()
{
	std::string input = "foobar;";

	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() != 1)
		std::cout << "program->statements does not contain 1 statements, got " << program->statements.size() << std::endl;

	Statement *stmt;
	ExpressionStatement *expStmt;
	Identifier *ident;

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

		expStmt = ((ExpressionStatement *)stmt);

		if (expStmt->tokenLiteral() != "foobar")
			std::cout << "stmt->tokenLiteral() not 'foobar'"
					  << ", got " << stmt->tokenLiteral() << std::endl;

		ident = ((Identifier *)expStmt->expression);

		if (ident->value != "foobar")
			std::cout << "ident->value not 'foobar'"
					  << ", got " << stmt->tokenLiteral() << std::endl;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2e0, %rsp            # imm = 0x2E0
leaq -0x21(%rbp), %rdi
movq %rdi, -0x268(%rbp)
callq 0x5470
movq -0x268(%rbp), %rdx
leaq 0x19368(%rip), %rsi     # 0x261f1
leaq -0x20(%rbp), %rdi
callq 0xdb60
jmp 0xce94
leaq -0x21(%rbp), %rdi
callq 0x52c0
leaq -0x68(%rbp), %rdi
movq %rdi, -0x270(%rbp)
callq 0xde70
movq -0x270(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x12480
jmp 0xcebf
leaq -0x1d8(%rbp), %rdi
callq 0x197b0
jmp 0xcecd
leaq -0x1d8(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x19c70
jmp 0xcedf
leaq -0x1d8(%rbp), %rdi
callq 0x1c280
movq %rax, -0x278(%rbp)
jmp 0xcef4
movq -0x278(%rbp), %rax
movq %rax, -0x1e0(%rbp)
leaq -0x1d8(%rbp), %rdi
callq 0xd720
jmp 0xcf10
cmpq $0x0, -0x1e0(%rbp)
jne 0xcf89
movq 0x2b0af(%rip), %rdi     # 0x37fd0
leaq 0x191d1(%rip), %rsi     # 0x260f9
callq 0x5260
movq %rax, -0x280(%rbp)
jmp 0xcf36
movq -0x280(%rbp), %rdi
movq 0x2b064(%rip), %rsi     # 0x37fa8
callq 0x52a0
jmp 0xcf4b
jmp 0xcf89
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x21(%rbp), %rdi
callq 0x52c0
jmp 0xd2bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0xd2ad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0xd2a1
movq -0x1e0(%rbp), %rdi
addq $0x8, %rdi
callq 0xde90
cmpq $0x1, %rax
je 0xcffa
movq 0x2b02a(%rip), %rdi     # 0x37fd0
leaq 0x1924c(%rip), %rsi     # 0x261f9
callq 0x5260
movq %rax, -0x288(%rbp)
jmp 0xcfbb
movq -0x1e0(%rbp), %rdi
addq $0x8, %rdi
callq 0xde90
movq -0x288(%rbp), %rdi
movq %rax, %rsi
callq 0x50a0
movq %rax, -0x290(%rbp)
jmp 0xcfe3
movq -0x290(%rbp), %rdi
movq 0x2afb7(%rip), %rsi     # 0x37fa8
callq 0x52a0
jmp 0xcff8
jmp 0xcffa
movl $0x0, -0x1fc(%rbp)
movslq -0x1fc(%rbp), %rax
movq %rax, -0x298(%rbp)
movq -0x1e0(%rbp), %rdi
addq $0x8, %rdi
callq 0xde90
movq %rax, %rcx
movq -0x298(%rbp), %rax
cmpq %rcx, %rax
jae 0xd27a
movq -0x1e0(%rbp), %rdi
addq $0x8, %rdi
movslq -0x1fc(%rbp), %rsi
callq 0xdeb0
movq (%rax), %rax
movq %rax, -0x1e8(%rbp)
movq -0x1e8(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x1f0(%rbp), %rsi
movq (%rsi), %rax
movq (%rax), %rax
leaq -0x220(%rbp), %rdi
callq *%rax
jmp 0xd07c
leaq 0x1906f(%rip), %rsi     # 0x260f2
leaq -0x220(%rbp), %rdi
callq 0xdf90
movb %al, -0x299(%rbp)
jmp 0xd097
leaq -0x220(%rbp), %rdi
callq 0x54d8
movb -0x299(%rbp), %al
testb $0x1, %al
jne 0xd0b2
jmp 0xd17b
movq 0x2af17(%rip), %rdi     # 0x37fd0
leaq 0x19171(%rip), %rsi     # 0x26231
callq 0x5260
movq %rax, -0x2a8(%rbp)
jmp 0xd0ce
movq -0x2a8(%rbp), %rdi
leaq 0x1914e(%rip), %rsi     # 0x2622a
callq 0x5260
movq %rax, -0x2b0(%rbp)
jmp 0xd0ea
movq -0x1e8(%rbp), %rsi
movq (%rsi), %rax
movq (%rax), %rax
leaq -0x240(%rbp), %rdi
callq *%rax
jmp 0xd102
movq -0x2b0(%rbp), %rdi
leaq -0x240(%rbp), %rsi
callq 0x5230
movq %rax, -0x2b8(%rbp)
jmp 0xd11e
movq -0x2b8(%rbp), %rdi
movq 0x2ae7c(%rip), %rsi     # 0x37fa8
callq 0x52a0
jmp 0xd133
leaq -0x240(%rbp), %rdi
callq 0x54d8
jmp 0xd17b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x54d8
jmp 0xd2a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x240(%rbp), %rdi
callq 0x54d8
jmp 0xd2a1
movq -0x1f0(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x1f8(%rbp)
movq -0x1f8(%rbp), %rdi
addq $0x48, %rdi
leaq 0x18f53(%rip), %rsi     # 0x260f2
callq 0xdf90
movb %al, -0x2b9(%rbp)
jmp 0xd1ac
movb -0x2b9(%rbp), %al
testb $0x1, %al
jne 0xd1bb
jmp 0xd264
movq 0x2ae0e(%rip), %rdi     # 0x37fd0
leaq 0x1908a(%rip), %rsi     # 0x26253
callq 0x5260
movq %rax, -0x2c8(%rbp)
jmp 0xd1d7
movq -0x2c8(%rbp), %rdi
leaq 0x19045(%rip), %rsi     # 0x2622a
callq 0x5260
movq %rax, -0x2d0(%rbp)
jmp 0xd1f3
movq -0x1e8(%rbp), %rsi
movq (%rsi), %rax
movq (%rax), %rax
leaq -0x260(%rbp), %rdi
callq *%rax
jmp 0xd20b
movq -0x2d0(%rbp), %rdi
leaq -0x260(%rbp), %rsi
callq 0x5230
movq %rax, -0x2d8(%rbp)
jmp 0xd227
movq -0x2d8(%rbp), %rdi
movq 0x2ad73(%rip), %rsi     # 0x37fa8
callq 0x52a0
jmp 0xd23c
leaq -0x260(%rbp), %rdi
callq 0x54d8
jmp 0xd264
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x54d8
jmp 0xd2a1
jmp 0xd266
movl -0x1fc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1fc(%rbp)
jmp 0xd004
leaq -0x1d8(%rbp), %rdi
callq 0xdef0
leaq -0x68(%rbp), %rdi
callq 0xdf70
leaq -0x20(%rbp), %rdi
callq 0x54d8
addq $0x2e0, %rsp            # imm = 0x2E0
popq %rbp
retq
leaq -0x1d8(%rbp), %rdi
callq 0xdef0
leaq -0x68(%rbp), %rdi
callq 0xdf70
leaq -0x20(%rbp), %rdi
callq 0x54d8
movq -0x30(%rbp), %rdi
callq 0x5460
nopl (%rax,%rax)