Website Summary Files Commits Branches @commit @diff @stats
path: root / vm / src
diff options
context:
space:
mode:
Commit2653f4e53f9e878b8c4d09088fd79b4e22a48865 (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-02-14 16:06:45 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-02-14 16:06:45 +0200
Filesa82289da31eb8eed58d0383eb9495416f7cd9180 /vm/src
tonkobali-2653f4e53f9e878b8c4d09088fd79b4e22a48865.tar
tonkobali-2653f4e53f9e878b8c4d09088fd79b4e22a48865.tar.gz
tonkobali-2653f4e53f9e878b8c4d09088fd79b4e22a48865.zip
Parentc8955f48580db8067765f76c8967e44dbb06517a (diff)
feat(vm): Add ability to store data in memory and to start execution after halt
5 files changed, 47 insertions, 20 deletions
-rw-r--r--vm/src/main.rs8
-rw-r--r--vm/src/vm/mod.rs29
-rw-r--r--vm/src/vm/primitive.rs5
-rw-r--r--vm/src/vmm/command.rs22
-rw-r--r--vm/src/vmm/mod.rs3
diff --git a/vm/src/main.rs b/vm/src/main.rs
index 1753eb3..fa4a3c5 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -27,13 +27,7 @@ fn main() {
} else {
VirtualMachine::create(args.tick_gap)
};
-
- let _vm_handle = {
- let vm = Arc::clone(&vm);
- thread::spawn(move || {
- vm.start();
- })
- };
+ vm.spawn();
let mut monitor = VirtualMachineMonitor::new(args.refresh);
monitor.start(vm);
diff --git a/vm/src/vm/mod.rs b/vm/src/vm/mod.rs
index 9c92551..000e350 100644
--- a/vm/src/vm/mod.rs
+++ b/vm/src/vm/mod.rs
@@ -5,7 +5,7 @@ use std::{
sync::{ Arc, Mutex }, thread, time, fs
};
-use primitive::{spa, PrimitiveVirtualMachine};
+use primitive::PrimitiveVirtualMachine;
use memory::Word;
pub(crate) type VirtualMachine = Arc<Mutex<PrimitiveVirtualMachine>>;
@@ -14,8 +14,11 @@ pub(crate) trait VirtualMachineInterface {
fn create(tick_gap: u64) -> VirtualMachine;
fn create_from_file(tick_gap: u64, path: &str) -> VirtualMachine;
+ fn spawn(&self);
fn start(&self);
+ fn is_halted(&self) -> bool;
fn set_start(&mut self, index: Word);
+ fn set_word(&mut self, index: usize, value: Word);
fn get_word(&self, index: usize) -> Word;
}
@@ -37,6 +40,13 @@ impl VirtualMachineInterface for VirtualMachine {
create_with_memory(tick_gap, numbers)
}
+ fn spawn(&self) {
+ let vm = Arc::clone(&self);
+ thread::spawn(move || {
+ vm.start();
+ });
+ }
+
fn start(&self) {
let tick_gap = {
let vm = (*self).lock().unwrap();
@@ -46,9 +56,8 @@ impl VirtualMachineInterface for VirtualMachine {
loop {
{
let mut vm = (*self).lock().unwrap();
- vm.step();
- if vm.is_halted() {
- break;
+ if ! vm.is_halted() {
+ vm.step();
}
}
thread::sleep(time::Duration::from_millis(tick_gap));
@@ -57,7 +66,17 @@ impl VirtualMachineInterface for VirtualMachine {
fn set_start(&mut self, index: Word) {
let mut vm = (*self).lock().unwrap();
- vm.set_word(spa::PROGRAM_COUNTER, index);
+ vm.start_again(index);
+ }
+
+ fn is_halted(&self) -> bool {
+ let vm = (*self).lock().unwrap();
+ vm.is_halted()
+ }
+
+ fn set_word(&mut self, index: usize, value: Word) {
+ let mut vm = (*self).lock().unwrap();
+ vm.set_word(index, value);
}
fn get_word(&self, index: usize) -> Word {
diff --git a/vm/src/vm/primitive.rs b/vm/src/vm/primitive.rs
index e9d0d66..43f217f 100644
--- a/vm/src/vm/primitive.rs
+++ b/vm/src/vm/primitive.rs
@@ -84,6 +84,11 @@ impl PrimitiveVirtualMachine {
*self.mem.get_mut(index) = value;
}
+ pub fn start_again(&mut self, pc: Word) {
+ *self.pc_mut() = pc;
+ self.halted = false;
+ }
+
fn current_word(&self) -> &Word {
&self.mem[*self.pc() as usize]
}
diff --git a/vm/src/vmm/command.rs b/vm/src/vmm/command.rs
index 2688b5f..0811da3 100644
--- a/vm/src/vmm/command.rs
+++ b/vm/src/vmm/command.rs
@@ -21,17 +21,27 @@ pub(super) fn parse_and_exec(input: String, vm: &mut VirtualMachine) -> Result<(
}
match args[0] {
- "s" | "start" => {
+ "r" | "run" => {
expects_n_args(&args, 1)?;
+ if ! vm.is_halted() {
+ return Err(format!("Machine already running!"));
+ }
vm.set_start(args[1].parse().unwrap());
},
+ "s" | "store" => {
+ expects_n_args(&args, 2)?;
+
+ vm.set_word(args[1].parse().unwrap(), args[2].parse().unwrap());
+ },
"q" | "quit" | "e" | "exit" => return Err(String::new()),
_ => {
- if let Some(num) = args[0].parse::<usize>().ok() {
- println!("{}", vm.get_word(num));
- }
- else {
- return Err(format!("Unknown command '{}'!", args[0]));
+ for arg in args {
+ if let Some(num) = arg.parse::<usize>().ok() {
+ println!("{}", vm.get_word(num));
+ }
+ else {
+ return Err(format!("Unknown command '{}'!", arg));
+ }
}
},
}
diff --git a/vm/src/vmm/mod.rs b/vm/src/vmm/mod.rs
index afd8840..9ad250f 100644
--- a/vm/src/vmm/mod.rs
+++ b/vm/src/vmm/mod.rs
@@ -4,7 +4,7 @@ use std::{ thread, time, sync::mpsc, io::{ stdout, stdin, Write } };
use command::parse_and_exec;
-use super::vm::VirtualMachine;
+use super::vm::{ VirtualMachine, VirtualMachineInterface };
pub(crate) struct VirtualMachineMonitor {
refresh_rate: u64,
@@ -50,7 +50,6 @@ impl VirtualMachineMonitor {
}
{
- let vm = (*vm).lock().unwrap();
if vm.is_halted() {
print!(above!("HALTED!"));
}