int skip_labels(int labels) {
  while (numberp(Mcar(labels)) == Mtrue)
    labels = Mcdr(labels);
  return labels;
}

int find_label_target(int l, int labels) {
  return skip_labels(memv_(l, labels));
}

void update_branch(int instruction, int code) {
  int temp;
  temp = rplaca(
    Mcdr(instruction),
    find_label_target(Mcar(Mcdr(Mcdr(instruction))), code));
  return;
}

void resolve_labels(int code) {
  int temp;
  int instruction;
  instruction = code;
  while (instruction != 0) {
    if (Mlistp(Mcar(instruction))) {
      if (eq(Mcar(Mcar(instruction)), procatom) == Mtrue)
        temp = assemble(Mcdr(Mcar(instruction)));
      else
      if (memq_(Mcar(Mcar(instruction)), label_instructions) != Mfalse)
        update_branch(Mcar(instruction), code);
    }
    instruction = Mcdr(instruction);
  }
  return;
}

int eliminate_labels(int code) {
  int temp;
  int instruction;
  if (numberp(Mcar(code)) == Mtrue)
    code = skip_labels(code);

  instruction = code;
  while (instruction != 0) {
    if (numberp(Mcar(Mcdr(instruction))) == Mtrue)
      temp = rplacd(instruction, skip_labels(Mcdr(instruction)));
    else
    if (eq(Mcar(Mcar(instruction)), procatom) == Mtrue)
      temp =
        rplacd(Mcar(instruction), eliminate_labels(Mcdr(Mcar(instruction))));
    instruction = Mcdr(instruction);
  }
  return code;
}

int assemble(int code) {
  resolve_labels(code);
  return eliminate_labels(code);
}
