1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! # Manchester Small-Scale Experimental Machine "Baby" Emulator Library
//! 
//! [![crates.io](https://img.shields.io/crates/v/baby-emulator)](https://crates.io/crates/baby-emulator)
//! [![Released API docs](https://docs.rs/baby-emulator/badge.svg)](https://docs.rs/baby-emulator)
//! [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENCE)
//! 
//! This library provides a collections of types and methods for emulating & assembling code for 
//! the [Machester Baby](https://www.scienceandindustrymuseum.org.uk/objects-and-stories/baby-and-modern-computing), the first program stored 
//! computer. 
//! 
//! ## Explaination
//! 
//! The Manchester "Baby" was the first computer to store both its program 
//! code and data in a common randomly-accessible memory, it is for this 
//! reason the Baby is considered the first machine to run "true" software, 
//! providing a familiar (abeit, primitive) programming environment to anyone 
//! familiar with assembly, this library can be included  in a variety of 
//! software and platforms allowing emulation functionality of this historic machine. 
//! 
//! This library provides an interface for emulating the Baby as a bytecode 
//! interpreter ([baby_emulator::core][crate::core]), and also a library for assembling 
//! asm using both modern and original asm notations into a format that 
//! can be ran by the emulator ([baby_emulator::assmebler][crate::assembler]). 
//! 
//! Please log any questions or issues to the [GitHub repo](https://github.com/jasonalexander-ja/SSEMBabyEmulator).
//! 
//! ## Installation 
//! 
//! Command line: 
//! ```text 
//! cargo add baby-emulator 
//! ```
//! 
//! Cargo.toml: 
//! ```text 
//! baby-emulator = "0.1.7" 
//! ``` 
//! 
//! ## Example 
//! 
//! This shows a few short examples of what this library is capable of, designed to be a 
//! starting point allowing further experimentation by the "user".
//! See [baby_emulator::core][crate::core] and [baby_emulator::assembler][crate::assembler] 
//! for further examples and info. 
//! 
//! ### Bytecode Interpreter Emulation
//! 
//! The core of this library is [baby_emulator::core::BabyModel][crate::core::BabyModel], 
//! this struct has fields representing all of the Baby's internal 
//! registers and 32 word memory, you can initialise this struct with 
//! an array of `[i32; 32]`, this array can contain the program code 
//! instructions starting at position 0. 
//! 
//! This example runs an example program that adds 5 to 5 and stores 
//! the result in the accumulator. Running here is done with the [BabyModel::run_loop][crate::core::BabyModel::run_loop]
//! method, this method will simply execute sucessive instructions until 
//! either an error is thrown (like a stop instruction), or the number
//! os iterations exceeds the specified limmit. 
//! 
//! ```rust
//! use baby_emulator::core::BabyModel;
//! use baby_emulator::core::errors::BabyErrors;
//! use baby_emulator::core::errors::BabyError;
//! 
//! let model = BabyModel::new_example_program();
//! match model.run_loop(100) {
//!     (model, BabyErrors::Stop(_)) => println!("{}", model.core_dump()),
//!     (_, err) => println!("{}", err.get_descriptor())
//! }
//! ```
//! 
//! You can also single set through an emulation, executing a single 
//! instruction at a time using the `execute` method and seeing the 
//! direct result. 
//! 
//! ```rust
//! use baby_emulator::core::BabyModel;
//! use baby_emulator::core::errors::BabyError;
//! 
//! let model = BabyModel::new_example_program();
//! match model.execute() {
//!     Ok(m) => println!("{}", m.core_dump()),
//!     Err(e) => println!("Error {}", e.get_descriptor())
//! }
//! ```
//! 
//! ### Assembly
//! 
//! Here is an example of assembling a Baby asm string using 
//! modern notation, then running the resultant program,
//! see the [baby_emulator::assembler][crate::assembler]  docs for more information:
//! 
//! ```rust
//! use baby_emulator::assembler::assemble; 
//! use baby_emulator::core::{BabyModel, instructions::BabyInstruction};
//!  
//!  
//! const ASM: &str = 
//! "
//! ldn $start_value  ; Loads 10 into the accumulator 
//!   
//! :loop_start_value ; The memory address the loop should return to 
//! sub $subtract_val ; Subtract 1 from the accumulator 
//! cmp               ; Skip the next jump instruction if the accumulator is negative 
//! jmp $loop_start   ; Jump to the start of the loop 
//! stp               ; Program stops when the accumulator is negative 
//! 
//! :loop_start       ; Pointer to the memory address the loop should return to 
//! abs $loop_start_value
//! 
//! :subtract_val     ; Value to be subtracted
//! abs 0d1
//!   
//! :start_value ; Value to start in the accumulator 
//! abs 0d-10
//! ";
//! 
//! fn main() {
//!     let instructions = match assemble(&String::from(ASM), false) {
//!         Ok(v) => v,
//!         Err(e) => { println!("{}", e.describe(true)); return; }
//!     };
//!     let main_store = BabyInstruction::to_numbers(instructions);
//!  
//!     let mut model = BabyModel::new_with_program(main_store);
//!     loop {
//!         model = match model.execute() {
//!             Ok(m) => m,
//!             Err(_) => break
//!         };
//!     }
//!     println!("{}", model.core_dump());
//! }
//! ```
//! 


/// Contains the core models and emulation functionality. 
pub mod core;
/// Contains types and functionality for assembling Baby asm. 
pub mod assembler;