changes i forgor to commit

This commit is contained in:
Freya Murphy 2024-02-23 11:33:21 -05:00
parent a888c09bd5
commit a9c5ffe62f
Signed by: freya
GPG key ID: 744AB800E383AE52
2 changed files with 44 additions and 3 deletions

11
Cargo.lock generated
View file

@ -138,6 +138,16 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "ctrlc"
version = "3.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b"
dependencies = [
"nix",
"windows-sys",
]
[[package]] [[package]]
name = "endian-type" name = "endian-type"
version = "0.1.2" version = "0.1.2"
@ -219,6 +229,7 @@ name = "matrix-bin"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"clap", "clap",
"ctrlc",
"matrix", "matrix",
"matrix-stdlib", "matrix-stdlib",
"rustyline", "rustyline",

View file

@ -1,4 +1,4 @@
use std::{rc::Rc, fmt::{Debug, Display}, usize, ops::{Index, IndexMut}, collections::HashMap, cell::RefCell}; use std::{rc::Rc, fmt::{Debug, Display}, usize, ops::{Index, IndexMut}, collections::HashMap, cell::RefCell, sync::{atomic::{AtomicUsize, Ordering}, Arc}};
use crate::{value::{Value, self, ValueMap}, gc::Gc, chunk::{Function, Instruction, Chunk, InnerFunction}, Result, compiler::NamesTable}; use crate::{value::{Value, self, ValueMap}, gc::Gc, chunk::{Function, Instruction, Chunk, InnerFunction}, Result, compiler::NamesTable};
#[derive(Debug)] #[derive(Debug)]
@ -108,6 +108,10 @@ impl StackFrame {
} }
} }
pub enum Interupt {
KeyboardInterupt = 1
}
pub struct Vm { pub struct Vm {
stack: Stack<Value>, stack: Stack<Value>,
locals: Stack<Value>, locals: Stack<Value>,
@ -115,6 +119,7 @@ pub struct Vm {
globals: HashMap<u16, Value>, globals: HashMap<u16, Value>,
names: NamesTable, names: NamesTable,
global_names: NamesTable, global_names: NamesTable,
interupt: Arc<AtomicUsize>,
} }
impl Vm { impl Vm {
@ -135,6 +140,10 @@ impl Vm {
self.global_names.clone() self.global_names.clone()
} }
pub fn interupt(&self) -> Arc<AtomicUsize> {
self.interupt.clone()
}
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
stack: Stack::new(), stack: Stack::new(),
@ -142,7 +151,8 @@ impl Vm {
frames: Vec::new(), frames: Vec::new(),
globals: HashMap::new(), globals: HashMap::new(),
names: Rc::new(RefCell::new(Vec::new())), names: Rc::new(RefCell::new(Vec::new())),
global_names: Rc::new(RefCell::new(Vec::new())) global_names: Rc::new(RefCell::new(Vec::new())),
interupt: Arc::new(AtomicUsize::new(0)),
} }
} }
@ -164,8 +174,14 @@ impl Vm {
)) ))
} }
fn check_interupt(&self) -> bool {
self.interupt.load(Ordering::Relaxed) != 0
}
pub fn run(&mut self, fun: Rc<Function>) -> Result<Value> { pub fn run(&mut self, fun: Rc<Function>) -> Result<Value> {
let mut frame = self.init_frame(fun)?; let mut frame = self.init_frame(fun)?;
self.interupt.store(0, Ordering::SeqCst);
loop { loop {
use Instruction::*; use Instruction::*;
let ins = frame.body.code[frame.ip].clone(); let ins = frame.body.code[frame.ip].clone();
@ -223,13 +239,24 @@ impl Vm {
let domain = list.len() / codomain; let domain = list.len() / codomain;
self.push(Value::Matrix(Gc::new((domain, codomain, list.inner)))); self.push(Value::Matrix(Gc::new((domain, codomain, list.inner))));
} }
Jump(idx) => frame.ip = idx as usize, Jump(idx) => {
if self.check_interupt() {
return Ok(Value::Nil)
}
frame.ip = idx as usize;
}
JumpTrue(idx) => { JumpTrue(idx) => {
if self.check_interupt() {
return Ok(Value::Nil)
}
if !!self.pop() { if !!self.pop() {
frame.ip = idx as usize; frame.ip = idx as usize;
} }
}, },
JumpFalse(idx) => { JumpFalse(idx) => {
if self.check_interupt() {
return Ok(Value::Nil)
}
if !self.pop() { if !self.pop() {
frame.ip = idx as usize; frame.ip = idx as usize;
} }
@ -268,6 +295,9 @@ impl Vm {
} }
}, },
Return => { Return => {
if self.check_interupt() {
return Ok(Value::Nil)
}
let Some(prev_frame) = self.frames.pop() else { let Some(prev_frame) = self.frames.pop() else {
break; break;
}; };