// File: /workspace/github_c_makefile_star2_O0/oridb[P]mc/parse/infer.c
// Function: inferpat
static void
inferpat(Node **np, Node *val, Node ***bind, size_t *nbind)
{
	size_t i;
	Node **args;
	Node *s, *n;
	Stab *ns;
	Type *t;

	n = *np;
	n = checkns(n, np);
	n->expr.ispat = 1;
	args = n->expr.args;
	for (i = 0; i < n->expr.nargs; i++)
		if (args[i]->type == Nexpr) {
			inferpat(&args[i], val, bind, nbind);
		}
	switch (exprop(n)) {
	case Otup:
	case Ostruct:
	case Oarr:
	case Olit:
	case Omemb:
	case Olor:
		infernode(np, NULL, NULL);
		break;
		/* arithmetic expressions just need to be constant */
	case Oneg:
	case Oadd:
	case Osub:
	case Omul:
	case Odiv:
	case Obsl:
	case Obsr:
	case Oband:
	case Obor:
	case Obxor:
	case Obnot:
		infernode(np, NULL, NULL);
		if (!n->expr.isconst)
			fatal(n, "matching against non-constant expression near %s", ctxstr(n));
		break;
	case Oucon:
		inferucon(n, &n->expr.isconst);
		break;
	case Ovar:
		ns = curstab();
		if (args[0]->name.ns)
			ns = getns(args[0]->name.ns);
		s = getdcl(ns, args[0]);
		if (s && !s->decl.ishidden) {
			if (s->decl.isgeneric)
				t = tysubst(s->decl.type, s->decl.type);
			else if (s->decl.isconst)
				t = s->decl.type;
			else
				fatal(n, "pattern shadows variable declared on %s:%d near %s",
						fname(s->loc), lnum(s->loc), ctxstr(s));
		} else {
			/* Scan the already collected bound variables in the pattern of this match case.
			 * If a bound variable with the same name is found, assign the variable the existing decl.
			 * Otherwise, create a new decl for the variable */
			s = NULL;
			for (i = 0; !s && i < *nbind; i++)
				if (nameeq(args[0], (*bind)[i]->decl.name))
					s = (*bind)[i];

			if (s) {
				t = s->decl.type;
			} else {
				t = mktyvar(n->loc);
				s = mkdecl(n->loc, n->expr.args[0], t);
				s->decl.init = val;
				settype(n, t);
				lappend(bind, nbind, s);
			}
		}
		settype(n, t);
		n->expr.did = s->decl.did;
		n->expr.isconst = s->decl.isconst;
		break;
	case Oaddr:
		infernode(np, NULL, NULL);
		break;
	case Ogap:
		infernode(np, NULL, NULL);	break;
	default: fatal(n, "invalid pattern"); break;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x2cf40
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl $0x1, 0x34(%rax)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x30(%rbp)
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq 0x40(%rcx), %rax
jae 0x2b436
movq -0x30(%rbp), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpl $0x8, 0x8(%rax)
jne 0x2b426
movq -0x30(%rbp), %rdi
movq -0x28(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x2b390
jmp 0x2b428
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x2b3e6
movq -0x40(%rbp), %rdi
callq 0x2f210
addl $-0x2, %eax
movl %eax, %ecx
movq %rcx, -0x58(%rbp)
subl $0x37, %eax
ja 0x2b700
movq -0x58(%rbp), %rax
leaq 0x2659c(%rip), %rcx     # 0x519f8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x260b0
jmp 0x2b712
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x260b0
movq -0x40(%rbp), %rax
cmpl $0x0, 0x30(%rax)
jne 0x2b4ba
movq -0x40(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x40(%rbp), %rdi
callq 0x27be0
movq -0x60(%rbp), %rdi
movq %rax, %rdx
leaq 0x26f10(%rip), %rsi     # 0x523c3
movb $0x0, %al
callq 0x1dfe0
jmp 0x2b712
movq -0x40(%rbp), %rdi
movq -0x40(%rbp), %rsi
addq $0x18, %rsi
addq $0x18, %rsi
callq 0x2d0c0
jmp 0x2b712
callq 0x32d60
movq %rax, -0x48(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rax
cmpq $0x0, 0x18(%rax)
je 0x2b504
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq 0x18(%rax), %rdi
callq 0x330b0
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
movq -0x30(%rbp), %rax
movq (%rax), %rsi
callq 0x334b0
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x2b5c1
movq -0x38(%rbp), %rax
cmpb $0x0, 0x76(%rax)
jne 0x2b5c1
movq -0x38(%rbp), %rax
cmpb $0x0, 0x73(%rax)
je 0x2b556
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rsi
callq 0x2ad80
movq %rax, -0x50(%rbp)
jmp 0x2b5bc
movq -0x38(%rbp), %rax
cmpb $0x0, 0x72(%rax)
je 0x2b56e
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x50(%rbp)
jmp 0x2b5ba
movq -0x40(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x38(%rbp), %rax
movq (%rax), %rdi
callq 0x2f090
movq %rax, -0x70(%rbp)
movq -0x38(%rbp), %rax
movq (%rax), %rdi
callq 0x2f0b0
movl %eax, -0x64(%rbp)
movq -0x38(%rbp), %rdi
callq 0x27be0
movq -0x78(%rbp), %rdi
movq -0x70(%rbp), %rdx
movl -0x64(%rbp), %ecx
movq %rax, %r8
leaq 0x26e41(%rip), %rsi     # 0x523f4
movb $0x0, %al
callq 0x1dfe0
jmp 0x2b5bc
jmp 0x2b6ae
movq $0x0, -0x38(%rbp)
movq $0x0, -0x28(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x38(%rbp)
movb %al, -0x79(%rbp)
jne 0x2b5ee
movq -0x28(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq (%rcx), %rax
setb %al
movb %al, -0x79(%rbp)
movb -0x79(%rbp), %al
testb $0x1, %al
jne 0x2b5f7
jmp 0x2b63e
movq -0x30(%rbp), %rax
movq (%rax), %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rsi
callq 0x30670
cmpl $0x0, %eax
je 0x2b62e
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x38(%rbp)
jmp 0x2b630
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x2b5d1
cmpq $0x0, -0x38(%rbp)
je 0x2b653
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x50(%rbp)
jmp 0x2b6ac
movq -0x40(%rbp), %rax
movq (%rax), %rdi
callq 0x370c0
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rax
movq -0x40(%rbp), %rcx
movq 0x50(%rcx), %rcx
movq (%rcx), %rsi
movq -0x50(%rbp), %rdx
movq (%rax), %rdi
callq 0x2ff20
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x40(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x2ce80
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x38(%rbp), %rdx
callq 0x48290
jmp 0x2b6ae
movq -0x40(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x2ce80
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x38(%rbp), %rax
movsbl 0x72(%rax), %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0x30(%rax)
jmp 0x2b712
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x260b0
jmp 0x2b712
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x260b0
jmp 0x2b712
movq -0x40(%rbp), %rdi
leaq 0x26d1c(%rip), %rsi     # 0x52427
movb $0x0, %al
callq 0x1dfe0
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax,%rax)