// File: /workspace/github_c_makefile_star2_O2/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 $0x68, %rsp
movq %rsi, 0x48(%rsp)
movl %ecx, 0x24(%rsp)
movq %rdx, 0x50(%rsp)
subl %edx, %ecx
movl %ecx, 0x5c(%rsp)
jge 0xbca2
andl $0x0, 0x1861c(%rip)     # 0x242a8
pushq $0xc
popq %r14
movl %r14d, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r9, 0x40(%rsp)
movl %r8d, 0x3c(%rsp)
leaq 0x1440(%rdi), %r12
movq %rdi, 0x28(%rsp)
leaq 0x1200(%rdi), %rax
movq %rax, 0x60(%rsp)
xorl %ebp, %ebp
movq $0x0, 0x10(%rsp)
xorl %r13d, %r13d
movq $0x0, 0x30(%rsp)
xorl %ebx, %ebx
movq $0x0, 0x18(%rsp)
movq 0x50(%rsp), %rax
leal (%rax,%rbp), %r14d
cmpl 0x24(%rsp), %r14d
jg 0xbdbf
movl %r13d, 0xc(%rsp)
movq 0x48(%rsp), %rdi
movl %r14d, %esi
callq 0x9088
movl (%rax), %r15d
movq %r12, %r13
movq %r12, %rdi
movl %r15d, %esi
callq 0x9088
movq %rax, %r12
movl (%rax), %esi
movq 0x60(%rsp), %rdi
callq 0x9088
movl 0xc(%rax), %ecx
testl %ebp, %ebp
je 0xbd9a
cmpl %ebx, %ecx
jle 0xbd4d
movq 0x10(%rsp), %rax
movl %eax, %r14d
movl 0xc(%rsp), %r15d
movl %ebx, %ecx
movq 0x18(%rsp), %rax
jmp 0xbda3
cmpl $-0x1, 0x10(%rax)
je 0xbd79
cmpl %ebp, 0x5c(%rsp)
je 0xbd5f
cmpl $-0x1, 0x14(%rax)
je 0xbd79
movslq %ecx, %rdx
movq 0x28(%rsp), %rsi
movq 0x1240(%rsi), %rsi
cmpl $0x1, -0x4(%rsi,%rdx,4)
je 0xbd9a
cmpl %ebx, %ecx
jl 0xbd9a
cmpl $0x1, %ebx
movq %r13, %r12
movl 0xc(%rsp), %r13d
je 0xbdbf
movq 0x10(%rsp), %rax
movl %eax, %r14d
movl %r13d, %r15d
movl %ebx, %ecx
movq 0x18(%rsp), %rax
jmp 0xbda6
addq $0x28, %r12
movq %r12, 0x30(%rsp)
movq %r13, %r12
incl %ebp
movl %r14d, %edx
movq %rdx, 0x10(%rsp)
movl %r15d, %r13d
movl %ecx, %ebx
movq %rax, 0x18(%rsp)
jmp 0xbce6
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
movl 0x30(%rax), %esi
movl 0x3c(%rsp), %ebp
movslq %ebp, %rbx
testl %esi, %esi
je 0xbe1e
cmpl $0xa, %ebp
jne 0xbdef
movq 0xa8(%rsp), %rax
movl %esi, (%rax)
xorl %r14d, %r14d
jmp 0xbe70
movq 0x28(%rsp), %rax
movl 0x140c(%rax,%rbx,4), %ebp
movq %r12, %rdi
callq 0x9088
testl %ebp, %ebp
je 0xc0bb
movl %ebp, 0x30(%rax)
movq 0x30(%rsp), %rax
movq (%rax), %rax
movb $0x1, (%rax,%rbx)
movl 0x3c(%rsp), %ebp
xorl %r14d, %r14d
cmpl $0x9, %ebp
jg 0xbe70
movq 0x30(%rsp), %rax
movq (%rax), %rax
cmpb $0x0, (%rax,%rbx)
movq 0x10(%rsp), %r15
jne 0xbe75
movq 0x28(%rsp), %rcx
leaq (%rcx,%rbx,4), %rcx
addq $0x1254, %rcx           # imm = 0x1254
xorl %edx, %edx
cmpq $0xa, %rdx
je 0xc139
cmpb $0x0, (%rax,%rdx)
je 0xbe67
movl (%rcx), %r14d
testl %r14d, %r14d
jne 0xc0e4
incq %rdx
addq $0x2c, %rcx
jmp 0xbe4b
movq 0x10(%rsp), %r15
movl %r14d, 0xc(%rsp)
movq 0x40(%rsp), %rbx
movq (%rbx), %rax
movl %r13d, (%rax)
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
leaq 0x8(%rax), %rcx
movq %rcx, (%rbx)
andl $0x0, 0x8(%rax)
movq 0x18(%rsp), %rax
movl 0x10(%rax), %r14d
cmpl $-0x1, %r14d
je 0xbf1a
decl %r15d
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
addq $0x30, %rax
movq 0x28(%rsp), %rdi
movq 0x48(%rsp), %rsi
movq 0x50(%rsp), %rdx
movl %r15d, %ecx
movl %r14d, %r8d
movq %rbx, %r9
pushq %rax
pushq 0x38(%rsp)
callq 0xbc61
addq $0x10, %rsp
testl %eax, %eax
je 0xbf25
movl %eax, %r14d
cmpl $0xc, %eax
jne 0xbc90
cmpl $0x0, 0x183af(%rip)     # 0x242a8
jne 0xbc90
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
movl 0x4(%rax), %eax
movl %eax, 0x18395(%rip)     # 0x242a8
pushq $0xd
jmp 0xbc8e
cmpl 0x50(%rsp), %r15d
jne 0xbfbe
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
cmpl $0x0, 0x14(%rax)
je 0xbfd9
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
movl 0x10(%rax), %r14d
movq (%rbx), %rax
movl %r14d, (%rax)
movq 0x10(%rsp), %r15
movq %r12, %rdi
movl %r14d, %esi
callq 0x9088
movl 0xc(%rax), %ebx
movq %r12, %rdi
movl %r14d, %esi
callq 0x9088
addq $0xc, %rax
testl %ebx, %ebx
je 0xbf7a
movl (%rax), %r14d
jmp 0xbf54
movq 0x40(%rsp), %rbx
movq %rax, (%rbx)
movl %r13d, %r14d
movq %r12, %rdi
movl %r14d, %esi
callq 0x9088
cmpl $0x0, 0x14(%rax)
je 0xbfde
movq %r12, %rdi
movl %r14d, %esi
callq 0x9088
movl 0x14(%rax), %r14d
movq 0x18(%rsp), %rax
movl 0x28(%rax), %esi
movq 0x60(%rsp), %rdi
callq 0x9088
movq %rax, 0x18(%rsp)
jmp 0xbf85
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
movl 0x4(%rax), %eax
movl %eax, 0x182d6(%rip)     # 0x242a8
pushq $0xf
jmp 0xbc8e
movq 0x10(%rsp), %r15
movq 0x18(%rsp), %rax
movl 0x14(%rax), %r14d
cmpl $-0x1, %r14d
je 0xc05c
incl %r15d
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
addq $0x30, %rax
movq 0x28(%rsp), %rdi
movq 0x48(%rsp), %rsi
movl %r15d, %edx
movl 0x24(%rsp), %ecx
movl %r14d, %r8d
movq %rbx, %r9
pushq %rax
pushq 0x38(%rsp)
callq 0xbc61
addq $0x10, %rsp
testl %eax, %eax
je 0xc063
movl %eax, %r14d
cmpl $0xc, %eax
jne 0xbc90
cmpl $0x0, 0x1826d(%rip)     # 0x242a8
jne 0xbc90
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
movl 0x4(%rax), %eax
movl %eax, 0x18253(%rip)     # 0x242a8
pushq $0xe
jmp 0xbc8e
cmpl 0x24(%rsp), %r15d
jne 0xc0c9
movl 0xc(%rsp), %esi
testl %esi, %esi
cmovel %r13d, %esi
movq %r12, %rdi
callq 0x9088
leaq 0xc(%rax), %rcx
movq %rcx, (%rbx)
andl $0x0, 0xc(%rax)
xorl %r14d, %r14d
cmpl $0xa, %ebp
jne 0xbc90
movq 0xa0(%rsp), %rcx
movq (%rcx), %rax
cmpb $0x0, 0xa(%rax)
je 0xbc90
movq %r12, %rdi
movl %r13d, %esi
movq %rcx, %rbx
callq 0x9088
movq 0x28(%rax), %rax
movq %rax, (%rbx)
jmp 0xbc90
movl 0x4(%rax), %eax
movl %eax, 0x181e4(%rip)     # 0x242a8
jmp 0xbc8c
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
movl 0x4(%rax), %eax
movl %eax, 0x181cb(%rip)     # 0x242a8
pushq $0x10
jmp 0xbc8e
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
movl 0x4(%rax), %edx
movq 0x28(%rsp), %rdi
movl %r14d, %esi
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0xb2eb
movl %eax, %r14d
testl %eax, %eax
jne 0xbc90
movl (%r12), %r14d
movq 0x40(%rsp), %rbx
movq (%rbx), %rax
movl %r14d, (%rax)
movq %r12, %rdi
movl %r14d, %esi
callq 0x9088
addq $0x8, %rax
movq %rax, (%rbx)
testl %r14d, %r14d
jne 0xbe75
movq %r12, %rdi
movl %r13d, %esi
callq 0x9088
movl 0x4(%rax), %eax
movl %eax, 0x1815b(%rip)     # 0x242a8
pushq $0x11
jmp 0xbc8e