// File: /workspace/github_c_makefile_star2_O3/Yamsman[P]scc/src/parse.c
// Function: parse_sdef
s_type *parse_sdef(lexer *lx) {
	s_type *type = type_new(TYPE_UNDEF);
	switch (lex_peek(lx).type) {
		case TOK_KW_STRUCT:
			type->kind = TYPE_STRUCT;
			break;
		case TOK_KW_UNION:
			type->kind = TYPE_UNION;
			break;
		default:
			type_del(type);
			return NULL;
	}
	lex_adv(lx);

	//Get identifier and member list
	char *tname = NULL;
	s_pos nloc, aloc;
	if (lex_peek(lx).type == TOK_IDENT) {
		tname = lex_peek(lx).dat.sval;
		nloc = lex_peek(lx).loc;
		lex_adv(lx);
	}
	aloc = lex_peek(lx).loc;
	if (lex_peek(lx).type == TOK_LBR)
		type->param = parse_sdef_body(lx);

	/* 
	 * Four cases:
	 * struct is anonymous (list but no name)
	 * struct is already defined (name but no list)
	 * struct needs to be defined (name and list)
	 * invalid (no name and no list)
	 */
	if (tname == NULL) {
		if (type->param.len == VECTOR_EMPTY) {
			c_error(&aloc, "Expected '{' or identifier before ...\n");
			type_del(type);
			return NULL;
		} 
	} else {
		symbol *s = NULL;
		if (type->param.len == VECTOR_EMPTY) {
			//Search the symbol table for an existing definition
			s = symtable_search(lx->stb, tname);
			type_del(type);
			if (s == NULL) {
				c_error(&nloc, "Undefined struct '%s'\n", tname);
				free(tname);
				return NULL;
			}
			free(tname);
			type = type_clone(s->type);
		} else {
			s = symtable_def(lx->stb, tname, type_clone(type), &nloc);
		}
	}

	return type;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq %rdi, %r14
xorl %edi, %edi
callq 0xbf35
movq %rax, %rbx
leaq 0x128(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x79dc
movl (%r15), %eax
cmpl $0x49, %eax
je 0x8ada
cmpl $0x4a, %eax
jne 0x8bdb
movl $0x9, %eax
jmp 0x8adf
movl $0x8, %eax
movl %eax, (%rbx)
movq %r14, %rdi
callq 0x7a19
leaq 0xf8(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x79dc
cmpl $0x35, (%r15)
jne 0x8b4a
leaq 0xc8(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x79dc
movq 0x20(%r15), %r15
leaq 0x98(%rsp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x79dc
movq 0x18(%r12), %rax
movq %rax, 0x10(%rsp)
movups 0x8(%r12), %xmm0
movaps %xmm0, (%rsp)
movq %r14, %rdi
callq 0x7a19
jmp 0x8b4d
xorl %r15d, %r15d
leaq 0x68(%rsp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x79dc
movq 0x18(%r12), %rax
movq %rax, 0x30(%rsp)
movups 0x8(%r12), %xmm0
movaps %xmm0, 0x20(%rsp)
leaq 0x38(%rsp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x79dc
cmpl $0x5, (%r12)
jne 0x8b99
movq %r14, %rdi
callq 0x9561
movq %rax, 0x28(%rbx)
movq %rdx, 0x30(%rbx)
movl 0x30(%rbx), %eax
testq %r15, %r15
je 0x8bc4
movq 0x60(%r14), %r14
testl %eax, %eax
je 0x8bf7
movq %rbx, %rdi
callq 0xc2cb
movq %rsp, %rcx
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0xbe8d
jmp 0x8be5
testl %eax, %eax
jne 0x8be5
leaq 0x5de9(%rip), %rsi      # 0xe9b8
leaq 0x20(%rsp), %rdi
xorl %eax, %eax
callq 0x3250
movq %rbx, %rdi
callq 0xc233
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq %r14, %rdi
movq %r15, %rsi
callq 0xc187
movq %rax, %r14
movq %rbx, %rdi
callq 0xc233
testq %r14, %r14
je 0x8c28
movq %r15, %rdi
callq 0x3030
movq 0x8(%r14), %rdi
callq 0xc2cb
movq %rax, %rbx
jmp 0x8be5
leaq 0x5db0(%rip), %rsi      # 0xe9df
xorl %ebx, %ebx
movq %rsp, %rdi
movq %r15, %rdx
xorl %eax, %eax
callq 0x3250
movq %r15, %rdi
callq 0x3030
jmp 0x8be5