Include io::Error in file API's.

This commit is contained in:
Stephen Chung 2020-03-02 16:29:50 +08:00
parent 318bf97986
commit 103c62fb43
2 changed files with 24 additions and 30 deletions

View File

@ -8,11 +8,7 @@ impl Engine {
/// Compile a string into an AST /// Compile a string into an AST
pub fn compile(input: &str) -> Result<AST, ParseError> { pub fn compile(input: &str) -> Result<AST, ParseError> {
let tokens = lex(input); let tokens = lex(input);
parse(&mut tokens.peekable())
let mut peekables = tokens.peekable();
let tree = parse(&mut peekables);
tree
} }
/// Compile a file into an AST /// Compile a file into an AST
@ -21,12 +17,12 @@ impl Engine {
use std::io::prelude::*; use std::io::prelude::*;
let mut f = File::open(filename) let mut f = File::open(filename)
.map_err(|_| EvalAltResult::ErrorCantOpenScriptFile(filename.into()))?; .map_err(|err| EvalAltResult::ErrorCantOpenScriptFile(filename.into(), err))?;
let mut contents = String::new(); let mut contents = String::new();
f.read_to_string(&mut contents) f.read_to_string(&mut contents)
.map_err(|_| EvalAltResult::ErrorCantOpenScriptFile(filename.into())) .map_err(|err| EvalAltResult::ErrorCantOpenScriptFile(filename.into(), err))
.and_then(|_| Self::compile(&contents).map_err(EvalAltResult::ErrorParsing)) .and_then(|_| Self::compile(&contents).map_err(EvalAltResult::ErrorParsing))
} }
@ -36,12 +32,12 @@ impl Engine {
use std::io::prelude::*; use std::io::prelude::*;
let mut f = File::open(filename) let mut f = File::open(filename)
.map_err(|_| EvalAltResult::ErrorCantOpenScriptFile(filename.into()))?; .map_err(|err| EvalAltResult::ErrorCantOpenScriptFile(filename.into(), err))?;
let mut contents = String::new(); let mut contents = String::new();
f.read_to_string(&mut contents) f.read_to_string(&mut contents)
.map_err(|_| EvalAltResult::ErrorCantOpenScriptFile(filename.into())) .map_err(|err| EvalAltResult::ErrorCantOpenScriptFile(filename.into(), err))
.and_then(|_| self.eval::<T>(&contents)) .and_then(|_| self.eval::<T>(&contents))
} }
@ -107,12 +103,12 @@ impl Engine {
use std::io::prelude::*; use std::io::prelude::*;
let mut f = File::open(filename) let mut f = File::open(filename)
.map_err(|_| EvalAltResult::ErrorCantOpenScriptFile(filename.into()))?; .map_err(|err| EvalAltResult::ErrorCantOpenScriptFile(filename.into(), err))?;
let mut contents = String::new(); let mut contents = String::new();
f.read_to_string(&mut contents) f.read_to_string(&mut contents)
.map_err(|_| EvalAltResult::ErrorCantOpenScriptFile(filename.into())) .map_err(|err| EvalAltResult::ErrorCantOpenScriptFile(filename.into(), err))
.and_then(|_| self.consume(&contents)) .and_then(|_| self.consume(&contents))
} }

View File

