// File: /workspace/github_c_makefile_star2_O1/janet-lang[P]janet/src/core/peg.c
// Function: peg_compile1
static uint32_t peg_compile1(Builder *b, Janet peg) {

    /* Keep track of the form being compiled for error purposes */
    Janet old_form = b->form;
    JanetTable *old_grammar = b->grammar;
    b->form = peg;

    /* Resolve keyword references */
    int i = JANET_RECURSION_GUARD;
    JanetTable *grammar = old_grammar;
    for (; i > 0 && janet_checktype(peg, JANET_KEYWORD); --i) {
        Janet nextPeg = janet_table_get_ex(grammar, peg, &grammar);
        if (!grammar || janet_checktype(nextPeg, JANET_NIL)) {
            nextPeg = (b->default_grammar == NULL)
                      ? janet_wrap_nil()
                      : janet_table_get(b->default_grammar, peg);
            if (janet_checktype(nextPeg, JANET_NIL)) {
                peg_panic(b, "unknown rule");
            }
        }
        peg = nextPeg;
        b->form = peg;
        b->grammar = grammar;
    }
    if (i == 0)
        peg_panic(b, "reference chain too deep");

    /* Check cache - for tuples we check only the local cache, as
     * in a different grammar, the same tuple can compile to a different
     * rule - for example, (+ :a :b) depends on whatever :a and :b are bound to. */
    Janet check = janet_checktype(peg, JANET_TUPLE)
                  ? janet_table_rawget(grammar, peg)
                  : janet_table_get(grammar, peg);
    if (!janet_checktype(check, JANET_NIL)) {
        b->form = old_form;
        b->grammar = old_grammar;
        return (uint32_t) janet_unwrap_number(check);
    }

    /* Check depth */
    if (b->depth-- == 0)
        peg_panic(b, "peg grammar recursed too deeply");

    /* The final rule to return */
    uint32_t rule = janet_v_count(b->bytecode);

    /* Add to cache. Do not cache structs, as we don't yet know
     * what rule they will return! We can just as effectively cache
     * the structs main rule. */
    if (!janet_checktype(peg, JANET_STRUCT)) {
        JanetTable *which_grammar = grammar;
        /* If we are a primitive pattern, add to the global cache (root grammar table) */
        if (!janet_checktype(peg, JANET_TUPLE)) {
            while (which_grammar->proto)
                which_grammar = which_grammar->proto;
        }
        janet_table_put(which_grammar, peg, janet_wrap_number(rule));
    }

    switch (janet_type(peg)) {
        default:
            peg_panic(b, "unexpected peg source");
            return 0;

        case JANET_BOOLEAN: {
            int n = janet_unwrap_boolean(peg);
            Reserve r = reserve(b, 2);
            emit_1(r, n ? RULE_NCHAR : RULE_NOTNCHAR, 0);
            break;
        }
        case JANET_NUMBER: {
            int32_t n = peg_getinteger(b, peg);
            Reserve r = reserve(b, 2);
            if (n < 0) {
                emit_1(r, RULE_NOTNCHAR, -n);
            } else {
                emit_1(r, RULE_NCHAR, n);
            }
            break;
        }
        case JANET_STRING: {
            const uint8_t *str = janet_unwrap_string(peg);
            int32_t len = janet_string_length(str);
            emit_bytes(b, RULE_LITERAL, len, str);
            break;
        }
        case JANET_BUFFER: {
            const JanetBuffer *buf = janet_unwrap_buffer(peg);
            emit_bytes(b, RULE_LITERAL, buf->count, buf->data);
            break;
        }
        case JANET_TABLE: {
            /* Build grammar table */
            JanetTable *new_grammar = janet_table_clone(janet_unwrap_table(peg));
            new_grammar->proto = grammar;
            b->grammar = grammar = new_grammar;
            /* Run the main rule */
            Janet main_rule = janet_table_rawget(grammar, janet_ckeywordv("main"));
            if (janet_checktype(main_rule, JANET_NIL))
                peg_panic(b, "grammar requires :main rule");
            rule = peg_compile1(b, main_rule);
            break;
        }
        case JANET_STRUCT: {
            /* Build grammar table */
            const JanetKV *st = janet_unwrap_struct(peg);
            JanetTable *new_grammar = janet_table(2 * janet_struct_capacity(st));
            for (int32_t i = 0; i < janet_struct_capacity(st); i++) {
                if (janet_checktype(st[i].key, JANET_KEYWORD)) {
                    janet_table_put(new_grammar, st[i].key, st[i].value);
                }
            }
            new_grammar->proto = grammar;
            b->grammar = grammar = new_grammar;
            /* Run the main rule */
            Janet main_rule = janet_table_rawget(grammar, janet_ckeywordv("main"));
            if (janet_checktype(main_rule, JANET_NIL))
                peg_panic(b, "grammar requires :main rule");
            rule = peg_compile1(b, main_rule);
            break;
        }
        case JANET_TUPLE: {
            const Janet *tup = janet_unwrap_tuple(peg);
            int32_t len = janet_tuple_length(tup);
            if (len == 0) peg_panic(b, "tuple in grammar must have non-zero length");
            if (janet_checkint(tup[0])) {
                int32_t n = janet_unwrap_integer(tup[0]);
                if (n < 0) {
                    peg_panicf(b, "expected non-negative integer, got %d", n);
                }
                spec_repeat(b, len, tup);
                break;
            }
            if (!janet_checktype(tup[0], JANET_SYMBOL))
                peg_panicf(b, "expected grammar command, found %v", tup[0]);
            const uint8_t *sym = janet_unwrap_symbol(tup[0]);
            const SpecialPair *sp = janet_strbinsearch(
                                        &peg_specials,
                                        sizeof(peg_specials) / sizeof(SpecialPair),
                                        sizeof(SpecialPair),
                                        sym);
            if (sp) {
                sp->special(b, len - 1, tup + 1);
            } else {
                peg_panicf(b, "unknown special %S", sym);
            }
            break;
        }
    }

    /* Increase depth again */
    b->depth++;
    b->form = old_form;
    b->grammar = old_grammar;
    return rule;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %rbx
movabsq $-0x800000000000, %r13  # imm = 0xFFFF800000000000
movabsq $-0x5000000000000, %rdx # imm = 0xFFFB000000000000
movabsq $-0x7800000000000, %rcx # imm = 0xFFF8800000000000
movq (%rdi), %r15
movq 0x28(%rdi), %rax
movq %rax, -0x38(%rbp)
movq %rdi, -0x30(%rbp)
movq %rsi, 0x28(%rdi)
movq %r15, -0x40(%rbp)
movq %rsi, %r14
andq %r13, %r14
cmpq %rdx, %r14
movq %r15, -0x50(%rbp)
jne 0x3d36b
movl $0x400, %r15d           # imm = 0x400
leaq 0x1(%rcx), %rax
movq %rax, -0x58(%rbp)
movq %rbx, %r12
movq -0x40(%rbp), %rdi
movq %r12, %rsi
leaq -0x40(%rbp), %rdx
callq 0x4800c
cmpq $0x0, -0x40(%rbp)
movq -0x30(%rbp), %r14
je 0x3d2f7
movq %rax, %rbx
andq %r13, %rax
movabsq $-0x7800000000000, %rcx # imm = 0xFFF8800000000000
cmpq %rcx, %rax
jne 0x3d32c
movq 0x8(%r14), %rdi
testq %rdi, %rdi
je 0x3d30a
movq %r12, %rsi
callq 0x47f51
jmp 0x3d313
movq -0x58(%rbp), %rdi
callq 0x4f95a
movq %rax, %rbx
andq %r13, %rax
movabsq $-0x7800000000000, %rcx # imm = 0xFFF8800000000000
cmpq %rcx, %rax
je 0x3d743
movq %rbx, 0x28(%r14)
movq -0x40(%rbp), %rax
movq %rax, (%r14)
leal -0x1(%r15), %eax
movq %rbx, %r14
andq %r13, %r14
cmpl $0x2, %r15d
jb 0x3d360
movq %rbx, %r12
movl %eax, %r15d
movabsq $-0x5000000000000, %rcx # imm = 0xFFFB000000000000
cmpq %rcx, %r14
je 0x3d2c7
testl %eax, %eax
sete %al
movq -0x50(%rbp), %r15
jmp 0x3d36d
xorl %eax, %eax
testb %al, %al
jne 0x3d752
movabsq $-0x4000000000000, %r12 # imm = 0xFFFC000000000000
movq -0x40(%rbp), %rdi
movq %rbx, %rsi
cmpq %r12, %r14
jne 0x3d392
callq 0x480d2
jmp 0x3d397
callq 0x47f51
movq %rax, %rcx
andq %r13, %rcx
movabsq $-0x7800000000000, %rdx # imm = 0xFFF8800000000000
cmpq %rdx, %rcx
jne 0x3d3c9
movq -0x30(%rbp), %rdi
subl $0x1, 0x30(%rdi)
jb 0x3d762
movq 0x20(%rdi), %rax
testq %rax, %rax
je 0x3d3e7
movl -0x4(%rax), %r15d
jmp 0x3d3ea
movq -0x30(%rbp), %rcx
movq -0x38(%rbp), %rdx
movq %rdx, 0x28(%rcx)
movq %r15, (%rcx)
movq %rax, %xmm0
cvttsd2si %xmm0, %r15
jmp 0x3d731
xorl %r15d, %r15d
movabsq $-0x3000000000000, %rax # imm = 0xFFFD000000000000
cmpq %rax, %r14
je 0x3d42e
movq -0x40(%rbp), %rax
cmpq %r12, %r14
jne 0x3d407
movq %rax, %r12
jmp 0x3d413
movq %rax, %r12
movq 0x28(%rax), %rax
testq %rax, %rax
jne 0x3d407
movl %r15d, %eax
cvtsi2sd %rax, %xmm0
callq 0x4fab8
movq %r12, %rdi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x481b3
movq %rbx, %xmm0
movq %rbx, %rcx
shrq $0x2f, %rcx
andl $0xf, %ecx
xorl %eax, %eax
ucomisd %xmm0, %xmm0
cmovpl %ecx, %eax
cmpl $0xb, %eax
ja 0x3d76e
leaq 0x2b486(%rip), %rcx     # 0x688dc
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x30(%rbp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x3d8b0
movl %eax, %r14d
movq %r12, %rdi
movl $0x2, %esi
callq 0x3d82f
testl %r14d, %r14d
js 0x3d69c
leaq -0x44(%rbp), %r8
movl %r14d, (%r8)
movq %rax, %rdi
movq %rdx, %rsi
movl $0x1, %edx
jmp 0x3d6b1
movq %rbx, %rdi
callq 0x4f838
movq %rax, %rdi
callq 0x483b2
movq %rax, %r14
movq -0x40(%rbp), %rax
movq %rax, 0x28(%r14)
movq %r14, -0x40(%rbp)
movq -0x30(%rbp), %rbx
movq %r14, (%rbx)
leaq 0x2baaa(%rip), %rdi     # 0x68f75
callq 0x47cd3
movq %rax, %rdi
movabsq $-0x5000000000000, %rsi # imm = 0xFFFB000000000000
callq 0x4f9ad
movq %r14, %rdi
movq %rax, %rsi
callq 0x480d2
andq %rax, %r13
movabsq $-0x7800000000000, %rcx # imm = 0xFFF8800000000000
cmpq %rcx, %r13
je 0x3d777
movq %rbx, %rdi
movq %rax, %rsi
callq 0x3d25a
movl %eax, %r15d
movq %rbx, %r14
jmp 0x3d71e
movl $0x2, %r12d
movq -0x30(%rbp), %r14
movq %r14, %rdi
movl $0x2, %esi
callq 0x3d82f
andl $0x1, %ebx
subl %ebx, %r12d
leaq -0x44(%rbp), %r8
movl $0x0, (%r8)
movq %rax, %rdi
movq %rdx, %rsi
movl %r12d, %edx
movl $0x1, %ecx
callq 0x3da7a
jmp 0x3d71e
movq %rbx, %rdi
callq 0x4f838
movq %rax, %r12
movl -0x10(%rax), %edi
addl %edi, %edi
callq 0x47e96
movq %rax, %r15
cmpl $0x0, -0x10(%r12)
jle 0x3d5b8
movq %r12, %rbx
addq $0x8, %rbx
xorl %r14d, %r14d
movq -0x8(%rbx), %rsi
movq %rsi, %rax
andq %r13, %rax
movabsq $-0x5000000000000, %rcx # imm = 0xFFFB000000000000
cmpq %rcx, %rax
jne 0x3d5a7
movq (%rbx), %rdx
movq %r15, %rdi
callq 0x481b3
incq %r14
movslq -0x10(%r12), %rax
addq $0x10, %rbx
cmpq %rax, %r14
jl 0x3d583
movq -0x40(%rbp), %rax
movq %rax, 0x28(%r15)
movq %r15, -0x40(%rbp)
movq -0x30(%rbp), %r14
movq %r15, (%r14)
leaq 0x2b9a3(%rip), %rdi     # 0x68f75
callq 0x47cd3
movq %rax, %rdi
movabsq $-0x5000000000000, %rsi # imm = 0xFFFB000000000000
callq 0x4f9ad
movq %r15, %rdi
movq %rax, %rsi
callq 0x480d2
andq %rax, %r13
movabsq $-0x7800000000000, %rcx # imm = 0xFFF8800000000000
cmpq %rcx, %r13
je 0x3d786
movq %r14, %rdi
movq %rax, %rsi
callq 0x3d25a
movl %eax, %r15d
jmp 0x3d71e
movq %rbx, %rdi
callq 0x4f838
movl -0x8(%rax), %esi
movq -0x30(%rbp), %r14
movq %r14, %rdi
movq %rax, %rdx
jmp 0x3d692
movq %rbx, %rdi
callq 0x4f838
movl -0x10(%rax), %r12d
testl %r12d, %r12d
je 0x3d78f
movq %rax, %r14
movq (%rax), %rdi
callq 0x4a41f
testl %eax, %eax
je 0x3d6c1
cvttsd2si (%r14), %esi
testl %esi, %esi
js 0x3d798
movq -0x30(%rbp), %rdi
movl %r12d, %esi
movq %r14, %rdx
movq %rdi, %r14
callq 0x3d9f9
jmp 0x3d71e
movq %rbx, %rdi
callq 0x4f838
movl 0x10(%rax), %esi
movq 0x18(%rax), %rdx
movq -0x30(%rbp), %r14
movq %r14, %rdi
callq 0x3d8f3
jmp 0x3d71e
negl %r14d
leaq -0x44(%rbp), %r8
movl %r14d, (%r8)
movq %rax, %rdi
movq %rdx, %rsi
movl $0x2, %edx
movl $0x1, %ecx
callq 0x3da7a
movq -0x30(%rbp), %r14
jmp 0x3d71e
movq (%r14), %rsi
andq %rsi, %r13
movabsq $-0x5800000000000, %rax # imm = 0xFFFA800000000000
cmpq %rax, %r13
jne 0x3d7a8
movq %rsi, %rdi
callq 0x4f838
movq %rax, %r13
leaq 0x470e4(%rip), %rdi     # 0x847d0
movl $0x36, %esi
movl $0x10, %edx
movq %rax, %rcx
callq 0x4927d
testq %rax, %rax
je 0x3d7b1
decl %r12d
addq $0x8, %r14
movq -0x30(%rbp), %rdi
movl %r12d, %esi
movq %r14, %rdx
movq %rdi, %r14
callq *0x8(%rax)
movq -0x38(%rbp), %rax
incl 0x30(%r14)
movq %rax, 0x28(%r14)
movq -0x50(%rbp), %rax
movq %rax, (%r14)
movl %r15d, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2b7cf(%rip), %rsi     # 0x68f19
movq %r14, %rdi
callq 0x3d808
leaq 0x2b7cd(%rip), %rsi     # 0x68f26
movq -0x30(%rbp), %rdi
callq 0x3d808
leaq 0x2b7d6(%rip), %rsi     # 0x68f3f
callq 0x3d808
leaq 0x2b7ea(%rip), %rsi     # 0x68f5f
jmp 0x3d759
leaq 0x2b7fc(%rip), %rsi     # 0x68f7a
movq %rbx, %rdi
callq 0x3d808
leaq 0x2b7ed(%rip), %rsi     # 0x68f7a
jmp 0x3d74a
leaq 0x2b800(%rip), %rsi     # 0x68f96
jmp 0x3d759
leaq 0x2b822(%rip), %rdi     # 0x68fc1
xorl %eax, %eax
callq 0x3fd86
jmp 0x3d7c2
leaq 0x2b838(%rip), %rdi     # 0x68fe7
jmp 0x3d7bb
leaq 0x2b852(%rip), %rdi     # 0x6900a
movq %r13, %rsi
xorl %eax, %eax
callq 0x3fd86
movq -0x30(%rbp), %rdi
movq %rax, %rsi
callq 0x3d808