BOOL CCgxWindow::getCommand(int index, RECT* rectOut) { int size = getCommandSize(); if(index < 0 || index >= size) return FALSE; memcpy(rectOut, &commandRECTs[index], sizeof(RECT)); return TRUE; }
/** * First compiler transition mainly for searching all labels and data array building * Algorithem: * 1. int ic = 0, dc = 0; * 2. Read next line * 3. check is label exists in the line start * 4. Rise isLabelExists flag - if it exists * 5. if it is .data or .string command? if not go to step 8 * 6. if there is a label add it to the symbols table with the value of dc counter (if it exists in the table throw error) * 7. identify the data type and store it in the data AssemblyBytes * 7.1. update the dc counter according to the data size return to step 2(!) * 8. if the command is .extern or .entry (if not go to step 11) * 9. it is .extern order add it to the symbols table with extern flag on and no value * 10. return to step 2 * 11. if there is a label add it to the symbols table with the value of ic counter (if it exists in the table throw error) * 12. Check command & operands type and calculate the command memory size * 13. Add to ic the value of ic + the calculated command size value * 14. go back to step 2 * 15. When all lines have been process check for failures and see that the RAM size doesnt exceeds the maximum allowed * 16. Update the data labels (.data or .string) in the symbols table with the mathcing address (the dc location + calulated final ic) * @param fileContent parsed file lines * @param assembly final struct to fill with symbols and bytes, should be PARCIALLY FULL by the end of the method * @return Status (Pass/Fail) */ Status runFirstTransition(FileContent *fileContent, AssemblyStructure *assembly) { int i, calcCommandSize; Status status = Pass; assembly->ic = ASSEMBLY_CODE_START_ADDRESS; assembly->dc = 0; for (i=0; i < fileContent->size; i++){ /* For every line in file */ FileLine line = fileContent->line[i]; bool isLabelExists = false; if (line.label != NULL) { /* If Label Exists for line */ isLabelExists = true; } /* Handle Data Storage Symbols */ if (line.actionType == DATA || line.actionType == STRING) { /* Steps 6 ,7 and 7.1 */ /* Push into data array */ int calcDataSize = 0; int firstByte = 0; bool isMemAllocOk; if (line.actionType == DATA ) { calcDataSize = line.firstOperValue->dataSize; /* check how much space to save in data array */ firstByte = line.firstOperValue->data[0]; isMemAllocOk = pushBytesFromIntArray(assembly->dataArray, line.firstOperValue->data, /* push data into data array */ line.firstOperValue->dataSize); } else { calcDataSize = (int)strlen(line.firstOperValue->string) + 1; /* calculate how much space needed to save for string - +1 for /0 at the end of string */ firstByte = line.firstOperValue->string[0]; isMemAllocOk = pushBytesFromString(assembly->dataArray, line.firstOperValue->string); /* Push string into data array */ } if(isMemAllocOk == false) { /* if any error in memory allocation, throw error */ printInternalError(ERR_DATA_RAM_OVERFLOW, fileContent->filename); status = Fail; continue; } if (isLabelExists) { /* if .data/.string has label then add it to symbols table and check that it does not already exist */ if (addNewLabelToTable(assembly->symbolsTable, line.label, assembly->dc, false, false, false, firstByte) == false) { printCompileError(errMessage(ERR_LABEL_DEFINED_TWICE, line.label), fileContent->filename, line.lineNumber); /* throw error if label exist twice */ status = Fail; continue; } } assembly->dc += calcDataSize; /* increase dc size */ } /* Handle External Symbols */ else if (line.actionType == EXTERN || line.actionType == ENTRY) { if (isLabelExists) { /* Throw warning if .extern/.entry has label */ printCompileWarning(errMessage(WARN_LABEL_IN_BAD_LOCATION, line.label), fileContent->filename, line.lineNumber); } /* Steps 9, 9.1, 10 */ if (line.actionType == EXTERN) { /* add extern label to symbols table */ addNewLabelToTable(assembly->symbolsTable, line.firstOperValue->entryOrExtern, 0, true, false, false, 0); } } else {/* handle command line */ /* Handle Command labels */ if (isLabelExists) { /* if there is label, add it to symbols table and calculate its binary bits (if needed by another dynamic cmd) */ /* Step 11 */ int binCommandForDynamicAddressing = buildBinaryCommand(line); /* calculate dynamic binary bits */ if (addNewLabelToTable(assembly->symbolsTable, line.label, assembly->ic, false, true, false, /* add to sybolsTable and check no duplication */ binCommandForDynamicAddressing) == false) { printCompileError(errMessage(ERR_LABEL_DEFINED_TWICE, line.label), fileContent->filename, line.lineNumber); /* Throw error if label is duplicated */ status = Fail; continue; } } /* Steps 12, 13, 13.1, 14 */ /* handle Command size */ calcCommandSize = getCommandSize(&line); /* Step 14 */ assembly->ic += calcCommandSize; } } if (status == Fail) { return Fail; } if (assembly->ic + assembly->dc >= MAX_CPU_MEMORY) { /* If more than 1000 commands, throw error */ printInternalError(ERR_RAM_OVERFLOW, fileContent->filename); return Fail; } /* update the .data & .string records in the symbols table */ updateSymbolsTableDataAddresses(assembly->symbolsTable, assembly->ic); return Pass; }