bool CompileRepeatVariable(int column, int param)
{
    param = param; // stop warning

    unsigned char varType = 0;
    unsigned char varSize = 0;
    int varAddress = 0;
    int varIndexSourcePtr = 0;
    if (!GetVariable(varType, varSize, varAddress, varIndexSourcePtr))
    {
        return false;
    }

    bool bEof = false;
    if (!g_pElementizer->GetNext(bEof)) // get 'from'
    {
        return false;
    }
    if (g_pElementizer->GetType() != type_from)
    {
        g_pCompilerData->error = true;
        g_pCompilerData->error_msg = g_pErrorStrings[error_efrom];
        return false;
    }
    int fromSourcePtr = g_pElementizer->GetSourcePtr();
    g_pCompilerData->str_enable = false;
    if (!CompileExpression()) // compile 'from' expression (string not allowed)
    {
        return false;
    }
    g_pCompilerData->str_enable = true;

    if (!CompileVariable(1, 0, varType, varSize, varAddress, varIndexSourcePtr)) // compile var write
    {
        return false;
    }
    BlockStack_Write(2, g_pCompilerData->obj_ptr); // set reverse address

    if (!g_pElementizer->GetNext(bEof)) // get 'to'
    {
        return false;
    }
    if (g_pElementizer->GetType() != type_to)
    {
        g_pCompilerData->error = true;
        g_pCompilerData->error_msg = g_pErrorStrings[error_eto];
        return false;
    }
    g_pCompilerData->str_enable = false;
    if (!SkipExpression()) // skip 'to' expression (string not allowed)
    {
        return false;
    }
    g_pCompilerData->str_enable = true;

    if (!g_pElementizer->GetNext(bEof)) // check for 'step'
    {
        return false;
    }
    unsigned char byteCode = 0;
    if (g_pElementizer->GetType() == type_step)
    {
        // handle step
        int savedSourcePtr = g_pElementizer->GetSourcePtr();
        g_pCompilerData->str_enable = false;
        if (!SkipExpression()) // skip 'step' expression (string not allowed)
        {
            return false;
        }
        g_pCompilerData->str_enable = true;
        if (!g_pElementizer->GetElement(type_end))
        {
            return false;
        }
        if (!CompileBlock(column))
        {
            return false;
        }
        BlockStack_Write(0, g_pCompilerData->obj_ptr); // set 'next' address
        if (!CompileOutOfSequenceExpression(savedSourcePtr)) // compile the step expression
        {
            return false;
        }
        byteCode = 0x06; // (repeat-var w/step)
    }
    else if (g_pElementizer->GetType() == type_end)
    {
        // no step, compile block
        if (!CompileBlock(column))
        {
            return false;
        }
        BlockStack_Write(0, g_pCompilerData->obj_ptr); // set 'next' address
        byteCode = 0x02; // (repeat-var)
    }
    else
    {
        g_pCompilerData->error = true;
        g_pCompilerData->error_msg = g_pErrorStrings[error_esoeol];
        return false;
    }

    int savedSourcePtr = g_pElementizer->GetSourcePtr();
    g_pElementizer->SetSourcePtr(fromSourcePtr);
    if (!CompileExpression()) // compile 'from' expression
    {
        return false;
    }
    if (!g_pElementizer->GetNext(bEof)) // skip 'to'
    {
        return false;
    }
    if (!CompileExpression()) // compile 'to' expression
    {
        return false;
    }
    g_pElementizer->SetSourcePtr(savedSourcePtr);
    if (!CompileVariable_Assign(byteCode, varType, varSize, varAddress, varIndexSourcePtr)) // compile repeat-var
    {
        return false;
    }
    if (!BlockStack_CompileAddress(2)) // compile reverse address
    {
        return false;
    }
    BlockStack_Write(1, g_pCompilerData->obj_ptr); // set 'quit'/forward address
    return true;
}
Esempio n. 2
0
bool CompileVariable(unsigned char vOperation, unsigned char vOperator, unsigned char type, unsigned char size, int address, int indexSourcePtr)
{
    // compile and index(s)
    if (type != type_reg)
    {
        if (type == type_spr || type == type_size)
        {
            if (!CompileOutOfSequenceExpression(address))
            {
                return false;
            }
        }
        if (type != type_spr)
        {
            if (indexSourcePtr != 0)
            {
                if (!CompileOutOfSequenceExpression(indexSourcePtr))
                {
                    return false;
                }
            }
        }
    }

    unsigned char byteCode = 0;

    if (type == type_spr)
    {
        byteCode = 0x24 | vOperation;
    }
    else if (type == type_reg)
    {
        byteCode = 0x3F;
        if (size != 2)
        {
            bool bRange = false;
            if (!CompileOutOfSequenceRange(indexSourcePtr, bRange))
            {
                return false;
            }
            if (bRange)
            {
                byteCode = 0x3E;
            }
            else
            {
                byteCode = 0x3D;
            }
        }
        if (!EnterObj(byteCode))
        {
            return false;
        }
        // byteCode = 1 in high bit, bottom 2 bits of vOperation in next two bits, then bottom 5 bits of address
        byteCode = 0x80 | ((vOperation & 3) << 5) | (address & 0x1F);
    }
    else
    {
        if ((type != type_var_byte && type != type_loc_byte) || size != 2 || address >= 8*4 || indexSourcePtr != 0)
        {
            // not compact
            byteCode = 0x80 | (size << 5);
            if (indexSourcePtr != 0)
            {
                byteCode |= 0x10;
            }
            byteCode |= vOperation;
            if (type != type_size)
            {
                if (type == type_dat_byte)
                {
                    byteCode += 4;
                }
                else if (type == type_var_byte)
                {
                    byteCode += 8;
                }
                else if (type == type_loc_byte)
                {
                    byteCode += 12;
                }
                else
                {
                    g_pCompilerData->error = true;
                    g_pCompilerData->error_msg = g_pErrorStrings[error_internal];
                    return false;
                }
                if (!EnterObj(byteCode))
                {
                    return false;
                }
                if (address > 0x7F)
                {
                    // two byte address
                    byteCode = (unsigned char)(address >> 8) | 0x80;
                    if (!EnterObj(byteCode))
                    {
                        return false;
                    }
                }
                byteCode = (unsigned char)address;
            }
        }