// File: /workspace/github_c_makefile_star2_O3/heltilda[P]cicada/cmpile.c
// Function: relinkBestToken
ccInt relinkBestToken(compiler_type *compiler, linkedlist *OoOblock, ccInt firstToken, ccInt lastToken, ccInt expectedType,
        ccInt **lastOrderedToken, ccBool **lastRtrnTypes, ccInt *lastTokenToFix)
{
    ccInt lowOoO = 0, bestToken = 0, lowOoOpos = 0, blockOpCounter, tokenNum = 0, rtrn;       // inits to suppress warning
    ccInt innerToken, adapter = 0, tokenToFix, *argPtr, loopArgType;
    ccBool **rtrnTypes = NULL;
    tokenSpecType *oneSpec, *bestSpec = NULL;
    scriptTokenType *oneScriptToken;
    
    
        // find the lowest-precedence token
    
    if (lastToken < firstToken)  {
        errPosition = 0;                        // temporary -- we will update errPosition later
        return arg_expected_err;        }
    
    for (blockOpCounter = firstToken; blockOpCounter <= lastToken; blockOpCounter++)  {
        
        tokenNum = *LL_int(OoOblock, blockOpCounter);
        oneScriptToken = scriptToken(tokenNum);
        oneSpec = tokenSpec(oneScriptToken->tokenID);
        
        if ((blockOpCounter == firstToken) || (oneSpec->precedence <= lowOoO))  {
            if ((blockOpCounter == firstToken) || ((oneSpec->leftArgType != -1)
                        && ((blockOpCounter == lastToken) || (oneSpec->rightArgType != -1))
                        && ((compiler->OoOdirections[oneSpec->precedence-1] == l_to_r) || (oneSpec->precedence < lowOoO))) )  {
                bestToken = tokenNum;
                bestSpec = oneSpec;
                rtrnTypes = &(oneScriptToken->rtrnTypes);
                lowOoO = oneSpec->precedence;
                lowOoOpos = blockOpCounter;         }
            
            else if (lowOoO == 1)  break;     // speeds up sentence-parsing (\n is highest-precedence)
    }   }
    
    
        // in rare cases we may have a type-X no-argument adapter whose type needs setting (if possible)
        // (it might be either this operator or else an enclosed operator)
        // 
        // 2 possibilities:  either we know what type we are expecting, in which case we 'fix' the adapter
        // type (or throw an error if we don't have an adapter of the appropriate type);
        // or else we don't know because it is an enclosed argument, so we feed the token # that needs fixing
        // back to the enclosing operator
    
    tokenToFix = scriptToken(bestToken)->adapterTokenToFix;
    if (tokenToFix != 0)  {
        if (expectedType == 10)  *lastTokenToFix = tokenToFix;
        else if (compiler->adapters[10][expectedType] != 0)  {
            scriptToken(tokenToFix)->adapterTokenToFix = compiler->adapters[10][expectedType];
            (*rtrnTypes)[expectedType] = ccTrue;     }
        else  {
            errPosition = scriptToken(tokenToFix)->tokenCharNum;
            return arg_expected_err;
    }   }
    
    
        // check to see if the best token is not of a type that we expected;
        // if possible, add an adapter to the argument
        //
        // Note:  the adapters are all added at the END of the bytecode
        // so as not to disrupt the positions of earlier tokens which may already be linked
    
    if (expectedType < (ccInt) (*typeXarg - *type0arg))  {
    if (!((*rtrnTypes)[expectedType]))  {
        
        for (loopArgType = 0; loopArgType < 10; loopArgType++)  {
        if (((*rtrnTypes)[loopArgType]) && (compiler->adapters[loopArgType][expectedType] != 0))  {
            
            rtrn = addScriptToken(compiler, compiler->adapters[loopArgType][expectedType], scriptToken(bestToken)->tokenCharNum, NULL, 0);
            if (rtrn != passed)  return rtrn;
            
            adapter = compiler->scriptTokens.elementNum;
            **lastOrderedToken = adapter;
            *lastOrderedToken = &(scriptToken(adapter)->firstArg);
            
            break;
        }}
        
            // otherwise throw a type-mismatch error
        
        if (adapter == 0)  {
            errPosition = scriptToken(bestToken)->tokenCharNum;
            return type_mismatch_err;
    }}  }
    
    
        // build the link to bestToken from some previous token
        // (lastOrderedToken is either the firstArg or nextExpression field of that prior token)
    
    **lastOrderedToken = bestToken;
    
    
        // now set bestToken's firstArg field to point to the lowest-OoO operator of its first argument
        // 
        // this low-OoO token's nextExpression field will point to the second argument of bestToken;
        // then that token's nextExpression will point to the third argument; etc.
        // 
        // the last argument's nextExpression field (or firstArg, if there are no arguments) is set to zero
    
    argPtr = &(scriptToken(bestToken)->firstArg);
    *lastOrderedToken = argPtr;
    **lastOrderedToken = 0;
    
    
        // link the left-hand argument
    
    if (bestSpec->leftArgType != -1)  {
        rtrn = relinkBestToken(compiler, OoOblock, firstToken, lowOoOpos-1, bestSpec->leftArgType, lastOrderedToken,
            rtrnTypes, &(scriptToken(bestToken)->adapterTokenToFix));
        if (rtrn != passed)  {
            if ((rtrn == arg_expected_err) && (errPosition == 0))  {
                rtrn = left_arg_expected_err;
                errPosition = scriptToken(bestToken)->tokenCharNum;     }
            return rtrn;
    }   }
    else if (lowOoOpos != firstToken)  {
        errPosition = scriptToken(bestToken)->tokenCharNum;
        return no_left_arg_allowed_err;     }
    
    
        // link any enclosed arguments -- these have already been chained via their nextExpression fields
    
    if (scriptToken(bestToken)->nextScriptToken != 0)  {
        
        ccInt tokenInExpression = bestToken;
        
        innerToken = scriptToken(bestToken)->enclosedArgs;
        **lastOrderedToken = innerToken;
        while (scriptToken(innerToken)->nextExpression != 0)  innerToken = scriptToken(innerToken)->nextExpression;
        *lastOrderedToken = &(scriptToken(innerToken)->nextExpression);
        
        
            // update bestSpec to get our final right-hand argument
        
        while (scriptToken(tokenInExpression)->nextScriptToken != 0)  {
            tokenInExpression = scriptToken(tokenInExpression)->nextScriptToken;
            bestSpec = tokenSpec(bestSpec->nextToken);
    }   }
    
    
        // link the right-hand argument
    
    if (bestSpec->rightArgType != -1)  {
        rtrn = relinkBestToken(compiler, OoOblock, lowOoOpos+1, lastToken, bestSpec->rightArgType, lastOrderedToken,
            rtrnTypes, &(scriptToken(bestToken)->adapterTokenToFix));
        if (rtrn != passed)  {
            if ((rtrn == arg_expected_err) && (errPosition == 0))  {
                rtrn = right_arg_expected_err;
                errPosition = scriptToken(bestToken)->tokenCharNum;     }
            return rtrn;
    }   }
    else if (lowOoOpos != lastToken)  {
        errPosition = scriptToken(bestToken)->tokenCharNum;
        return no_right_arg_allowed_err;     }
    
    
        // finally, prepare to link to the token of the next argument bestToken
        // if this token is an argument of another token, then this will be the next argument of that token
        // the linking is done one level up, so all we have to do is set the pointer here
    
    if (adapter == 0)  argPtr = &(scriptToken(bestToken)->nextExpression);
    else  argPtr = &(scriptToken(adapter)->nextExpression);
    
    *lastOrderedToken = argPtr;
    **lastOrderedToken = 0;
    
    
        // if the enclosing operator is, say, a ( .. ), feed the return type of this operator on back
    
    if (((*lastRtrnTypes)[10]) && (expectedType == 10))  {
        *lastRtrnTypes = scriptToken(bestToken)->rtrnTypes;       }
    
    return passed;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rsi, 0x30(%rsp)
movl %ecx, %esi
movq %rdx, 0x38(%rsp)
subl %edx, %esi
jge 0xc3b0
movl $0x0, 0x18f0e(%rip)     # 0x252a8
movl $0xc, %ebp
movl %ebp, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %ecx, 0x28(%rsp)
movq %r9, 0x40(%rsp)
movl %r8d, (%rsp)
leaq 0x1440(%rdi), %r15
movq %rdi, 0x8(%rsp)
leaq 0x1200(%rdi), %rax
movq %rax, 0x48(%rsp)
movq %rsi, 0x50(%rsp)
leal 0x1(%rsi), %eax
movl %eax, 0x4(%rsp)
xorl %ebx, %ebx
movq $0x0, 0x18(%rsp)
xorl %r12d, %r12d
movq $0x0, 0x20(%rsp)
movl $0x0, 0x2c(%rsp)
movq $0x0, 0x10(%rsp)
movq 0x38(%rsp), %rax
leal (%rax,%rbx), %ebp
movq 0x30(%rsp), %rdi
movl %ebp, %esi
callq 0x91d8
movl (%rax), %r13d
movq %r15, %r14
movq %r15, %rdi
movl %r13d, %esi
callq 0x91d8
movq %rax, %r15
movl (%rax), %esi
movq 0x48(%rsp), %rdi
callq 0x91d8
movl 0xc(%rax), %ecx
testl %ebx, %ebx
je 0xc481
cmpl %r12d, %ecx
jg 0xc49e
cmpl $-0x1, 0x10(%rax)
je 0xc476
cmpl %ebx, 0x50(%rsp)
je 0xc45b
cmpl $-0x1, 0x14(%rax)
je 0xc476
movslq %ecx, %rdx
movq 0x8(%rsp), %rsi
movq 0x1240(%rsi), %rsi
cmpl $0x1, -0x4(%rsi,%rdx,4)
je 0xc481
cmpl %r12d, %ecx
jl 0xc481
cmpl $0x1, %r12d
movq %r14, %r15
jne 0xc4a1
jmp 0xc4ad
addq $0x28, %r15
movl %ebp, %edx
movq %rdx, 0x10(%rsp)
movl %r13d, 0x2c(%rsp)
movq %r15, 0x20(%rsp)
movl %ecx, %r12d
movq %rax, 0x18(%rsp)
movq %r14, %r15
incl %ebx
cmpl %ebx, 0x4(%rsp)
jne 0xc409
movq %r15, %rdi
movl 0x2c(%rsp), %r12d
movl %r12d, %esi
callq 0x91d8
movl 0x30(%rax), %esi
testl %esi, %esi
movl (%rsp), %r13d
je 0xc50f
cmpl $0xa, %r13d
jne 0xc4e1
movq 0x98(%rsp), %rax
movl %esi, (%rax)
xorl %ebp, %ebp
movq 0x40(%rsp), %rbx
jmp 0xc531
movslq %r13d, %rbx
movq 0x8(%rsp), %rax
movl 0x140c(%rax,%rbx,4), %ebp
movq %r15, %rdi
callq 0x91d8
testl %ebp, %ebp
je 0xc7a7
movl %ebp, 0x30(%rax)
movq 0x20(%rsp), %rax
movq (%rax), %rax
movb $0x1, (%rax,%rbx)
xorl %ebp, %ebp
cmpl $0x9, %r13d
movq 0x40(%rsp), %rbx
jg 0xc531
movq 0x20(%rsp), %rax
movq (%rax), %rax
movslq %r13d, %rcx
cmpb $0x0, (%rax,%rcx)
je 0xc7b5
movl %ebp, 0x4(%rsp)
movq (%rbx), %rax
movl %r12d, (%rax)
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
leaq 0x8(%rax), %rcx
movq %rcx, (%rbx)
movl $0x0, 0x8(%rax)
movq 0x18(%rsp), %rax
movl 0x10(%rax), %ebp
cmpl $-0x1, %ebp
je 0xc5dc
movq 0x10(%rsp), %rax
leal -0x1(%rax), %r15d
movq %r14, %rdi
movl %r12d, %esi
callq 0x91d8
addq $0x30, %rax
movq 0x8(%rsp), %rdi
movq 0x30(%rsp), %rsi
movq 0x38(%rsp), %rdx
movl %r15d, %ecx
movq %r14, %r15
movl %ebp, %r8d
movq %rbx, %r9
pushq %rax
pushq 0x28(%rsp)
callq 0xc372
addq $0x10, %rsp
testl %eax, %eax
je 0xc5eb
movl %eax, %ebp
cmpl $0xc, %eax
jne 0xc39f
cmpl $0x0, 0x18cf0(%rip)     # 0x252a8
jne 0xc39f
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
movl 0x4(%rax), %eax
movl %eax, 0x18cd6(%rip)     # 0x252a8
movl $0xd, %ebp
jmp 0xc39f
movq 0x38(%rsp), %rax
cmpl %eax, 0x10(%rsp)
jne 0xc71b
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
cmpl $0x0, 0x14(%rax)
je 0xc68f
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
movl 0x10(%rax), %ebp
movq (%rbx), %rax
movl %ebp, (%rax)
movq %r15, %rdi
movl %ebp, %esi
callq 0x91d8
cmpl $0x0, 0xc(%rax)
je 0xc632
movq %r15, %rdi
movl %ebp, %esi
callq 0x91d8
movl 0xc(%rax), %ebp
jmp 0xc613
movq %r15, %rdi
movl %ebp, %esi
callq 0x91d8
addq $0xc, %rax
movq %rax, (%rbx)
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
cmpl $0x0, 0x14(%rax)
je 0xc68f
movl %r12d, %ebp
movq 0x48(%rsp), %r14
movq 0x18(%rsp), %r13
movq %r15, %rdi
movl %ebp, %esi
callq 0x91d8
movl 0x14(%rax), %ebp
movl 0x28(%r13), %esi
movq %r14, %rdi
callq 0x91d8
movq %rax, %r13
movq %r15, %rdi
movl %ebp, %esi
callq 0x91d8
cmpl $0x0, 0x14(%rax)
jne 0xc661
jmp 0xc694
movq 0x18(%rsp), %r13
movl 0x14(%r13), %ebp
cmpl $-0x1, %ebp
je 0xc739
movq 0x10(%rsp), %r14
incl %r14d
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
addq $0x30, %rax
movq 0x8(%rsp), %rdi
movq 0x30(%rsp), %rsi
movl %r14d, %edx
movl 0x28(%rsp), %ecx
movl %ebp, %r8d
movq %rbx, %r9
pushq %rax
pushq 0x28(%rsp)
callq 0xc372
addq $0x10, %rsp
testl %eax, %eax
movl (%rsp), %r14d
je 0xc74c
movl %eax, %ebp
cmpl $0xc, %eax
jne 0xc39f
cmpl $0x0, 0x18bb1(%rip)     # 0x252a8
jne 0xc39f
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
movl 0x4(%rax), %eax
movl %eax, 0x18b97(%rip)     # 0x252a8
movl $0xe, %ebp
jmp 0xc39f
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
movl 0x4(%rax), %eax
movl %eax, 0x18b79(%rip)     # 0x252a8
movl $0xf, %ebp
jmp 0xc39f
movq 0x10(%rsp), %rax
cmpl 0x28(%rsp), %eax
movl (%rsp), %r14d
jne 0xc7fe
movl 0x4(%rsp), %esi
testl %esi, %esi
cmovel %r12d, %esi
movq %r15, %rdi
callq 0x91d8
leaq 0xc(%rax), %rcx
movq %rcx, (%rbx)
movl $0x0, 0xc(%rax)
xorl %ebp, %ebp
cmpl $0xa, %r14d
jne 0xc39f
movq 0x90(%rsp), %rcx
movq (%rcx), %rax
cmpb $0x0, 0xa(%rax)
je 0xc39f
movq %r15, %rdi
movl %r12d, %esi
movq %rcx, %rbx
callq 0x91d8
movq 0x28(%rax), %rax
movq %rax, (%rbx)
jmp 0xc39f
movl 0x4(%rax), %eax
movl %eax, 0x18af8(%rip)     # 0x252a8
jmp 0xc39a
movq 0x8(%rsp), %rdx
leaq (%rdx,%rcx,4), %rcx
addq $0x1254, %rcx           # imm = 0x1254
xorl %edx, %edx
cmpb $0x0, (%rax,%rdx)
je 0xc7d3
movl (%rcx), %ebp
testl %ebp, %ebp
jne 0xc81c
incq %rdx
addq $0x2c, %rcx
cmpq $0xa, %rdx
jne 0xc7c7
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
movl 0x4(%rax), %eax
movl %eax, 0x18ab4(%rip)     # 0x252a8
movl $0x11, %ebp
jmp 0xc39f
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
movl 0x4(%rax), %eax
movl %eax, 0x18a96(%rip)     # 0x252a8
movl $0x10, %ebp
jmp 0xc39f
movq %r15, %rdi
movl %r12d, %esi
callq 0x91d8
movl 0x4(%rax), %edx
movq 0x8(%rsp), %rdi
movl %ebp, %esi
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0xb846
movl %eax, %ebp
testl %eax, %eax
jne 0xc39f
movl (%r15), %ebp
movq (%rbx), %rax
movl %ebp, (%rax)
movq %r15, %rdi
movl %ebp, %esi
callq 0x91d8
addq $0x8, %rax
movq %rax, (%rbx)
testl %ebp, %ebp
jne 0xc531
jmp 0xc7e0
nop