/** * This function returns the next line on file. * fp - the file. * ln - empty array , will contain the line. * stepOneEnd - boolean pointer. (is EOF?) */ void getLine(FILE* fp, line ln[], bool* stepOneEnd) { string startline = malloc(sizeof(char) * maxLineLength); int idx = 0, i = 1; fgets(startline, maxLineLength, fp); while(idx < strlen(startline) && i < lineVar){ readNextWord(startline, &idx, stepOneEnd, (ln + i)); if(strcmp(ln[i].word, "EMPTY") == 0) break; if(i == 1 && isLabel(ln[i])){ ln[i].word[idx - 2] = (char)'\0'; i--; ln[i].word = malloc(sizeof(string) * 100); strcpy(ln[i].word, ln[i + 1].word); ln[i].wordIdx = ln[i + 1].wordIdx; free(ln[i + 1].word); ln[i + 1].word = "NULL"; } if(strcmp(ln[i].word, ".data") == 0){ ln[i].wordIdx = handleData(idx, startline, stepOneEnd); break; } if(idx < strlen(startline)) ln[i + 1].wordIdx = ln[i].wordIdx; i++; } free(startline); }
Word Story::read(OperandType operandType) { switch(operandType) { case OperandType::Large: return readNextWord(); case OperandType::Small: return readNextByte(); case OperandType::Variable: { auto variableID = readNextByte(); return loadVariable(variableID); } case OperandType::Omitted: { throw Exception("Omitted unexpected"); } default: { throw Exception("unexpected operand type"); } } }
/** * This function handles the data input. * idx - the current index on the stream. * stream - contains string with the last line. * stepOneEnd - boolean pointer. (is EOF?) * return the number of new variables on memory. */ int handleData(int idx, string stream, bool* stepOneEnd) { int startDC = DC, diff = 0; line ln; while(idx < strlen(stream)){ readNextWord(stream, &idx, stepOneEnd, &ln); if(strcmp(ln.word, "EMPTY") == 0 ) break; guidel[DC].data = atoi(ln.word); guidel[DC++].isData = 1; } diff = DC- startDC; DC = startDC; return diff; }
void Story::callRoutine(Address routineAddress, Word returnVariable, const std::vector<Word> &arguments) { // NOTE: special case! A call to address 0 means return false! if(routineAddress == 0) { returnFromCall(0); return; // NOTE: Early return } Address returnAddress = m_PC; auto normalizedAddress = expandPackedRoutineAddress(routineAddress); // Point to the new routine setPC(normalizedAddress); auto numberOfLocals = readNextByte(); auto stackFrame = allocateNewFrame(returnAddress, arguments.size(), numberOfLocals, returnVariable); // The local default values are stored next if(m_Version <= 4) { // The defaults are next for(Byte i = 0; i < numberOfLocals; i++) { auto value = readNextWord(); storeVariable(i + 1, value); } } else { // They all default to 0 for(Byte i = 0; i < numberOfLocals; i++) { storeVariable(i + 1, 0); } } // Now layer the arguments on top auto argumentsToCopy = std::min(numberOfLocals, static_cast<Byte>(arguments.size())); for(Byte i = 0; i < argumentsToCopy; i++) { storeVariable(i + 1, arguments[i]); } }