From 6261d9fe379457e322d829df8d2c0dd248d8a35f Mon Sep 17 00:00:00 2001 From: Jaka Furlan Date: Sat, 13 Dec 2025 17:27:34 +0100 Subject: [PATCH] working on prehod 2... --- ass3/zbirnik/lib/drugiPrehod.ml | 50 ++++++++++++++++++---------- ass3/zbirnik/lib/dune | 4 ++- ass3/zbirnik/lib/encoder.ml | 13 +++++--- ass3/zbirnik/lib/instruction.ml | 32 ++++++++++++++++++ ass3/zbirnik/lib/prehodPrvi.ml | 2 +- ass3/zbirnik/lib/semanticAnalyzer.ml | 10 ++++-- 6 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 ass3/zbirnik/lib/instruction.ml diff --git a/ass3/zbirnik/lib/drugiPrehod.ml b/ass3/zbirnik/lib/drugiPrehod.ml index a36d1e1..0fd04b9 100644 --- a/ass3/zbirnik/lib/drugiPrehod.ml +++ b/ass3/zbirnik/lib/drugiPrehod.ml @@ -2,6 +2,7 @@ open Simtab open SemanticAnalyzer open Encoder +open Instruction let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : string list = let prviUkaz, ostaliUkazi = @@ -10,19 +11,21 @@ let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : st | x :: xs -> x, xs in (*if Opcode == start then*) - let objectCodeList = (*string list ki hrani vrstice objektne kode*) + let objectCodeList, start = (*string list ki hrani vrstice objektne kode, start se uporabi še v E zapisu*) if prviUkaz.opcode = START then - getZaglavje prviUkaz lenProg + getZaglavjeAndStart prviUkaz lenProg else failwith "prvi ukaz ni START" in - let instructionList : string list = [] in (*opcodeList shranjuje kode ukazov pretvorjene v stringe, ko se napolni se appenda k objectCodeList*) + 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 - | [] -> () (*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*) + | [] -> 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 @@ -36,20 +39,31 @@ let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : st 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 [] + | _ -> loop xs (newTextLine :: 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*) - () + 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 - 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*) - () + 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 \ No newline at end of file diff --git a/ass3/zbirnik/lib/dune b/ass3/zbirnik/lib/dune index 6a786c3..4309626 100644 --- a/ass3/zbirnik/lib/dune +++ b/ass3/zbirnik/lib/dune @@ -5,4 +5,6 @@ simtab semanticAnalyzer prehodPrvi - encoder)) + encoder + drugiPrehod + instruction)) diff --git a/ass3/zbirnik/lib/encoder.ml b/ass3/zbirnik/lib/encoder.ml index c58b4e6..cd7eafe 100644 --- a/ass3/zbirnik/lib/encoder.ml +++ b/ass3/zbirnik/lib/encoder.ml @@ -2,7 +2,7 @@ open SemanticAnalyzer (*vrne H vrstico*) -let getZaglavje (prviUkaz : lineSemantic) (lenProg : int) : string list = +let getZaglavjeAndStart (prviUkaz : lineSemantic) (lenProg : int) : string list * int = 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*) @@ -17,14 +17,19 @@ let getZaglavje (prviUkaz : lineSemantic) (lenProg : int) : string list = | _ -> failwith "getZaglavje: invalid mnemonic_type" in let lenObjectCode = Printf.sprintf "%06X" lenProg in - ["H" ^ name ^ startAddr ^ lenObjectCode] (*vrnemo concatiniran string in startAddr*) + ["H" ^ name ^ startAddr ^ lenObjectCode], int_of_string startAddr (*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 + "T" ^ startAddr ^ lenString ^ objectCode (*vrnemo concatiniran T zapis*) + +(*vrne E vrstico*) +let getEnd (start : int) : string = + let start = Printf.sprintf "%06X" start in + "E" ^ start \ No newline at end of file diff --git a/ass3/zbirnik/lib/instruction.ml b/ass3/zbirnik/lib/instruction.ml new file mode 100644 index 0000000..9b71ffe --- /dev/null +++ b/ass3/zbirnik/lib/instruction.ml @@ -0,0 +1,32 @@ +(*naloga instruction modula je ustvarjanje instructionLista, torej vsebine T zapisa*) +(*sem spada izbira nacina naslavljanja, dolocanje ali je operand simbol itd..*) + +open SemanticAnalyzer + + +let string_is_symbol (s : string) : bool * string = + try + let _ = int_of_string s in + true, "" + with Failure _ -> false, s + +(*preveri ali je operand iz mnemonic_type simbol ali stevilo*) +let operand_is_symbol (operand : mnemonic_type) : bool * string = (*vrne isSymbol in symbol*) + match operand with + | MnemonicD -> false, "" + | MnemonicDn s -> string_is_symbol s + | MnemonicF1 -> false, "" + | MnemonicF2n _ -> false, "" + | MnemonicF2r _ -> false, "" + | MnemonicF2rn (_, _) -> false, "" + | MnemonicF2rr (_, _) -> false, "" + | MnemonicF3 -> false, "" + | MnemonicF3m s -> string_is_symbol s + | MnemonicF4m s -> string_is_symbol s + | MnemonicSd s -> string_is_symbol s + | MnemonicSn _ -> false, "" + | COMMENT -> false, "" + + +let create_opcode_symbol (opcode : mnemonic) (locSimbola : int) : string = + (*izberi nacin naslavljanja in naredi string ukaza*) \ No newline at end of file diff --git a/ass3/zbirnik/lib/prehodPrvi.ml b/ass3/zbirnik/lib/prehodPrvi.ml index 1573b98..d80d55c 100644 --- a/ass3/zbirnik/lib/prehodPrvi.ml +++ b/ass3/zbirnik/lib/prehodPrvi.ml @@ -35,7 +35,7 @@ let prviPrehod (code : lineSemantic list) : int*lineSemantic list*symtab= (*while opcode != END loop*) let rec loop ostaliUkazi prgLen intermediateFileList = match ostaliUkazi with - | [] -> prgLen, (List.rev intermediateFileList), simtab (*smo konec*) + | [] -> 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 diff --git a/ass3/zbirnik/lib/semanticAnalyzer.ml b/ass3/zbirnik/lib/semanticAnalyzer.ml index 47e21c4..461da51 100644 --- a/ass3/zbirnik/lib/semanticAnalyzer.ml +++ b/ass3/zbirnik/lib/semanticAnalyzer.ml @@ -1,6 +1,10 @@ (*prebere parsano kodo in izvede semantično analizo*) type register = | A | X | L | B | S | T | F | PC | SW +let string_of_register (r : register) : string = + match r with + | A -> "A" | X -> "X" | L -> "L" | B -> "B" | S -> "S" | T -> "T" | F -> "F" | PC -> "PC" | SW -> "SW" + let parse_register = function | "A" -> A | "X" -> X | "L" -> L | "B" -> B | "S" -> S | "T" -> T | "F" -> F | "PC" -> PC | "SW" -> SW @@ -27,9 +31,9 @@ let string_of_mnemonic_type = function | MnemonicDn s -> "MnemonicDn(" ^ s ^ ")" | MnemonicF1 -> "MnemonicF1" | MnemonicF2n n -> "MnemonicF2n(" ^ string_of_int n ^ ")" - | MnemonicF2r _ -> "MnemonicF2r" - | MnemonicF2rn (_, _) -> "MnemonicF2rn" - | MnemonicF2rr (_, _) -> "MnemonicF2rr" + | MnemonicF2r r1 -> "MnemonicF2r(" ^ string_of_register r1 ^ ")" + | MnemonicF2rn (r1, n) -> "MnemonicF2rn(" ^ string_of_register r1 ^ ", " ^ string_of_int n ^ ")" + | MnemonicF2rr (r1, r2) -> "MnemonicF2rr(" ^ string_of_register r1 ^ ", " ^ string_of_register r2 ^ ")" | MnemonicF3 -> "MnemonicF3" | MnemonicF3m s -> "MnemonicF3m(" ^ s ^ ")" | MnemonicF4m s -> "MnemonicF4m(" ^ s ^ ")"