diff --git a/ass3/zbirnik/lib/drugiPrehod.ml b/ass3/zbirnik/lib/drugiPrehod.ml index 5ea62ee..a36d1e1 100644 --- a/ass3/zbirnik/lib/drugiPrehod.ml +++ b/ass3/zbirnik/lib/drugiPrehod.ml @@ -1,17 +1,55 @@ (*funkcija drugega prehoda*) open Simtab open SemanticAnalyzer +open Encoder -let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) = +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 _ = + let objectCodeList = (*string list ki hrani vrstice objektne kode*) if prviUkaz.opcode = START then - (*TODO write listing line*) + getZaglavje prviUkaz lenProg + else + failwith "prvi ukaz ni START" in - (*TODO write header record to object program*) - (*TODO initialize first text record*) \ No newline at end of file + let instructionList : string list = [] in (*opcodeList 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 + | [] -> () (*smo konec*) + | x :: _ when x.opcode = END -> () (*TODO write last text record to object programm*) + (*TODO write end record to object program*) + (*TODOwrite last listing line*) + | 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 [] + | ntl -> loop xs (ntl :: objectCodeList) newStartAddress [] + end + | _ -> (*if not comment or reserve*) + let opcode = getOpcode x.opcode in + (*if simbol na mestu opeanda*) + let isSymbol, symbol = operand_is_symbol x.mnem in + if isSymbol then + let locSimbola = find_symbol tab symbol in + let opcode = create_opcode x.opcode locSimbola in + (*TODO dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*) + () + else + let opcode = create_opcode x.opcode (int_of_string symbol) in (*symbol je tukaj kar stevilska vrednost/register*) + (*TODO dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*) + () + + in loop ostaliUkazi objectCodeList startAddr instructionList \ No newline at end of file diff --git a/ass3/zbirnik/lib/dune b/ass3/zbirnik/lib/dune index deeb942..6a786c3 100644 --- a/ass3/zbirnik/lib/dune +++ b/ass3/zbirnik/lib/dune @@ -1,3 +1,8 @@ (library (name zbirnik) - (libraries str)) + (libraries str) + (modules parser + simtab + semanticAnalyzer + prehodPrvi + encoder)) diff --git a/ass3/zbirnik/lib/encoder.ml b/ass3/zbirnik/lib/encoder.ml new file mode 100644 index 0000000..c58b4e6 --- /dev/null +++ b/ass3/zbirnik/lib/encoder.ml @@ -0,0 +1,30 @@ +(*naloga encoderja je, da pretvarja iz lineSemantic tipa v stringe ki jih appendamo v object file*) + +open SemanticAnalyzer +(*vrne H vrstico*) +let getZaglavje (prviUkaz : lineSemantic) (lenProg : int) : string list = + let name = match prviUkaz.label with + | None -> "MOJPROG" (*default ime*) + | Some s -> if String.length s > 6 then "MOJPROG" else String.make (6 - String.length s) '0' ^ s (*paddamo z 0 če je < 6*) + in + let startAddr = match prviUkaz.mnem with + | MnemonicDn s -> (*preverimo ali je pravilne dolzine in naredimo string dolzine 6*) + let n = int_of_string s in + if n < 0 || n > 0xFFFFFF then + invalid_arg "getZaglavje: zacetni naslov out of range" + else + Printf.sprintf "%06X" n + | _ -> failwith "getZaglavje: invalid mnemonic_type" + in + let lenObjectCode = Printf.sprintf "%06X" lenProg in + ["H" ^ name ^ startAddr ^ lenObjectCode] (*vrnemo concatiniran string in startAddr*) + + +(*vrne T vrstico*) +let instructionList_to_objectCode (instructionList : string list) (startAddr : int) : string = + + let startAddr = Printf.sprintf "%06X" startAddr in + let objectCode = String.concat "" instructionList in + let len = (String.length objectCode) / 2 in (*delimo z dva ker hočemo dolžino v bytih ne nibblih*) + let lenString = Printf.sprintf "%02X" len in + "T" ^ startAddr ^ lenString ^ objectCode (*vrnemo concatiniran T zapis*) \ No newline at end of file diff --git a/ass3/zbirnik/lib/simtab.ml b/ass3/zbirnik/lib/simtab.ml index bd5acec..5658f7e 100644 --- a/ass3/zbirnik/lib/simtab.ml +++ b/ass3/zbirnik/lib/simtab.ml @@ -9,4 +9,7 @@ let add_symbol (tab : symtab) (label : string) (addr : int) = if Hashtbl.mem tab label then failwith "Duplicate symbol in simtab" else - Hashtbl.add tab label addr \ No newline at end of file + Hashtbl.add tab label addr + +let find_symbol (tab : symtab) (label : string) : int = + Hashtbl.find tab label \ No newline at end of file