// File: /workspace/github_cpp_makefile_star2_O2/skeeto[P]elisp-ffi/ffi-glue.cc
// Function: main
int main() {
    Machine vm{std::cout};
    Reader reader{vm, std::cin};

    while (!std::cin.eof()) {
        int command = std::cin.get();
        switch (command) {
        /* push signed integer */
        case 'i' + 0: /* i */
            reader.read_sint8();
            break;
        case 'i' + 1: /* j */
            reader.read_sint16();
            break;
        case 'i' + 2: /* k */
            reader.read_sint32();
            break;
        case 'i' + 3: /* l */
            reader.read_sint64();
            break;

        /* push unsigned integer */
        case 'u' + 0: /* u */
            reader.read_uint8();
            break;
        case 'u' + 1: /* v */
            reader.read_uint16();
            break;
        case 'u' + 2: /* w */
            reader.read_uint32();
            break;
        case 'u' + 3: /* x */
            reader.read_uint64();
            break;

        /* push float */
        case 'f':
            reader.read_float();
            break;
        case 'd':
            reader.read_double();
            break;

        /* push pointer */
        case 'p':
            reader.read_pointer();
            break;

        /* push void */
        case 'V':
            vm.stack.push();
            break;

        /* peek */
        case 'e':
            vm.peek();
            break;

        /* pop */
        case 'o':
            vm.pop();
            break;

        /* call */
        case 'c':
            vm.call(false);
            break;

        /* call with errno */
        case 'E':
            vm.call(true);
            break;

        /* call */
        case 'C':
            vm.cif();
            break;

        /* "malloc" */
        case 'M':
            reader.read(vm.stack.pop().value.u32);
            break;

        /* free */
        case 'F':
            vm.free();
            break;

        /* dl calls */
        case 'O':
            vm.dlopen();
            break;
        case 'S':
            vm.dlsym();
            break;

        /* strlen */
        case 'L':
            vm.strlen();
            break;

        /* dump */
        case 'D':
            vm.dump();
            break;

        /* read from memory */
        case 'r':
            vm.read_mem();
            break;

        /* array read from memory */
        case 'A':
            vm.read_array();
            break;

        /* duplicate top value */
        case '!':
            vm.stack.dup();
            break;

        /* get stack size */
        case '?':
            vm.size();
            break;

        /* no-op */
        case ' ':
        case '\n':
        case '\r':
        case -1:
            break;

        default:
            std::cerr << "invalid op: " << static_cast<char>(command) << std::endl;
            break;
        }
        std::cout.flush();
    }

    std::cout << std::endl;
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
xorps %xmm0, %xmm0
leaq 0x10(%rsp), %rbx
andq $0x0, 0x10(%rbx)
movaps %xmm0, (%rbx)
movq 0x4994(%rip), %r14      # 0x6fa0
movq %r14, 0x18(%rbx)
movaps %xmm0, 0x20(%rbx)
movaps %xmm0, 0x30(%rbx)
movaps %xmm0, 0x40(%rbx)
movq (%r14), %rax
movq -0x18(%rax), %rax
movq $0xf, 0x8(%r14,%rax)
movq %rbx, (%rsp)
movq 0x4991(%rip), %r15      # 0x6fc8
movq %r15, 0x8(%rsp)
movabsq $0x200004801, %r12      # imm = 0x200004801
leaq 0x19b7(%rip), %r13      # 0x4004
movq (%r15), %rax
movq -0x18(%rax), %rax
testb $0x2, 0x20(%r15,%rax)
jne 0x2833
movq %r15, %rdi
callq 0x21f0
movl %eax, %ebp
leal -0x3f(%rbp), %eax
cmpl $0x39, %eax
ja 0x268b
movslq (%r13,%rax,4), %rax
addq %r13, %rax
jmpq *%rax
leaq 0x10(%rsp), %rdi
callq 0x31fe
jmp 0x2826
leal 0x1(%rbp), %eax
cmpl $0x22, %eax
ja 0x26b0
btq %rax, %r12
jb 0x2826
cmpq $0x22, %rax
jne 0x26b0
movq %rbx, %rdi
callq 0x31f0
jmp 0x2826
movq 0x4939(%rip), %rdi      # 0x6ff0
leaq 0x1afd(%rip), %rsi      # 0x41bb
callq 0x21a0
movsbl %bpl, %esi
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
callq 0x20a0
jmp 0x2826
movq %rsp, %rdi
callq 0x297a
jmp 0x2826
movq %rsp, %rdi
callq 0x294e
jmp 0x2826
movq %rsp, %rdi
callq 0x2922
jmp 0x2826
movq %rsp, %rdi
callq 0x28cc
jmp 0x2826
movq %rsp, %rdi
callq 0x29a6
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2cfc
jmp 0x2826
movq %rsp, %rdi
callq 0x28f8
jmp 0x2826
movq %rsp, %rdi
callq 0x29fe
jmp 0x2826
movq %rsp, %rdi
callq 0x2a2a
jmp 0x2826
xorl %eax, %eax
jmp 0x2793
movq %rsp, %rdi
callq 0x2874
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2d4a
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2c98
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2bba
jmp 0x2826
movb $0x1, %al
movzbl %al, %esi
leaq 0x10(%rsp), %rdi
callq 0x2ace
jmp 0x2826
movq %rsp, %rdi
callq 0x29d0
jmp 0x2826
movq 0x18(%rsp), %rax
movl -0x8(%rax), %esi
addq $-0x10, %rax
movq %rax, 0x18(%rsp)
movq %rsp, %rdi
callq 0x2c60
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2ec0
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2aa0
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2cb4
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2d2e
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2a58
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2d72
jmp 0x2826
leaq 0x10(%rsp), %rdi
callq 0x2a7a
jmp 0x2826
movq %rsp, %rdi
callq 0x28a0
movq %r14, %rdi
callq 0x2110
jmp 0x264d
movq 0x4766(%rip), %rdi      # 0x6fa0
callq 0x20a0
leaq 0x10(%rsp), %rdi
callq 0x320e
xorl %eax, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x285e
jmp 0x285e
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x320e
movq %rbx, %rdi
callq 0x22c0
nop