// File: /workspace/github_c_makefile_star2_O1/mattn[P]orelang/ore.c
// Function: ore_call
static ore_value
ore_call(ore_context* ore, mpc_ast_t *t) {
  ore_value fn;
  const char* pfn = NULL;
  if (is_a(t->children[0], "ident")) {
    pfn = t->children[0]->contents;
    fn = ore_get(ore, pfn);
  } else if (is_a(t->children[0], "prop")) {
    pfn = t->children[0]->children[2]->contents;
    fn = ore_eval(ore, t->children[0]);
    if (fn.t == ORE_TYPE_NIL) {
      // FIXME
      ore_context* tmp = ore;
      ore_value inst = ore_eval(tmp, t->children[0]->children[0]);
      while (1) {
        inst = ore_prop(inst.v.o->e, "super");
        if (inst.t == ORE_TYPE_NIL)
          break;
        fn = ore_prop(inst.v.o->e, pfn);
        if (fn.t == ORE_TYPE_FUNC || fn.t == ORE_TYPE_CFUNC) {
          break;
        }
      }
    }
  } else {
    pfn = "<anonymous>";
    fn = ore_eval(ore, t->children[0]);
  }
  if (ore->err != ORE_ERROR_NONE)
    return ore_value_nil();
  if (fn.t != ORE_TYPE_FUNC && fn.t != ORE_TYPE_CFUNC) {
    fprintf(stderr, "unknown function '%s'\n", pfn);
    ore->err = ORE_ERROR_EXCEPTION;
    return ore_value_nil();
  }
  ore_value v = ore_value_nil();
  switch (fn.t) {
    case ORE_TYPE_CFUNC:
      {
        int num_in = t->children_num / 2 - 1, n = 0, i;
        if (num_in < fn.v.f.num_in || (fn.v.f.max_in != -1 && num_in > fn.v.f.max_in)) {
          fprintf(stderr, "number of arguments mismatch: %d for %d\n",
            num_in, fn.v.f.num_in);
          ore->err = ORE_ERROR_EXCEPTION;
          return ore_value_nil();
        }
        ore_value* args = (ore_value*) malloc(sizeof(ore_value) * num_in);
        if (!args) {
          fprintf(stderr, "failed to allocate memory\n");
          ore->err = ORE_ERROR_EXCEPTION;
          return ore_value_nil();
        }
        for (i = 2; i < t->children_num - 1; i += 2) {
          args[n++] = ore_eval(ore, t->children[i]);
        }
        v = ((ore_cfunc_t)fn.v.f.x.c) ((ore_context*) ore, num_in, args, fn.v.f.u);
        free(args);
      }
      break;
    case ORE_TYPE_FUNC:
      {
        ore_context* env = ore_new((ore_context*) fn.v.f.ore);
        mpc_ast_t* stmts = ore_find_statements(fn.v.f.x.o);
        if (stmts) {
          ore_value* args = ore_bind_args(ore, fn.v.f.x.o, env, t);
          v = ore_eval(env, stmts);
          if (env->err == ORE_ERROR_EXCEPTION)
            ore->err = env->err;
          char buf[64];
          sprintf(buf, "0x%p", env->env);
          ore_define(ore, buf, ore_value_env_from_context(env));
          free(args);
        }
      }
      break;
    default:
      fprintf(stderr, "invalid function call\n");
      ore->err = ORE_ERROR_EXCEPTION;
      return ore_value_nil();
  }
  return v;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rdx, %r15
movq %rsi, %rbp
movq %rdi, %r14
movq 0x30(%rdx), %rax
movq (%rax), %rbx
movq (%rbx), %r12
leaq 0x2bea(%rip), %rsi      # 0x14b5a
movq %r12, %rdi
callq 0x2290
testq %rax, %rax
movq %r14, 0x30(%rsp)
je 0x11fdf
movq 0x8(%rbx), %rdx
leaq 0x80(%rsp), %r13
movq %r13, %rdi
movq %rbp, %rsi
movq %rdx, 0x28(%rsp)
callq 0xd012
movl (%r13), %r14d
movq 0x8(%r13), %rbx
movq %rbp, %rsi
movl 0x10(%r13), %ecx
movl 0x14(%r13), %r12d
movq 0x18(%r13), %rdx
movq 0x20(%r13), %rbp
cmpl $0x0, 0x20(%rsi)
je 0x12152
xorps %xmm0, %xmm0
movq 0x30(%rsp), %rax
movups %xmm0, 0x10(%rax)
movups %xmm0, (%rax)
movq $0x0, 0x20(%rax)
jmp 0x12379
leaq 0x2bb4(%rip), %rsi      # 0x14b9a
movq %r12, %rdi
callq 0x2290
testq %rax, %rax
je 0x1238b
movq 0x30(%rbx), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rax
movq %rax, 0x28(%rsp)
leaq 0x80(%rsp), %r13
movq %r13, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xdee3
movl (%r13), %r14d
movq 0x8(%r13), %rbx
movq %rbp, %rsi
movl 0x10(%r13), %ecx
movl 0x14(%r13), %r12d
movq 0x18(%r13), %rdx
movq 0x20(%r13), %rbp
testl %r14d, %r14d
jne 0x11fb9
movq %r15, %rax
movl %ecx, %r15d
movq %rdx, %r13
movq %rax, 0x70(%rsp)
movq 0x30(%rax), %rax
movq (%rax), %rax
movq 0x30(%rax), %rax
movq (%rax), %rdx
leaq 0x80(%rsp), %r14
movq %r14, %rdi
movq %rsi, 0x38(%rsp)
callq 0xdee3
movq 0x8(%r14), %rax
movq 0x10(%rax), %rsi
leaq 0x40c0(%rip), %rdx      # 0x16142
leaq 0x40(%rsp), %rdi
callq 0xcec9
leaq 0x40(%rsp), %rcx
movq 0x20(%rcx), %rax
movq %rax, 0x20(%r14)
movups (%rcx), %xmm0
movups 0x10(%rcx), %xmm1
movaps %xmm1, 0x10(%r14)
movaps %xmm0, (%r14)
cmpl $0x0, (%r14)
je 0x123cd
movq 0x88(%rsp), %rax
movq 0x10(%rax), %rsi
leaq 0x40(%rsp), %rdi
movq 0x28(%rsp), %rdx
callq 0xcec9
movl 0x40(%rsp), %r14d
movq 0x48(%rsp), %rbx
movl 0x50(%rsp), %r15d
movl 0x54(%rsp), %r12d
movq 0x58(%rsp), %r13
movq 0x60(%rsp), %rbp
movl %r14d, %eax
andl $-0x2, %eax
cmpl $0x8, %eax
je 0x123d0
movq 0x88(%rsp), %rax
movq 0x10(%rax), %rsi
leaq 0x40(%rsp), %rdi
leaq 0x402f(%rip), %rdx      # 0x16142
callq 0xcec9
movq 0x60(%rsp), %rax
movq %rax, 0xa0(%rsp)
movups 0x40(%rsp), %xmm0
movups 0x50(%rsp), %xmm1
movaps %xmm1, 0x90(%rsp)
movaps %xmm0, 0x80(%rsp)
cmpl $0x0, 0x80(%rsp)
jne 0x120b3
jmp 0x123d0
movq %rsi, 0x38(%rsp)
leaq 0x20(%rsi), %r13
leal -0xa(%r14), %eax
cmpl $-0x3, %eax
jbe 0x123e5
xorps %xmm0, %xmm0
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
movq $0x0, 0x60(%rsp)
cmpl $0x8, %r14d
je 0x12296
cmpl $0x9, %r14d
jne 0x1243b
movl 0x28(%r15), %eax
movl %eax, %esi
shrl $0x1f, %esi
addl %eax, %esi
sarl %esi
leal -0x1(%rsi), %r14d
cmpl %ecx, %esi
jle 0x12404
cmpl $-0x1, %r12d
setne %al
cmpl %r12d, %r14d
setg %sil
andb %al, %sil
cmpb $0x1, %sil
je 0x12404
movq %rbp, 0x70(%rsp)
movq %rdx, 0x28(%rsp)
movslq %r14d, %rax
shlq $0x3, %rax
leaq (%rax,%rax,4), %rdi
callq 0x21a0
movq %rax, %r12
testq %rax, %rax
je 0x12450
movq %r12, %r13
movl %r14d, 0x7c(%rsp)
cmpl $0x4, 0x28(%r15)
movq 0x38(%rsp), %rbp
jl 0x12260
movl $0x2, %r14d
leaq 0x80(%rsp), %rbx
movq %r13, %r12
movq 0x30(%r15), %rax
movq (%rax,%r14,8), %rdx
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xdee3
movq 0xa0(%rsp), %rax
movq %rax, 0x20(%r12)
movups 0x80(%rsp), %xmm0
movups 0x90(%rsp), %xmm1
movups %xmm1, 0x10(%r12)
movups %xmm0, (%r12)
addq $0x2, %r14
movslq 0x28(%r15), %rax
decq %rax
addq $0x28, %r12
cmpq %rax, %r14
jl 0x12211
leaq 0x40(%rsp), %rdi
movq %rbp, %rsi
movl 0x7c(%rsp), %edx
movq %r13, %r12
movq %r13, %rcx
movq 0x70(%rsp), %r8
callq *0x28(%rsp)
movq %r13, %rdi
callq 0x22c0
testq %r12, %r12
movq 0x30(%rsp), %r14
jne 0x1235a
jmp 0x12376
movq %r13, 0x28(%rsp)
movq %rdx, %r12
movq %rbx, %rdi
callq 0xd863
movq %rax, %rbx
movq %r12, %rdi
callq 0x12511
testq %rax, %rax
movq 0x30(%rsp), %r14
je 0x1235a
movq %rax, %r13
movq 0x38(%rsp), %rbp
movq %rbp, %rdi
movq %r12, %rsi
movq %rbx, %rdx
movq %r15, %rcx
callq 0x12b7c
movq %rax, %r15
leaq 0x40(%rsp), %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0xdee3
cmpl $0x1, 0x20(%rbx)
jne 0x122fc
movq 0x28(%rsp), %rax
movl $0x1, (%rax)
movq (%rbx), %rdx
leaq 0x285a(%rip), %rsi      # 0x14b60
leaq 0x80(%rsp), %r12
movq %r12, %rdi
xorl %eax, %eax
callq 0x2240
leaq 0xc0(%rsp), %r13
movq %r13, %rdi
movq %rbx, %rsi
callq 0xce19
movq 0x20(%r13), %rax
movq %rax, 0x20(%rsp)
movups (%r13), %xmm0
movups 0x10(%r13), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %rbp, %rdi
movq %r12, %rsi
callq 0xd5d3
movq %r15, %rdi
callq 0x22c0
movq 0x60(%rsp), %rax
movq %rax, 0x20(%r14)
movaps 0x40(%rsp), %xmm0
movaps 0x50(%rsp), %xmm1
movups %xmm1, 0x10(%r14)
movups %xmm0, (%r14)
movq %r14, %rax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x80(%rsp), %r13
movq %r13, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xdee3
movl (%r13), %r14d
movq 0x8(%r13), %rbx
movq %rbp, %rsi
movl 0x10(%r13), %ecx
movl 0x14(%r13), %r12d
movq 0x18(%r13), %rdx
movq 0x20(%r13), %rbp
leaq 0x3d8a(%rip), %rax      # 0x1614d
movq %rax, 0x28(%rsp)
jmp 0x11fb9
xorl %r14d, %r14d
movq 0x38(%rsp), %rsi
movq %r13, %rdx
movl %r15d, %ecx
movq 0x70(%rsp), %r15
jmp 0x11fb9
movq 0x9c0c(%rip), %rax      # 0x1bff8
movq (%rax), %rdi
leaq 0x3d63(%rip), %rsi      # 0x16159
movq 0x28(%rsp), %rdx
xorl %eax, %eax
callq 0x2160
jmp 0x1241f
movq 0x9bed(%rip), %rax      # 0x1bff8
movq (%rax), %rdi
leaq 0x2715(%rip), %rsi      # 0x14b2a
movl %r14d, %edx
xorl %eax, %eax
callq 0x2160
movl $0x1, (%r13)
xorps %xmm0, %xmm0
movq 0x30(%rsp), %rax
movups %xmm0, (%rax)
movups %xmm0, 0x10(%rax)
jmp 0x11fd2
movq %r13, %rdi
movq 0x30(%rsp), %r14
movq %r14, %rsi
callq 0x2973
jmp 0x12376
movq %r13, %rdi
movq 0x30(%rsp), %rsi
callq 0x292f
jmp 0x12283