This commit is contained in:
Jaka Furlan 2025-12-07 20:13:19 +01:00
parent 586a58fd94
commit c707e3253c
53 changed files with 500 additions and 27 deletions

3
ass3/zbirnik/lib/dune Normal file
View file

@ -0,0 +1,3 @@
(library
(name zbirnik)
(libraries str))

View file

@ -0,0 +1,88 @@
(*sprejme .asm file in pretvori v neko interno predstavitev*)
type line = {
line_no : int;
label : string option;
opcode : string;
operand : string list; (*list of operands*)
comment : string option;
mutable loc : int option; (* assigned in pass1 *)
}
let parseLine (lineNo : int) (line : string) : line option=
let trimmedLine = String.trim (line) in (*Znebimo se zacetnih in koncnih presledkov*)
(*empty line or comment line*)
if trimmedLine = "" then None
else if trimmedLine.[0] = '.' then
Some {
line_no = lineNo;
label = None;
opcode = "COMMENT";
operand = [];
comment = Some trimmedLine ;
loc = None;
}
else
(*razdelimo na kodo in komentar za njo*)
let code, (comment : string option) =
match String.index_opt line '.' with
| None -> line, None
| Some i ->
(*izluščimo komentar in komentarju odstranimo predhodnje presledke*)
let c = String.sub line i (String.length line - i) |> String.trim in
(*izluščimo kodo, je pa ne trimamo, ker rabimo prvo presledek da razločimo opcode od label-a*)
let code = String.sub line 0 i in
code, Some c
in
let tokens =
code
|> String.map (fun c -> if c = ',' then ' ' else c) (*zamenja , z ' ' da lepo parsamo npr RMO A, B*)
|> String.split_on_char ' '
|> List.map String.trim (* removes surrounding spaces and \r *)
|> List.filter (fun s -> s <> "") in
match tokens with
| [] ->
Some{
line_no = lineNo;
label = None;
opcode = "";
operand = [];
comment;
loc = None;
}
| x :: xs ->
if code.[0] <> ' ' && code.[0] <> '\t' then (*pogledamo whitespace ali tab*)
(*se ne začne z presledkom ali tab -> imamo labelo*)
let label = Some x in
match xs with
(*samo labela*)
| [] -> Some{line_no = lineNo; label = label; opcode = ""; operand = []; comment = comment; loc = None}
(*labela + opcode + še nekaj*)
| opcode :: operand ->
Some{line_no = lineNo; label = label;opcode = opcode; operand = operand; comment = comment; loc = None}
else
(*nimamo labele*)
let opcode = x in
let operand = xs in
Some{line_no = lineNo; label = None; opcode = opcode; operand = operand; comment = comment; loc = None}
(*naredi listo line-ov iz filename*)
let parser (filename : string) : line list =
let ic = open_in filename in
let rec loop line_no acc =
match input_line ic with
| line ->
begin
match parseLine line_no line with
| Some parsed_line -> loop (line_no + 1) (parsed_line :: acc)
| None -> loop (line_no + 1) acc
end
| exception End_of_file ->
close_in ic;
List.rev acc
in
loop 1 []

View file

@ -0,0 +1,45 @@
(*tukaj je vse povezano s prvim prehodom zbirnika*)
open SemanticAnalyzer
let startAddr = ref 0
let locctr = ref 0
let prviPrehod (code : lineSemantic list) =
let prviUkaz, ostaliUkazi =
match code with
| [] -> failwith "empty code"
| x :: xs -> x, xs
in
(*if Opcode == start then*)
if prviUkaz.opcode = START then
let stAdr = get_string_from_mnemType prviUkaz.mnem in
let stAdr = match stAdr with | Some s -> s | None -> "0" in
startAddr := (int_of_string stAdr);
locctr := !startAddr;
(*TODO write line to intermediate file*)
else
(*initialize locctr to 0*)
locctr := 0
;
(*while opcode != END loop*)
let rec loop ostaliUkazi =
match ostaliUkazi with
| [] -> () (*smo konec*)
| x :: _ when x.opcode = END -> () (*konec while loopa*) (*TODO write last line to intermediate file, save the locctr - st addr as prg len*)
| x :: xs -> match x.opcode with
| COMMENT -> loop xs (*if this is a comment line*)
| _ ->
(*if there is a symmbol in label field*)
let s = match x.label with
| None -> ()
| Some s -> () (*search simtab for s ...*)
in
(*search opcode -> smo ze naredili v semanticni analizi, tu bomo le ustrezno povečali locctr*)
locctr := !locctr + x.len;
(*TODO write line to intermediate file*)
loop xs (*read nex input line end while*)
in loop ostaliUkazi