Source: machine/innerComponents/serie.js

const assert = require('../../tools/assert');

const NB_INST_SERIES_3 = require("../constants").NB_INST_SERIES_3
const NB_INST_PER_SERIE = require("../constants").NB_INST_PER_SERIE
const NB_INST_PER_MEM = require("../constants").NB_INST_PER_MEM
const NB_MEMORIES_PER_OCTAD = require("../constants").NB_MEMORIES_PER_OCTAD
NOP = require("../../assembly/NOP").NOP

/**
 * A Series is Group which content is interpreted as instructions
 */
class Serie {

  /**
   * constructs a new instance of Series
   * @param id the id of this Series
   * @param bullGamma the machine attached to this Serie
   * @param group the group encapsulated in the Series
   */
  constructor(id, bullGamma, group) {
    assert(id >= 0, "id should not be negative");
    assert(bullGamma, "bullGamma should neither be null nor undefined");
    this.id = id;
    this.bullGamma = bullGamma;
    if (group !== undefined) {
      this.group = group;
    }
    this.nbInst = NB_INST_PER_SERIE;
    this.maxNbInst = NB_INST_PER_SERIE;
  }

  /**
   * Return the instructions list of the series
   */
  getInstruction(line) {
    assert(this.group, "group attribute is undefined");
    assert(line >= 0 && line < this.maxNbInst, true, "invalid instruction index");
    let q = Math.floor(line / NB_INST_PER_MEM);
    let r = line % NB_INST_PER_MEM;

    // blank line every 3 instructions
    if (r === NB_INST_PER_MEM - 1) {
      return new NOP(this.bullGamma);
    }

    let mem = this.group.octads[Math.floor(q / NB_MEMORIES_PER_OCTAD)].getMemory(q % NB_MEMORIES_PER_OCTAD);
    let TO = mem.blocks[4 * r + 3];
    let AD = mem.blocks[4 * r + 2];
    let OD = mem.blocks[4 * r + 1];
    let OF = mem.blocks[4 * r];

    // try to compute an instruction, else return nop as an instruction
    // that does not have implementation
    try {
      return this.bullGamma.parser.parseInstruction(TO, AD, OD, OF);
    } catch (error) {
      return new NOP(this.bullGamma);
    }
  }

  /**
   * Return the instruction at the given line, or null if not found
   * @param line programm line of the desired instruction
   */
  getInstructions() {
    let list = [];
    for (let i=0; i<this.maxNbInst; i++) {
      list.push(this.getInstruction(i));
    }
    return list;
  }

}

module.exports.Serie = Serie;