69 lines
No EOL
3.7 KiB
OCaml
69 lines
No EOL
3.7 KiB
OCaml
(*funkcija drugega prehoda*)
|
|
open Simtab
|
|
open SemanticAnalyzer
|
|
open Encoder
|
|
open Instruction
|
|
|
|
let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : string list =
|
|
let prviUkaz, ostaliUkazi =
|
|
match ifl with
|
|
| [] -> failwith "empty code"
|
|
| x :: xs -> x, xs
|
|
in
|
|
(*if Opcode == start then*)
|
|
let objectCodeList, start = (*string list ki hrani vrstice objektne kode, start se uporabi še v E zapisu*)
|
|
if prviUkaz.opcode = START then
|
|
getZaglavjeAndStart prviUkaz lenProg
|
|
else
|
|
failwith "prvi ukaz ni START"
|
|
in
|
|
let instructionList : string list = [] in (*instructionList shranjuje kode ukazov pretvorjene v stringe, ko se napolni se appenda k objectCodeList*)
|
|
let rec loop (ostaliUkazi : lineSemantic list) (objectCodeList : string list) (startAddr : int) (instructionList : string list) : string list =
|
|
match ostaliUkazi with
|
|
| [] -> failwith "no END mnemonic at the end of the code!"
|
|
| x :: _ when x.opcode = END -> (*write last text record to object programm*)
|
|
let newTextLine = instructionList_to_objectCode (List.rev instructionList) startAddr in (*naredimo novo T vrstico*)
|
|
let endLine = getEnd start in (*naredimo End zapis*)
|
|
let objectCodeList = List.rev (endLine :: newTextLine :: objectCodeList) in
|
|
objectCodeList (*vrnemo celotno objektno kodo*)
|
|
| x :: xs ->
|
|
(*pridobi začeten naslov TEXT vrstice, če je le ta prazna*)
|
|
let newStartAddress = match instructionList with
|
|
| [] -> begin match x.loc with None -> failwith "ukaz nima lokacije!" | Some l -> l end
|
|
| _ -> startAddr
|
|
in
|
|
match x.opcode with
|
|
| COMMENT -> loop xs objectCodeList newStartAddress instructionList
|
|
| RESB | RESW -> (*dodamo trenutno TEXT vrstico k objektni kodi in inicializiramo novo*)
|
|
let newTextLine = instructionList_to_objectCode (List.rev instructionList) newStartAddress in (*naredimo novo T vrstico*)
|
|
begin
|
|
match instructionList with (*če je instructionList prazen, npr. 2 zaporedna RESB ukaza, ne dodamo te prazne T vrstice v obj kodo*)
|
|
| [] -> loop xs objectCodeList newStartAddress []
|
|
| _ -> loop xs (newTextLine :: objectCodeList) newStartAddress []
|
|
end
|
|
| _ -> (*if not comment or reserve*)
|
|
(*if simbol na mestu opeanda*)
|
|
let isSymbol, symbol = operand_is_symbol x.mnem in
|
|
if isSymbol then
|
|
begin
|
|
let locSimbola = find_symbol tab symbol in
|
|
let opcode = create_opcode_symbol x.opcode locSimbola in
|
|
(*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*)
|
|
if String.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*)
|
|
let newTextLine = instructionList_to_objectCode (List.rev instructionList) newStartAddress in (*naredimo novo T vrstico*)
|
|
loop xs (newTextLine :: objectCodeList) newStartAddress []
|
|
else
|
|
loop xs objectCodeList newStartAddress (opcode :: instructionList)
|
|
end
|
|
else
|
|
let opcode = create_opcode x.opcode x.mnem in (*symbol je tukaj kar stevilska vrednost/register*)
|
|
(*TODO dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*)
|
|
begin
|
|
if String.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*)
|
|
let newTextLine = instructionList_to_objectCode (List.rev instructionList) newStartAddress in (*naredimo novo T vrstico*)
|
|
loop xs (newTextLine :: objectCodeList) newStartAddress []
|
|
else
|
|
loop xs objectCodeList newStartAddress (opcode :: instructionList)
|
|
end
|
|
|
|
in loop ostaliUkazi objectCodeList startAddr instructionList |