// File: /workspace/github_cpp_makefile_star2_O1/kipa00[P]AplusB-mc/compiler/main.cpp
// Function: main
int main(int argc, char *argv[]) {
	if (argc <= 1) {
		fprintf(stderr, "Usage: %s <region file name> [input list]\n", argv[0]);
		return -1;
	} else if (argc == 2) {
		fprintf(stderr, "Warning: no input specified\n");
	}
	vector<int> input_order;
	for (int i=2; i<argc; ++i) {
		int v = color_to_int(argv[i]);
		if (v < 0) {
			fprintf(stderr, "Error: unknown color '%s'\n", argv[i]);
			return -1;
		}
		input_order.push_back(v);
	}
	FILE *fp = fopen(argv[1], "rb");
	world w;
	try {
		w.init(fp);
	} catch (int err) {
		fprintf(stderr, "Compilation aborted.\n");
		return -1;
	}
	fclose(fp);

	int **u = new int *[16384], cnt = 0;
	memset(u, 0, sizeof(int *) * 16384);
	traverse_world(w, [&] (int x, int y, int z) {
		if (is_redstone_component(w, x, y, z)) {
			int **ptr = u + (((z >> 4) << 9) | ((x >> 4) << 4) | (y >> 4));
			if (!*ptr) {
				*ptr = new int[4096];
				memset(*ptr, 0, sizeof(int) * 4096);
			}
			(*ptr)[((z & 15) << 8) | ((x & 15) << 4) | (y & 15)] = ++cnt;
		}
	});

	fp = fopen("a.out", "wb");
	traverse_world(w, [&] (int x, int y, int z) {
		vector<int> info;
		const int type = analyze(w, x, y, z, info);
		if (type) {
			int byte_type = 0;
			if (type == 1) {
				byte_type = 16 | (w.getXYZ(x, y, z) & 15);
			} else {
				byte_type = (type << 4) | (w.getXYZ(x, y, z) & POWERED ? 15 : 0);
			}
			write_byte(fp, byte_type);
			for (const int &x : info) {
				write_int(fp, x >= 0 ? u[x >> 12][x & 4095] : -1);
			}
			write_int(fp, -1);
			if (type == 1 || type == 2) {
				for (int i=0; i<wide_len; ++i) {
					const int nx = x + wide_dx[i], ny = y + wide_dy[i], nz = z + wide_dz[i];
					if (is_redstone_component(w, nx, ny, nz)) {
						vector<int> temp;
						analyze(w, nx, ny, nz, temp);
						const int target = pack(x, y, z);
						const int idx = pack(nx, ny, nz);
						for (const int &v : temp) {
							if (v == target) {
								write_int(fp, u[idx >> 12][idx & 4095]);
								break;
							}
						}
					}
				}
			} else {
				for (int i=0; i<narrow_len; ++i) {
					int nx = x + narrow_dx[i], ny = y + narrow_dy[i], nz = z + narrow_dz[i];
					if (is_redstone_component(w, nx, ny, nz)) {
						const int idx = pack(nx, ny, nz);
						write_int(fp, u[idx >> 12][idx & 4095]);
					}
					if (type != 10) {
						switch (w.getXYZ(x, y, z) & 3) {
							case EAST: --nx; break;
							case WEST: ++nx; break;
							case SOUTH: --nz; break;
							case NORTH: ++nz; break;
						}
						if (is_redstone_component(w, nx, ny, nz) && !(nx == x && nz == z)) {
							int idx = pack(nx, ny, nz);
							write_int(fp, u[idx >> 12][idx & 4095]);
						}
					}
				}
			}
			write_int(fp, -1);
		}
	});
	write_byte(fp, -1);

	vector<std::pair<int, int> > inputs[16], output;
	traverse_world(w, [&] (int x, int y, int z) {
		byte fetched = w.getXYZ(x, y, z);
		if ((fetched & BLOCK_ONLY) == LEVER) {
			int nx = x, ny = y, nz = z;
			switch (fetched & 3) {
				case EAST: --nx; break;
				case WEST: ++nx; break;
				case SOUTH: --nz; break;
				case NORTH: ++nz; break;
			}
			byte facing = w.getXYZ(nx, ny, nz);
			if ((facing & BLOCK_ONLY) == CONCRETE) {
				inputs[facing & 15].emplace_back((z << 17) | (x << 8) | y, pack(x, y, z));
			}
		} else if ((fetched & BLOCK_ONLY) == REDSTONE_LAMP) {
			output.emplace_back((z << 17) | (x << 8) | y, pack(x, y, z));
		}
	});
	for (int i=0; i<16; ++i) {
		sort(inputs[i].begin(), inputs[i].end());
	}
	sort(output.begin(), output.end());

	for (const int &i : input_order) {
		for (const auto &[_, idx] : inputs[i]) {
			write_int(fp, u[idx >> 12][idx & 4095]);
		}
		write_int(fp, -1);
	}
	write_int(fp, -1);
	for (const auto &[_, idx] : output) {
		write_int(fp, u[idx >> 12][idx & 4095]);
	}
	write_int(fp, -1);
	fclose(fp);
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x278, %rsp            # imm = 0x278
movq %rsi, %r14
cmpl $0x1, %edi
jle 0x2bc9
movl %edi, %ebx
cmpl $0x2, %edi
je 0x2bd8
xorps %xmm0, %xmm0
movaps %xmm0, 0x30(%rsp)
movq $0x0, 0x40(%rsp)
cmpl $0x2, %ebx
setne %bpl
movq %r14, 0x60(%rsp)
je 0x27da
movl %ebx, %eax
movq %rax, 0x68(%rsp)
cmpl $0x4, %ebx
movl $0x3, %eax
cmovgel %ebx, %eax
addq $0x10, %r14
movl $0x2, %ebx
subq %rax, %rbx
movl $0x0, 0xc(%rsp)
movl $0x3, %r12d
leaq 0xd0(%rsp), %r15
movq (%r14), %rsi
movq %r15, %rdi
leaq 0x10(%rsp), %rdx
callq 0x33ec
movq %r15, %rdi
callq 0x7d1c
movl %eax, %r13d
movq 0xd0(%rsp), %rdi
leaq 0xe0(%rsp), %rax
cmpq %rax, %rdi
je 0x2767
movq 0xe0(%rsp), %rsi
incq %rsi
callq 0x2150
movl %r13d, 0xf0(%rsp)
testl %r13d, %r13d
js 0x27c8
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x278e
movl %r13d, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x38(%rsp)
jmp 0x27a0
leaq 0x30(%rsp), %rdi
leaq 0xf0(%rsp), %rdx
callq 0x34c4
testl %r13d, %r13d
js 0x27e2
cmpq 0x68(%rsp), %r12
setb %bpl
addq $0x8, %r14
leaq (%rbx,%r12), %rax
incq %rax
incq %r12
cmpq $0x3, %rax
jne 0x2727
jmp 0x27e2
movq %r14, %rdi
callq 0x227c
movl $0xffffffff, 0xc(%rsp)  # imm = 0xFFFFFFFF
jmp 0x27a0
movl $0x0, 0xc(%rsp)
testb $0x1, %bpl
movl 0xc(%rsp), %ebx
jne 0x2b9e
movq 0x60(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x5a73(%rip), %rsi      # 0x8273
callq 0x2190
movq %rax, (%rsp)
leaq 0x50(%rsp), %rdi
callq 0x4f40
movq (%rsp), %rsi
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
callq 0x4f48
movq (%rsp), %rdi
callq 0x2130
movl $0x20000, %edi          # imm = 0x20000
callq 0x2030
movq %rax, 0x48(%rsp)
movl $0x0, 0x5c(%rsp)
movl $0x20000, %edx          # imm = 0x20000
movq %rax, %rdi
xorl %esi, %esi
callq 0x20c0
xorps %xmm0, %xmm0
movaps %xmm0, 0xb0(%rsp)
movaps %xmm0, 0xc0(%rsp)
movl $0x18, %edi
callq 0x2140
movq %rbx, (%rax)
leaq 0x48(%rsp), %r14
movq %r14, 0x8(%rax)
leaq 0x5c(%rsp), %rcx
movq %rcx, 0x10(%rax)
leaq 0xb0(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x4b5(%rip), %rax       # 0x2d4c
movq %rax, 0x18(%rsi)
leaq 0x54c(%rip), %rax       # 0x2dee
movq %rax, 0x10(%rsi)
movq %rbx, %rdi
callq 0x257c
movq 0xc0(%rsp), %rax
testq %rax, %rax
je 0x28cd
leaq 0xb0(%rsp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
leaq 0x59b8(%rip), %rdi      # 0x828c
leaq 0x59b7(%rip), %rsi      # 0x8292
callq 0x2190
movq %rax, (%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x90(%rsp)
movaps %xmm0, 0xa0(%rsp)
movl $0x18, %edi
callq 0x2140
movq %rbx, (%rax)
movq %rsp, %rcx
movq %rcx, 0x8(%rax)
movq %r14, 0x10(%rax)
leaq 0x90(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x537(%rip), %rax       # 0x2e58
movq %rax, 0x18(%rsi)
leaq 0x8d6(%rip), %rax       # 0x3202
movq %rax, 0x10(%rsi)
movq %rbx, %rdi
callq 0x257c
movq 0xa0(%rsp), %rax
testq %rax, %rax
je 0x2957
leaq 0x90(%rsp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movq (%rsp), %rsi
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x21b0
leaq 0xf0(%rsp), %r14
movl $0x180, %edx            # imm = 0x180
movq %r14, %rdi
xorl %esi, %esi
callq 0x20c0
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x80(%rsp)
movl $0x18, %edi
callq 0x2140
movq %rbx, (%rax)
movq %r14, 0x8(%rax)
leaq 0x10(%rsp), %rcx
movq %rcx, 0x10(%rax)
leaq 0x70(%rsp), %rsi
movq %rax, (%rsi)
leaq 0x8a9(%rip), %rax       # 0x326c
movq %rax, 0x18(%rsi)
leaq 0x980(%rip), %rax       # 0x334e
movq %rax, 0x10(%rsi)
movq %rbx, %rdi
callq 0x257c
movq 0x80(%rsp), %rax
testq %rax, %rax
je 0x29f6
leaq 0x70(%rsp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movl $0x8, %r15d
movq 0xe8(%rsp,%r15), %rbx
movq 0xf0(%rsp,%r15), %r14
cmpq %r14, %rbx
je 0x2a3e
movq %r14, %rax
subq %rbx, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x378b
movq %rbx, %rdi
movq %r14, %rsi
callq 0x383e
addq $0x18, %r15
cmpq $0x188, %r15            # imm = 0x188
jne 0x29fc
movq 0x10(%rsp), %rbx
movq 0x18(%rsp), %r14
cmpq %r14, %rbx
je 0x2a87
movq %r14, %rax
subq %rbx, %rax
sarq $0x3, %rax
bsrq %rax, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x378b
movq %rbx, %rdi
movq %r14, %rsi
callq 0x383e
movq 0x30(%rsp), %rbx
movq 0x38(%rsp), %r14
cmpq %r14, %rbx
je 0x2af3
movslq (%rbx), %rax
leaq (%rax,%rax,2), %rax
movq 0xf0(%rsp,%rax,8), %r15
movq 0xf8(%rsp,%rax,8), %r12
cmpq %r12, %r15
je 0x2adf
movq (%rsp), %rdi
movq 0x48(%rsp), %rax
movl 0x4(%r15), %ecx
movl %ecx, %edx
sarl $0xc, %edx
movslq %edx, %rdx
movq (%rax,%rdx,8), %rax
andl $0xfff, %ecx            # imm = 0xFFF
movl (%rax,%rcx,4), %esi
callq 0x2660
addq $0x8, %r15
jmp 0x2aad
movq (%rsp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x2660
addq $0x4, %rbx
jmp 0x2a91
movq (%rsp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x2660
movq 0x10(%rsp), %rbx
movq 0x18(%rsp), %r14
cmpq %r14, %rbx
je 0x2b3c
movq (%rsp), %rdi
movq 0x48(%rsp), %rax
movl 0x4(%rbx), %ecx
movl %ecx, %edx
sarl $0xc, %edx
movslq %edx, %rdx
movq (%rax,%rdx,8), %rax
andl $0xfff, %ecx            # imm = 0xFFF
movl (%rax,%rcx,4), %esi
callq 0x2660
addq $0x8, %rbx
jmp 0x2b0b
movq (%rsp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x2660
movq (%rsp), %rdi
callq 0x2130
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x2b6a
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2150
movl $0x180, %ebx            # imm = 0x180
movq 0xd8(%rsp,%rbx), %rdi
testq %rdi, %rdi
je 0x2b8c
movq 0xe8(%rsp,%rbx), %rsi
subq %rdi, %rsi
callq 0x2150
addq $-0x18, %rbx
jne 0x2b6f
xorl %ebx, %ebx
leaq 0x50(%rsp), %rdi
callq 0x529e
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x2bb5
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2150
movl %ebx, %eax
addq $0x278, %rsp            # imm = 0x278
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
callq 0x22cc
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0x2bb5
callq 0x2260
jmp 0x26d0
jmp 0x2c7a
jmp 0x2c7a
jmp 0x2c7a
movq %rax, %rbx
movq 0x80(%rsp), %rax
testq %rax, %rax
je 0x2ce2
leaq 0x70(%rsp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
jmp 0x2ce2
jmp 0x2c7a
jmp 0x2cdf
movq %rax, %rbx
movq 0xa0(%rsp), %rax
testq %rax, %rax
je 0x2d22
leaq 0x90(%rsp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
jmp 0x2d22
jmp 0x2c7a
jmp 0x2c84
movq %rax, %rbx
movq 0xc0(%rsp), %rax
testq %rax, %rax
je 0x2d22
leaq 0xb0(%rsp), %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
jmp 0x2d22
movq %rax, %rdi
callq 0x3429
jmp 0x2c84
movq %rax, %rbx
jmp 0x2d22
movq %rax, %rbx
cmpl $0x1, %edx
jne 0x2d22
movq %rbx, %rdi
callq 0x22a0
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0x2b94
jmp 0x2cb0
jmp 0x2cdf
jmp 0x2cb0
movq %rax, %rbx
jmp 0x2d2c
movq %rax, %rbx
movq 0xd0(%rsp), %rdi
leaq 0xe0(%rsp), %rax
cmpq %rax, %rdi
je 0x2d2c
movq 0xe0(%rsp), %rsi
incq %rsi
callq 0x2150
jmp 0x2d2c
movq %rax, %rbx
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x2cf9
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2150
movl $0x180, %r14d           # imm = 0x180
movq 0xd8(%rsp,%r14), %rdi
testq %rdi, %rdi
je 0x2d1c
movq 0xe8(%rsp,%r14), %rsi
subq %rdi, %rsi
callq 0x2150
addq $-0x18, %r14
jne 0x2cff
leaq 0x50(%rsp), %rdi
callq 0x529e
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x2d43
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2150
movq %rbx, %rdi
callq 0x2220
nop