// File: /workspace/github_c_makefile_star2_O0/codeplea[P]tinyexpr/smoke.c
// Function: test_closure
void test_closure() {

    double extra;
    double c[] = {5,6,7,8,9};

    te_variable lookup[] = {
        {"c0", clo0, TE_CLOSURE0, &extra},
        {"c1", clo1, TE_CLOSURE1, &extra},
        {"c2", clo2, TE_CLOSURE2, &extra},
        {"cell", cell, TE_CLOSURE1, c},
    };

    test_case cases[] = {
        {"c0", 6},
        {"c1 4", 8},
        {"c2 (10, 20)", 30},
    };

    int i;
    for (i = 0; i < sizeof(cases) / sizeof(test_case); ++i) {
        const char *expr = cases[i].expr;
        const double answer = cases[i].answer;

        int err;
        te_expr *ex = te_compile(expr, lookup, sizeof(lookup)/sizeof(te_variable), &err);
        lok(ex);

        extra = 0;
        lfequal(te_eval(ex), answer + extra);

        extra = 10;
        lfequal(te_eval(ex), answer + extra);

        te_free(ex);
    }


    test_case cases2[] = {
        {"cell 0", 5},
        {"cell 1", 6},
        {"cell 0 + cell 1", 11},
        {"cell 1 * cell 3 + cell 4", 57},
    };

    for (i = 0; i < sizeof(cases2) / sizeof(test_case); ++i) {
        const char *expr = cases2[i].expr;
        const double answer = cases2[i].answer;

        int err;
        te_expr *ex = te_compile(expr, lookup, sizeof(lookup)/sizeof(te_variable), &err);
        lok(ex);
        lfequal(te_eval(ex), answer);
        te_free(ex);
    }
}

