// File: /workspace/github_c_makefile_star2_O0/Ihsoh[P]ilang/compiler/frontend/irgen.c
// Function: ir_var
static void _ir_var(
	IRGeneratorContext *ctx,
	ParserASTNode *node
) {
	assert(ctx);
	assert(node);
	assert(node->type == FE_NODE_VAR);
	assert(node->nchilds > 0);

	int align = FE_VAR_AST_NODE_GET_ALIGN(node);

	for (int i = 0; i < node->nchilds; i++) {
		ParserASTNode *node_var_item = node->childs[i];
		assert(node_var_item->type == FE_NODE_VAR_ITEM);
		assert(node_var_item->nchilds == 2 || node_var_item->nchilds == 3);

		ParserASTNode *node_identifier = node_var_item->childs[0];
		assert(node_identifier->type == FE_NODE_IDENTIFIER);
		ParserASTNode *node_type = node_var_item->childs[1];
		ParserASTNode *node_expr = NULL;

		if (node_var_item->nchilds == 3) {
			node_expr = node_var_item->childs[2];
		}

		switch (FE_VAR_AST_NODE_GET_TYPE(node)) {
			case FE_VAR_TYPE_GLOBAL: {
				ResizableString rstr_id;
				rstr_init(&rstr_id);
				_ir_identifier_name(ctx, &rstr_id, node_identifier);

				ResizableString rstr;
				rstr_init(&rstr);

				if (align > 0) {
					rstr_appendf(&rstr, "align(%d) ", align);
				}

				rstr_append_with_cstr(&rstr, "var ");
				rstr_append_with_cstr(&rstr, RSTR_CSTR(&rstr_id));
				rstr_append_with_char(&rstr, ':');

				ResizableString rstr_type;
				rstr_init(&rstr_type);
				_ir_type(ctx, &rstr_type, node_type);
				rstr_append_with_cstr(&rstr, RSTR_CSTR(&rstr_type));
				rstr_free(&rstr_type);

				if (node_expr != NULL) {
					rstr_append_with_cstr(&rstr, " = ");
					_ir_constexpr_initializer(ctx, &rstr, node_expr);
				}

				rstr_append_with_cstr(&rstr, ";\n");

				rstr_append_with_cstr(ctx->body, RSTR_CSTR(&rstr));

				rstr_free(&rstr);

				// 更新全局变量符号在代码生成时的名字。
				ParserSymbol *symbol = FE_VAR_ITEM_AST_NODE_GET_SYMBOL(node_var_item);
				FE_VAR_SYMBOL_SET_HAS_CODE_GEN_NAME(symbol, true);
				rstr_init(FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol));
				rstr_append_with_raw(
					FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol),
					RSTR_CSTR(&rstr_id),
					RSTR_LEN(&rstr_id)
				);
				
				rstr_free(&rstr_id);
				break;
			}
			case FE_VAR_TYPE_LOCAL: {
				ResizableString rstr_id;
				rstr_init(&rstr_id);
				_ir_identifier_name(ctx, &rstr_id, node_identifier);
				size_t no = FE_FUNC_SYMBOL_NEXT_NO(ctx->func_symbol);
				rstr_appendf(&rstr_id, ".%zu__", no);

				ResizableString rstr;
				rstr_init(&rstr);

				if (align > 0) {
					rstr_appendf(&rstr, "align(%d) ", align);
				}

				rstr_append_with_cstr(&rstr, "var ");
				rstr_append_with_cstr(&rstr, RSTR_CSTR(&rstr_id));
				rstr_append_with_char(&rstr, ':');

				ResizableString rstr_type;
				rstr_init(&rstr_type);
				_ir_type(ctx, &rstr_type, node_type);
				rstr_append_with_cstr(&rstr, RSTR_CSTR(&rstr_type));
				rstr_free(&rstr_type);

				rstr_append_with_cstr(&rstr, ";\n");

				rstr_append_with_cstr(ctx->body, RSTR_CSTR(&rstr));

				rstr_free(&rstr);

				if (node_expr != NULL) {
					ResizableString rstr_expr;
					rstr_init(&rstr_expr);

					_ExprResult result;
					_expr_result_init(&result);

					_ExprResult casted_result;
					_expr_result_init(&casted_result);

					_ir_expr_wrapper_val(ctx, &rstr_expr, &result, node_expr);
					_expr_result_cast(
						ctx,
						&casted_result,
						node_type,
						&result,
						FE_EXPR_AST_NODE_GET_TYPE_NODE(node_expr)
					);
					rstr_append_with_rstr(&rstr_expr, &(casted_result.rstr_for_result_ptr));
					rstr_append_with_rstr(&rstr_expr, &(casted_result.rstr_for_result));

					rstr_appendf(
						&rstr_expr,
						"assign %s, %s;\n",
						RSTR_CSTR(&rstr_id),
						RSTR_CSTR(&(casted_result.rstr_result))
					);

					rstr_append_with_rstr(ctx->body, &rstr_expr);

					rstr_init(&rstr_expr);
					_expr_result_free(&result);
					_expr_result_free(&casted_result);
				}

				// 更新全局变量符号在代码生成时的名字。
				ParserSymbol *symbol = FE_VAR_ITEM_AST_NODE_GET_SYMBOL(node_var_item);
				FE_VAR_SYMBOL_SET_HAS_CODE_GEN_NAME(symbol, true);
				rstr_init(FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol));
				rstr_append_with_raw(
					FE_VAR_SYMBOL_GET_CODE_GEN_NAME(symbol),
					RSTR_CSTR(&rstr_id),
					RSTR_LEN(&rstr_id)
				);
				
				rstr_free(&rstr_id);
				break;
			}
			case FE_VAR_TYPE_STRUCT_MEMBER: {
				assert(node_expr == NULL);
				
				ResizableString rstr_id;
				rstr_init(&rstr_id);
				_ir_identifier_name(ctx, &rstr_id, node_identifier);

				ResizableString rstr;
				rstr_init(&rstr);

				rstr_append_with_cstr(&rstr, "var ");
				rstr_append_with_cstr(&rstr, RSTR_CSTR(&rstr_id));
				rstr_append_with_char(&rstr, ':');

				ResizableString rstr_type;
				rstr_init(&rstr_type);
				_ir_type(ctx, &rstr_type, node_type);
				rstr_append_with_cstr(&rstr, RSTR_CSTR(&rstr_type));
				rstr_free(&rstr_type);

				rstr_append_with_cstr(&rstr, ";\n");

				rstr_append_with_cstr(ctx->body, RSTR_CSTR(&rstr));

				rstr_free(&rstr);
				rstr_free(&rstr_id);
				break;
			}
			default: {
				assert(0);
			}
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x210, %rsp            # imm = 0x210
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0xfb5c
jmp 0xfb7b
leaq 0x6c9f3(%rip), %rdi     # 0x7c556
leaq 0x6482a(%rip), %rsi     # 0x74394
movl $0xe86, %edx            # imm = 0xE86
leaq 0x64a0b(%rip), %rcx     # 0x74581
callq 0x30a0
cmpq $0x0, -0x10(%rbp)
je 0xfb84
jmp 0xfba3
leaq 0x66448(%rip), %rdi     # 0x75fd3
leaq 0x64802(%rip), %rsi     # 0x74394
movl $0xe87, %edx            # imm = 0xE87
leaq 0x649e3(%rip), %rcx     # 0x74581
callq 0x30a0
movq -0x10(%rbp), %rax
cmpl $0xc00, (%rax)          # imm = 0xC00
jne 0xfbb1
jmp 0xfbd0
leaq 0x6ec1e(%rip), %rdi     # 0x7e7d6
leaq 0x647d5(%rip), %rsi     # 0x74394
movl $0xe88, %edx            # imm = 0xE88
leaq 0x649b6(%rip), %rcx     # 0x74581
callq 0x30a0
movq -0x10(%rbp), %rax
cmpl $0x0, 0x44(%rax)
jle 0xfbdc
jmp 0xfbfb
leaq 0x649d2(%rip), %rdi     # 0x745b5
leaq 0x647aa(%rip), %rsi     # 0x74394
movl $0xe89, %edx            # imm = 0xE89
leaq 0x6498b(%rip), %rcx     # 0x74581
callq 0x30a0
movq -0x10(%rbp), %rax
movl 0x70(%rax), %eax
movl %eax, -0x14(%rbp)
movl $0x0, -0x18(%rbp)
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x44(%rcx), %eax
jge 0x10456
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movslq -0x18(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpl $0xc01, (%rax)          # imm = 0xC01
jne 0xfc3e
jmp 0xfc5d
leaq 0x64982(%rip), %rdi     # 0x745c7
leaq 0x64748(%rip), %rsi     # 0x74394
movl $0xe8f, %edx            # imm = 0xE8F
leaq 0x64929(%rip), %rcx     # 0x74581
callq 0x30a0
movq -0x20(%rbp), %rax
cmpl $0x2, 0x44(%rax)
je 0xfc71
movq -0x20(%rbp), %rax
cmpl $0x3, 0x44(%rax)
jne 0xfc73
jmp 0xfc92
leaq 0x64975(%rip), %rdi     # 0x745ef
leaq 0x64713(%rip), %rsi     # 0x74394
movl $0xe90, %edx            # imm = 0xE90
leaq 0x648f4(%rip), %rcx     # 0x74581
callq 0x30a0
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpl $0x200, (%rax)          # imm = 0x200
jne 0xfcaf
jmp 0xfcce
leaq 0x64974(%rip), %rdi     # 0x7462a
leaq 0x646d7(%rip), %rsi     # 0x74394
movl $0xe93, %edx            # imm = 0xE93
leaq 0x648b8(%rip), %rcx     # 0x74581
callq 0x30a0
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x3, 0x44(%rax)
jne 0xfd00
movq -0x20(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movzbl 0x60(%rax), %eax
movl %eax, -0x174(%rbp)
subl $0x1, %eax
je 0xfd3a
jmp 0xfd15
movl -0x174(%rbp), %eax
subl $0x2, %eax
je 0xff20
jmp 0xfd26
movl -0x174(%rbp), %eax
subl $0x3, %eax
je 0x10296
jmp 0x10427
leaq -0x48(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rdx
leaq -0x48(%rbp), %rsi
callq 0x10be0
leaq -0x58(%rbp), %rdi
callq 0x8c90
cmpl $0x0, -0x14(%rbp)
jle 0xfd78
movl -0x14(%rbp), %edx
leaq -0x58(%rbp), %rdi
leaq 0x648e5(%rip), %rsi     # 0x74656
movb $0x0, %al
callq 0x94d0
leaq -0x58(%rbp), %rdi
leaq 0x648de(%rip), %rsi     # 0x74661
callq 0x8d70
cmpq $0x0, -0x40(%rbp)
jne 0xfd9f
leaq 0x67b1f(%rip), %rax     # 0x778b5
movq %rax, -0x180(%rbp)
jmp 0xfdaa
movq -0x40(%rbp), %rax
movq %rax, -0x180(%rbp)
movq -0x180(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x8d70
leaq -0x58(%rbp), %rdi
movl $0x3a, %esi
callq 0x8ea0
leaq -0x68(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rdx
leaq -0x68(%rbp), %rsi
callq 0x10ca0
cmpq $0x0, -0x60(%rbp)
jne 0xfdf9
leaq 0x67ac5(%rip), %rax     # 0x778b5
movq %rax, -0x188(%rbp)
jmp 0xfe04
movq -0x60(%rbp), %rax
movq %rax, -0x188(%rbp)
movq -0x188(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x8d70
leaq -0x68(%rbp), %rdi
callq 0x9310
cmpq $0x0, -0x38(%rbp)
je 0xfe45
leaq -0x58(%rbp), %rdi
leaq 0x68d55(%rip), %rsi     # 0x78b84
callq 0x8d70
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rdx
leaq -0x58(%rbp), %rsi
callq 0x112e0
leaq -0x58(%rbp), %rdi
leaq 0x66d0e(%rip), %rsi     # 0x76b5e
callq 0x8d70
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x190(%rbp)
cmpq $0x0, -0x50(%rbp)
jne 0xfe7b
leaq 0x67a43(%rip), %rax     # 0x778b5
movq %rax, -0x198(%rbp)
jmp 0xfe86
movq -0x50(%rbp), %rax
movq %rax, -0x198(%rbp)
movq -0x190(%rbp), %rdi
movq -0x198(%rbp), %rsi
callq 0x8d70
leaq -0x58(%rbp), %rdi
callq 0x9310
movq -0x20(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movb $0x1, 0x48(%rax)
movq -0x70(%rbp), %rdi
addq $0x30, %rdi
addq $0x20, %rdi
callq 0x8c90
movq -0x70(%rbp), %rax
addq $0x30, %rax
addq $0x20, %rax
movq %rax, -0x1a0(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0xfef1
leaq 0x679cd(%rip), %rax     # 0x778b5
movq %rax, -0x1a8(%rbp)
jmp 0xfefc
movq -0x40(%rbp), %rax
movq %rax, -0x1a8(%rbp)
movq -0x1a0(%rbp), %rdi
movq -0x1a8(%rbp), %rsi
movl -0x44(%rbp), %edx
callq 0x8f90
leaq -0x48(%rbp), %rdi
callq 0x9310
jmp 0x10446
leaq -0x80(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rdx
leaq -0x80(%rbp), %rsi
callq 0x10be0
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rcx
movl 0x54(%rcx), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, 0x54(%rcx)
movl %eax, %eax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rdx
leaq -0x80(%rbp), %rdi
leaq 0x65007(%rip), %rsi     # 0x74f6f
movb $0x0, %al
callq 0x94d0
leaq -0x98(%rbp), %rdi
callq 0x8c90
cmpl $0x0, -0x14(%rbp)
jle 0xff99
movl -0x14(%rbp), %edx
leaq -0x98(%rbp), %rdi
leaq 0x646c4(%rip), %rsi     # 0x74656
movb $0x0, %al
callq 0x94d0
leaq -0x98(%rbp), %rdi
leaq 0x646ba(%rip), %rsi     # 0x74661
callq 0x8d70
cmpq $0x0, -0x78(%rbp)
jne 0xffc3
leaq 0x678fb(%rip), %rax     # 0x778b5
movq %rax, -0x1b0(%rbp)
jmp 0xffce
movq -0x78(%rbp), %rax
movq %rax, -0x1b0(%rbp)
movq -0x1b0(%rbp), %rsi
leaq -0x98(%rbp), %rdi
callq 0x8d70
leaq -0x98(%rbp), %rdi
movl $0x3a, %esi
callq 0x8ea0
leaq -0xa8(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rdx
leaq -0xa8(%rbp), %rsi
callq 0x10ca0
cmpq $0x0, -0xa0(%rbp)
jne 0x1002c
leaq 0x67892(%rip), %rax     # 0x778b5
movq %rax, -0x1b8(%rbp)
jmp 0x1003a
movq -0xa0(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x1b8(%rbp), %rsi
leaq -0x98(%rbp), %rdi
callq 0x8d70
leaq -0xa8(%rbp), %rdi
callq 0x9310
leaq -0x98(%rbp), %rdi
leaq 0x66af7(%rip), %rsi     # 0x76b5e
callq 0x8d70
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x1c0(%rbp)
cmpq $0x0, -0x90(%rbp)
jne 0x10095
leaq 0x67829(%rip), %rax     # 0x778b5
movq %rax, -0x1c8(%rbp)
jmp 0x100a3
movq -0x90(%rbp), %rax
movq %rax, -0x1c8(%rbp)
movq -0x1c0(%rbp), %rdi
movq -0x1c8(%rbp), %rsi
callq 0x8d70
leaq -0x98(%rbp), %rdi
callq 0x9310
cmpq $0x0, -0x38(%rbp)
je 0x1020c
leaq -0xb8(%rbp), %rdi
callq 0x8c90
leaq -0xf8(%rbp), %rdi
callq 0x113b0
leaq -0x138(%rbp), %rdi
callq 0x113b0
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rcx
leaq -0xb8(%rbp), %rsi
leaq -0xf8(%rbp), %rdx
callq 0x11420
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rax
movq 0x68(%rax), %r8
leaq -0x138(%rbp), %rsi
leaq -0xf8(%rbp), %rcx
callq 0x11460
leaq -0x138(%rbp), %rsi
addq $0x10, %rsi
leaq -0xb8(%rbp), %rdi
callq 0x9100
leaq -0x138(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0x9100
cmpq $0x0, -0x78(%rbp)
jne 0x10170
leaq 0x6774e(%rip), %rax     # 0x778b5
movq %rax, -0x1d0(%rbp)
jmp 0x1017b
movq -0x78(%rbp), %rax
movq %rax, -0x1d0(%rbp)
movq -0x1d0(%rbp), %rax
movq %rax, -0x1d8(%rbp)
cmpq $0x0, -0x110(%rbp)
jne 0x101a3
leaq 0x6771b(%rip), %rax     # 0x778b5
movq %rax, -0x1e0(%rbp)
jmp 0x101b1
movq -0x110(%rbp), %rax
movq %rax, -0x1e0(%rbp)
movq -0x1d8(%rbp), %rdx
movq -0x1e0(%rbp), %rcx
leaq -0xb8(%rbp), %rdi
leaq 0x64499(%rip), %rsi     # 0x74666
movb $0x0, %al
callq 0x94d0
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x9100
leaq -0xb8(%rbp), %rdi
callq 0x8c90
leaq -0xf8(%rbp), %rdi
callq 0x130a0
leaq -0x138(%rbp), %rdi
callq 0x130a0
movq -0x20(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x140(%rbp)
movq -0x140(%rbp), %rax
movb $0x1, 0x48(%rax)
movq -0x140(%rbp), %rdi
addq $0x30, %rdi
addq $0x20, %rdi
callq 0x8c90
movq -0x140(%rbp), %rax
addq $0x30, %rax
addq $0x20, %rax
movq %rax, -0x1e8(%rbp)
cmpq $0x0, -0x78(%rbp)
jne 0x10267
leaq 0x67657(%rip), %rax     # 0x778b5
movq %rax, -0x1f0(%rbp)
jmp 0x10272
movq -0x78(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x1e8(%rbp), %rdi
movq -0x1f0(%rbp), %rsi
movl -0x7c(%rbp), %edx
callq 0x8f90
leaq -0x80(%rbp), %rdi
callq 0x9310
jmp 0x10446
cmpq $0x0, -0x38(%rbp)
jne 0x1029f
jmp 0x102be
leaq 0x643d0(%rip), %rdi     # 0x74676
leaq 0x640e7(%rip), %rsi     # 0x74394
movl $0xf19, %edx            # imm = 0xF19
leaq 0x642c8(%rip), %rcx     # 0x74581
callq 0x30a0
leaq -0x150(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rdx
leaq -0x150(%rbp), %rsi
callq 0x10be0
leaq -0x160(%rbp), %rdi
callq 0x8c90
leaq -0x160(%rbp), %rdi
leaq 0x64369(%rip), %rsi     # 0x74661
callq 0x8d70
cmpq $0x0, -0x148(%rbp)
jne 0x10317
leaq 0x675a7(%rip), %rax     # 0x778b5
movq %rax, -0x1f8(%rbp)
jmp 0x10325
movq -0x148(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movq -0x1f8(%rbp), %rsi
leaq -0x160(%rbp), %rdi
callq 0x8d70
leaq -0x160(%rbp), %rdi
movl $0x3a, %esi
callq 0x8ea0
leaq -0x170(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rdx
leaq -0x170(%rbp), %rsi
callq 0x10ca0
cmpq $0x0, -0x168(%rbp)
jne 0x10383
leaq 0x6753b(%rip), %rax     # 0x778b5
movq %rax, -0x200(%rbp)
jmp 0x10391
movq -0x168(%rbp), %rax
movq %rax, -0x200(%rbp)
movq -0x200(%rbp), %rsi
leaq -0x160(%rbp), %rdi
callq 0x8d70
leaq -0x170(%rbp), %rdi
callq 0x9310
leaq -0x160(%rbp), %rdi
leaq 0x667a0(%rip), %rsi     # 0x76b5e
callq 0x8d70
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x208(%rbp)
cmpq $0x0, -0x158(%rbp)
jne 0x103ec
leaq 0x674d2(%rip), %rax     # 0x778b5
movq %rax, -0x210(%rbp)
jmp 0x103fa
movq -0x158(%rbp), %rax
movq %rax, -0x210(%rbp)
movq -0x208(%rbp), %rdi
movq -0x210(%rbp), %rsi
callq 0x8d70
leaq -0x160(%rbp), %rdi
callq 0x9310
leaq -0x150(%rbp), %rdi
callq 0x9310
jmp 0x10446
leaq 0x6202d(%rip), %rdi     # 0x7245b
leaq 0x63f5f(%rip), %rsi     # 0x74394
movl $0xf35, %edx            # imm = 0xF35
leaq 0x64140(%rip), %rcx     # 0x74581
callq 0x30a0
jmp 0x10448
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0xfc0c
addq $0x210, %rsp            # imm = 0x210
popq %rbp
retq
nop