From ace046624d2e23fba67564a86af7f03ed8a48eae Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 29 Feb 2024 21:05:10 -0500 Subject: remove unwraps, fix utf8 --- matrix-bin/src/main.rs | 90 ++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 44 deletions(-) (limited to 'matrix-bin/src/main.rs') 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), + Compile(Vec, 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) -> Result { - 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> { - match Program::load(&body)? { + pub fn load_program(&mut self, mut buffer: Vec) -> Result> { + 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) -> Result { + 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}"); + } } -- cgit v1.2.3-freya