summaryrefslogtreecommitdiff
path: root/matrix-bin/src/main.rs
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-02-29 21:05:10 -0500
committerFreya Murphy <freya@freyacat.org>2024-02-29 21:05:10 -0500
commitace046624d2e23fba67564a86af7f03ed8a48eae (patch)
tree21ae64bc5897b1b89ee2ab8563b0e7ce047bf34a /matrix-bin/src/main.rs
parentfix readme (diff)
downloadmatrix-ace046624d2e23fba67564a86af7f03ed8a48eae.tar.gz
matrix-ace046624d2e23fba67564a86af7f03ed8a48eae.tar.bz2
matrix-ace046624d2e23fba67564a86af7f03ed8a48eae.zip
remove unwraps, fix utf8
Diffstat (limited to 'matrix-bin/src/main.rs')
-rw-r--r--matrix-bin/src/main.rs90
1 files changed, 46 insertions, 44 deletions
diff --git a/matrix-bin/src/main.rs b/matrix-bin/src/main.rs
index 64d1b3f..8321796 100644
--- a/matrix-bin/src/main.rs
+++ b/matrix-bin/src/main.rs
@@ -1,4 +1,4 @@
-use std::{path::PathBuf, io::{self, Read, IsTerminal}, fs, cell::RefCell, rc::Rc};
+use std::{path::PathBuf, io::{self, Read, IsTerminal}, cell::RefCell, rc::Rc};
use clap::{Parser as ArgParser, ColorChoice};
use matrix_lang::prelude::*;
use repl::Repl;
@@ -35,8 +35,8 @@ pub struct Args {
pub enum Mode {
Repl,
- Execute(String),
- Compile(String, PathBuf),
+ Execute(Vec<u8>),
+ Compile(Vec<u8>, PathBuf),
}
pub struct State<'a> {
@@ -46,18 +46,26 @@ pub struct State<'a> {
color: bool,
}
-impl<'a> State<'a> {
- pub fn new (args: Args) -> (Self, Mode) {
+pub fn error(err: Exception, state: &State) {
+ if state.color {
+ println!("\x1b[31mError:\x1b[0m {err}");
+ } else {
+ println!("Error: {err}");
+ }
+}
- let stdin = read_stdin();
+impl<'a> State<'a> {
+ pub fn new (args: Args) -> Result<(Self, Mode)> {
- let file;
+ let mut buffer = Vec::new();
if let Some(path) = &args.file {
- file = Some(fs::read_to_string(path).unwrap());
- } else if stdin.len() > 0 {
- file = Some(stdin);
+ let mut f = File::open(path)?;
+ f.read_to_end(&mut buffer)?;
} else {
- file = None;
+ let mut stdin = io::stdin();
+ if !stdin.is_terminal() {
+ stdin.read_to_end(&mut buffer)?;
+ }
}
let mode;
@@ -74,11 +82,10 @@ impl<'a> State<'a> {
PathBuf::from("matc.out")
}
};
- let file = file.unwrap_or(String::new());
- mode = Mode::Compile(file, path);
+ mode = Mode::Compile(buffer, path);
repl = false;
- } else if let Some(file) = file {
- mode = Mode::Execute(file);
+ } else if buffer.len() > 0 {
+ mode = Mode::Execute(buffer);
repl = false;
} else {
mode = Mode::Repl;
@@ -106,16 +113,16 @@ impl<'a> State<'a> {
Some(ColorChoice::Never) => false,
};
- (Self {
+ Ok((Self {
parser,
vm: Rc::new(RefCell::new(vm)),
compiler,
color,
- }, mode)
+ }, mode))
}
pub fn execute(&mut self, fun: Rc<Function>) -> Result<Value> {
- let val = self.vm.try_borrow_mut().unwrap().run(fun)?;
+ let val = self.vm.borrow_mut().run(fun)?;
Ok(val)
}
@@ -125,47 +132,37 @@ impl<'a> State<'a> {
Ok(fun)
}
- pub fn load_program(&mut self, body: String) -> Result<Rc<Function>> {
- match Program::load(&body)? {
+ pub fn load_program(&mut self, mut buffer: Vec<u8>) -> Result<Rc<Function>> {
+ let res = Program::load(buffer.as_mut_slice())?;
+ match res {
Some(fun) => {
Ok(fun)
},
None => {
+ let body = buffer_to_string(buffer)?;
self.compile(body)
},
}
}
}
-pub fn error(err: Exception, state: &State) {
- if state.color {
- println!("\x1b[31mError:\x1b[0m {err}");
- } else {
- println!("Error: {err}");
- }
-}
-
-fn read_stdin() -> String {
- let mut buffer = String::new();
- let mut stdin = io::stdin();
- if stdin.is_terminal() {
- return String::new();
- }
- stdin.read_to_string(&mut buffer).unwrap();
- buffer
+fn buffer_to_string(buffer: Vec<u8>) -> Result<String> {
+ String::from_utf8(buffer)
+ .map_err(|e| exception!(IO_EXCEPTION, "{e}"))
}
fn handle_mode(state: &mut State, mode: Mode) -> Result<()> {
match mode {
Mode::Repl => {
let mut repl = Repl::new(state);
- repl.run();
+ repl.run()?;
},
- Mode::Execute(body) => {
- let fun = state.load_program(body)?;
+ Mode::Execute(buffer) => {
+ let fun = state.load_program(buffer)?;
state.execute(fun)?;
},
- Mode::Compile(body, path) => {
+ Mode::Compile(buffer, path) => {
+ let body = buffer_to_string(buffer)?;
let fun = state.compile(body)?;
let mut file = File::create(path).map_err(|e|
exception!(IO_EXCEPTION, "{e}")
@@ -176,12 +173,17 @@ fn handle_mode(state: &mut State, mode: Mode) -> Result<()> {
Ok(())
}
-fn main() {
-
+fn load() -> Result<()> {
let args = Args::parse();
- let (mut state, mode) = State::new(args);
-
+ let (mut state, mode) = State::new(args)?;
if let Err(e) = handle_mode(&mut state, mode) {
error(e, &state);
}
+ Ok(())
+}
+
+fn main() {
+ if let Err(e) = load() {
+ println!("\x1b[31mFatal:\x1b[0m {e}");
+ }
}