// File: /workspace/github_c_makefile_star2_O0/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
subq $0xbc0, %rsp            # imm = 0xBC0
movq %rdi, -0xbb8(%rbp)
movq %rdi, %rax
movq %rax, -0xbc0(%rbp)
movq %rsi, -0x8(%rbp)
movq %rdx, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
movl $0x0, (%rdi)
callq 0x61d0
movq -0xbb8(%rbp), %rdi
movq %rax, -0x28(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x28(%rbp), %rax
movq %rax, 0x378(%rdi)
movq -0x20(%rbp), %rax
movq %rax, 0x380(%rdi)
callq 0x61d0
movq -0xbb8(%rbp), %rdi
movq %rax, -0x38(%rbp)
movq %rdx, -0x30(%rbp)
movq -0x38(%rbp), %rax
movq %rax, 0x8(%rdi)
movq -0x30(%rbp), %rax
movq %rax, 0x10(%rdi)
movq -0x18(%rbp), %rax
cmpl $0x1e, (%rax)
jne 0x4925
movq -0x8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x48(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
callq 0xccc0
movq %rax, -0x58(%rbp)
leaq -0x48(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rax
movq -0x58(%rbp), %rcx
movq %rcx, (%rax)
movq -0x50(%rbp), %rcx
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
cmpl $0x1f, (%rax)
jne 0x46f1
movq -0xbc0(%rbp), %rax
movq -0x18(%rbp), %rcx
addq $0x20, %rcx
movq %rcx, -0x18(%rbp)
movq -0x18(%rbp), %rdx
movq -0x10(%rbp), %rcx
movq %rdx, (%rcx)
movq -0x8(%rbp), %rcx
movq -0x48(%rbp), %rdx
movq %rdx, (%rcx)
movq -0x40(%rbp), %rdx
movq %rdx, 0x8(%rcx)
addq $0xbc0, %rsp            # imm = 0xBC0
popq %rbp
retq
movq -0x18(%rbp), %rdi
callq 0xc270
cmpl $0x0, %eax
je 0x48c5
leaq -0x18(%rbp), %rdi
callq 0xc0a0
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
je 0x47bc
movl $0xa, -0x3f0(%rbp)
leaq -0x3f0(%rbp), %rdi
addq $0x320, %rdi            # imm = 0x320
movq -0x60(%rbp), %rsi
movl $0x50, %edx
callq 0x10e0
movq $0x0, -0x80(%rbp)
callq 0x61d0
movq %rax, -0x400(%rbp)
movq %rdx, -0x3f8(%rbp)
movq -0x400(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x3f8(%rbp), %rax
movq %rax, -0x70(%rbp)
movl $0x1, %edi
movl $0x390, %esi            # imm = 0x390
callq 0x10b0
movq %rax, -0x408(%rbp)
movq -0x408(%rbp), %rdi
leaq -0x3f0(%rbp), %rsi
movl $0x390, %edx            # imm = 0x390
callq 0x10e0
movq -0xbb8(%rbp), %rdi
addq $0x8, %rdi
movq -0x408(%rbp), %rsi
callq 0x62c0
jmp 0x46ae
leaq -0x468(%rbp), %rdi
leaq -0x18(%rbp), %rsi
leaq -0x410(%rbp), %rdx
leaq -0x418(%rbp), %rcx
callq 0xc300
cmpl $0x3, -0x468(%rbp)
jne 0x47ef
leaq 0xf3c6(%rip), %rdi      # 0x13bb0
callq 0xb1f0
movq -0xbb8(%rbp), %r8
movq -0x8(%rbp), %rdi
movq -0x410(%rbp), %rdx
movq -0x418(%rbp), %rcx
leaq -0x468(%rbp), %rsi
callq 0x49b0
movq %rax, -0x470(%rbp)
cmpq $0x0, -0x470(%rbp)
je 0x48c3
movl $0x9, -0x800(%rbp)
leaq -0x800(%rbp), %rdi
addq $0x18, %rdi
movq -0x470(%rbp), %rsi
movl $0x100, %edx            # imm = 0x100
callq 0x10e0
callq 0x61d0
movq %rax, -0x810(%rbp)
movq %rdx, -0x808(%rbp)
movq -0x810(%rbp), %rax
movq %rax, -0x488(%rbp)
movq -0x808(%rbp), %rax
movq %rax, -0x480(%rbp)
movl $0x1, %edi
movl $0x390, %esi            # imm = 0x390
callq 0x10b0
movq %rax, -0x818(%rbp)
movq -0x818(%rbp), %rdi
leaq -0x800(%rbp), %rsi
movl $0x390, %edx            # imm = 0x390
callq 0x10e0
movq -0xbb8(%rbp), %rdi
addq $0x8, %rdi
movq -0x818(%rbp), %rsi
callq 0x62c0
jmp 0x491e
movq -0x8(%rbp), %rsi
leaq -0xba8(%rbp), %rdi
leaq -0x18(%rbp), %rdx
callq 0x3720
movl $0x1, %edi
movl $0x390, %esi            # imm = 0x390
callq 0x10b0
movq %rax, -0xbb0(%rbp)
movq -0xbb0(%rbp), %rdi
leaq -0xba8(%rbp), %rsi
movl $0x390, %edx            # imm = 0x390
callq 0x10e0
movq -0xbb8(%rbp), %rdi
addq $0x8, %rdi
movq -0xbb0(%rbp), %rsi
callq 0x62c0
jmp 0x4920
jmp 0x46ae
movq 0x176cc(%rip), %rax     # 0x1bff8
movq (%rax), %rdi
movq -0x18(%rbp), %rax
movl (%rax), %r8d
leaq 0xf2a5(%rip), %rsi      # 0x13be2
leaq 0xf34f(%rip), %rdx      # 0x13c93
movl $0x1e, %ecx
movb $0x0, %al
callq 0x10d0
movl $0x1, %edi
callq 0x1150
nopw (%rax,%rax)