working on ass3, todo pc, nixbpe
This commit is contained in:
parent
6261d9fe37
commit
beabcde7db
15 changed files with 412 additions and 194 deletions
|
|
@ -2,31 +2,143 @@
|
|||
(*sem spada izbira nacina naslavljanja, dolocanje ali je operand simbol itd..*)
|
||||
|
||||
open SemanticAnalyzer
|
||||
open Simtab
|
||||
open OpcodeTable
|
||||
|
||||
type operand =
|
||||
| R of register
|
||||
| RR of register * register
|
||||
| RN of register * int (*register in število*)
|
||||
| N of int (*številski operand*)
|
||||
| S of string (*simbol*)
|
||||
| None
|
||||
|
||||
|
||||
let string_is_symbol (s : string) : bool * string =
|
||||
let string_is_symbol (s : string) : bool * operand =
|
||||
try
|
||||
let _ = int_of_string s in
|
||||
true, ""
|
||||
with Failure _ -> false, s
|
||||
let n = int_of_string s in
|
||||
false, N n
|
||||
with Failure _ -> true, S s
|
||||
|
||||
(*preveri ali je operand iz mnemonic_type simbol ali stevilo*)
|
||||
let operand_is_symbol (operand : mnemonic_type) : bool * string = (*vrne isSymbol in symbol*)
|
||||
let operand_is_symbol (x : lineSemantic) : (bool * operand * int) option = (*vrne isSymbol, operand in dolzino ukaza, ali none, če ukaza/direktive ne bomo zapisali v T file*)
|
||||
match x.mnem with
|
||||
| MnemonicD -> None
|
||||
| MnemonicDn s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len)
|
||||
| MnemonicF1 -> Some (false, None, x.len)
|
||||
| MnemonicF2n n -> Some (false, N n, x.len)
|
||||
| MnemonicF2r r1 -> Some (false, R r1, x.len)
|
||||
| MnemonicF2rn (r1, n) -> Some (false, RN (r1, n), x.len)
|
||||
| MnemonicF2rr (r1, r2) -> Some (false, RR (r1, r2), x.len)
|
||||
| MnemonicF3 -> Some (false, None, x.len)
|
||||
| MnemonicF3m s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len)
|
||||
| MnemonicF4m s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len)
|
||||
| MnemonicSd s -> let (issym, operand) = string_is_symbol s in Some (issym, operand, x.len)
|
||||
| MnemonicSn _ -> None(*RESW in RESB že drugje obdelamo*)
|
||||
| COMMENT -> None (*Comment ze obdelamo drugje*)
|
||||
|
||||
(*helper funkcija za registre*)
|
||||
let int_of_reg (reg : register) : int =
|
||||
match reg with
|
||||
| A -> 0
|
||||
| X -> 1
|
||||
| L -> 2
|
||||
| B -> 3
|
||||
| S -> 4
|
||||
| T -> 5
|
||||
| F -> 6
|
||||
| PC -> 8
|
||||
| SW -> 9
|
||||
|
||||
(*helper funkcija*)
|
||||
let int_to_hex_width (width : int) (n : int) : string =
|
||||
let s = Printf.sprintf "%X" n in
|
||||
let len = String.length s in
|
||||
if len >= width then s
|
||||
else String.make (width - len) '0' ^ s
|
||||
|
||||
let char_to_hex c =
|
||||
Printf.sprintf "%02X" (Char.code c)
|
||||
|
||||
(*naredi binaren zapis F1 oz string nibblov celotnega ukaza*)
|
||||
let get_bin_instruction_F1 (opcode : int) : string =
|
||||
int_to_hex_width 2 opcode
|
||||
|
||||
(*naredi binaren zapis F2 oz string nibblov celotnega ukaza*)
|
||||
let get_bin_instruction_F2 (opcode : int) (operand : operand) : string =
|
||||
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, ""
|
||||
| RR (r1, r2) -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 (int_of_reg r1)) ^ (int_to_hex_width 1 (int_of_reg r2))
|
||||
| RN (r1, n) -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 (int_of_reg r1)) ^ (int_to_hex_width 1 n)
|
||||
| R r1 -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 (int_of_reg r1)) ^ (int_to_hex_width 1 0) (*r2 -> 0*)
|
||||
| N n -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 n) ^ (int_to_hex_width 1 0)
|
||||
| _ -> failwith "invalid operand type for F2 instruction"
|
||||
|
||||
let get_bin_instruction_F3 (opcode : int) (simtab : symtab) (operand : operand) (_ : int option) : string =
|
||||
match operand with
|
||||
| None -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 4 0) (*RSUB damo z disp = 0*)
|
||||
| N n -> (*todo dodaj n_i*) (int_to_hex_width 2 opcode) ^ (*todo add xbpe*) (int_to_hex_width 1 0) ^ (int_to_hex_width 3 n)
|
||||
| S s -> let operand = Hashtbl.find simtab s in (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 0) ^ (int_to_hex_width 3 operand)
|
||||
| _ -> ""
|
||||
|
||||
let get_bin_instruction_F4 (opcode : int) (simtab : symtab) (operand : operand) (_ : int option) : string =
|
||||
match operand with
|
||||
| None -> (int_to_hex_width 2 opcode) ^ (int_to_hex_width 6 0) (*RSUB damo z disp = 0*)
|
||||
| N n -> (*todo dodaj n_i*) (int_to_hex_width 2 opcode) ^ (*todo add xbpe*) (int_to_hex_width 1 0) ^ (int_to_hex_width 5 n)
|
||||
| S s -> let operand = Hashtbl.find simtab s in (int_to_hex_width 2 opcode) ^ (int_to_hex_width 1 0) ^ (int_to_hex_width 5 operand)
|
||||
| _ -> ""
|
||||
|
||||
let create_opcode (simtab : symtab) (opcodeTab : opcodeTab) (opcode : mnemonic) (operand : operand) (formatLen : int) (loc : int option) : string =
|
||||
(*izberi nacin naslavljanja in naredi string ukaza*)
|
||||
match formatLen with
|
||||
| 1 -> get_bin_instruction_F1 (find_opcode opcodeTab opcode)
|
||||
| 2 -> get_bin_instruction_F2 (find_opcode opcodeTab opcode) operand
|
||||
| 3 -> get_bin_instruction_F3 (find_opcode opcodeTab opcode) simtab operand loc
|
||||
| 4 -> get_bin_instruction_F4 (find_opcode opcodeTab opcode) simtab operand loc
|
||||
| _ -> failwith "invalid formatLen"
|
||||
|
||||
(*opcode BYTE direktive*)
|
||||
let create_opcode_byte (operand : string) : string =
|
||||
if String.length operand < 3 then
|
||||
failwith "Invalid BYTE operand, use X'...' or C'...'!"
|
||||
else
|
||||
match operand.[0] with
|
||||
| 'C' ->
|
||||
(* e.g., C'EOF' *)
|
||||
let content = String.sub operand 2 (String.length operand - 3) in
|
||||
let len = String.length content in
|
||||
if len <> 1 then failwith "BYTE C'...' has to have a operand of length 1 inside hte '...' brackets!" else
|
||||
String.concat "" (List.init (String.length content) (fun i -> char_to_hex content.[i]))
|
||||
| 'X' ->
|
||||
(* e.g., X'F1' *)
|
||||
let hex = String.sub operand 2 (String.length operand - 3) in
|
||||
if String.length hex >= 6 then
|
||||
failwith "WORD X'...' has to have a operand of length <= 6 inside hte '...' brackets!"
|
||||
else String.make (2 - String.length hex) '0' ^ hex
|
||||
| _ ->
|
||||
let n = int_of_string operand in
|
||||
Printf.sprintf "%02X" n
|
||||
|
||||
let create_opcode_word (operand : string) : string =
|
||||
if String.length operand = 0 then
|
||||
failwith "Invalid WORD operand use X'...' or C'...'!"
|
||||
else
|
||||
match operand.[0] with
|
||||
| 'C' ->
|
||||
(* WORD as C'...' *)
|
||||
let content = String.sub operand 2 (String.length operand - 3) in
|
||||
let len = String.length content in
|
||||
if len <> 3 then failwith "WORD C'...' has to have a operand of length 3 inside hte '...' brackets!" else
|
||||
let hex = String.concat "" (List.init len (fun i -> char_to_hex content.[i])) in
|
||||
(* pad to 6 hex digits for WORD *)
|
||||
if String.length hex >= 6 then hex else String.make (6 - String.length hex) '0' ^ hex
|
||||
| 'X' ->
|
||||
(* WORD as X'...' *)
|
||||
let hex = String.sub operand 2 (String.length operand - 3) in
|
||||
if String.length hex >= 6 then
|
||||
failwith "WORD X'...' has to have a operand of length <= 6 inside hte '...' brackets!"
|
||||
else String.make (6 - String.length hex) '0' ^ hex
|
||||
| _ ->
|
||||
(* numeric constant *)
|
||||
let n = int_of_string operand in
|
||||
Printf.sprintf "%06X" n
|
||||
|
||||
let create_opcode_symbol (opcode : mnemonic) (locSimbola : int) : string =
|
||||
(*izberi nacin naslavljanja in naredi string ukaza*)
|
||||
Loading…
Add table
Add a link
Reference in a new issue