// Assembly:
subq $0x198, %rsp            # imm = 0x198
leaq 0x160(%rsp), %rdi
xorl %esi, %esi
movl $0x28, %edx
callq 0x3090
movsd 0x45e5(%rip), %xmm0     # 0xb028
movsd %xmm0, 0x160(%rsp)
movsd 0x45fc(%rip), %xmm0     # 0xb050
movsd %xmm0, 0x168(%rsp)
movsd 0x4603(%rip), %xmm0     # 0xb068
movsd %xmm0, 0x170(%rsp)
movsd 0x45ea(%rip), %xmm0     # 0xb060
movsd %xmm0, 0x178(%rsp)
movsd 0x45d1(%rip), %xmm0     # 0xb058
movsd %xmm0, 0x180(%rsp)
leaq 0x4c2f(%rip), %rax      # 0xb6c6
movq %rax, 0xe0(%rsp)
leaq -0x196(%rip), %rax      # 0x6910
movq %rax, 0xe8(%rsp)
movl $0x10, 0xf0(%rsp)
leaq 0x190(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x4bf9(%rip), %rax      # 0xb6c9
movq %rax, 0x100(%rsp)
leaq -0x18f(%rip), %rax      # 0x6950
movq %rax, 0x108(%rsp)
movl $0x11, 0x110(%rsp)
leaq 0x190(%rsp), %rax
movq %rax, 0x118(%rsp)
leaq 0x4bc3(%rip), %rax      # 0xb6cc
movq %rax, 0x120(%rsp)
leaq -0x178(%rip), %rax      # 0x69a0
movq %rax, 0x128(%rsp)
movl $0x12, 0x130(%rsp)
leaq 0x190(%rsp), %rax
movq %rax, 0x138(%rsp)
leaq 0x4b8d(%rip), %rax      # 0xb6cf
movq %rax, 0x140(%rsp)
leaq -0x161(%rip), %rax      # 0x69f0
movq %rax, 0x148(%rsp)
movl $0x11, 0x150(%rsp)
leaq 0x160(%rsp), %rax
movq %rax, 0x158(%rsp)
leaq 0xb0(%rsp), %rdi
leaq 0x7c7d(%rip), %rsi      # 0xe800
movl $0x30, %edx
callq 0x30e0
movl $0x0, 0xac(%rsp)
movslq 0xac(%rsp), %rax
cmpq $0x3, %rax
jae 0x6e12
movslq 0xac(%rsp), %rcx
leaq 0xb0(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movq %rax, 0xa0(%rsp)
movslq 0xac(%rsp), %rcx
leaq 0xb0(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x98(%rsp)
movq 0xa0(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
movl $0x4, %edx
leaq 0x94(%rsp), %rcx
callq 0x8ff0
movq %rax, 0x88(%rsp)
movl 0x84db(%rip), %eax      # 0xf0fc
addl $0x1, %eax
movl %eax, 0x84d2(%rip)      # 0xf0fc
cmpq $0x0, 0x88(%rsp)
jne 0x6c5e
movl 0x84c5(%rip), %eax      # 0xf100
addl $0x1, %eax
movl %eax, 0x84bc(%rip)      # 0xf100
leaq 0x4762(%rip), %rdi      # 0xb3ad
leaq 0x4769(%rip), %rsi      # 0xb3bb
movl $0x205, %edx            # imm = 0x205
movb $0x0, %al
callq 0x3080
jmp 0x6c60
xorps %xmm0, %xmm0
movsd %xmm0, 0x190(%rsp)
movl 0x848a(%rip), %eax      # 0xf0fc
addl $0x1, %eax
movl %eax, 0x8481(%rip)      # 0xf0fc
movq 0x88(%rsp), %rdi
callq 0x8450
movsd 0x98(%rsp), %xmm1
addsd 0x190(%rsp), %xmm1
subsd %xmm1, %xmm0
movaps 0x43db(%rip), %xmm1     # 0xb080
pand %xmm1, %xmm0
movsd %xmm0, 0x80(%rsp)
movsd 0x80(%rsp), %xmm0
movsd 0x4345(%rip), %xmm1     # 0xb008
ucomisd %xmm1, %xmm0
ja 0x6ce1
movsd 0x80(%rsp), %xmm0
ucomisd 0x80(%rsp), %xmm0
jne 0x6ce1
jp 0x6ce1
jmp 0x6d29
movl 0x8419(%rip), %eax      # 0xf100
addl $0x1, %eax
movl %eax, 0x8410(%rip)      # 0xf100
movq 0x88(%rsp), %rdi
callq 0x8450
movsd 0x98(%rsp), %xmm1
addsd 0x190(%rsp), %xmm1
leaq 0x46ad(%rip), %rdi      # 0xb3c3
leaq 0x469e(%rip), %rsi      # 0xb3bb
movl $0x208, %edx            # imm = 0x208
movb $0x2, %al
callq 0x3080
jmp 0x6d2b
movsd 0x433d(%rip), %xmm0     # 0xb070
movsd %xmm0, 0x190(%rsp)
movl 0x83ba(%rip), %eax      # 0xf0fc
addl $0x1, %eax
movl %eax, 0x83b1(%rip)      # 0xf0fc
movq 0x88(%rsp), %rdi
callq 0x8450
movsd 0x98(%rsp), %xmm1
addsd 0x190(%rsp), %xmm1
subsd %xmm1, %xmm0
movaps 0x430b(%rip), %xmm1     # 0xb080
pand %xmm1, %xmm0
movsd %xmm0, 0x78(%rsp)
movsd 0x78(%rsp), %xmm0
movsd 0x427b(%rip), %xmm1     # 0xb008
ucomisd %xmm1, %xmm0
ja 0x6da5
movsd 0x78(%rsp), %xmm0
ucomisd 0x78(%rsp), %xmm0
jne 0x6da5
jp 0x6da5
jmp 0x6ded
movl 0x8355(%rip), %eax      # 0xf100
addl $0x1, %eax
movl %eax, 0x834c(%rip)      # 0xf100
movq 0x88(%rsp), %rdi
callq 0x8450
movsd 0x98(%rsp), %xmm1
addsd 0x190(%rsp), %xmm1
leaq 0x45e9(%rip), %rdi      # 0xb3c3
leaq 0x45da(%rip), %rsi      # 0xb3bb
movl $0x20b, %edx            # imm = 0x20B
movb $0x2, %al
callq 0x3080
jmp 0x6def
movq 0x88(%rsp), %rdi
callq 0x7e40
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x6b98
leaq 0x30(%rsp), %rdi
leaq 0x7a12(%rip), %rsi      # 0xe830
movl $0x40, %edx
callq 0x30e0
movl $0x0, 0xac(%rsp)
movslq 0xac(%rsp), %rax
cmpq $0x4, %rax
jae 0x6f96
movslq 0xac(%rsp), %rcx
leaq 0x30(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movq %rax, 0x28(%rsp)
movslq 0xac(%rsp), %rcx
leaq 0x30(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movq 0x28(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
movl $0x4, %edx
leaq 0x1c(%rsp), %rcx
callq 0x8ff0
movq %rax, 0x10(%rsp)
movl 0x8255(%rip), %eax      # 0xf0fc
addl $0x1, %eax
movl %eax, 0x824c(%rip)      # 0xf0fc
cmpq $0x0, 0x10(%rsp)
jne 0x6ee1
movl 0x8242(%rip), %eax      # 0xf100
addl $0x1, %eax
movl %eax, 0x8239(%rip)      # 0xf100
leaq 0x44df(%rip), %rdi      # 0xb3ad
leaq 0x44e6(%rip), %rsi      # 0xb3bb
movl $0x21e, %edx            # imm = 0x21E
movb $0x0, %al
callq 0x3080
jmp 0x6ee3
jmp 0x6ee5
movl 0x8211(%rip), %eax      # 0xf0fc
addl $0x1, %eax
movl %eax, 0x8208(%rip)      # 0xf0fc
movq 0x10(%rsp), %rdi
callq 0x8450
subsd 0x20(%rsp), %xmm0
movaps 0x4175(%rip), %xmm1     # 0xb080
pand %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8(%rsp), %xmm0
movsd 0x40e5(%rip), %xmm1     # 0xb008
ucomisd %xmm1, %xmm0
ja 0x6f3b
movsd 0x8(%rsp), %xmm0
ucomisd 0x8(%rsp), %xmm0
jne 0x6f3b
jp 0x6f3b
jmp 0x6f74
movl 0x81bf(%rip), %eax      # 0xf100
addl $0x1, %eax
movl %eax, 0x81b6(%rip)      # 0xf100
movq 0x10(%rsp), %rdi
callq 0x8450
movsd 0x20(%rsp), %xmm1
leaq 0x4462(%rip), %rdi      # 0xb3c3
leaq 0x4453(%rip), %rsi      # 0xb3bb
movl $0x21f, %edx            # imm = 0x21F
movb $0x2, %al
callq 0x3080
jmp 0x6f76
movq 0x10(%rsp), %rdi
callq 0x7e40
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0x6e33
addq $0x198, %rsp            # imm = 0x198
retq
nop