summaryrefslogtreecommitdiff
path: root/matrix-lang
diff options
context:
space:
mode:
Diffstat (limited to 'matrix-lang')
-rw-r--r--matrix-lang/src/binary/mod.rs6
-rw-r--r--matrix-lang/src/compiler.rs2
-rw-r--r--matrix-lang/src/lex.rs4
-rw-r--r--matrix-lang/src/parse.rs2
-rw-r--r--matrix-lang/src/prelude.rs1
-rw-r--r--matrix-lang/src/value/exception.rs23
-rw-r--r--matrix-lang/src/value/matrix.rs2
-rw-r--r--matrix-lang/src/vm.rs4
8 files changed, 33 insertions, 11 deletions
diff --git a/matrix-lang/src/binary/mod.rs b/matrix-lang/src/binary/mod.rs
index 53b3fe5..780d2a0 100644
--- a/matrix-lang/src/binary/mod.rs
+++ b/matrix-lang/src/binary/mod.rs
@@ -13,8 +13,7 @@ pub struct Program {
const PROGRAM_HEADER: [u8; 5] = [0x00, 0x4d, 0x41, 0x54, 0x0a];
impl Program {
- pub fn load(body: &str) -> Result<Option<Rc<Function>>> {
- let mut bytes = body.as_bytes();
+ pub fn load(bytes: &mut [u8]) -> Result<Option<Rc<Function>>> {
if bytes.len() < 6 {
return Ok(None)
}
@@ -22,7 +21,8 @@ impl Program {
if header != &PROGRAM_HEADER {
return Ok(None)
}
- let mut s = ProgramDeserializer::from(&mut bytes);
+ let mut a = &bytes[..];
+ let mut s = ProgramDeserializer::from(&mut a);
let program = <Self>::deserialize(&mut s)?;
s.finish()?;
Ok(Some(program.fun.clone()))
diff --git a/matrix-lang/src/compiler.rs b/matrix-lang/src/compiler.rs
index 95c6ccf..da1ecf7 100644
--- a/matrix-lang/src/compiler.rs
+++ b/matrix-lang/src/compiler.rs
@@ -142,7 +142,7 @@ impl<'c> Compiler<'c> {
fn collapse_scopes(&mut self, top_scope: usize) {
let mut cutoff = usize::MAX;
while self.scopes.len() > top_scope {
- cutoff = self.scopes.pop().unwrap()
+ cutoff = self.scopes.pop().expect("bypassed compiler scope check")
}
if cutoff < self.locals.len() {
self.emit(Instruction::DiscardLocals((self.locals.len() - cutoff) as u16), self.last_pos());
diff --git a/matrix-lang/src/lex.rs b/matrix-lang/src/lex.rs
index b2487ad..82545c4 100644
--- a/matrix-lang/src/lex.rs
+++ b/matrix-lang/src/lex.rs
@@ -286,7 +286,7 @@ impl Lexer {
buf.push(char::from_u32(
n1.to_digit(16).ok_or(error!("invalid digit '{n1}'"))? * 16 +
n2.to_digit(16).ok_or(error!("invalid digit '{n2}'"))?
- ).unwrap());
+ ).expect("bypassed digit check"));
},
'u' => {
self.next_expect('{')?;
@@ -416,7 +416,7 @@ impl Lexer {
}
}
- let last: char = buf.chars().last().unwrap();
+ let last: char = buf.chars().last().unwrap_or('\0');
let is_range = initial != '.' && last == '.' && self.peek() == '.';
if is_range {
diff --git a/matrix-lang/src/parse.rs b/matrix-lang/src/parse.rs
index c476650..04f09ee 100644
--- a/matrix-lang/src/parse.rs
+++ b/matrix-lang/src/parse.rs
@@ -169,7 +169,7 @@ impl Parser {
};
}
if parts.len() == 1 {
- Ok((E::List(parts.pop().unwrap()), pos).into())
+ Ok((E::List(parts.pop().expect("bypassed vec length")), pos).into())
} else {
let codomain = parts.len();
let domain = parts[0].len();
diff --git a/matrix-lang/src/prelude.rs b/matrix-lang/src/prelude.rs
index c5af0c8..cf51a63 100644
--- a/matrix-lang/src/prelude.rs
+++ b/matrix-lang/src/prelude.rs
@@ -2,6 +2,7 @@ pub type Result<T> = std::result::Result<T, Exception>;
pub use crate::value::Value as Value;
pub use crate::value::exception::Exception as Exception;
+pub use crate::value::exception::Except as Except;
pub use crate::value::matrix::Matrix as Matrix;
pub use crate::value::gc::Gc as Gc;
pub use crate::value::hash::ValueMap as ValueMap;
diff --git a/matrix-lang/src/value/exception.rs b/matrix-lang/src/value/exception.rs
index 0df6f5c..c4ae606 100644
--- a/matrix-lang/src/value/exception.rs
+++ b/matrix-lang/src/value/exception.rs
@@ -1,4 +1,4 @@
-use std::{fmt::{Debug, Display}, error::Error};
+use std::{fmt::{Debug, Display}, error::Error, io};
use crate::prelude::*;
#[macro_export]
@@ -76,3 +76,24 @@ impl<T> From<Exception> for Result<T> {
Err(value)
}
}
+
+impl From<io::Error> for Exception {
+ fn from(value: io::Error) -> Self {
+ exception!(IO_EXCEPTION, "{value}")
+ }
+}
+
+pub trait Except {
+ type Output;
+ fn exception(self) -> Result<Self::Output>;
+}
+
+impl<T, E: std::error::Error> Except for std::result::Result<T, E> {
+ type Output = T;
+
+ fn exception(self) -> Result<Self::Output> {
+ self.map_err(|e| {
+ Exception::msg("unknown", format!("{e}").as_str())
+ })
+ }
+}
diff --git a/matrix-lang/src/value/matrix.rs b/matrix-lang/src/value/matrix.rs
index 91e3ec2..1d55210 100644
--- a/matrix-lang/src/value/matrix.rs
+++ b/matrix-lang/src/value/matrix.rs
@@ -184,7 +184,7 @@ impl Matrix {
let values = rows
.into_iter()
.reduce(|mut a,b| {a.extend(b); a})
- .unwrap();
+ .ok_or(error!("matrix row smashed"))?;
Ok(Matrix::new(self.domain + other.domain, self.codomain, values))
}
diff --git a/matrix-lang/src/vm.rs b/matrix-lang/src/vm.rs
index bac6341..b8da01f 100644
--- a/matrix-lang/src/vm.rs
+++ b/matrix-lang/src/vm.rs
@@ -217,7 +217,7 @@ impl Vm {
let val = self.globals
.borrow_mut()
.get(&idx)
- .unwrap()
+ .ok_or(exception!(RUNTIME_EXCEPTION, "undefined global at index {idx}"))?
.clone();
self.stack.push(val);
},
@@ -380,7 +380,7 @@ impl Vm {
self.trystack.push(scope);
},
I::TryEnd => {
- self.trystack.pop().unwrap();
+ self.trystack.pop().ok_or(exception!(RUNTIME_EXCEPTION, "try stack smashed"))?;
},
};