// File: iamlouk[P]asbi/src/macros.cc
// Function: macro_reduce(int, asbi::Context*, std::shared_ptr<asbi::Env>)
static Value macro_reduce(int n, Context* ctx, std::shared_ptr<Env> env) {
	if (n != 3)
		throw std::runtime_error("reduce macro usage error");

	auto map = ctx->pop();
	auto acc = ctx->pop();
	auto fn  = ctx->pop();
	if (map.type != type_t::Map || fn.type != type_t::Lambda)
		throw std::runtime_error("reduce macro usage error");

	auto &vecdata = map._map->vecdata;
	for (unsigned int i = 0; i < vecdata.size(); ++i) {
		ctx->push(vecdata[i]);
		ctx->push(Value::number(i));
		ctx->push(acc);
		acc = fn.call(ctx, 3, env);
	}

	for (auto [key, value]: map._map->data) {
		ctx->push(value);
		ctx->push(key);
		ctx->push(acc);
		acc = fn.call(ctx, 3, env);
	}

	return acc;
}

// Assembly:
subq $0x1d8, %rsp            # imm = 0x1D8
movq %rdx, 0x78(%rsp)
movl %edi, 0x1c4(%rsp)
movq %rsi, 0x1b8(%rsp)
movq %rdx, 0x1b0(%rsp)
cmpl $0x3, 0x1c4(%rsp)
je 0x2b53b
movl $0x10, %edi
callq 0x6200
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x70(%rsp)
leaq 0xdf3f(%rip), %rsi      # 0x39438
callq 0x6160
jmp 0x2b500
movq 0x70(%rsp), %rdi
movq 0x20ae4(%rip), %rsi     # 0x4bff0
movq 0x20a8d(%rip), %rdx     # 0x4bfa0
callq 0x6780
movq 0x70(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
callq 0x6320
jmp 0x2b9e1
movq 0x1b8(%rsp), %rdi
callq 0x26b50
movl %eax, 0x190(%rsp)
movq %rdx, 0x198(%rsp)
movq 0x1b8(%rsp), %rdi
callq 0x26b50
movl %eax, 0x1c8(%rsp)
movq %rdx, 0x1d0(%rsp)
movq 0x1b8(%rsp), %rdi
callq 0x26b50
movl %eax, 0x180(%rsp)
movq %rdx, 0x188(%rsp)
cmpl $0x6, 0x190(%rsp)
jne 0x2b5a3
cmpl $0x5, 0x180(%rsp)
je 0x2b601
movl $0x10, %edi
callq 0x6200
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x68(%rsp)
leaq 0xde79(%rip), %rsi      # 0x39438
callq 0x6160
jmp 0x2b5c6
movq 0x68(%rsp), %rdi
movq 0x20a1e(%rip), %rsi     # 0x4bff0
movq 0x209c7(%rip), %rdx     # 0x4bfa0
callq 0x6780
movq 0x68(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
callq 0x6320
jmp 0x2b9e1
movq 0x198(%rsp), %rax
addq $0x50, %rax
movq %rax, 0x178(%rsp)
movl $0x0, 0x174(%rsp)
movl 0x174(%rsp), %eax
movq %rax, 0x60(%rsp)
movq 0x178(%rsp), %rdi
callq 0x1d030
movq %rax, %rcx
movq 0x60(%rsp), %rax
cmpq %rcx, %rax
jae 0x2b7cf
movq 0x1b8(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x178(%rsp), %rdi
movl 0x174(%rsp), %eax
movl %eax, %esi
callq 0x22c80
movq 0x30(%rsp), %rdi
movups (%rax), %xmm0
movaps %xmm0, 0x160(%rsp)
movl 0x160(%rsp), %esi
movq 0x168(%rsp), %rdx
callq 0x26b20
movq 0x1b8(%rsp), %rax
movq %rax, 0x38(%rsp)
movl 0x174(%rsp), %eax
cvtsi2sd %rax, %xmm0
callq 0x1d090
movq 0x38(%rsp), %rdi
movl %eax, 0x150(%rsp)
movq %rdx, 0x158(%rsp)
movl 0x150(%rsp), %esi
movq 0x158(%rsp), %rdx
callq 0x26b20
movq 0x1b8(%rsp), %rdi
movups 0x1c8(%rsp), %xmm0
movaps %xmm0, 0x140(%rsp)
movl 0x140(%rsp), %esi
movq 0x148(%rsp), %rdx
callq 0x26b20
movq 0x78(%rsp), %rsi
movq 0x1b8(%rsp), %rax
movq %rax, 0x40(%rsp)
leaq 0x120(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x7d80
movq 0x40(%rsp), %rsi
movq 0x48(%rsp), %rcx
leaq 0x180(%rsp), %rdi
movl $0x3, %edx
callq 0x219c0
movq %rdx, 0x50(%rsp)
movl %eax, 0x5c(%rsp)
jmp 0x2b74e
movq 0x50(%rsp), %rax
movl 0x5c(%rsp), %ecx
movl %ecx, 0x130(%rsp)
movq %rax, 0x138(%rsp)
movq 0x130(%rsp), %rax
movq %rax, 0x1c8(%rsp)
movq 0x138(%rsp), %rax
movq %rax, 0x1d0(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x7db0
movl 0x174(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x174(%rsp)
jmp 0x2b620
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x7db0
jmp 0x2b9e1
movq 0x198(%rsp), %rax
addq $0x18, %rax
movq %rax, 0x118(%rsp)
movq 0x118(%rsp), %rdi
callq 0x22fc0
movq %rax, 0x110(%rsp)
movq 0x118(%rsp), %rdi
callq 0x22d20
movq %rax, 0x108(%rsp)
leaq 0x110(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0x22ae0
testb $0x1, %al
jne 0x2b82b
jmp 0x2b9ca
leaq 0x110(%rsp), %rdi
callq 0x22ff0
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movaps %xmm1, 0xf0(%rsp)
movaps %xmm0, 0xe0(%rsp)
leaq 0xe0(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x22b20
movq 0x8(%rsp), %rdi
movq %rax, 0xd8(%rsp)
callq 0x22b30
movq %rax, 0xd0(%rsp)
movq 0x1b8(%rsp), %rdi
movq 0xd0(%rsp), %rax
movups (%rax), %xmm0
movaps %xmm0, 0xc0(%rsp)
movl 0xc0(%rsp), %esi
movq 0xc8(%rsp), %rdx
callq 0x26b20
movq 0x1b8(%rsp), %rdi
movq 0xd8(%rsp), %rax
movups (%rax), %xmm0
movaps %xmm0, 0xb0(%rsp)
movl 0xb0(%rsp), %esi
movq 0xb8(%rsp), %rdx
callq 0x26b20
movq 0x1b8(%rsp), %rdi
movups 0x1c8(%rsp), %xmm0
movaps %xmm0, 0xa0(%rsp)
movl 0xa0(%rsp), %esi
movq 0xa8(%rsp), %rdx
callq 0x26b20
movq 0x78(%rsp), %rsi
movq 0x1b8(%rsp), %rax
movq %rax, 0x10(%rsp)
leaq 0x80(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x7d80
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rcx
leaq 0x180(%rsp), %rdi
movl $0x3, %edx
callq 0x219c0
movq %rdx, 0x20(%rsp)
movl %eax, 0x2c(%rsp)
jmp 0x2b950
movq 0x20(%rsp), %rax
movl 0x2c(%rsp), %ecx
movl %ecx, 0x90(%rsp)
movq %rax, 0x98(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x1c8(%rsp)
movq 0x98(%rsp), %rax
movq %rax, 0x1d0(%rsp)
leaq 0x80(%rsp), %rdi
callq 0x7db0
leaq 0x110(%rsp), %rdi
callq 0x23010
jmp 0x2b80d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
leaq 0x80(%rsp), %rdi
callq 0x7db0
jmp 0x2b9e1
movl 0x1c8(%rsp), %eax
movq 0x1d0(%rsp), %rdx
addq $0x1d8, %rsp            # imm = 0x1D8
retq
movq 0x1a8(%rsp), %rdi
callq 0x67a0
nop