// File: /workspace/github_c_makefile_star2_O2/hoobaa[P]ficl/dictionary.c
// Function: ficlDictionarySee
void ficlDictionarySee(ficlDictionary *dictionary, ficlWord *word, ficlCallback *callback)
{
    char *trace;
    ficlCell *cell = word->param;
    ficlCell *param0 = cell;
    char buffer[128];

    for (; cell->i != ficlInstructionSemiParen; cell++)
    {
        ficlWord *word = (ficlWord *)(cell->p);

        trace = buffer;
        if ((void *)cell == (void *)buffer)
            *trace++ = '>';
        else
            *trace++ = ' ';
        trace += sprintf(trace, "%3d   ", cell - param0);
        
        if (ficlDictionaryIsAWord(dictionary, word))
        {
            ficlWordKind kind = ficlWordClassify(word);
            ficlCell c, c2;

            switch (kind)
            {
            case FICL_WORDKIND_INSTRUCTION:
                sprintf(trace, "%s (instruction %ld)", ficlDictionaryInstructionNames[(long)word], (long)word);
                break;
            case FICL_WORDKIND_INSTRUCTION_WITH_ARGUMENT:
                c = *++cell;
                sprintf(trace, "%s (instruction %ld), with argument %ld (%#lx)", ficlDictionaryInstructionNames[(long)word], (long)word, c.i, c.u);
                break;
            case FICL_WORDKIND_INSTRUCTION_WORD:
                sprintf(trace, "%s :: executes %s (instruction word %ld)", word->name, ficlDictionaryInstructionNames[(long)word->code], (long)word->code);
                break;
            case FICL_WORDKIND_LITERAL:
                c = *++cell;
                if (ficlDictionaryIsAWord(dictionary, c.p) && (c.i >= ficlInstructionLast))
                {
                    ficlWord *word = (ficlWord *)c.p;
                    sprintf(trace, "%.*s ( %#lx literal )", 
                        word->length, word->name, c.u);
                }
                else
                    sprintf(trace, "literal %ld (%#lx)", c.i, c.u);
                break;
            case FICL_WORDKIND_2LITERAL:
                c = *++cell;
                c2 = *++cell;
                sprintf(trace, "2literal %d %d (%#lx %#lx)", c2.i, c.i, c2.u, c.u);
                break;
#if FICL_WANT_FLOAT
            case FICL_WORDKIND_FLITERAL:
                c = *++cell;
                sprintf(trace, "fliteral %f (%#lx)", c.f, c.u);
                break;
#endif /* FICL_WANT_FLOAT */
            case FICL_WORDKIND_STRING_LITERAL:
                {
                    ficlCountedString *counted = (ficlCountedString *)(void *)++cell;
                    cell = (ficlCell *)ficlAlignPointer(counted->text + counted->length + 1) - 1;
                    sprintf(trace, "s\" %.*s\"", counted->length, counted->text);
                }
                break;
            case FICL_WORDKIND_CSTRING_LITERAL:
                {
                    ficlCountedString *counted = (ficlCountedString *)(void *)++cell;
                    cell = (ficlCell *)ficlAlignPointer(counted->text + counted->length + 1) - 1;
                    sprintf(trace, "c\" %.*s\"", counted->length, counted->text);
                }
                break;
            case FICL_WORDKIND_BRANCH0:
                c = *++cell;
                sprintf(trace, "branch0 %d", cell + c.i - param0);
                break;                                                           
            case FICL_WORDKIND_BRANCH:
                c = *++cell;
                sprintf(trace, "branch %d",     cell + c.i - param0);
                break;

            case FICL_WORDKIND_QDO:
                c = *++cell;
                sprintf(trace, "?do (leave %d)",  (ficlCell *)c.p - param0);
                break;
            case FICL_WORDKIND_DO:
                c = *++cell;
                sprintf(trace, "do (leave %d)", (ficlCell *)c.p - param0);
                break;
            case FICL_WORDKIND_LOOP:
                c = *++cell;
                sprintf(trace, "loop (branch %d)", cell + c.i - param0);
                break;
            case FICL_WORDKIND_OF:
                c = *++cell;
                sprintf(trace, "of (branch %d)",      cell + c.i - param0);
                break;
            case FICL_WORDKIND_PLOOP:
                c = *++cell;
                sprintf(trace, "+loop (branch %d)", cell + c.i - param0);
                break;
            default:
                sprintf(trace, "%.*s", word->length, word->name);
                break;
            }
 
        }
        else /* probably not a word - punt and print value */
        {
            sprintf(trace, "%ld ( %#lx )", cell->i, cell->u);
        }

        ficlCallbackTextOut(callback, buffer);
        ficlCallbackTextOut(callback, "\n");
    }

    ficlCallbackTextOut(callback, ";\n");
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, 0x8(%rsp)
addq $0x28, %r14
leaq 0x10(%rsp), %r15
movq %r14, (%rsp)
movq (%r14), %r12
cmpq $0x2b, %r12
je 0xc22d
movq %r15, %r13
cmpq %r15, %r14
pushq $0x20
popq %rax
pushq $0x3e
popq %rcx
cmovel %ecx, %eax
movb %al, 0x10(%rsp)
movq %r14, %rdx
subq (%rsp), %rdx
sarq $0x3, %rdx
leaq 0x11(%rsp), %r15
movq %r15, %rdi
leaq 0x3783(%rip), %rsi      # 0xf66e
xorl %eax, %eax
callq 0x32f0
movslq %eax, %rbp
addq %r15, %rbp
movq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0xbd80
testl %eax, %eax
je 0xbf56
movq %r12, %rdi
callq 0xb28e
cmpl $0x16, %eax
movq %r13, %r15
ja 0xc06b
movl %eax, %eax
leaq 0x3686(%rip), %rcx      # 0xf5ac
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x8(%r14), %r12
movq 0x8(%r14), %rax
leaq (%r14,%rax,8), %rdx
addq $0x8, %rdx
subq (%rsp), %rdx
sarq $0x3, %rdx
movq %rbp, %rdi
leaq 0x3805(%rip), %rsi      # 0xf756
jmp 0xc1e7
movq (%r14), %rcx
movq %rbp, %rdi
leaq 0x3832(%rip), %rsi      # 0xf795
movq %rcx, %rdx
xorl %eax, %eax
callq 0x32f0
movq %r13, %r15
jmp 0xc1f1
movq 0x10(%r12), %rdx
movq 0x18(%r12), %r8
leaq 0xcf6a(%rip), %rax      # 0x18ef0
movq (%rax,%r8,8), %rcx
movq %rbp, %rdi
leaq 0x3725(%rip), %rsi      # 0xf6b9
xorl %eax, %eax
callq 0x32f0
jmp 0xc1f1
leaq 0x9(%r14), %r13
movzbl 0x8(%r14), %eax
leaq (%r14,%rax), %rdi
addq $0xa, %rdi
callq 0xad30
movq %rax, %r12
addq $-0x8, %r12
movzbl 0x8(%r14), %edx
movq %rbp, %rdi
leaq 0x376d(%rip), %rsi      # 0xf739
jmp 0xc05c
leaq 0xcf18(%rip), %rax      # 0x18ef0
movq (%rax,%r12,8), %rdx
movq %rbp, %rdi
leaq 0x368f(%rip), %rsi      # 0xf675
jmp 0xc221
movq 0x8(%r14), %rdx
addq $0x8, %r14
subq (%rsp), %rdx
sarq $0x3, %rdx
movq %rbp, %rdi
leaq 0x375c(%rip), %rsi      # 0xf761
jmp 0xc1bc
movq 0x8(%r14), %rdx
addq $0x8, %r14
movd %edx, %xmm0
cvtss2sd %xmm0, %xmm0
movq %rbp, %rdi
leaq 0x3702(%rip), %rsi      # 0xf726
movb $0x1, %al
callq 0x32f0
jmp 0xc1f1
leaq 0x9(%r14), %r13
movzbl 0x8(%r14), %eax
leaq (%r14,%rax), %rdi
addq $0xa, %rdi
callq 0xad30
movq %rax, %r12
addq $-0x8, %r12
movzbl 0x8(%r14), %edx
movq %rbp, %rdi
leaq 0x36e6(%rip), %rsi      # 0xf742
movq %r13, %rcx
xorl %eax, %eax
callq 0x32f0
jmp 0xc1ee
movzbl 0xb(%r12), %edx
movq 0x10(%r12), %rcx
movq %rbp, %rdi
leaq 0x3710(%rip), %rsi      # 0xf790
xorl %eax, %eax
callq 0x32f0
jmp 0xc1f1
leaq 0x8(%r14), %r12
movq 0x8(%r14), %rax
leaq (%r14,%rax,8), %rdx
addq $0x8, %rdx
subq (%rsp), %rdx
sarq $0x3, %rdx
movq %rbp, %rdi
leaq 0x369d(%rip), %rsi      # 0xf74b
jmp 0xc1e7
leaq 0x8(%r14), %r12
movq 0x8(%r14), %rax
leaq (%r14,%rax,8), %rdx
addq $0x8, %rdx
subq (%rsp), %rdx
sarq $0x3, %rdx
movq %rbp, %rdi
leaq 0x36aa(%rip), %rsi      # 0xf77f
jmp 0xc1e7
leaq 0x8(%r14), %r12
movq 0x8(%r14), %rax
leaq (%r14,%rax,8), %rdx
addq $0x8, %rdx
subq (%rsp), %rdx
sarq $0x3, %rdx
movq %rbp, %rdi
leaq 0x3673(%rip), %rsi      # 0xf76f
jmp 0xc1e7
leaq 0xcde8(%rip), %rax      # 0x18ef0
movq (%rax,%r12,8), %rdx
movq 0x8(%r14), %r8
addq $0x8, %r14
movq %rbp, %rdi
leaq 0x356c(%rip), %rsi      # 0xf68a
movq %r12, %rcx
movq %r8, %r9
xorl %eax, %eax
callq 0x32f0
jmp 0xc1f1
movq 0x8(%r14), %r12
addq $0x8, %r14
movq 0x8(%rsp), %rdi
movq %r12, %rsi
callq 0xbd80
testl %eax, %eax
sete %al
cmpq $0xb4, %r12
setl %cl
orb %al, %cl
jne 0xc214
movzbl 0xb(%r12), %edx
movq 0x10(%r12), %rcx
movq %rbp, %rdi
leaq 0x3571(%rip), %rsi      # 0xf6e2
movq %r12, %r8
xorl %eax, %eax
callq 0x32f0
jmp 0xc1f1
leaq 0x10(%r14), %r12
movq 0x8(%r14), %rcx
movq 0x10(%r14), %rdx
movq %rbp, %rdi
leaq 0x3578(%rip), %rsi      # 0xf70b
movq %rdx, %r8
movq %rcx, %r9
xorl %eax, %eax
callq 0x32f0
jmp 0xc1ee
movq 0x8(%r14), %rdx
addq $0x8, %r14
subq (%rsp), %rdx
sarq $0x3, %rdx
movq %rbp, %rdi
leaq 0x35a4(%rip), %rsi      # 0xf760
xorl %eax, %eax
callq 0x32f0
jmp 0xc1f1
leaq 0x8(%r14), %r12
movq 0x8(%r14), %rax
leaq (%r14,%rax,8), %rdx
addq $0x8, %rdx
subq (%rsp), %rdx
sarq $0x3, %rdx
movq %rbp, %rdi
leaq 0x3597(%rip), %rsi      # 0xf77e
xorl %eax, %eax
callq 0x32f0
movq %r12, %r14
movq %rbx, %rdi
movq %r15, %rsi
callq 0xb1ac
movq %rbx, %rdi
leaq 0x2163(%rip), %rsi      # 0xe369
callq 0xb1ac
addq $0x8, %r14
jmp 0xbeb1
movq %rbp, %rdi
leaq 0x34da(%rip), %rsi      # 0xf6f8
movq %r12, %rdx
movq %r12, %rcx
xorl %eax, %eax
callq 0x32f0
jmp 0xc1f1
leaq 0x356e(%rip), %rsi      # 0xf7a2
movq %rbx, %rdi
callq 0xb1ac
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq