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