// File: /workspace/github_c_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %r12
movq (%rdi), %rdi
movq %r12, %rsi
callq 0x1c8b9
movq %rax, %rbx
movl $0x1, 0x34(%rax)
movq 0x50(%rax), %rax
movq %rax, (%rsp)
cmpq $0x0, 0x40(%rbx)
je 0x1bc6a
xorl %ebp, %ebp
movq (%rsp), %r13
movq (%r13), %rax
cmpl $0x8, 0x8(%rax)
jne 0x1bc5d
movq %r13, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x1bc07
incq %rbp
addq $0x8, %r13
cmpq 0x40(%rbx), %rbp
jb 0x1bc45
movq %rbx, %rdi
callq 0x1d672
cmpl $0x11, %eax
jg 0x1bcac
leal -0x7(%rax), %ecx
cmpl $0x7, %ecx
jb 0x1bc87
addl $-0x2, %eax
cmpl $0x4, %eax
jae 0x1bce8
movq %r12, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x188e1
cmpl $0x0, 0x30(%rbx)
je 0x1be50
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leal -0x2a(%rax), %ecx
cmpl $0xf, %ecx
ja 0x1bcde
leaq 0x19e7d(%rip), %rax     # 0x35b38
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq %r12, %rdi
xorl %esi, %esi
xorl %edx, %edx
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x188e1
cmpl $0x12, %eax
je 0x1bcc4
cmpl $0x14, %eax
je 0x1bcc4
leaq 0x1a799(%rip), %rsi     # 0x36488
movq %rbx, %rdi
xorl %eax, %eax
callq 0x13aa3
movq %rbx, %rsi
addq $0x30, %rsi
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1c9c7
callq 0x20037
movq (%rsp), %rcx
movq (%rcx), %rcx
movq 0x18(%rcx), %rdi
testq %rdi, %rdi
je 0x1bd30
callq 0x2022f
movq (%rsp), %rcx
movq (%rcx), %rsi
movq %rax, %rdi
callq 0x2048b
testq %rax, %rax
je 0x1bd51
movq %rax, %r12
cmpb $0x0, 0x76(%rax)
je 0x1bdd2
xorl %r13d, %r13d
cmpq (%r14), %r13
jae 0x1bd8f
movq (%rsp), %rax
movq (%rax), %rdi
movq (%r15), %rax
movq (%rax,%r13,8), %rax
movq 0x20(%rax), %rsi
callq 0x1e773
testl %eax, %eax
je 0x1bd7d
movq (%r15), %rax
movq (%rax,%r13,8), %r12
jmp 0x1bd80
xorl %r12d, %r12d
incq %r13
testq %r12, %r12
je 0x1bd54
movq 0x28(%r12), %r13
jmp 0x1bdea
movq (%rbx), %rdi
callq 0x22fd7
movq %rax, %r13
movq (%rbx), %rdi
movq 0x50(%rbx), %rax
movq (%rax), %rsi
movq %r13, %rdx
callq 0x1e29f
movq %rax, %r12
movq $0x0, 0x30(%rax)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x1c85b
movq %r15, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0x2d3ff
jmp 0x1bdea
cmpb $0x0, 0x73(%r12)
je 0x1be0c
movq 0x28(%r12), %rdi
movq %rdi, %rsi
callq 0x1b815
movq %rax, %r13
movq %rbx, %rdi
movq %r13, %rsi
callq 0x1c85b
movq 0x18(%r12), %rax
movq %rax, 0x38(%rbx)
movsbl 0x72(%r12), %eax
movl %eax, 0x30(%rbx)
jmp 0x1bc9d
cmpb $0x0, 0x72(%r12)
jne 0x1bd88
movq (%r12), %rdi
callq 0x1d56c
movq %rax, %r14
movq (%r12), %rdi
callq 0x1d580
movl %eax, %ebp
movq %r12, %rdi
callq 0x19a6f
leaq 0x1a617(%rip), %rsi     # 0x36455
movq %rbx, %rdi
movq %r14, %rdx
movl %ebp, %ecx
movq %rax, %r8
xorl %eax, %eax
callq 0x13aa3
movq %rbx, %rdi
callq 0x19a6f
leaq 0x1a5c5(%rip), %rsi     # 0x36424
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x13aa3