standalone exapunks vm in ocaml
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
5open Common
6open Utils
7
8type t = Common.exa
9
10let exa_counter = ref 0
11
12let next_name (name : string) : string =
13 let ret = !exa_counter in
14 exa_counter := !exa_counter + 1;
15 name ^ string_of_int ret
16
17let show_code (exa : t) : string =
18 exa.code |> Dynarray.to_list |> List.map OpCode.show |> String.concat "\n"
19
20let length (exa : t) = Dynarray.length exa.code [@@inline always]
21
22let inc_instruction (exa : t) : unit =
23 let new_ip = exa.ip + 1 in
24 if new_ip <= length exa then exa.ip <- new_ip;
25 ()
26
27let get_instruction (exa : t) : OpCode.t option =
28 if exa.ip >= length exa then None else Some (Dynarray.get exa.code exa.ip)
29
30let is_m_instruction (exa : t) : bool =
31 match get_instruction exa with
32 | None -> false
33 | Some op -> OpCode.is_m_op op
34
35let get_label (exa : t) (label : string) : int = StringMap.find exa.labels label
36
37let create (name : string) (host : host) (code : code) : t =
38 {
39 name;
40 dead = false;
41 x = Int 0;
42 t = Int 0;
43 f = None;
44 f_pos = 0;
45 mode = GLOBAL;
46 code = Dynarray.of_list code.ops;
47 labels = code.labels;
48 ip = 0;
49 host;
50 waiting = false;
51 }
52
53let copy (exa : t) : t =
54 let name = next_name exa.name in
55 {
56 name;
57 dead = false;
58 x = Int 0;
59 t = Int 0;
60 f = None;
61 f_pos = 0;
62 mode = exa.mode;
63 code = Dynarray.copy exa.code;
64 labels = StringMap.copy exa.labels;
65 ip = 0;
66 host = exa.host;
67 waiting = false;
68 }