// File: yanlinlin82[P]icpp/icpp.cpp
// Function: parse()
void parse()
{
	init_symbol();

	for (next(); !token.empty();) {
		if (token == "using") {
			next(); while (!token.empty() && token != ";") next();
			if (token.empty()) { err("missing ';' for 'using'!\n"); }
			log<3>("[DEBUG] => 'using' statement skipped\n");
			next();
		} else if (token == "typedef") {
			skip_until(";", token);
			log<3>("[DEBUG] => 'typedef' statement skipped\n");
			next();
		} else if (token == "enum") {
			parse_enum();
		} else if (token == "union" || token == "struct" || token == "class" || token == "namespace") {
			string keyword = token;
			next();
			string name = token;
			next();
			expect_token("{", keyword + " " + name);
			scopes.push_back(make_pair(keyword, name));
			log<3>("[DEBUG] => (%s %s) start\n", keyword.c_str(), name.c_str());
			next();
		} else if (token == "template") {
			skip_until(";", token);
			log<3>("[DEBUG] => 'template' statement skipped\n");
			next();
		} else if (token == ";") {
			log<3>("[DEBUG] => ';' - end of statement\n");
			next();
		} else if (token == "}") {
			string scope_type;
			string scope_name;
			if (!scopes.empty()) {
				scope_type = scopes.back().first;
				scope_name = scopes.back().second;
				scopes.pop_back();
			}
			log<3>("[DEBUG] => '}' - end of block (%s,%s)\n", scope_type.c_str(), scope_name.c_str());
			if (scope_type == "function") {
				if (returned_functions.find(scope_name) == returned_functions.end()) {
					add_assembly_code(LEAVE);
					add_assembly_code(RET, get<3>(current_function));
				}
				current_function = make_tuple("", "", "", 0);
				stack_frame_table.pop_back();
			}
			next();
		} else {
			parse_statements();
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2a0, %rsp            # imm = 0x2A0
callq 0x14d50
callq 0x6030
leaq 0x3a90c(%rip), %rdi     # 0x504e8
callq 0x3430
xorb $-0x1, %al
testb $0x1, %al
jne 0x15bec
jmp 0x16487
leaq 0x3a8f5(%rip), %rdi     # 0x504e8
leaq 0x222f3(%rip), %rsi     # 0x37eed
callq 0x1a9c0
testb $0x1, %al
jne 0x15c08
jmp 0x15c8c
callq 0x6030
leaq 0x3a8d4(%rip), %rdi     # 0x504e8
callq 0x3430
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x24d(%rbp)
jne 0x15c41
leaq 0x3a8b9(%rip), %rdi     # 0x504e8
leaq 0x2151c(%rip), %rsi     # 0x37152
callq 0x1b450
movb %al, -0x24d(%rbp)
movb -0x24d(%rbp), %al
testb $0x1, %al
jne 0x15c4d
jmp 0x15c54
callq 0x6030
jmp 0x15c0d
leaq 0x3a88d(%rip), %rdi     # 0x504e8
callq 0x3430
testb $0x1, %al
jne 0x15c66
jmp 0x15c74
leaq 0x22286(%rip), %rdi     # 0x37ef3
movb $0x0, %al
callq 0x1a780
leaq 0x22292(%rip), %rdi     # 0x37f0d
movb $0x0, %al
callq 0x19760
callq 0x6030
jmp 0x16482
leaq 0x3a855(%rip), %rdi     # 0x504e8
leaq 0x21fbd(%rip), %rsi     # 0x37c57
callq 0x1a9c0
testb $0x1, %al
jne 0x15ca8
jmp 0x15d6d
leaq -0x21(%rbp), %rdi
movq %rdi, -0x258(%rbp)
callq 0x3470
movq -0x258(%rbp), %rdx
leaq 0x2148c(%rip), %rsi     # 0x37152
leaq -0x20(%rbp), %rdi
callq 0x199b0
jmp 0x15cd1
leaq 0x3a810(%rip), %rsi     # 0x504e8
leaq -0x58(%rbp), %rdi
callq 0x3120
jmp 0x15ce3
leaq -0x20(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x6810
jmp 0x15cf2
leaq -0x58(%rbp), %rdi
callq 0x34d8
leaq -0x20(%rbp), %rdi
callq 0x34d8
leaq -0x21(%rbp), %rdi
callq 0x32b0
leaq 0x2221f(%rip), %rdi     # 0x37f33
movb $0x0, %al
callq 0x19760
callq 0x6030
jmp 0x16480
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x15d5f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x15d56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x34d8
leaq -0x20(%rbp), %rdi
callq 0x34d8
leaq -0x21(%rbp), %rdi
callq 0x32b0
jmp 0x16490
leaq 0x3a774(%rip), %rdi     # 0x504e8
leaq 0x221e0(%rip), %rsi     # 0x37f5b
callq 0x1a9c0
testb $0x1, %al
jne 0x15d86
jmp 0x15d90
callq 0x14160
jmp 0x1647e
leaq 0x3a751(%rip), %rdi     # 0x504e8
leaq 0x221c2(%rip), %rsi     # 0x37f60
callq 0x1a9c0
testb $0x1, %al
jne 0x15df1
leaq 0x3a73a(%rip), %rdi     # 0x504e8
leaq 0x221b1(%rip), %rsi     # 0x37f66
callq 0x1a9c0
testb $0x1, %al
jne 0x15df1
leaq 0x3a723(%rip), %rdi     # 0x504e8
leaq 0x221a1(%rip), %rsi     # 0x37f6d
callq 0x1a9c0
testb $0x1, %al
jne 0x15df1
leaq 0x3a70c(%rip), %rdi     # 0x504e8
leaq 0x22190(%rip), %rsi     # 0x37f73
callq 0x1a9c0
testb $0x1, %al
jne 0x15df1
jmp 0x1601a
leaq 0x3a6f0(%rip), %rsi     # 0x504e8
leaq -0x78(%rbp), %rdi
callq 0x3120
callq 0x6030
jmp 0x15e08
leaq 0x3a6d9(%rip), %rsi     # 0x504e8
leaq -0x98(%rbp), %rdi
callq 0x3120
jmp 0x15e1d
callq 0x6030
jmp 0x15e24
leaq -0xb9(%rbp), %rdi
movq %rdi, -0x260(%rbp)
callq 0x3470
movq -0x260(%rbp), %rdx
leaq 0x2156d(%rip), %rsi     # 0x373b2
leaq -0xb8(%rbp), %rdi
callq 0x199b0
jmp 0x15e53
leaq 0x21366(%rip), %rdx     # 0x371c0
leaq -0x100(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x1a540
jmp 0x15e6c
leaq -0xe0(%rbp), %rdi
leaq -0x100(%rbp), %rsi
leaq -0x98(%rbp), %rdx
callq 0x1a4f0
jmp 0x15e88
leaq -0xb8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x6790
jmp 0x15e9d
leaq -0xe0(%rbp), %rdi
callq 0x34d8
leaq -0x100(%rbp), %rdi
callq 0x34d8
leaq -0xb8(%rbp), %rdi
callq 0x34d8
leaq -0xb9(%rbp), %rdi
callq 0x32b0
leaq -0x140(%rbp), %rdi
leaq -0x78(%rbp), %rsi
leaq -0x98(%rbp), %rdx
callq 0x1bba0
jmp 0x15ee6
leaq 0x3a61b(%rip), %rdi     # 0x50508
leaq -0x140(%rbp), %rsi
callq 0x1bb70
jmp 0x15efb
leaq -0x140(%rbp), %rdi
callq 0x1bbe0
leaq -0x78(%rbp), %rdi
callq 0x3110
movq %rax, -0x268(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x3110
movq -0x268(%rbp), %rsi
movq %rax, %rdx
leaq 0x22049(%rip), %rdi     # 0x37f7d
xorl %eax, %eax
callq 0x19760
jmp 0x15f3d
callq 0x6030
jmp 0x15f44
leaq -0x98(%rbp), %rdi
callq 0x34d8
leaq -0x78(%rbp), %rdi
callq 0x34d8
jmp 0x1647c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x1600c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x16000
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x15fda
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x15fce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x15fc2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0xe0(%rbp), %rdi
callq 0x34d8
leaq -0x100(%rbp), %rdi
callq 0x34d8
leaq -0xb8(%rbp), %rdi
callq 0x34d8
leaq -0xb9(%rbp), %rdi
callq 0x32b0
jmp 0x16000
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x1bbe0
leaq -0x98(%rbp), %rdi
callq 0x34d8
leaq -0x78(%rbp), %rdi
callq 0x34d8
jmp 0x16490
leaq 0x3a4c7(%rip), %rdi     # 0x504e8
leaq 0x21f6f(%rip), %rsi     # 0x37f97
callq 0x1a9c0
testb $0x1, %al
jne 0x16036
jmp 0x1611c
leaq -0x161(%rbp), %rdi
movq %rdi, -0x270(%rbp)
callq 0x3470
movq -0x270(%rbp), %rdx
leaq 0x210fb(%rip), %rsi     # 0x37152
leaq -0x160(%rbp), %rdi
callq 0x199b0
jmp 0x16065
leaq 0x3a47c(%rip), %rsi     # 0x504e8
leaq -0x188(%rbp), %rdi
callq 0x3120
jmp 0x1607a
leaq -0x160(%rbp), %rdi
leaq -0x188(%rbp), %rsi
callq 0x6810
jmp 0x1608f
leaq -0x188(%rbp), %rdi
callq 0x34d8
leaq -0x160(%rbp), %rdi
callq 0x34d8
leaq -0x161(%rbp), %rdi
callq 0x32b0
leaq 0x21ee6(%rip), %rdi     # 0x37fa0
movb $0x0, %al
callq 0x19760
callq 0x6030
jmp 0x1647a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x1610b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x160ff
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x34d8
leaq -0x160(%rbp), %rdi
callq 0x34d8
leaq -0x161(%rbp), %rdi
callq 0x32b0
jmp 0x16490
leaq 0x3a3c5(%rip), %rdi     # 0x504e8
leaq 0x21028(%rip), %rsi     # 0x37152
callq 0x1a9c0
testb $0x1, %al
jne 0x16135
jmp 0x1614d
leaq 0x21e8d(%rip), %rdi     # 0x37fc9
movb $0x0, %al
callq 0x19760
callq 0x6030
jmp 0x16478
leaq 0x3a394(%rip), %rdi     # 0x504e8
leaq 0x20ff5(%rip), %rsi     # 0x37150
callq 0x1a9c0
testb $0x1, %al
jne 0x16169
jmp 0x1646f
leaq -0x1a8(%rbp), %rdi
callq 0x3380
leaq -0x1c8(%rbp), %rdi
callq 0x3380
leaq 0x3a380(%rip), %rdi     # 0x50508
callq 0x1baf0
testb $0x1, %al
jne 0x161ee
leaq 0x3a370(%rip), %rdi     # 0x50508
callq 0x1bb30
movq %rax, %rsi
leaq -0x1a8(%rbp), %rdi
callq 0x3030
jmp 0x161ae
leaq 0x3a353(%rip), %rdi     # 0x50508
callq 0x1bb30
movq %rax, %rsi
addq $0x20, %rsi
leaq -0x1c8(%rbp), %rdi
callq 0x3030
jmp 0x161cf
leaq 0x3a332(%rip), %rdi     # 0x50508
callq 0x1c700
jmp 0x161ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x16455
leaq -0x1a8(%rbp), %rdi
callq 0x3110
movq %rax, -0x278(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x3110
movq -0x278(%rbp), %rsi
movq %rax, %rdx
leaq 0x21dce(%rip), %rdi     # 0x37fec
xorl %eax, %eax
callq 0x19760
jmp 0x16227
leaq 0x2143e(%rip), %rsi     # 0x3766c
leaq -0x1a8(%rbp), %rdi
callq 0x1a9c0
movb %al, -0x279(%rbp)
jmp 0x16242
movb -0x279(%rbp), %al
testb $0x1, %al
jne 0x16251
jmp 0x16434
leaq 0x3a2c8(%rip), %rdi     # 0x50520
leaq -0x1c8(%rbp), %rsi
callq 0x1c760
movq %rax, -0x288(%rbp)
jmp 0x1626d
movq -0x288(%rbp), %rax
movq %rax, -0x1d0(%rbp)
leaq 0x3a29e(%rip), %rdi     # 0x50520
callq 0x1ae40
movq %rax, -0x1d8(%rbp)
leaq -0x1d0(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0x1c730
testb $0x1, %al
jne 0x162aa
jmp 0x163e7
leaq -0x1f9(%rbp), %rdi
movq %rdi, -0x290(%rbp)
callq 0x3470
movq -0x290(%rbp), %rdx
leaq 0x220f9(%rip), %rsi     # 0x383c4
leaq -0x1f8(%rbp), %rdi
callq 0x199b0
jmp 0x162d9
movl $0x24, %edi
xorl %esi, %esi
leaq -0x1f8(%rbp), %rdx
callq 0x56e0
jmp 0x162ee
leaq -0x1f8(%rbp), %rdi
callq 0x34d8
leaq -0x1f9(%rbp), %rdi
callq 0x32b0
leaq 0x3a42b(%rip), %rdi     # 0x50738
callq 0x1c3b0
movl (%rax), %eax
movl %eax, -0x29c(%rbp)
leaq -0x221(%rbp), %rdi
movq %rdi, -0x298(%rbp)
callq 0x3470
movq -0x298(%rbp), %rdx
leaq 0x22089(%rip), %rsi     # 0x383c4
leaq -0x220(%rbp), %rdi
callq 0x199b0
jmp 0x16349
movl -0x29c(%rbp), %esi
movl $0x26, %edi
leaq -0x220(%rbp), %rdx
callq 0x56e0
jmp 0x16362
leaq -0x220(%rbp), %rdi
callq 0x34d8
leaq -0x221(%rbp), %rdi
callq 0x32b0
jmp 0x163e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x163a2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x34d8
leaq -0x1f9(%rbp), %rdi
callq 0x32b0
jmp 0x16455
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x163d9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x34d8
leaq -0x221(%rbp), %rdi
callq 0x32b0
jmp 0x16455
movl $0x0, -0x24c(%rbp)
leaq 0x21fcc(%rip), %rcx     # 0x383c4
leaq -0x248(%rbp), %rdi
leaq -0x24c(%rbp), %r8
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x1c790
jmp 0x16413
leaq 0x3a31e(%rip), %rdi     # 0x50738
leaq -0x248(%rbp), %rsi
callq 0x1c7e0
jmp 0x16428
leaq 0x3a169(%rip), %rdi     # 0x50598
callq 0x1c810
callq 0x6030
jmp 0x1643b
leaq -0x1c8(%rbp), %rdi
callq 0x34d8
leaq -0x1a8(%rbp), %rdi
callq 0x34d8
jmp 0x16476
leaq -0x1c8(%rbp), %rdi
callq 0x34d8
leaq -0x1a8(%rbp), %rdi
callq 0x34d8
jmp 0x16490
xorl %edi, %edi
callq 0x12070
jmp 0x16478
jmp 0x1647a
jmp 0x1647c
jmp 0x1647e
jmp 0x16480
jmp 0x16482
jmp 0x15bd5
addq $0x2a0, %rsp            # imm = 0x2A0
popq %rbp
retq
movq -0x30(%rbp), %rdi
callq 0x3460
nopl (%rax)