working on pass 2

This commit is contained in:
Jaka Furlan 2025-12-13 16:11:31 +01:00
parent 7810346819
commit f79aa96359
4 changed files with 83 additions and 7 deletions

View file

@ -1,17 +1,55 @@
(*funkcija drugega prehoda*) (*funkcija drugega prehoda*)
open Simtab open Simtab
open SemanticAnalyzer 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 = let prviUkaz, ostaliUkazi =
match ifl with match ifl with
| [] -> failwith "empty code" | [] -> failwith "empty code"
| x :: xs -> x, xs | x :: xs -> x, xs
in in
(*if Opcode == start then*) (*if Opcode == start then*)
let _ = let objectCodeList = (*string list ki hrani vrstice objektne kode*)
if prviUkaz.opcode = START then if prviUkaz.opcode = START then
(*TODO write listing line*) getZaglavje prviUkaz lenProg
else
failwith "prvi ukaz ni START"
in in
(*TODO write header record to object program*) let instructionList : string list = [] in (*opcodeList shranjuje kode ukazov pretvorjene v stringe, ko se napolni se appenda k objectCodeList*)
(*TODO initialize first text record*) 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

View file

@ -1,3 +1,8 @@
(library (library
(name zbirnik) (name zbirnik)
(libraries str)) (libraries str)
(modules parser
simtab
semanticAnalyzer
prehodPrvi
encoder))

View file

@ -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*)

View file

@ -9,4 +9,7 @@ let add_symbol (tab : symtab) (label : string) (addr : int) =
if Hashtbl.mem tab label then if Hashtbl.mem tab label then
failwith "Duplicate symbol in simtab" failwith "Duplicate symbol in simtab"
else else
Hashtbl.add tab label addr Hashtbl.add tab label addr
let find_symbol (tab : symtab) (label : string) : int =
Hashtbl.find tab label