diff options
author | Freya Murphy <freya@freyacat.org> | 2024-02-29 21:05:10 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-02-29 21:05:10 -0500 |
commit | ace046624d2e23fba67564a86af7f03ed8a48eae (patch) | |
tree | 21ae64bc5897b1b89ee2ab8563b0e7ce047bf34a /matrix-bin | |
parent | fix readme (diff) | |
download | matrix-ace046624d2e23fba67564a86af7f03ed8a48eae.tar.gz matrix-ace046624d2e23fba67564a86af7f03ed8a48eae.tar.bz2 matrix-ace046624d2e23fba67564a86af7f03ed8a48eae.zip |
remove unwraps, fix utf8
Diffstat (limited to 'matrix-bin')
-rw-r--r-- | matrix-bin/src/main.rs | 90 | ||||
-rw-r--r-- | matrix-bin/src/repl.rs | 16 |
2 files changed, 55 insertions, 51 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}"); + } } diff --git a/matrix-bin/src/repl.rs b/matrix-bin/src/repl.rs index fe9975f..444faef 100644 --- a/matrix-bin/src/repl.rs +++ b/matrix-bin/src/repl.rs @@ -20,12 +20,12 @@ impl<'s, 'a> Repl<'s, 'a> { Ok(val) } - pub fn run(&mut self) { + pub fn run(&mut self) -> Result<()> { let interupt = self.state.vm.borrow().interupt(); ctrlc::set_handler(move || { interupt.store(Interupt::KeyboardInterupt as usize, Ordering::SeqCst); - }).unwrap(); + }).exception()?; let config = Config::builder() .indent_size(4) @@ -39,10 +39,10 @@ impl<'s, 'a> Repl<'s, 'a> { let histfile = std::env::var("MATRIX_HISTORY").ok(); - let mut rl = Editor::with_config(config).unwrap(); + let mut rl = Editor::with_config(config).exception()?; rl.set_helper(Some(helper)); if let Some(hf) = &histfile { - rl.load_history(hf).ok(); + rl.load_history(hf).exception()?; } loop { @@ -52,7 +52,7 @@ impl<'s, 'a> Repl<'s, 'a> { Err(_) => continue, }; - rl.add_history_entry(&line).ok(); + rl.add_history_entry(&line).exception()?; match self.execute(line) { Ok(val) => { @@ -66,12 +66,14 @@ impl<'s, 'a> Repl<'s, 'a> { } Err(err) => crate::error(err, &self.state), }; - std::io::stdout().flush().ok(); + std::io::stdout().flush().exception()?; } if let Some(hf) = &histfile { - rl.save_history(hf).ok(); + rl.save_history(hf).exception()?; } + + Ok(()) } } |