working on pass 2
This commit is contained in:
parent
7810346819
commit
f79aa96359
4 changed files with 83 additions and 7 deletions
|
|
@ -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
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
(library
|
(library
|
||||||
(name zbirnik)
|
(name zbirnik)
|
||||||
(libraries str))
|
(libraries str)
|
||||||
|
(modules parser
|
||||||
|
simtab
|
||||||
|
semanticAnalyzer
|
||||||
|
prehodPrvi
|
||||||
|
encoder))
|
||||||
|
|
|
||||||
30
ass3/zbirnik/lib/encoder.ml
Normal file
30
ass3/zbirnik/lib/encoder.ml
Normal 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*)
|
||||||
|
|
@ -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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue