// File: /workspace/github_c_makefile_star2_O1/Ihsoh[P]ilang/compiler/backend/semantics.c
// Function: _type
static void __type(
	ParserContext *ctx,
	ParserASTNode *node,
	uint8_t *type,
	bool first_type
) {
	assert(ctx);
	assert(node);
	
	#define _SET_TYPE(t) { if (type != NULL) { *type = (t); } }

	switch (node->type) {
		case BE_NODE_TYPE_CHAR: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_CHAR)
			break;
		}
		case BE_NODE_TYPE_INT8: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_INT8)
			break;
		}
		case BE_NODE_TYPE_UINT8: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_UINT8)
			break;
		}
		case BE_NODE_TYPE_INT16: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_INT16)
			break;
		}
		case BE_NODE_TYPE_UINT16: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_UINT16)
			break;
		}
		case BE_NODE_TYPE_INT32: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_INT32)
			break;
		}
		case BE_NODE_TYPE_UINT32: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_UINT32)
			break;
		}
		case BE_NODE_TYPE_INT64: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_INT64)
			break;
		}
		case BE_NODE_TYPE_UINT64: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_UINT64)
			break;
		}
		case BE_NODE_TYPE_FLOAT: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_FLOAT)
			break;
		}
		case BE_NODE_TYPE_DOUBLE: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_DOUBLE)
			break;
		}
		case BE_NODE_TYPE_VA_LIST: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_VA_LIST)
			break;
		}
		case BE_NODE_TYPE_STRUCT: {
			assert(node->nchilds == 1);

			_SET_TYPE(BE_TYPE_STRUCT)

			ParserASTNode *node_id = node->childs[0];
			assert(node_id->type == BE_NODE_IDENTIFIER);

			LexerToken *token = node_id->token;
			ParserSymbol *symbol_struct = parser_get_symbol_from_node(ctx, node, BE_SYM_STRUCT, token);
			if (symbol_struct == NULL) {
				_SYNERR_TOKEN(ctx, token, "undefined struct.");
			} else {
				if (first_type
						&& BE_STRUCT_SYMBOL_GET_DUMMY(symbol_struct)) {
					_SYNERR_TOKEN(ctx, token, "struct not implemented.");
				}
			}

			break;
		}
		case BE_NODE_TYPE_ARRAY: {
			assert(node->nchilds == 2);

			_SET_TYPE(BE_TYPE_ARRAY)

			ParserASTNode *node_array_dims = node->childs[0];
			assert(node_array_dims->type == BE_NODE_TYPE_ARRAY_DIMS);
			for (int i = 0; i < node_array_dims->nchilds; i++) {
				ParserASTNode *node_array_dim = node_array_dims->childs[i];
				assert(node_array_dim->type == BE_NODE_LITERAL_UINT);

				uint64_t dim = be_parser_get_uint_val(ctx, node_array_dim);
				if (dim == 0) {
					_SYNERR_NODE(
						ctx,
						node_array_dim,
						"array dimension size cannot be 0."
					);
				}
			}
			
			ParserASTNode *node_type = node->childs[1];
			__type(ctx, node_type, NULL, false);

			break;
		}
		case BE_NODE_TYPE_FUNC: {
			assert(node->nchilds == 1 || node->nchilds == 2);

			_SET_TYPE(BE_TYPE_FUNC)

			ParserASTNode *node_params = NULL;
			ParserASTNode *node_type = NULL;

			node_params = node->childs[0];
			for (int i = 0; i < node_params->nchilds; i++) {
				ParserASTNode *node_param = node_params->childs[i];
				switch (node_param->type) {
					case BE_NODE_FUNC_PARAMS_ELLIPSIS_ITEM: {

						break;
					}
					case BE_NODE_FUNC_PARAMS_ITEM: {
						assert(node_param->nchilds == 2);
						
						ParserASTNode *node_param_id = node_param->childs[0];

						ParserASTNode *node_param_type = node_param->childs[1];
						__type(ctx, node_param_type, NULL, false);

						break;
					}
					default: {
						assert(0);
					}
				}
			}
			
			if (node->nchilds == 2) {
				node_type = node->childs[1];
				__type(ctx, node_type, NULL, false);
			}

			break;
		}
		case BE_NODE_TYPE_POINTER: {
			assert(node->nchilds == 1);

			_SET_TYPE(BE_TYPE_POINTER)

			ParserASTNode *node_type = node->childs[0];
			__type(ctx, node_type, NULL, false);

			break;
		}
		case BE_NODE_TYPE_VOID: {
			assert(node->nchilds == 0);
			_SET_TYPE(BE_TYPE_VOID)
			break;
		}
		default: {
			assert(0);
		}
	}

	#undef	_SET_TYPE
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x408, %rsp            # imm = 0x408
movl %ecx, %r15d
movq %rsi, %r14
movq %rdi, %rbx
testq %r14, %r14
je 0x2eade
movl (%r14), %eax
cmpl $0x43f, %eax            # imm = 0x43F
jg 0x2e793
cmpl $0x430, %eax            # imm = 0x430
jne 0x2e7be
movl 0x44(%r14), %eax
decl %eax
cmpl $0x2, %eax
jae 0x2eafd
testq %rdx, %rdx
je 0x2e725
movb $0xf, (%rdx)
movq 0x48(%r14), %rax
movq (%rax), %r15
cmpl $0x0, 0x44(%r15)
jle 0x2e77e
xorl %r12d, %r12d
movq 0x48(%r15), %rax
movq (%rax,%r12,8), %rax
movl (%rax), %ecx
cmpl $0xa03, %ecx            # imm = 0xA03
je 0x2e772
cmpl $0xa02, %ecx            # imm = 0xA02
jne 0x2eabf
cmpl $0x2, 0x44(%rax)
jne 0x2eaa0
movq 0x48(%rax), %rax
movq 0x8(%rax), %rsi
movq %rbx, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x2e6cf
incq %r12
movslq 0x44(%r15), %rax
cmpq %rax, %r12
jl 0x2e736
cmpl $0x2, 0x44(%r14)
jne 0x2ea6a
movq 0x48(%r14), %rax
movq 0x8(%rax), %r14
jmp 0x2e7b4
cmpl $0x440, %eax            # imm = 0x440
jne 0x2e7f8
cmpl $0x1, 0x44(%r14)
jne 0x2eb1c
testq %rdx, %rdx
je 0x2e7ad
movb $0x10, (%rdx)
movq 0x48(%r14), %rax
movq (%rax), %r14
xorl %edx, %edx
xorl %r15d, %r15d
jmp 0x2e6ec
addl $0xfffffc00, %eax       # imm = 0xFFFFFC00
cmpl $0x20, %eax
ja 0x2eb3b
leaq 0x1f001(%rip), %rcx     # 0x4d7d4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x0, 0x44(%r14)
jne 0x2eb79
testq %rdx, %rdx
je 0x2ea6a
movb $0x1, (%rdx)
jmp 0x2ea6a
cmpl $0x4ff, %eax            # imm = 0x4FF
jne 0x2eb3b
cmpl $0x0, 0x44(%r14)
jne 0x2ed2b
testq %rdx, %rdx
je 0x2ea6a
movb $-0x1, (%rdx)
jmp 0x2ea6a
cmpl $0x0, 0x44(%r14)
jne 0x2eb98
testq %rdx, %rdx
je 0x2ea6a
movb $0xc, (%rdx)
jmp 0x2ea6a
cmpl $0x0, 0x44(%r14)
jne 0x2ebb7
testq %rdx, %rdx
je 0x2ea6a
movb $0x9, (%rdx)
jmp 0x2ea6a
cmpl $0x1, 0x44(%r14)
jne 0x2ebd6
testq %rdx, %rdx
je 0x2e86a
movb $0xd, (%rdx)
movq 0x48(%r14), %rax
movq (%rax), %rax
cmpl $0x200, (%rax)          # imm = 0x200
jne 0x2ed4a
movq 0x10(%rax), %r12
movq %rbx, %rdi
movq %r14, %rsi
movl $0x2, %edx
movq %r12, %rcx
callq 0x6d79
testq %rax, %rax
je 0x2ea7c
testb $0x1, %r15b
je 0x2ea6a
cmpb $0x1, 0x40(%rax)
jne 0x2ea6a
movq 0x50(%rbx), %rax
leaq 0x1fc9b(%rip), %rdx     # 0x4e557
jmp 0x2ea87
cmpl $0x0, 0x44(%r14)
jne 0x2ebf5
testq %rdx, %rdx
je 0x2ea6a
movb $0x4, (%rdx)
jmp 0x2ea6a
cmpl $0x0, 0x44(%r14)
jne 0x2ec14
testq %rdx, %rdx
je 0x2ea6a
movb $0x2, (%rdx)
jmp 0x2ea6a
cmpl $0x0, 0x44(%r14)
jne 0x2ec33
testq %rdx, %rdx
je 0x2ea6a
movb $0xa, (%rdx)
jmp 0x2ea6a
cmpl $0x0, 0x44(%r14)
jne 0x2ec52
testq %rdx, %rdx
je 0x2ea6a
movb $0x8, (%rdx)
jmp 0x2ea6a
cmpl $0x0, 0x44(%r14)
jne 0x2ec71
testq %rdx, %rdx
je 0x2ea6a
movb $0x3, (%rdx)
jmp 0x2ea6a
cmpl $0x0, 0x44(%r14)
jne 0x2ec90
testq %rdx, %rdx
je 0x2ea6a
movb $0x5, (%rdx)
jmp 0x2ea6a
cmpl $0x0, 0x44(%r14)
jne 0x2ecaf
testq %rdx, %rdx
je 0x2ea6a
movb $0x6, (%rdx)
jmp 0x2ea6a
cmpl $0x0, 0x44(%r14)
jne 0x2ecce
testq %rdx, %rdx
je 0x2ea6a
movb $0x7, (%rdx)
jmp 0x2ea6a
cmpl $0x0, 0x44(%r14)
jne 0x2eced
testq %rdx, %rdx
je 0x2ea6a
movb $0xb, (%rdx)
jmp 0x2ea6a
cmpl $0x2, 0x44(%r14)
jne 0x2ed0c
testq %rdx, %rdx
je 0x2e9d0
movb $0xe, (%rdx)
movq 0x48(%r14), %rax
movq (%rax), %r13
cmpl $0x421, (%r13)          # imm = 0x421
jne 0x2ed69
cmpl $0x0, 0x44(%r13)
jle 0x2ea56
xorl %r15d, %r15d
movq 0x48(%r13), %rax
movq (%rax,%r15,8), %r12
cmpl $0x300, (%r12)          # imm = 0x300
jne 0x2eb5a
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2312b
testq %rax, %rax
jne 0x2ea4a
movups 0x1fbc1(%rip), %xmm0    # 0x4e5dd
movaps %xmm0, -0x420(%rbp)
movups 0x1fba3(%rip), %xmm0    # 0x4e5cd
movaps %xmm0, -0x430(%rbp)
movw $0x2e, -0x410(%rbp)
movq %rbx, %rdi
movq %r12, %rsi
leaq -0x430(%rbp), %rdx
callq *0x58(%rbx)
incq %r15
movslq 0x44(%r13), %rax
cmpq %rax, %r15
jl 0x2e9ef
movq 0x48(%r14), %rax
movq 0x8(%rax), %rsi
movq %rbx, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x2e6cf
addq $0x408, %rsp            # imm = 0x408
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x50(%rbx), %rax
leaq 0x1fabe(%rip), %rdx     # 0x4e545
movq %rbx, %rdi
movq %r12, %rsi
addq $0x408, %rsp            # imm = 0x408
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmpq *%rax
leaq 0x1fb71(%rip), %rdi     # 0x4e618
leaq 0x1f6c2(%rip), %rsi     # 0x4e170
leaq 0x1fa3d(%rip), %rcx     # 0x4e4f2
movl $0x3ce, %edx            # imm = 0x3CE
callq 0x30a0
leaq 0x118c7(%rip), %rdi     # 0x4038d
leaq 0x1f6a3(%rip), %rsi     # 0x4e170
leaq 0x1fa1e(%rip), %rcx     # 0x4e4f2
movl $0x3d8, %edx            # imm = 0x3D8
callq 0x30a0
leaq 0x14466(%rip), %rdi     # 0x42f4b
leaq 0x1f684(%rip), %rsi     # 0x4e170
leaq 0x1f9ff(%rip), %rcx     # 0x4e4f2
movl $0x34d, %edx            # imm = 0x34D
callq 0x30a0
leaq 0x1faeb(%rip), %rdi     # 0x4e5ef
leaq 0x1f665(%rip), %rsi     # 0x4e170
leaq 0x1f9e0(%rip), %rcx     # 0x4e4f2
movl $0x3be, %edx            # imm = 0x3BE
callq 0x30a0
leaq 0x150be(%rip), %rdi     # 0x43be1
leaq 0x1f646(%rip), %rsi     # 0x4e170
leaq 0x1f9c1(%rip), %rcx     # 0x4e4f2
movl $0x3e5, %edx            # imm = 0x3E5
callq 0x30a0
leaq 0x1184b(%rip), %rdi     # 0x4038d
leaq 0x1f627(%rip), %rsi     # 0x4e170
leaq 0x1f9a2(%rip), %rcx     # 0x4e4f2
movl $0x3f4, %edx            # imm = 0x3F4
callq 0x30a0
leaq 0x1fa3f(%rip), %rdi     # 0x4e5a0
leaq 0x1f608(%rip), %rsi     # 0x4e170
leaq 0x1f983(%rip), %rcx     # 0x4e4f2
movl $0x3ac, %edx            # imm = 0x3AC
callq 0x30a0
leaq 0x1f9b2(%rip), %rdi     # 0x4e532
leaq 0x1f5e9(%rip), %rsi     # 0x4e170
leaq 0x1f964(%rip), %rcx     # 0x4e4f2
movl $0x353, %edx            # imm = 0x353
callq 0x30a0
leaq 0x1f993(%rip), %rdi     # 0x4e532
leaq 0x1f5ca(%rip), %rsi     # 0x4e170
leaq 0x1f945(%rip), %rcx     # 0x4e4f2
movl $0x38a, %edx            # imm = 0x38A
callq 0x30a0
leaq 0x1f974(%rip), %rdi     # 0x4e532
leaq 0x1f5ab(%rip), %rsi     # 0x4e170
leaq 0x1f926(%rip), %rcx     # 0x4e4f2
movl $0x37b, %edx            # imm = 0x37B
callq 0x30a0
leaq 0x15004(%rip), %rdi     # 0x43be1
leaq 0x1f58c(%rip), %rsi     # 0x4e170
leaq 0x1f907(%rip), %rcx     # 0x4e4f2
movl $0x38f, %edx            # imm = 0x38F
callq 0x30a0
leaq 0x1f936(%rip), %rdi     # 0x4e532
leaq 0x1f56d(%rip), %rsi     # 0x4e170
leaq 0x1f8e8(%rip), %rcx     # 0x4e4f2
movl $0x36c, %edx            # imm = 0x36C
callq 0x30a0
leaq 0x1f917(%rip), %rdi     # 0x4e532
leaq 0x1f54e(%rip), %rsi     # 0x4e170
leaq 0x1f8c9(%rip), %rcx     # 0x4e4f2
movl $0x358, %edx            # imm = 0x358
callq 0x30a0
leaq 0x1f8f8(%rip), %rdi     # 0x4e532
leaq 0x1f52f(%rip), %rsi     # 0x4e170
leaq 0x1f8aa(%rip), %rcx     # 0x4e4f2
movl $0x380, %edx            # imm = 0x380
callq 0x30a0
leaq 0x1f8d9(%rip), %rdi     # 0x4e532
leaq 0x1f510(%rip), %rsi     # 0x4e170
leaq 0x1f88b(%rip), %rcx     # 0x4e4f2
movl $0x371, %edx            # imm = 0x371
callq 0x30a0
leaq 0x1f8ba(%rip), %rdi     # 0x4e532
leaq 0x1f4f1(%rip), %rsi     # 0x4e170
leaq 0x1f86c(%rip), %rcx     # 0x4e4f2
movl $0x362, %edx            # imm = 0x362
callq 0x30a0
leaq 0x1f89b(%rip), %rdi     # 0x4e532
leaq 0x1f4d2(%rip), %rsi     # 0x4e170
leaq 0x1f84d(%rip), %rcx     # 0x4e4f2
movl $0x376, %edx            # imm = 0x376
callq 0x30a0
leaq 0x1f87c(%rip), %rdi     # 0x4e532
leaq 0x1f4b3(%rip), %rsi     # 0x4e170
leaq 0x1f82e(%rip), %rcx     # 0x4e4f2
movl $0x35d, %edx            # imm = 0x35D
callq 0x30a0
leaq 0x1f85d(%rip), %rdi     # 0x4e532
leaq 0x1f494(%rip), %rsi     # 0x4e170
leaq 0x1f80f(%rip), %rcx     # 0x4e4f2
movl $0x367, %edx            # imm = 0x367
callq 0x30a0
leaq 0x1f83e(%rip), %rdi     # 0x4e532
leaq 0x1f475(%rip), %rsi     # 0x4e170
leaq 0x1f7f0(%rip), %rcx     # 0x4e4f2
movl $0x385, %edx            # imm = 0x385
callq 0x30a0
leaq 0x1f8f2(%rip), %rdi     # 0x4e605
leaq 0x1f456(%rip), %rsi     # 0x4e170
leaq 0x1f7d1(%rip), %rcx     # 0x4e4f2
movl $0x3a4, %edx            # imm = 0x3A4
callq 0x30a0
leaq 0x1f800(%rip), %rdi     # 0x4e532
leaq 0x1f437(%rip), %rsi     # 0x4e170
leaq 0x1f7b2(%rip), %rcx     # 0x4e4f2
movl $0x3ef, %edx            # imm = 0x3EF
callq 0x30a0
leaq 0x14a83(%rip), %rdi     # 0x437d4
leaq 0x1f418(%rip), %rsi     # 0x4e170
leaq 0x1f793(%rip), %rcx     # 0x4e4f2
movl $0x394, %edx            # imm = 0x394
callq 0x30a0
leaq 0x1f7ff(%rip), %rdi     # 0x4e56f
leaq 0x1f3f9(%rip), %rsi     # 0x4e170
leaq 0x1f774(%rip), %rcx     # 0x4e4f2
movl $0x3a9, %edx            # imm = 0x3A9
callq 0x30a0