bool CompileRepeatPreWhileOrUntil(int column, int param) { BlockStack_Write(0, g_pCompilerData->obj_ptr); // set 'next'/reverse address if (!CompileExpression()) // compile pre-while/until expression { return false; } if (!g_pElementizer->GetElement(type_end)) { return false; } if (!EnterObj((unsigned char)(param & 0xFF))) // enter the passed in bytecode (jz or jnz) { return false; } if (!BlockStack_CompileAddress(1)) // compile forward address { return false; } if (!CompileBlock(column)) // compile repeat-while/until block { return false; } if (!EnterObj(0x04)) // (jmp) { return false; } if (!BlockStack_CompileAddress(0)) // compile reverse address { return false; } BlockStack_Write(1, g_pCompilerData->obj_ptr); // set 'quit'/forward address return true; }
bool CompileIfOrIfNot_FinalJmp(int& addressCount) { if (!EnterObj(0x04)) // jmp { return false; } if (!BlockStack_CompileAddress(0)) { return false; } BlockStack_Write(addressCount, g_pCompilerData->obj_ptr); addressCount++; return true; }
bool CompileRepeatCount(int column, int param) { param = param; // stop warning if (!CompileExpression()) // compile count expression { return false; } if (!g_pElementizer->GetElement(type_end)) { return false; } if (!EnterObj(0x08)) // (tjz) { return false; } if (!BlockStack_CompileAddress(1)) // compile forward address { return false; } BlockStack_Write(2, g_pCompilerData->obj_ptr); // set reverse address if (!CompileBlock(column)) // compile repeat-count block { return false; } BlockStack_Write(0, g_pCompilerData->obj_ptr); // set 'next' address if (!EnterObj(0x09)) // (djnz) { 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 CompileTopBlock() { g_pCompilerData->bnest_ptr = 0; g_pCompilerData->bstack_ptr = 0; StringConstant_PreProcess(); if (!CompileBlock(0)) { return false; } // enter a return into obj if (!EnterObj(0x32)) // 0x32 = 00110010b { return false; } return StringConstant_PostProcess(); }
bool CompileIfOrIfNot_Condition(int& addressCount, unsigned char byteCode) { if (!CompileExpression()) { return false; } if (!g_pElementizer->GetElement(type_end)) { return false; } if (!EnterObj(byteCode)) { return false; } if (!BlockStack_CompileAddress(addressCount)) { return false; } return true; }
bool CompileRepeatPlain(int column, int param) { param = param; // stop warning BlockStack_Write(2, g_pCompilerData->obj_ptr); // set revearse address if (!s_bHasPost) { BlockStack_Write(0, g_pCompilerData->obj_ptr); // set plain 'next' address } if (!CompileBlock(column)) { return false; } bool bEof = false; if (!g_pElementizer->GetNext(bEof)) { return false; } unsigned char byteCode = 0x04; if (!bEof) { s_column = g_pElementizer->GetColumn(); if (s_column < column) { g_pElementizer->Backup(); } else { // check for post while or until int postType = g_pElementizer->GetType(); if ((postType == type_while) || (postType == type_until)) { s_bHasPost = true; BlockStack_Write(0, g_pCompilerData->obj_ptr); // set post-while/until 'next' address if (!CompileExpression()) // compile post-while/until expression { return false; } if (!g_pElementizer->GetElement(type_end)) { return false; } byteCode = (postType == type_while) ? 0x0B : 0x0A; } else { g_pElementizer->Backup(); } } } if (!EnterObj(byteCode)) { return false; } if (!BlockStack_CompileAddress(2)) // compile reverse address { return false; } BlockStack_Write(1, g_pCompilerData->obj_ptr); // set 'quit' address return true; }
bool CompileCase(int column, int param) { param = param; // stop warning if (!BlockStack_CompileConstant()) { return false; } if (!CompileExpression()) { return false; } if (!g_pElementizer->GetElement(type_end)) { return false; } int savedSourcePtr = g_pElementizer->GetSourcePtr(); int otherSourcePtr = 0; bool bOther = false; int caseCount = 0; bool bEof = false; while (!bEof) { if (!g_pElementizer->GetNext(bEof)) { return false; } if (bEof) { break; } if (g_pElementizer->GetType() == type_end) { continue; } s_column = g_pElementizer->GetColumn(); g_pElementizer->Backup(); if (s_column <= column) { break; } if (bOther) // if we have OTHER: it should have been the last case, so we shouldn't get here again { g_pCompilerData->error = true; g_pCompilerData->error_msg = g_pErrorStrings[error_omblc]; return false; } if (g_pElementizer->GetType() == type_other) { bOther = true; if (!g_pElementizer->GetNext(bEof)) // get/skip 'other' { return false; } otherSourcePtr = g_pCompilerData->source_start; // save the pointer to the beginning of 'other' } else { caseCount++; if (caseCount > case_limit) { g_pCompilerData->error = true; g_pCompilerData->error_msg = g_pErrorStrings[error_loxce]; return false; } while (1) { bool bRange = false; if (!CompileRange(bRange)) { return false; } if (!EnterObj(bRange ? 0x0E : 0x0D)) // enter bytecode for case range or case value into obj { return false; } if (!BlockStack_CompileAddress(caseCount)) { return false; } if (!g_pElementizer->CheckElement(type_comma)) { break; } } } if (!g_pElementizer->GetElement(type_colon)) { return false; } if (!SkipBlock(s_column)) { return false; } } if (caseCount == 0) { g_pCompilerData->error = true; g_pCompilerData->error_msg = g_pErrorStrings[error_nce]; return false; } if (bOther) { // set the source pointer to where the OTHER is at, then get it to set the column g_pElementizer->SetSourcePtr(otherSourcePtr); if (!g_pElementizer->GetNext(bEof)) { return false; } int new_column = g_pElementizer->GetColumn(); // skip the colon if (!g_pElementizer->GetNext(bEof)) { return false; } if (!CompileBlock(new_column)) { return false; } } if (!EnterObj(0x0C)) // casedone, end of range checks { return false; } g_pElementizer->SetSourcePtr(savedSourcePtr); caseCount = 0; bOther = false; bEof = false; while(!bEof) { if (!g_pElementizer->GetNext(bEof)) { return false; } if (bEof) { break; } if (g_pElementizer->GetType() == type_end) { continue; } s_column = g_pElementizer->GetColumn(); g_pElementizer->Backup(); if (s_column <= column) { break; } if (g_pElementizer->GetType() == type_other) { // skip over other, already compiled if (!g_pElementizer->GetNext(bEof)) { return false; } if (!g_pElementizer->GetNext(bEof)) { return false; } if (!SkipBlock(s_column)) { return false; } } else { // skip over range/values(s), allready compiled while (1) { if (!SkipRange()) { return false; } if (!g_pElementizer->CheckElement(type_comma)) { break; } } caseCount++; BlockStack_Write(caseCount, g_pCompilerData->obj_ptr); if (!g_pElementizer->GetElement(type_colon)) { return false; } if (!CompileBlock(s_column)) { return false; } if (!EnterObj(0x0C)) // casedone { return false; } } } BlockStack_Write(0, g_pCompilerData->obj_ptr); 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; } }