working on ass3, todo pc, nixbpe
This commit is contained in:
parent
6261d9fe37
commit
beabcde7db
15 changed files with 412 additions and 194 deletions
|
|
@ -3,8 +3,9 @@ open Simtab
|
|||
open SemanticAnalyzer
|
||||
open Encoder
|
||||
open Instruction
|
||||
open OpcodeTable
|
||||
|
||||
let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : string list =
|
||||
let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (opcodeTab : opcodeTab) (lenProg : int) : string list =
|
||||
let prviUkaz, ostaliUkazi =
|
||||
match ifl with
|
||||
| [] -> failwith "empty code"
|
||||
|
|
@ -41,29 +42,35 @@ let drugiPrehod (ifl : lineSemantic list) (simtab : symtab) (lenProg : int) : st
|
|||
| [] -> loop xs objectCodeList newStartAddress []
|
||||
| _ -> loop xs (newTextLine :: objectCodeList) newStartAddress []
|
||||
end
|
||||
| BYTE ->
|
||||
let operand = match x.mnem with | MnemonicSd s -> s | _ -> failwith "narobe mnemType za BYTE" in
|
||||
let opcode = create_opcode_byte operand in
|
||||
(*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*)
|
||||
if List.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*)
|
||||
let newTextLine = instructionList_to_objectCode (List.rev (opcode :: instructionList)) newStartAddress in (*naredimo novo T vrstico*)
|
||||
loop xs (newTextLine :: objectCodeList) newStartAddress []
|
||||
else
|
||||
loop xs objectCodeList newStartAddress (opcode :: instructionList)
|
||||
| WORD ->
|
||||
let operand = match x.mnem with | MnemonicSd s -> s | _ -> failwith "narobe mnemType za WORD" in
|
||||
let opcode = create_opcode_word operand in
|
||||
(*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*)
|
||||
if List.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*)
|
||||
let newTextLine = instructionList_to_objectCode (List.rev (opcode :: instructionList)) newStartAddress in (*naredimo novo T vrstico*)
|
||||
loop xs (newTextLine :: objectCodeList) newStartAddress []
|
||||
else
|
||||
loop xs objectCodeList newStartAddress (opcode :: instructionList)
|
||||
| _ -> (*if not comment or reserve*)
|
||||
(*if simbol na mestu opeanda*)
|
||||
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
|
||||
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
|
||||
match operand_is_symbol x with
|
||||
| None -> loop xs objectCodeList newStartAddress instructionList (*None -> ta ukaz se ne zapiše, ga skipamo*)
|
||||
| Some (_, operand, formatLen) ->
|
||||
let opcode = create_opcode simtab opcodeTab x.opcode operand formatLen x.loc in
|
||||
(*dodaj opcode v line, ce ni prostora dodaj line v file in naredi novega*)
|
||||
if List.length instructionList > 25 then (*če ratuje T zapis predolg dodamo še tole in nato nadaljujemo z novim*)
|
||||
let newTextLine = instructionList_to_objectCode (List.rev (opcode :: instructionList)) newStartAddress in (*naredimo novo T vrstico*)
|
||||
loop xs (newTextLine :: objectCodeList) newStartAddress []
|
||||
else
|
||||
loop xs objectCodeList newStartAddress (opcode :: instructionList)
|
||||
|
||||
in loop ostaliUkazi objectCodeList startAddr instructionList
|
||||
in loop ostaliUkazi objectCodeList start instructionList
|
||||
|
|
@ -1,10 +1,3 @@
|
|||
(library
|
||||
(name zbirnik)
|
||||
(libraries str)
|
||||
(modules parser
|
||||
simtab
|
||||
semanticAnalyzer
|
||||
prehodPrvi
|
||||
encoder
|
||||
drugiPrehod
|
||||
instruction))
|
||||
(libraries str))
|
||||
|
|
|
|||
|
|
@ -7,17 +7,17 @@ let getZaglavjeAndStart (prviUkaz : lineSemantic) (lenProg : int) : string list
|
|||
| 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
|
||||
let startAddrString, startAddrInt = 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
|
||||
(Printf.sprintf "%06X" n), n
|
||||
| _ -> failwith "getZaglavje: invalid mnemonic_type"
|
||||
in
|
||||
let lenObjectCode = Printf.sprintf "%06X" lenProg in
|
||||
["H" ^ name ^ startAddr ^ lenObjectCode], int_of_string startAddr (*vrnemo concatiniran string in startAddr*)
|
||||
["H" ^ name ^ startAddrString ^ lenObjectCode], startAddrInt(*vrnemo concatiniran string in startAddr*)
|
||||
|
||||
|
||||
(*vrne T vrstico*)
|
||||
|
|
|
|||
|
|
@ -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*)
|
||||
77
ass3/zbirnik/lib/opcodeTable.ml
Normal file
77
ass3/zbirnik/lib/opcodeTable.ml
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
open SemanticAnalyzer
|
||||
|
||||
type opcodeTab = (mnemonic, int) Hashtbl.t
|
||||
|
||||
let find_opcode (tab : opcodeTab) (mnemonic : mnemonic) : int =
|
||||
try
|
||||
Hashtbl.find tab mnemonic
|
||||
with
|
||||
| Not_found -> failwith (Printf.sprintf "[OpcodeTable] Mnemonic not found: '%s'." (string_of_mnemonic mnemonic) )
|
||||
|
||||
let get_opcode_table () : opcodeTab=
|
||||
let opcode_table : (mnemonic, int) Hashtbl.t = Hashtbl.create 128 in
|
||||
let add mnemonic opcode =
|
||||
Hashtbl.add opcode_table mnemonic opcode
|
||||
in
|
||||
|
||||
(* Format 1 *)
|
||||
add FIX 0xC4;
|
||||
add FLOAT 0xC0;
|
||||
add HIO 0xC8;
|
||||
add NORM 0xC1;
|
||||
add SIO 0xF0;
|
||||
add TIO 0xF8;
|
||||
|
||||
(* Format 2 *)
|
||||
add ADDR 0x90;
|
||||
add CLEAR 0xB4;
|
||||
add COMPR 0xA0;
|
||||
add DIVR 0x9C;
|
||||
add MULR 0x98;
|
||||
add RMO 0xAC;
|
||||
add SHIFTL 0xA4;
|
||||
add SHIFTR 0xA8;
|
||||
add SUBR 0x94;
|
||||
add SVC 0xB0;
|
||||
add TIXR 0xB8;
|
||||
|
||||
(* Format 3 / 4 *)
|
||||
add ADD 0x18;
|
||||
add ADDF 0x58;
|
||||
add AND 0x40;
|
||||
add COMP 0x28;
|
||||
add COMPF 0x88;
|
||||
add DIV 0x24;
|
||||
add J 0x3C;
|
||||
add JEQ 0x30;
|
||||
add JGT 0x34;
|
||||
add JLT 0x38;
|
||||
add JSUB 0x48;
|
||||
add LDA 0x00;
|
||||
add LDB 0x68;
|
||||
add LDCH 0x50;
|
||||
add LDF 0x70;
|
||||
add LDL 0x08;
|
||||
add LDS 0x6C;
|
||||
add LDT 0x74;
|
||||
add LDX 0x04;
|
||||
add LPS 0xD0;
|
||||
add MUL 0x20;
|
||||
add OR 0x44;
|
||||
add RD 0xD8;
|
||||
add RSUB 0x4C;
|
||||
add STA 0x0C;
|
||||
add STB 0x78;
|
||||
add STCH 0x54;
|
||||
add STF 0x80;
|
||||
add STL 0x14;
|
||||
add STS 0x7C;
|
||||
add STSW 0xE8;
|
||||
add STT 0x84;
|
||||
add STX 0x10;
|
||||
add SUB 0x1C;
|
||||
add SUBF 0x5C;
|
||||
add TD 0xE0;
|
||||
add TIX 0x2C;
|
||||
add WD 0xDC;
|
||||
opcode_table
|
||||
|
|
@ -117,6 +117,9 @@ type lineSemantic = {
|
|||
ext : bool; (*za razlikovanje med F3 in F4*)
|
||||
opcode : mnemonic;
|
||||
mnem : mnemonic_type;
|
||||
x : bool; (*ali imamo X naslavljanje*)
|
||||
n : bool;
|
||||
i : bool;
|
||||
comment : string option;
|
||||
len : int; (*dolžina, pove za koliko moramo povečati locctr*)
|
||||
mutable loc : int option; (* assigned in pass1 *)
|
||||
|
|
@ -130,78 +133,30 @@ let getMnem (opcode : string) : mnemonic * bool =
|
|||
let o =
|
||||
match opcode with
|
||||
(* ------------------- Format 1 instructions ------------------- *)
|
||||
| "FIX" -> FIX
|
||||
| "FLOAT" -> FLOAT
|
||||
| "HIO" -> HIO
|
||||
| "NORM" -> NORM
|
||||
| "SIO" -> SIO
|
||||
| "TIO" -> TIO
|
||||
| "FIX" -> FIX | "FLOAT" -> FLOAT | "HIO" -> HIO
|
||||
| "NORM" -> NORM | "SIO" -> SIO | "TIO" -> TIO
|
||||
|
||||
(* ------------------- Format 2 instructions ------------------- *)
|
||||
| "ADDR" -> ADDR
|
||||
| "CLEAR" -> CLEAR
|
||||
| "COMPR" -> COMPR
|
||||
| "DIVR" -> DIVR
|
||||
| "MULR" -> MULR
|
||||
| "RMO" -> RMO
|
||||
| "SHIFTL" -> SHIFTL
|
||||
| "SHIFTR" -> SHIFTR
|
||||
| "SUBR" -> SUBR
|
||||
| "SVC" -> SVC
|
||||
| "TIXR" -> TIXR
|
||||
| "ADDR" -> ADDR | "CLEAR" -> CLEAR | "COMPR" -> COMPR | "DIVR" -> DIVR
|
||||
| "MULR" -> MULR | "RMO" -> RMO | "SHIFTL" -> SHIFTL | "SHIFTR" -> SHIFTR
|
||||
| "SUBR" -> SUBR | "SVC" -> SVC | "TIXR" -> TIXR
|
||||
|
||||
(* ------------------- Format 3/4 instructions ------------------- *)
|
||||
| "ADD" -> ADD
|
||||
| "ADDF" -> ADDF
|
||||
| "AND" -> AND
|
||||
| "COMP" -> COMP
|
||||
| "COMPF" -> COMPF
|
||||
| "DIV" -> DIV
|
||||
| "J" -> J
|
||||
| "JEQ" -> JEQ
|
||||
| "JGT" -> JGT
|
||||
| "JLT" -> JLT
|
||||
| "JSUB" -> JSUB
|
||||
| "LDA" -> LDA
|
||||
| "LDB" -> LDB
|
||||
| "LDCH" -> LDCH
|
||||
| "LDF" -> LDF
|
||||
| "LDL" -> LDL
|
||||
| "LDS" -> LDS
|
||||
| "LDT" -> LDT
|
||||
| "LDX" -> LDX
|
||||
| "LPS" -> LPS
|
||||
| "MUL" -> MUL
|
||||
| "OR" -> OR
|
||||
| "RD" -> RD
|
||||
| "RSUB" -> RSUB
|
||||
| "STA" -> STA
|
||||
| "STB" -> STB
|
||||
| "STCH" -> STCH
|
||||
| "STF" -> STF
|
||||
| "STL" -> STL
|
||||
| "STS" -> STS
|
||||
| "STSW" -> STSW
|
||||
| "STT" -> STT
|
||||
| "STX" -> STX
|
||||
| "SUB" -> SUB
|
||||
| "SUBF" -> SUBF
|
||||
| "TD" -> TD
|
||||
| "TIX" -> TIX
|
||||
| "WD" -> WD
|
||||
| "ADD" -> ADD | "ADDF" -> ADDF | "AND" -> AND | "COMP" -> COMP
|
||||
| "COMPF" -> COMPF | "DIV" -> DIV | "J" -> J | "JEQ" -> JEQ
|
||||
| "JGT" -> JGT | "JLT" -> JLT | "JSUB" -> JSUB | "LDA" -> LDA
|
||||
| "LDB" -> LDB | "LDCH" -> LDCH | "LDF" -> LDF | "LDL" -> LDL
|
||||
| "LDS" -> LDS | "LDT" -> LDT | "LDX" -> LDX | "LPS" -> LPS
|
||||
| "MUL" -> MUL | "OR" -> OR | "RD" -> RD | "RSUB" -> RSUB | "STA" -> STA
|
||||
| "STB" -> STB | "STCH" -> STCH | "STF" -> STF | "STL" -> STL | "STS" -> STS
|
||||
| "STSW" -> STSW | "STT" -> STT | "STX" -> STX | "SUB" -> SUB
|
||||
| "SUBF" -> SUBF | "TD" -> TD | "TIX" -> TIX | "WD" -> WD
|
||||
|
||||
(* ------------------- SIC/XE Directives ------------------- *)
|
||||
| "START" -> START
|
||||
| "END" -> END
|
||||
| "ORG" -> ORG
|
||||
| "EQU" -> EQU
|
||||
| "BASE" -> BASE
|
||||
| "NOBASE" -> NOBASE
|
||||
| "LTORG" -> LTORG
|
||||
| "RESW" -> RESW
|
||||
| "RESB" -> RESB
|
||||
| "WORD" -> WORD
|
||||
| "BYTE" -> BYTE
|
||||
| "START" -> START | "END" -> END | "ORG" -> ORG
|
||||
| "EQU" -> EQU | "BASE" -> BASE | "NOBASE" -> NOBASE
|
||||
| "LTORG" -> LTORG | "RESW" -> RESW | "RESB" -> RESB
|
||||
| "WORD" -> WORD | "BYTE" -> BYTE
|
||||
|
||||
(*comment*)
|
||||
| "COMMENT" -> COMMENT
|
||||
|
|
@ -281,6 +236,7 @@ let getMnemType (opcode : mnemonic) (ext : bool) (operand : string list) : mnemo
|
|||
| _, _ -> failwith (Printf.sprintf "Invalid operands for opcode %s: %d operands"
|
||||
(string_of_mnemonic opcode) (List.length operand))
|
||||
|
||||
(*vrni dolzino ukaza*)
|
||||
let getLen (mnemType : mnemonic_type) (mnem : mnemonic) : int =
|
||||
match mnemType with
|
||||
(* ----------- directives with no memory ----------- *)
|
||||
|
|
@ -316,11 +272,48 @@ let getLen (mnemType : mnemonic_type) (mnem : mnemonic) : int =
|
|||
| _ -> failwith "Narobe mnemoic glede na mnemType"
|
||||
end
|
||||
|
||||
(*preveri ali imaš X naslavljanje*)
|
||||
let has_index (ops : string list) : bool * string list = (*vrne bool x in operande brez X*)
|
||||
match ops with
|
||||
| [lst; x] when String.uppercase_ascii x = "X" -> true, [lst] (*predpostavimo da se X pojavi na drugem mestu in nikoli na tretjem*)
|
||||
| _ -> false, ops
|
||||
|
||||
(*dobi n in i bita in operande brez # ali @*)
|
||||
let get_ni_bits (operands : string list) : bool * bool * string list =
|
||||
match operands with
|
||||
| [] ->
|
||||
(true, true, [])
|
||||
| op :: rest ->
|
||||
if String.length op = 0 then
|
||||
(true, true, operands)
|
||||
else
|
||||
match op.[0] with
|
||||
| '#' ->
|
||||
let stripped =String.sub op 1 (String.length op - 1) in
|
||||
(false, true, stripped :: rest)
|
||||
| '@' ->
|
||||
let stripped = String.sub op 1 (String.length op - 1) in
|
||||
(true, false, stripped :: rest)
|
||||
| _ ->
|
||||
(true, true, operands)
|
||||
|
||||
let checkLineSemantic (line : line) : lineSemantic =
|
||||
let mnem, ext = getMnem line.opcode in
|
||||
let mnemType = getMnemType mnem ext line.operand in
|
||||
let x, ops = has_index line.operand in
|
||||
let n, i, ops = get_ni_bits ops in
|
||||
let mnemType = getMnemType mnem ext ops in
|
||||
let dolzina = getLen mnemType mnem in
|
||||
{line_no = line.line_no; label = line.label; ext = ext; opcode = mnem; mnem = mnemType; comment = line.comment; len = dolzina; loc = line.loc}
|
||||
{ line_no = line.line_no;
|
||||
label = line.label;
|
||||
ext = ext;
|
||||
opcode = mnem;
|
||||
mnem = mnemType;
|
||||
x = x;
|
||||
n = n;
|
||||
i = i;
|
||||
comment = line.comment;
|
||||
len = dolzina;
|
||||
loc = line.loc}
|
||||
|
||||
let checkLineSemanticOfCode (code : line list) : lineSemantic list =
|
||||
List.map (checkLineSemantic) code
|
||||
|
|
|
|||
|
|
@ -11,5 +11,8 @@ let add_symbol (tab : symtab) (label : string) (addr : int) =
|
|||
else
|
||||
Hashtbl.add tab label addr
|
||||
|
||||
let find_symbol (tab : symtab) (label : string) : int =
|
||||
Hashtbl.find tab label
|
||||
let find_symbol (tab : symtab) (label : string) : int =
|
||||
try
|
||||
Hashtbl.find tab label
|
||||
with
|
||||
| Not_found -> failwith (Printf.sprintf "[SimTab] Symbol not found: '%s'." label)
|
||||
Loading…
Add table
Add a link
Reference in a new issue