// File: /workspace/github_c_makefile_star2_O0/hsjoihs[P]c-compiler/parse_expression.c
// Function: parse_postfix_expression
static struct UntypedExpr
parse_postfix_expression(const struct Token **ptr_tokvec)
{
	const struct Token *tokvec = *ptr_tokvec;

	struct UntypedExpr expr;
	if (tokvec[0].kind == IDENT_OR_RESERVED && tokvec[1].kind == LEFT_PAREN) {
		const char *ident_str = tokvec[0].ident_str;

		tokvec += 2;

		struct Vector /*<UntypedExpr>*/ arguments = parse_arguments(&tokvec);

		if (strncmp("__builtin", ident_str, strlen("__builtin")) == 0) {
			expr.category = BUILTIN_FUNCCALL;
		} else {
			expr.category =
			    FUNCCALL; /* later gets treated as FUNC_PTR_CALL if fp */
		}

		expr.arg_exprs_vec = arguments;
		expr.var_name = ident_str;
	} else {
		expr = parse_primary_expression(&tokvec);
	}

	while (1) {
		if (tokvec[0].kind == LEFT_PAREN) {
			tokvec++;

			/* this consumes the closing paren */
			struct Vector /*<UntypedExpr>*/ arguments =
			    parse_arguments(&tokvec);

			struct UntypedExpr *ptr_expr1 =
			    calloc(1, sizeof(struct UntypedExpr));
			*ptr_expr1 = expr;

			struct UntypedExpr new_expr;
			new_expr.category = FUNC_PTR_CALL;
			new_expr.arg_exprs_vec = arguments;
			new_expr.ptr1 = ptr_expr1;

			expr = new_expr;
		} else if (tokvec[0].kind == LEFT_BRACKET) {
			++tokvec;
			const struct UntypedExpr expr2 = parse_expression(&tokvec);
			expect_and_consume(&tokvec, RIGHT_BRACKET, "right bracket ]");

			const struct UntypedExpr e =
			    binary_op_untyped(&expr, &expr2, OP_PLUS);
			expr = unary_op_untyped(&e, OP_ASTERISK);
		} else if (tokvec[0].kind == OP_PLUS_PLUS ||
		           tokvec[0].kind == OP_MINUS_MINUS) {
			enum TokenKind opkind = tokvec[0].kind;
			tokvec++;

			struct UntypedExpr *ptr_expr1 =
			    calloc(1, sizeof(struct UntypedExpr));
			*ptr_expr1 = expr;

			struct UntypedExpr new_expr;
			new_expr.operator_ = opkind;
			new_expr.category = POSTFIX_EXPR;
			new_expr.ptr1 = ptr_expr1;
			new_expr.ptr2 = 0;
			new_expr.ptr3 = 0;

			expr = new_expr;
		} else if (tokvec[0].kind == DOT) {
			++tokvec;

			expect_and_consume(&tokvec, IDENT_OR_RESERVED,
			                   "identifier after a dot operator");
			const char *name = tokvec[-1].ident_str;

			const struct UntypedExpr f = ampersand_dot(&expr, name);
			expr = unary_op_untyped(&f, OP_ASTERISK);
		} else if (tokvec[0].kind == ARROW) {
			++tokvec;

			expect_and_consume(&tokvec, IDENT_OR_RESERVED,
			                   "identifier after an arrow operator");
			const char *name = tokvec[-1].ident_str;

			const struct UntypedExpr e = unary_op_untyped(&expr, OP_ASTERISK);
			const struct UntypedExpr f = ampersand_dot(&e, name);
			expr = unary_op_untyped(&f, OP_ASTERISK);
		} else {
			break;
		}
	}
	*ptr_tokvec = tokvec;
	return expr;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x750, %rsp            # imm = 0x750
movq %rdi, -0x750(%rbp)
movq %rdi, -0x748(%rbp)
movq %rsi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x18, (%rax)
jne 0xa275
movq -0x10(%rbp), %rax
cmpl $0x6, 0x20(%rax)
jne 0xa275
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
addq $0x40, %rax
movq %rax, -0x10(%rbp)
leaq -0x10(%rbp), %rdi
callq 0xa5f0
movq %rax, -0x28(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x18(%rbp), %rsi
leaq 0xb05f(%rip), %rdi      # 0x15286
movl $0x9, %edx
callq 0x1030
cmpl $0x0, %eax
jne 0xa246
movq -0x750(%rbp), %rax
movl $0xc, 0x4(%rax)
jmp 0xa254
movq -0x750(%rbp), %rax
movl $0x6, 0x4(%rax)
movq -0x750(%rbp), %rax
movq -0x28(%rbp), %rcx
movq %rcx, 0x38(%rax)
movq -0x20(%rbp), %rcx
movq %rcx, 0x40(%rax)
movq -0x18(%rbp), %rcx
movq %rcx, 0x28(%rax)
jmp 0xa29d
leaq -0xc8(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0xa730
movq -0x750(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
movl $0xa0, %edx
callq 0x10e0
jmp 0xa29f
movq -0x10(%rbp), %rax
cmpl $0x6, (%rax)
jne 0xa34e
movq -0x10(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x10(%rbp)
leaq -0x10(%rbp), %rdi
callq 0xa5f0
movq %rax, -0xd8(%rbp)
movq %rdx, -0xd0(%rbp)
movl $0x1, %edi
movl $0xa0, %esi
callq 0x10b0
movq -0x750(%rbp), %rsi
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rdi
movl $0xa0, %edx
callq 0x10e0
movq -0x750(%rbp), %rdi
movl $0x7, -0x17c(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0x148(%rbp)
movq -0xd0(%rbp), %rax
movq %rax, -0x140(%rbp)
movq -0xe0(%rbp), %rax
movq %rax, -0x178(%rbp)
leaq -0x180(%rbp), %rsi
movl $0xa0, %edx
callq 0x10e0
jmp 0xa5c3
movq -0x10(%rbp), %rax
cmpl $0x36, (%rax)
jne 0xa3dd
movq -0x10(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x10(%rbp)
leaq -0x220(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0xa050
leaq -0x10(%rbp), %rdi
movl $0x37, %esi
leaq 0xaf09(%rip), %rdx      # 0x15290
callq 0xb190
movq -0x750(%rbp), %rsi
leaq -0x2c0(%rbp), %rdi
leaq -0x220(%rbp), %rdx
xorl %ecx, %ecx
callq 0x9a70
leaq -0x360(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
movl $0x5, %edx
callq 0xa140
movq -0x750(%rbp), %rdi
leaq -0x360(%rbp), %rsi
movl $0xa0, %edx
callq 0x10e0
jmp 0xa5c1
movq -0x10(%rbp), %rax
cmpl $0x32, (%rax)
je 0xa3f3
movq -0x10(%rbp), %rax
cmpl $0x33, (%rax)
jne 0xa490
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x364(%rbp)
movq -0x10(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x10(%rbp)
movl $0x1, %edi
movl $0xa0, %esi
callq 0x10b0
movq -0x750(%rbp), %rsi
movq %rax, -0x370(%rbp)
movq -0x370(%rbp), %rdi
movl $0xa0, %edx
callq 0x10e0
movq -0x750(%rbp), %rdi
movl -0x364(%rbp), %eax
movl %eax, -0x410(%rbp)
movl $0x5, -0x40c(%rbp)
movq -0x370(%rbp), %rax
movq %rax, -0x408(%rbp)
movq $0x0, -0x400(%rbp)
movq $0x0, -0x3f8(%rbp)
leaq -0x410(%rbp), %rsi
movl $0xa0, %edx
callq 0x10e0
jmp 0xa5bf
movq -0x10(%rbp), %rax
cmpl $0x3c, (%rax)
jne 0xa518
movq -0x10(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x10(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x18, %esi
leaq 0xadeb(%rip), %rdx      # 0x152a0
callq 0xb190
movq -0x750(%rbp), %rsi
movq -0x10(%rbp), %rax
movq -0x18(%rax), %rax
movq %rax, -0x418(%rbp)
movq -0x418(%rbp), %rdx
leaq -0x4b8(%rbp), %rdi
callq 0xa860
leaq -0x558(%rbp), %rdi
leaq -0x4b8(%rbp), %rsi
movl $0x5, %edx
callq 0xa140
movq -0x750(%rbp), %rdi
leaq -0x558(%rbp), %rsi
movl $0xa0, %edx
callq 0x10e0
jmp 0xa5bd
movq -0x10(%rbp), %rax
cmpl $0x3d, (%rax)
jne 0xa5b9
movq -0x10(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x10(%rbp)
leaq -0x10(%rbp), %rdi
movl $0x18, %esi
leaq 0xad7f(%rip), %rdx      # 0x152c0
callq 0xb190
movq -0x750(%rbp), %rsi
movq -0x10(%rbp), %rax
movq -0x18(%rax), %rax
movq %rax, -0x560(%rbp)
leaq -0x600(%rbp), %rdi
movl $0x5, %edx
callq 0xa140
movq -0x560(%rbp), %rdx
leaq -0x6a0(%rbp), %rdi
leaq -0x600(%rbp), %rsi
callq 0xa860
leaq -0x740(%rbp), %rdi
leaq -0x6a0(%rbp), %rsi
movl $0x5, %edx
callq 0xa140
movq -0x750(%rbp), %rdi
leaq -0x740(%rbp), %rsi
movl $0xa0, %edx
callq 0x10e0
jmp 0xa5bb
jmp 0xa5c8
jmp 0xa5bd
jmp 0xa5bf
jmp 0xa5c1
jmp 0xa5c3
jmp 0xa29f
movq -0x748(%rbp), %rax
movq -0x10(%rbp), %rdx
movq -0x8(%rbp), %rcx
movq %rdx, (%rcx)
addq $0x750, %rsp            # imm = 0x750
popq %rbp
retq
nopw %cs:(%rax,%rax)