(*tukaj je vse povezano s prvim prehodom zbirnika*)
open SemanticAnalyzer
open Simtab



(*funkcija prvega prehoda, !!! za END ne sme biti nič več definiranih ukazov ali direktiv!*)
let prviPrehod (code : lineSemantic list) : int*lineSemantic list*symtab=
  (*inicializiramo startAddr, loctr in simtab*)
  let startAddr = ref 0 in
  let locctr = ref 0 in 
  let simtab = create_symtab () in

  let prviUkaz, ostaliUkazi = 
    match code with
    | [] -> failwith "empty code"
    | x :: xs -> x, xs
  in

  (*if Opcode == start then*)
  let intermediateFileList = 
    if prviUkaz.opcode = START then
      let stAdr = get_string_from_mnemType prviUkaz.mnem in
      let stAdr = match stAdr with | Some s -> s | None -> "0" in
      startAddr := (int_of_string stAdr);
      locctr := !startAddr;
      (*write line to intermediate file*)
      prviUkaz.loc <- Some !locctr;
      [prviUkaz] 
    else 
      (*initialize locctr to 0*)
      (locctr := 0;
      [])
  in
  (*while opcode != END loop*)
  let rec loop ostaliUkazi prgLen intermediateFileList = 
    match ostaliUkazi with
    | [] -> failwith "no END mnemonic at the end of the code!"
    | x :: _ when x.opcode = END -> (*konec while loopa*) (*write last line to intermediate file, save the locctr - st addr as prg len*)
      x.loc <- Some !locctr;
      let intermediateFileList = x :: intermediateFileList in
      let prgLen = !locctr - !startAddr in
      prgLen, (List.rev intermediateFileList), simtab (*vrnemo program length*)
    | x :: xs -> match x.opcode with (*loopamo*)
      | COMMENT -> loop xs prgLen intermediateFileList(*if this is a comment line*)
      | _ ->
        (*if there is a symmbol in label field*)
        begin
        match x.label with
        | None -> ()
        | Some s -> 
           (*search simtab for s ...*)
           (*doda simbol ce še ne obstaja, sier faila*)
           add_symbol simtab s !locctr
        end;

        (*write line to intermediate file*)
        x.loc <- Some !locctr;
        (*search opcode -> smo ze naredili v semanticni analizi, tu bomo le ustrezno povečali locctr*)
        locctr := !locctr + x.len; 
        let intermediateFileList = x :: intermediateFileList in
        loop xs prgLen (intermediateFileList) (*read nex input line end while*)
  in loop ostaliUkazi 0 intermediateFileList

