// File: /workspace/github_c_makefile_star2_O2/hsjoihs[P]c-compiler/parse_analyze_statement.c
// Function: parse_compound_statement
struct Statement parse_compound_statement(struct AnalyzerState *ptr_ps,
                                          const struct Token **ptr_tokvec)
{
	const struct Token *tokvec = *ptr_tokvec;
	struct Statement statement;
	statement.category = COMPOUND_STATEMENT;
	statement.labels = init_vector();
	statement.statement_vector = init_vector();
	if (tokvec[0].kind == LEFT_BRACE) {

		struct ScopeChain current_table = ptr_ps->scope_chain;

		struct ScopeChain new_table;
		new_table.var_table = init_map();

		/* current_table disappears at the end of this function,
		   but there is no problem because new_table itself gets overwritten at
		   the end of this function.
		 */
		new_table.outer = &current_table;

		ptr_ps->scope_chain = new_table;

		++tokvec;
		*ptr_tokvec = tokvec;
		while (1) {
			if (tokvec[0].kind == RIGHT_BRACE) {
				++tokvec;
				*ptr_tokvec = tokvec;
				ptr_ps->scope_chain = current_table;

				return statement;
			} else if (can_start_a_type(tokvec)) {
				struct Type *optional_ptr_type =
				    try_parse_type_specifier_and_semicolon(&tokvec);
				if (optional_ptr_type) {
					struct Statement s;
					s.category = DECLARATION_STATEMENT;
					s.declaration.type = *optional_ptr_type;
					s.declaration.ident_str = 0;
					s.labels = init_vector(); /* must initialize this, since it
					                             is used in goto traversal */
					struct Statement *ptr_s =
					    calloc(1, sizeof(struct Statement));
					*ptr_s = s;
					push_vector(&statement.statement_vector, ptr_s);
					continue;
				}

				const char *str;
				struct UntypedExpr *ptr_uexpr;
				const struct Type vartype =
				    parse_declaration(&tokvec, &str, &ptr_uexpr);

				/* while function prototypes are also allowed here in C, I will
				 * not implement it here */
				if (vartype.type_category == FN) {
					unsupported(
					    "declaring a function inside a compound statement\n");
					exit(EXIT_FAILURE);
				}

				struct Expr *ptr_expr = declare_var_and_return_initializer(
				    ptr_ps, &vartype, str, ptr_uexpr, &statement);

				if (ptr_expr) {
					struct Statement assignment;
					assignment.category = EXPRESSION_STATEMENT;
					assignment.expr1 = *ptr_expr;
					assignment.labels = init_vector();
					struct Statement *ptr_s =
					    calloc(1, sizeof(struct Statement));
					*ptr_s = assignment;
					push_vector(&statement.statement_vector, ptr_s);
				}

			} else {
				struct Statement s = parse_statement(ptr_ps, &tokvec);
				struct Statement *ptr_s = calloc(1, sizeof(struct Statement));
				*ptr_s = s;
				push_vector(&statement.statement_vector, ptr_s);
			}
		}
	} else {
		fprintf(stderr,
		        "****************************\n"
		        "* INTERNAL COMPILER ERROR @ %s\n"
		        "* Unexpected value: `tokvec[0].kind` != `LEFT_BRACE` (which "
		        "is %d), and is instead %d\n\n"
		        "****************************\n",
		        __func__, LEFT_BRACE, tokvec[0].kind);
		exit(EXIT_FAILURE);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x428, %rsp            # imm = 0x428
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, %rbx
movq (%rdx), %r14
andl $0x0, (%rdi)
callq 0x49e0
movq %rax, 0x378(%rbx)
movq %rdx, 0x380(%rbx)
callq 0x49e0
movq %rax, 0x8(%rbx)
movq %rdx, 0x10(%rbx)
movl (%r14), %r8d
cmpl $0x1e, %r8d
jne 0x366f
movq %rbx, -0x38(%rbp)
leaq 0x8(%rbx), %r12
movups (%r13), %xmm0
leaq -0x70(%rbp), %rbx
movaps %xmm0, (%rbx)
callq 0x9319
movq %rax, (%r13)
movq %rbx, 0x8(%r13)
addq $0x20, %r14
leaq -0x30(%rbp), %rbx
movq %r14, (%rbx)
movq %r15, -0x48(%rbp)
movq %r14, (%r15)
leaq -0x450(%rbp), %r15
movq %r13, -0x40(%rbp)
cmpl $0x1f, (%r14)
je 0x3639
movq %r14, %rdi
callq 0x8cfa
testl %eax, %eax
je 0x3549
movq %rbx, %rdi
callq 0x8bcf
testq %rax, %rax
je 0x3586
pushq $0x14
popq %rcx
leaq -0x134(%rbp), %rdi
movq %rax, %rsi
rep  movsl (%rsi), %es:(%rdi)
callq 0x49e0
movq %rax, %rbx
movq %rdx, %r14
movl $0x390, %esi            # imm = 0x390
pushq $0x1
popq %rdi
callq 0x10d0
movq %rax, %r13
movl $0xa, (%rax)
leaq 0x4(%rax), %rdi
movl $0x36c, %edx            # imm = 0x36C
movq %r15, %rsi
callq 0x1100
andq $0x0, 0x370(%r13)
movq %rbx, 0x378(%r13)
leaq -0x30(%rbp), %rbx
movq %r14, 0x380(%r13)
jmp 0x3621
movq %r15, %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x29f3
movl $0x390, %esi            # imm = 0x390
pushq $0x1
popq %rdi
callq 0x10d0
movq %rax, %rbx
movl $0x390, %edx            # imm = 0x390
movq %rax, %rdi
movq %r15, %rsi
callq 0x1100
movq %r12, %rdi
movq %rbx, %rsi
leaq -0x30(%rbp), %rbx
jmp 0x362b
leaq -0xc0(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rsi
leaq -0x58(%rbp), %rdx
leaq -0x50(%rbp), %rcx
callq 0x8d23
cmpl $0x3, -0xc0(%rbp)
je 0x3663
movq -0x58(%rbp), %rdx
movq -0x50(%rbp), %rcx
movq %r13, %rdi
movq %r14, %rsi
movq -0x38(%rbp), %r8
callq 0x36c5
testq %rax, %rax
je 0x3630
movl $0x100, %edx            # imm = 0x100
leaq -0x43c(%rbp), %rdi
movq %rax, %rsi
callq 0x1100
callq 0x49e0
movq %rax, %r14
movq %rdx, %rbx
movl $0x390, %esi            # imm = 0x390
pushq $0x1
popq %rdi
callq 0x10d0
movq %rax, %r13
movl $0x9, (%rax)
leaq 0x4(%rax), %rdi
movl $0x114, %edx            # imm = 0x114
movq %r15, %rsi
callq 0x1100
movq %r14, 0x378(%r13)
movq %rbx, 0x380(%r13)
leaq -0x30(%rbp), %rbx
movq %r12, %rdi
movq %r13, %rsi
movq -0x40(%rbp), %r13
callq 0x4a57
movq -0x30(%rbp), %r14
jmp 0x34c2
addq $0x20, %r14
movq -0x48(%rbp), %rax
movq %r14, (%rax)
movaps -0x70(%rbp), %xmm0
movups %xmm0, (%r13)
movq -0x38(%rbp), %rax
addq $0x428, %rsp            # imm = 0x428
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xa4da(%rip), %rdi      # 0xdb44
callq 0x8186
movq 0x12982(%rip), %rax     # 0x15ff8
movq (%rax), %rdi
leaq 0xa4f6(%rip), %rsi      # 0xdb76
leaq 0xa5a0(%rip), %rdx      # 0xdc27
pushq $0x1e
popq %rcx
xorl %eax, %eax
callq 0x10f0
pushq $0x1
popq %rdi
callq 0x1170