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; }
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; } }