@ -12,7 +12,7 @@ use crate::parser::{Expr, FnDef, ParseError, Stmt};
pub type Array = Vec<Dynamic>; pub type Array = Vec<Dynamic>;
pub type FnCallArgs<'a> = Vec<&'a mut Variant>; pub type FnCallArgs<'a> = Vec<&'a mut Variant>;
#[derive(Debug, Clone)] #[derive(Debug)]
pub enum EvalAltResult { pub enum EvalAltResult {
ErrorParsing(ParseError), ErrorParsing(ParseError),
ErrorFunctionNotFound(String), ErrorFunctionNotFound(String),
@ -27,7 +27,7 @@ pub enum EvalAltResult {
ErrorVariableNotFound(String), ErrorVariableNotFound(String),
ErrorAssignmentToUnknownLHS, ErrorAssignmentToUnknownLHS,
ErrorMismatchOutputType(String), ErrorMismatchOutputType(String),
ErrorCantOpenScriptFile(String), ErrorCantOpenScriptFile(String, std::io::Error),
ErrorDotExpr, ErrorDotExpr,
ErrorArithmetic(String), ErrorArithmetic(String),
LoopBreak, LoopBreak,
@ -37,8 +37,7 @@ pub enum EvalAltResult {
impl EvalAltResult { impl EvalAltResult {
fn as_str(&self) -> Option<&str> { fn as_str(&self) -> Option<&str> {
Some(match self { Some(match self {
Self::ErrorCantOpenScriptFile(s) Self::ErrorVariableNotFound(s)
| Self::ErrorVariableNotFound(s)
| Self::ErrorFunctionNotFound(s) | Self::ErrorFunctionNotFound(s)
| Self::ErrorMismatchOutputType(s) | Self::ErrorMismatchOutputType(s)
| Self::ErrorArithmetic(s) => s, | Self::ErrorArithmetic(s) => s,
@ -71,7 +70,7 @@ impl PartialEq for EvalAltResult {
(ErrorVariableNotFound(a), ErrorVariableNotFound(b)) => a == b, (ErrorVariableNotFound(a), ErrorVariableNotFound(b)) => a == b,
(ErrorAssignmentToUnknownLHS, ErrorAssignmentToUnknownLHS) => true, (ErrorAssignmentToUnknownLHS, ErrorAssignmentToUnknownLHS) => true,
(ErrorMismatchOutputType(a), ErrorMismatchOutputType(b)) => a == b, (ErrorMismatchOutputType(a), ErrorMismatchOutputType(b)) => a == b,
(ErrorCantOpenScriptFile(a), ErrorCantOpenScriptFile(b)) => a == b, (ErrorCantOpenScriptFile(a, _), ErrorCantOpenScriptFile(b, _)) => a == b,
(ErrorDotExpr, ErrorDotExpr) => true, (ErrorDotExpr, ErrorDotExpr) => true,
(ErrorArithmetic(a), ErrorArithmetic(b)) => a == b, (ErrorArithmetic(a), ErrorArithmetic(b)) => a == b,
(LoopBreak, LoopBreak) => true, (LoopBreak, LoopBreak) => true,
@ -106,7 +105,7 @@ impl Error for EvalAltResult {
"Assignment to an unsupported left-hand side expression" "Assignment to an unsupported left-hand side expression"
} }
Self::ErrorMismatchOutputType(_) => "Output type is incorrect", Self::ErrorMismatchOutputType(_) => "Output type is incorrect",
Self::ErrorCantOpenScriptFile(_) => "Cannot open script file", Self::ErrorCantOpenScriptFile(_, _) => "Cannot open script file",
Self::ErrorDotExpr => "Malformed dot expression", Self::ErrorDotExpr => "Malformed dot expression",
Self::ErrorArithmetic(_) => "Arithmetic error", Self::ErrorArithmetic(_) => "Arithmetic error",
Self::LoopBreak => "[Not Error] Breaks out of loop", Self::LoopBreak => "[Not Error] Breaks out of loop",
@ -125,29 +124,28 @@ impl std::fmt::Display for EvalAltResult {
write!(f, "{}: {}", self.description(), s) write!(f, "{}: {}", self.description(), s)
} else { } else {
match self { match self {
EvalAltResult::ErrorParsing(p) => write!(f, "Syntax error: {}", p), Self::ErrorCantOpenScriptFile(filename, err) => {
EvalAltResult::ErrorFunctionArgsMismatch(fun, n) => { write!(f, "Cannot open script file '{}': {}", filename, err)
}
Self::ErrorParsing(p) => write!(f, "Syntax error: {}", p),
Self::ErrorFunctionArgsMismatch(fun, n) => {
write!(f, "Function '{}' expects {} argument(s)", fun, n) write!(f, "Function '{}' expects {} argument(s)", fun, n)
} }
EvalAltResult::ErrorBooleanArgMismatch(op) => { Self::ErrorBooleanArgMismatch(op) => {
write!(f, "Boolean {} operator expects boolean operands", op) write!(f, "Boolean {} operator expects boolean operands", op)
} }
EvalAltResult::ErrorArrayBounds(_, index) if *index < 0 => { Self::ErrorArrayBounds(_, index) if *index < 0 => {
write!(f, "{}: {} < 0", self.description(), index) write!(f, "{}: {} < 0", self.description(), index)
} }
EvalAltResult::ErrorArrayBounds(max, _) if *max == 0 => { Self::ErrorArrayBounds(max, _) if *max == 0 => write!(f, "{}", self.description()),
write!(f, "{}", self.description()) Self::ErrorArrayBounds(max, index) => {
}
EvalAltResult::ErrorArrayBounds(max, index) => {
write!(f, "{} (max {}): {}", self.description(), max - 1, index) write!(f, "{} (max {}): {}", self.description(), max - 1, index)
} }
EvalAltResult::ErrorStringBounds(_, index) if *index < 0 => { Self::ErrorStringBounds(_, index) if *index < 0 => {
write!(f, "{}: {} < 0", self.description(), index) write!(f, "{}: {} < 0", self.description(), index)
} }
EvalAltResult::ErrorStringBounds(max, _) if *max == 0 => { Self::ErrorStringBounds(max, _) if *max == 0 => write!(f, "{}", self.description()),
write!(f, "{}", self.description()) Self::ErrorStringBounds(max, index) => {
}
EvalAltResult::ErrorStringBounds(max, index) => {
write!(f, "{} (max {}): {}", self.description(), max - 1, index) write!(f, "{} (max {}): {}", self.description(), max - 1, index)
} }
err => write!(f, "{}", err.description()), err => write!(f, "{}", err.description()),