type binop = Mod | Add | Sub (* opérations binaires modulo et addition *) type cmp = Le | Lt | Eq (* comparateurs <=, >=, == *) type register = int (* indice d'un registre de la machine*) type address = int (* adresse en mémoire *) type label = int (* indice d'un label dans le code *) (* instructions de la machine *) type instr = | Const of int * register (* constante: place l'entier dans le registre *) | Move of register * register (* déplacement de registres: place le contenu du premier *) (* registre dans le second *) | Bin of binop * register * register * register (* opération binaire: applique l'opération sur les deux premiers *) (* registres et place le résultat dans le troisième *) | Label of label (* positionnement d'un label dans le code *) | If of cmp * register * register * label (* branchement conditionel: si le résultat de la comparaison *) (* entre le contenu des deux registres est vrai aller au label, *) (* sinon passer à l'instruction suivante *) | Goto of label (* branchement: aller au label *) | System (* appel système: lève une exception Trap *) | Load of address * register (* écrire le contenu de l'adresse dans le registre *) | Store of register * address (* écrire le contenu du registre dans la mémoire *) (* code interprétable par la machine *) type code = instr array;; (* différentes exceptions levées par la machine *) exception Signal exception Segmentation_fault;; exception Trap (* nombre de registre *) let register_number = 20 (* liste des registres *) let zero = 0 let v0 = 1 let v1 = 2 let a0 = 3 let a1 = 4 let a2 = 5 let a4 = 6 let pc = 7 let sp = 8 let pt = 9 let t0 = 10 let t1 = 11 let t2 = 12 let t3 = 13 let t4 = 14 let t5 = 15 let t6 = 16 let t7 = 17 let t8 = 18 let t9 = 19 (* liste des noms de registres *) let register_names = let r = Array.make 20 "" in r.(zero) <- "zero"; r.(v0) <- "v0"; r.(v1) <- "v1"; r.(a0) <- "a0"; r.(a1) <- "a1"; r.(a2) <- "a2"; r.(a4) <- "a4"; r.(pc) <- "pc"; r.(sp) <- "sp"; r.(t0) <- "t0"; r.(t1) <- "t1"; r.(t2) <- "t2"; r.(t3) <- "t3"; r.(t4) <- "t4"; r.(t5) <- "t5"; r.(t6) <- "t6"; r.(t7) <- "t7"; r.(t8) <- "t8"; r.(t9) <- "t9"; r (* affichage des instructions *) let string_of_code registers = let reg n = Printf.sprintf "%s=%d" register_names.(n) registers.(n) in function | Bin (binop, r1, r2, r3) -> Printf.sprintf "Bin (%s, %s, %s, %s)" (match binop with Add -> "Add" | Mod -> "Mod" | Sub -> "Sub") (reg r1) (reg r2) (reg r3); | System -> Printf.sprintf "System" | If (cmp, r1, r2, int) -> Printf.sprintf "If (%s, %s, %s, %d)" (match cmp with Le -> "<=" | Lt -> "<" | Eq -> "=") (reg r1) (reg r2) int; | Const (int, r) -> Printf.sprintf "Const (%d, %s)" int (reg r) | Move (r1, r2) -> Printf.sprintf "Move (%s, %s)" (reg r1) (reg r2) | Goto int -> Printf.sprintf "Goto %d" int; | Label int -> Printf.sprintf "Label %d" int | Load (address, r) -> Printf.sprintf "Load (%d, %s)" address (reg r) | Store (r, address) -> Printf.sprintf "Store (%s, %d)" (reg r) address;; (* affichages verbeux *) let verbose = ref false