standalone exapunks vm in ocaml
at main 111 lines 2.9 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 5open Exapunks 6open Common 7open Helpers 8open Re 9 10let () = set_context __FILE__ 11 12let parse_code input = 13 let parsed_code = Reader.parse_code input in 14 if not (List.is_empty parsed_code.errors) then 15 Error 16 (parsed_code.errors 17 |> List.map (fun (error : syntax_error) -> error.msg) 18 |> String.concat ", ") 19 else Ok parsed_code.ops 20 21let parse_output input : (OpCode.t list, string) result = Ok input 22 23let () = 24 describe "#parse_code" (fun () -> 25 specify "happy path" (fun () -> 26 let code = 27 {| 28 NOOP 29 NOTE notes work 30 31 ; its own line 32 ; COPY F X 33 COPY F X ; at the end of a line 34 ADDI X F X 35 SUBI X F X 36 MULI X F X 37 DIVI X F X 38 MODI X F X 39 SWIZ X F X 40 MARK LOOP 41 JUMP LOOP 42 TJMP LOOP 43 FJMP LOOP 44 TEST X = F 45 TEST X < F 46 TEST X > F 47 REPL LOOP 48 HALT 49 LINK 800 50 HOST X 51 MODE 52 VOID M 53 TEST MRD 54 MAKE 55 GRAB 200 56 GRAB X 57 FILE T 58 SEEK 2 59 SEEK X 60 VOID F 61 DROP 62 WIPE 63 |} 64 in 65 let lines = parse_code code in 66 let expected = 67 Ok 68 [ 69 NOOP; 70 COPY (R F, X); 71 ADDI (R X, R F, X); 72 SUBI (R X, R F, X); 73 MULI (R X, R F, X); 74 DIVI (R X, R F, X); 75 MODI (R X, R F, X); 76 SWIZ (R X, R F, X); 77 MARK "LOOP"; 78 JUMP "LOOP"; 79 TJMP "LOOP"; 80 FJMP "LOOP"; 81 TEST_EQ (R X, R F); 82 TEST_LT (R X, R F); 83 TEST_GT (R X, R F); 84 REPL "LOOP"; 85 HALT; 86 LINK (N 800); 87 HOST X; 88 MODE; 89 VOID_M; 90 TEST_MRD; 91 MAKE; 92 GRAB (N 200); 93 GRAB (R X); 94 FILE T; 95 SEEK (N 2); 96 SEEK (R X); 97 VOID_F; 98 DROP; 99 WIPE; 100 ] 101 in 102 Alcotest.check t_parse_result "" expected lines; 103 104 ()); 105 106 specify "repeated registers in COPY" (fun () -> 107 let lines = parse_code "COPY X X" in 108 let expected = Error "CANNOT REPEAT REGISTERS" in 109 Alcotest.check t_parse_result_re "" expected lines; 110 ()); 111 ())