standalone exapunks vm in ocaml
at main 153 lines 4.6 kB view raw
1(* This Source Code Form is subject to the terms of the Mozilla Public 2 License, v. 2.0. If a copy of the MPL was not distributed with this 3 file, You can obtain one at https://mozilla.org/MPL/2.0/. *) 4 5type t = Common.op_code 6 7let is_m_op (op : t) = 8 match op with 9 | COPY (R M, _) 10 | COPY (_, M) 11 | VOID_M -> 12 true 13 | _ -> false 14 15let get_m_type (op : t) = 16 match op with 17 | COPY (_, M) -> `SEND 18 | COPY (R M, _) -> `RECEIVE 19 | VOID_M -> `VOID_M 20 | TEST_MRD -> `TEST_MRD 21 | _ -> raise Exit 22 23let regInstruction name r = Printf.sprintf "%s %s" name (Register.show r) 24 25let rnInstruction name rn = Printf.sprintf "%s %s" name (Register.show_r_n rn) 26 27let labelInstruction name label = Printf.sprintf "%s %s" name label 28 29let srcDestInstruction name src dest = 30 let left = Register.show_r_n src in 31 let right = Register.show dest in 32 Printf.sprintf "%s %s %s" name left right 33 34let mathInstruction name src i dest = 35 let left = Register.show_r_n src in 36 let right = Register.show_r_n i in 37 Printf.sprintf "%s %s %s %s" name left right (Register.show dest) 38 39let testInstruction name left func right = 40 let left = Register.show_r_n left in 41 let right = Register.show_r_n right in 42 Printf.sprintf "%s %s %s %s" name left func right 43 44let show (op : t) : string = 45 match op with 46 | NOOP -> "NOOP" 47 | COPY (src, dest) -> srcDestInstruction "COPY" src dest 48 | ADDI (src, i, dest) -> mathInstruction "ADDI" src i dest 49 | SUBI (src, i, dest) -> mathInstruction "SUBI" src i dest 50 | MULI (src, i, dest) -> mathInstruction "MULI" src i dest 51 | DIVI (src, i, dest) -> mathInstruction "DIVI" src i dest 52 | MODI (src, i, dest) -> mathInstruction "MODI" src i dest 53 | SWIZ (src, i, dest) -> mathInstruction "SWIZ" src i dest 54 | MARK label -> labelInstruction "MARK" label 55 | JUMP label -> labelInstruction "JUMP" label 56 | TJMP label -> labelInstruction "TJMP" label 57 | FJMP label -> labelInstruction "FJMP" label 58 | TEST_EQ (left, right) -> testInstruction "TEST" left "=" right 59 | TEST_LT (left, right) -> testInstruction "TEST" left "<" right 60 | TEST_GT (left, right) -> testInstruction "TEST" left ">" right 61 | HALT -> "HALT" 62 | REPL label -> labelInstruction "REPL" label 63 | LINK dest -> rnInstruction "LINK" dest 64 | HOST dest -> regInstruction "HOST" dest 65 | MODE -> "MODE" 66 | VOID_M -> "VOID M" 67 | TEST_MRD -> "TEST MRD" 68 | MAKE -> "MAKE" 69 | GRAB file -> rnInstruction "GRAB" file 70 | FILE dest -> regInstruction "FILE" dest 71 | SEEK value -> rnInstruction "SEEK" value 72 | VOID_F -> "VOID F" 73 | DROP -> "DROP" 74 | WIPE -> "WIPE" 75 | TEST_EOF -> "TEST EOF" 76 77let pp ppf op = Format.fprintf ppf "%s" (show op) 78 79let equal (op1 : t) (op2 : t) : bool = 80 match (op1, op2) with 81 | NOOP, NOOP -> 82 true 83 | NOOP, _ -> 84 false 85 | COPY (rn1, t1), COPY (rn2, t2) -> Register.equal_r_n rn1 rn2 && Register.equal t1 t2 86 | COPY _, _ -> false 87 | ADDI (src1, i1, dest1), ADDI (src2, i2, dest2) 88 | SUBI (src1, i1, dest1), SUBI (src2, i2, dest2) 89 | MULI (src1, i1, dest1), MULI (src2, i2, dest2) 90 | DIVI (src1, i1, dest1), DIVI (src2, i2, dest2) 91 | MODI (src1, i1, dest1), MODI (src2, i2, dest2) 92 | SWIZ (src1, i1, dest1), SWIZ (src2, i2, dest2) -> 93 Register.equal_r_n src1 src2 && Register.equal_r_n i1 i2 94 && Register.equal dest1 dest2 95 | DIVI _, _ 96 | ADDI _, _ 97 | SUBI _, _ 98 | MULI _, _ 99 | MODI _, _ 100 | SWIZ _, _ -> 101 false 102 | MARK l1, MARK l2 103 | JUMP l1, JUMP l2 104 | TJMP l1, TJMP l2 105 | FJMP l1, FJMP l2 -> 106 String.equal l1 l2 107 | MARK _, _ 108 | JUMP _, _ 109 | TJMP _, _ 110 | FJMP _, _ -> 111 false 112 | TEST_EQ (l1, r1), TEST_EQ (l2, r2) 113 | TEST_LT (l1, r1), TEST_LT (l2, r2) 114 | TEST_GT (l1, r1), TEST_GT (l2, r2) -> 115 Register.equal_r_n l1 l2 && Register.equal_r_n r1 r2 116 | TEST_EQ _, _ 117 | TEST_LT _, _ 118 | TEST_GT _, _ -> 119 false 120 | REPL l1, REPL l2 -> String.equal l1 l2 121 | REPL _, _ -> false 122 | HALT, HALT -> true 123 | HALT, _ -> false 124 | LINK dest1, LINK dest2 -> Register.equal_r_n dest1 dest2 125 | LINK _, _ -> false 126 | HOST r1, HOST r2 -> Register.equal r1 r2 127 | HOST _, _ -> false 128 | MODE, MODE 129 | VOID_M, VOID_M 130 | TEST_MRD, TEST_MRD -> 131 true 132 | MODE, _ 133 | VOID_M, _ 134 | TEST_MRD, _ -> 135 false 136 | MAKE, MAKE -> true 137 | MAKE, _ -> false 138 | GRAB f1, GRAB f2 -> Register.equal_r_n f1 f2 139 | GRAB _, _ -> false 140 | FILE dest1, FILE dest2 -> Register.equal dest1 dest2 141 | FILE _, _ -> false 142 | SEEK v1, SEEK v2 -> Register.equal_r_n v1 v2 143 | SEEK _, _ -> false 144 | VOID_F, VOID_F 145 | DROP, DROP 146 | WIPE, WIPE 147 | TEST_EOF, TEST_EOF -> 148 true 149 | VOID_F, _ 150 | DROP, _ 151 | WIPE, _ 152 | TEST_EOF, _ -> 153 false