// File: pranavmodx[P]modlang/src/evaluator.cpp
// Function: Evaluator::evalCallExpression(Object*, std::vector<Object*, std::allocator<Object*>>&)
Object *Evaluator::evalCallExpression(Object *fn, std::vector<Object *> &args)
{
	if (fn->type() != FUNCTION_OBJ && fn->type() != BUILTIN_OBJ)
		return new Error("error: not a function -> " + fn->type());

	if (fn->type() == BUILTIN_OBJ)
		return ((Builtin *)fn)->function(args);

	if (((Function *)fn)->parameters.size() != args.size())
		return new Error(
			"error: argument length (" + std::to_string(args.size()) +
			") not equal to parameter length (" + std::to_string(((Function *)fn)->parameters.size()) + ")");

	Environment *extendedEnv = extendFunctionEnv((Function *)fn, args, ((Function *)fn)->env);

	Object *evaluated = Eval(((Function *)fn)->body, extendedEnv);

	if (evaluated->type() == RETURN_VALUE_OBJ)
		return ((ReturnValue *)evaluated)->value;

	return evaluated;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x210, %rsp            # imm = 0x210
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1e0(%rbp)
movq -0x18(%rbp), %rsi
movq (%rsi), %rax
leaq -0x40(%rbp), %rdi
callq *(%rax)
leaq -0x40(%rbp), %rdi
leaq 0x32af6(%rip), %rsi     # 0x67280
callq 0x22d80
movb %al, %cl
movb $0x0, -0x6d(%rbp)
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1d1(%rbp)
jne 0x347a4
jmp 0x347d0
movq -0x18(%rbp), %rsi
movq (%rsi), %rax
movq (%rax), %rax
leaq -0x60(%rbp), %rdi
callq *%rax
jmp 0x347b6
movb $0x1, -0x6d(%rbp)
leaq -0x60(%rbp), %rdi
leaq 0x32bfb(%rip), %rsi     # 0x673c0
callq 0x22d80
movb %al, -0x1d1(%rbp)
movb -0x1d1(%rbp), %al
movb %al, -0x1e1(%rbp)
testb $0x1, -0x6d(%rbp)
jne 0x347e4
jmp 0x347ed
leaq -0x60(%rbp), %rdi
callq 0x5518
leaq -0x40(%rbp), %rdi
callq 0x5518
movb -0x1e1(%rbp), %al
testb $0x1, %al
jne 0x34805
jmp 0x3490d
movl $0x28, %edi
callq 0x52a0
movq %rax, -0x1f0(%rbp)
movb $0x1, -0xb1(%rbp)
movq -0x18(%rbp), %rsi
movq (%rsi), %rax
movq (%rax), %rax
leaq -0xb0(%rbp), %rdi
callq *%rax
jmp 0x34832
leaq 0x114f9(%rip), %rsi     # 0x45d32
leaq -0x90(%rbp), %rdi
leaq -0xb0(%rbp), %rdx
callq 0x1bde0
jmp 0x3484e
movq -0x1f0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x2b980
jmp 0x34863
movq -0x1f0(%rbp), %rax
movb $0x0, -0xb1(%rbp)
movq %rax, -0x8(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x5518
leaq -0xb0(%rbp), %rdi
callq 0x5518
jmp 0x34c3d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x5518
jmp 0x34c4a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x348ec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x348e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x5518
leaq -0xb0(%rbp), %rdi
callq 0x5518
testb $0x1, -0xb1(%rbp)
jne 0x348f7
jmp 0x34908
movq -0x1f0(%rbp), %rdi
movl $0x28, %esi
callq 0x52b0
jmp 0x34c4a
movq -0x18(%rbp), %rsi
movq (%rsi), %rax
leaq -0xd8(%rbp), %rdi
callq *(%rax)
leaq -0xd8(%rbp), %rdi
leaq 0x32a95(%rip), %rsi     # 0x673c0
callq 0x16920
movb %al, -0x1f1(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x5518
movb -0x1f1(%rbp), %al
testb $0x1, %al
jne 0x3494e
jmp 0x34965
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x20(%rbp), %rdi
callq *%rax
movq %rax, -0x8(%rbp)
jmp 0x34c3d
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
callq 0x1bf10
movq %rax, -0x200(%rbp)
movq -0x20(%rbp), %rdi
callq 0x373f0
movq %rax, %rcx
movq -0x200(%rbp), %rax
cmpq %rcx, %rax
je 0x34b98
movl $0x28, %edi
callq 0x52a0
movq %rax, -0x208(%rbp)
movb $0x1, -0x199(%rbp)
movq -0x20(%rbp), %rdi
callq 0x373f0
movq %rax, %rsi
leaq -0x178(%rbp), %rdi
callq 0x37410
jmp 0x349c7
leaq 0x10f4b(%rip), %rsi     # 0x45919
leaq -0x158(%rbp), %rdi
leaq -0x178(%rbp), %rdx
callq 0x1bde0
jmp 0x349e3
leaq 0x11362(%rip), %rdx     # 0x45d4c
leaq -0x138(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0x1bb10
jmp 0x349ff
movq -0x18(%rbp), %rdi
addq $0x8, %rdi
callq 0x1bf10
movq %rax, %rsi
leaq -0x198(%rbp), %rdi
callq 0x37410
jmp 0x34a1d
leaq -0x118(%rbp), %rdi
leaq -0x138(%rbp), %rsi
leaq -0x198(%rbp), %rdx
callq 0x1bb80
jmp 0x34a39
leaq 0x11246(%rip), %rdx     # 0x45c86
leaq -0xf8(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x1bb10
jmp 0x34a55
movq -0x208(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x2b980
jmp 0x34a6a
movq -0x208(%rbp), %rax
movb $0x0, -0x199(%rbp)
movq %rax, -0x8(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x5518
leaq -0x118(%rbp), %rdi
callq 0x5518
leaq -0x198(%rbp), %rdi
callq 0x5518
leaq -0x138(%rbp), %rdi
callq 0x5518
leaq -0x158(%rbp), %rdi
callq 0x5518
leaq -0x178(%rbp), %rdi
callq 0x5518
jmp 0x34c3d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x34b77
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x34b6b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x34b5f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x34b53
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x34b47
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x34b3b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x5518
leaq -0x118(%rbp), %rdi
callq 0x5518
leaq -0x198(%rbp), %rdi
callq 0x5518
leaq -0x138(%rbp), %rdi
callq 0x5518
leaq -0x158(%rbp), %rdi
callq 0x5518
leaq -0x178(%rbp), %rdi
callq 0x5518
testb $0x1, -0x199(%rbp)
jne 0x34b82
jmp 0x34b93
movq -0x208(%rbp), %rdi
movl $0x28, %esi
callq 0x52b0
jmp 0x34c4a
movq -0x1e0(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rcx
callq 0x36b00
movq -0x1e0(%rbp), %rdi
movq %rax, -0x1a8(%rbp)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rsi
movq -0x1a8(%rbp), %rdx
callq 0x32080
movq %rax, -0x1b0(%rbp)
movq -0x1b0(%rbp), %rsi
movq (%rsi), %rax
leaq -0x1d0(%rbp), %rdi
callq *(%rax)
leaq -0x1d0(%rbp), %rdi
leaq 0x327a2(%rip), %rsi     # 0x673a0
callq 0x16920
movb %al, -0x209(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x5518
movb -0x209(%rbp), %al
testb $0x1, %al
jne 0x34c21
jmp 0x34c32
movq -0x1b0(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x34c3d
movq -0x1b0(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x210, %rsp            # imm = 0x210
popq %rbp
retq
movq -0x68(%rbp), %rdi
callq 0x5490
nopw %cs:(%rax,%rax)