Move CompilationErrorKind into separate module (#416)

This commit is contained in:
Casey Rodarmor 2019-04-19 02:40:25 -07:00 committed by GitHub
parent 415c84ea39
commit 9c82a1e329
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 154 additions and 151 deletions

View File

@ -116,7 +116,7 @@ impl<'a, 'b> AssignmentEvaluator<'a, 'b> {
invocation_directory: &self.invocation_directory,
dotenv: self.dotenv,
};
evaluate_function(token, name, &context, &call_arguments)
Function::evaluate(token, name, &context, &call_arguments)
}
Expression::String { ref cooked_string } => Ok(cooked_string.cooked.to_string()),
Expression::Backtick { raw, ref token } => {

View File

@ -77,7 +77,7 @@ impl<'a: 'b, 'b> AssignmentResolver<'a, 'b> {
ref token,
ref arguments,
..
} => resolve_function(token, arguments.len())?,
} => Function::resolve(token, arguments.len())?,
Expression::Concatination { ref lhs, ref rhs } => {
self.resolve_expression(lhs)?;
self.resolve_expression(rhs)?;

View File

@ -26,11 +26,12 @@ pub(crate) use crate::{
assignment_evaluator::AssignmentEvaluator,
assignment_resolver::AssignmentResolver,
color::Color,
compilation_error::{CompilationError, CompilationErrorKind, CompilationResult},
compilation_error::CompilationError,
compilation_error_kind::CompilationErrorKind,
configuration::Configuration,
expression::Expression,
fragment::Fragment,
function::{evaluate_function, resolve_function},
function::Function,
function_context::FunctionContext,
functions::Functions,
interrupt_guard::InterruptGuard,
@ -45,7 +46,7 @@ pub(crate) use crate::{
recipe::Recipe,
recipe_context::RecipeContext,
recipe_resolver::RecipeResolver,
runtime_error::{RunResult, RuntimeError},
runtime_error::RuntimeError,
shebang::Shebang,
state::State,
string_literal::StringLiteral,
@ -56,6 +57,10 @@ pub(crate) use crate::{
verbosity::Verbosity,
};
pub type CompilationResult<'a, T> = Result<T, CompilationError<'a>>;
pub type RunResult<'a, T> = Result<T, RuntimeError<'a>>;
#[allow(unused_imports)]
pub(crate) use std::io::prelude::*;

View File

@ -2,8 +2,6 @@ use crate::common::*;
use crate::misc::{maybe_s, show_whitespace, write_error_context, Or};
pub type CompilationResult<'a, T> = Result<T, CompilationError<'a>>;
#[derive(Debug, PartialEq)]
pub struct CompilationError<'a> {
pub text: &'a str,
@ -14,96 +12,6 @@ pub struct CompilationError<'a> {
pub kind: CompilationErrorKind<'a>,
}
#[derive(Debug, PartialEq)]
pub enum CompilationErrorKind<'a> {
AliasShadowsRecipe {
alias: &'a str,
recipe_line: usize,
},
CircularRecipeDependency {
recipe: &'a str,
circle: Vec<&'a str>,
},
CircularVariableDependency {
variable: &'a str,
circle: Vec<&'a str>,
},
DependencyHasParameters {
recipe: &'a str,
dependency: &'a str,
},
DuplicateAlias {
alias: &'a str,
first: usize,
},
DuplicateDependency {
recipe: &'a str,
dependency: &'a str,
},
DuplicateParameter {
recipe: &'a str,
parameter: &'a str,
},
DuplicateRecipe {
recipe: &'a str,
first: usize,
},
DuplicateVariable {
variable: &'a str,
},
ExtraLeadingWhitespace,
FunctionArgumentCountMismatch {
function: &'a str,
found: usize,
expected: usize,
},
InconsistentLeadingWhitespace {
expected: &'a str,
found: &'a str,
},
Internal {
message: String,
},
InvalidEscapeSequence {
character: char,
},
MixedLeadingWhitespace {
whitespace: &'a str,
},
ParameterFollowsVariadicParameter {
parameter: &'a str,
},
ParameterShadowsVariable {
parameter: &'a str,
},
RequiredParameterFollowsDefaultParameter {
parameter: &'a str,
},
UndefinedVariable {
variable: &'a str,
},
UnexpectedToken {
expected: Vec<TokenKind>,
found: TokenKind,
},
UnknownAliasTarget {
alias: &'a str,
target: &'a str,
},
UnknownDependency {
recipe: &'a str,
unknown: &'a str,
},
UnknownFunction {
function: &'a str,
},
UnknownStartOfToken,
UnpairedCarriageReturn,
UnterminatedInterpolation,
UnterminatedString,
UnterminatedBacktick,
}
impl<'a> Display for CompilationError<'a> {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
use CompilationErrorKind::*;

View File

@ -0,0 +1,91 @@
use crate::common::*;
#[derive(Debug, PartialEq)]
pub enum CompilationErrorKind<'a> {
AliasShadowsRecipe {
alias: &'a str,
recipe_line: usize,
},
CircularRecipeDependency {
recipe: &'a str,
circle: Vec<&'a str>,
},
CircularVariableDependency {
variable: &'a str,
circle: Vec<&'a str>,
},
DependencyHasParameters {
recipe: &'a str,
dependency: &'a str,
},
DuplicateAlias {
alias: &'a str,
first: usize,
},
DuplicateDependency {
recipe: &'a str,
dependency: &'a str,
},
DuplicateParameter {
recipe: &'a str,
parameter: &'a str,
},
DuplicateRecipe {
recipe: &'a str,
first: usize,
},
DuplicateVariable {
variable: &'a str,
},
ExtraLeadingWhitespace,
FunctionArgumentCountMismatch {
function: &'a str,
found: usize,
expected: usize,
},
InconsistentLeadingWhitespace {
expected: &'a str,
found: &'a str,
},
Internal {
message: String,
},
InvalidEscapeSequence {
character: char,
},
MixedLeadingWhitespace {
whitespace: &'a str,
},
ParameterFollowsVariadicParameter {
parameter: &'a str,
},
ParameterShadowsVariable {
parameter: &'a str,
},
RequiredParameterFollowsDefaultParameter {
parameter: &'a str,
},
UndefinedVariable {
variable: &'a str,
},
UnexpectedToken {
expected: Vec<TokenKind>,
found: TokenKind,
},
UnknownAliasTarget {
alias: &'a str,
target: &'a str,
},
UnknownDependency {
recipe: &'a str,
unknown: &'a str,
},
UnknownFunction {
function: &'a str,
},
UnknownStartOfToken,
UnpairedCarriageReturn,
UnterminatedInterpolation,
UnterminatedString,
UnterminatedBacktick,
}

View File

@ -20,7 +20,7 @@ lazy_static! {
.collect();
}
enum Function {
pub enum Function {
Nullary(fn(&FunctionContext) -> Result<String, String>),
Unary(fn(&FunctionContext, &str) -> Result<String, String>),
Binary(fn(&FunctionContext, &str, &str) -> Result<String, String>),
@ -35,64 +35,64 @@ impl Function {
Binary(_) => 2,
}
}
}
pub fn resolve_function<'a>(token: &Token<'a>, argc: usize) -> CompilationResult<'a, ()> {
let name = token.lexeme();
if let Some(function) = FUNCTIONS.get(&name) {
use self::Function::*;
match (function, argc) {
(&Nullary(_), 0) | (&Unary(_), 1) | (&Binary(_), 2) => Ok(()),
_ => Err(
token.error(CompilationErrorKind::FunctionArgumentCountMismatch {
function: name,
found: argc,
expected: function.argc(),
}),
),
pub fn resolve<'a>(token: &Token<'a>, argc: usize) -> CompilationResult<'a, ()> {
let name = token.lexeme();
if let Some(function) = FUNCTIONS.get(&name) {
use self::Function::*;
match (function, argc) {
(&Nullary(_), 0) | (&Unary(_), 1) | (&Binary(_), 2) => Ok(()),
_ => Err(
token.error(CompilationErrorKind::FunctionArgumentCountMismatch {
function: name,
found: argc,
expected: function.argc(),
}),
),
}
} else {
Err(token.error(CompilationErrorKind::UnknownFunction {
function: token.lexeme(),
}))
}
} else {
Err(token.error(CompilationErrorKind::UnknownFunction {
function: token.lexeme(),
}))
}
}
pub fn evaluate_function<'a>(
token: &Token<'a>,
name: &'a str,
context: &FunctionContext,
arguments: &[String],
) -> RunResult<'a, String> {
if let Some(function) = FUNCTIONS.get(name) {
use self::Function::*;
let argc = arguments.len();
match (function, argc) {
(&Nullary(f), 0) => f(context).map_err(|message| RuntimeError::FunctionCall {
token: token.clone(),
message,
}),
(&Unary(f), 1) => f(context, &arguments[0]).map_err(|message| RuntimeError::FunctionCall {
token: token.clone(),
message,
}),
(&Binary(f), 2) => {
f(context, &arguments[0], &arguments[1]).map_err(|message| RuntimeError::FunctionCall {
pub fn evaluate<'a>(
token: &Token<'a>,
name: &'a str,
context: &FunctionContext,
arguments: &[String],
) -> RunResult<'a, String> {
if let Some(function) = FUNCTIONS.get(name) {
use self::Function::*;
let argc = arguments.len();
match (function, argc) {
(&Nullary(f), 0) => f(context).map_err(|message| RuntimeError::FunctionCall {
token: token.clone(),
message,
})
}),
(&Unary(f), 1) => f(context, &arguments[0]).map_err(|message| RuntimeError::FunctionCall {
token: token.clone(),
message,
}),
(&Binary(f), 2) => {
f(context, &arguments[0], &arguments[1]).map_err(|message| RuntimeError::FunctionCall {
token: token.clone(),
message,
})
}
_ => Err(RuntimeError::Internal {
message: format!(
"attempted to evaluate function `{}` with {} arguments",
name, argc
),
}),
}
_ => Err(RuntimeError::Internal {
message: format!(
"attempted to evaluate function `{}` with {} arguments",
name, argc
),
}),
} else {
Err(RuntimeError::Internal {
message: format!("attempted to evaluate unknown function: `{}`", name),
})
}
} else {
Err(RuntimeError::Internal {
message: format!("attempted to evaluate unknown function: `{}`", name),
})
}
}

View File

@ -19,6 +19,7 @@ mod color;
mod command_ext;
mod common;
mod compilation_error;
mod compilation_error_kind;
mod configuration;
mod expression;
mod fragment;

View File

@ -71,7 +71,7 @@ impl<'a, 'b> RecipeResolver<'a, 'b> {
}
fn resolve_function(&self, function: &Token, argc: usize) -> CompilationResult<'a, ()> {
resolve_function(function, argc).map_err(|error| CompilationError {
Function::resolve(function, argc).map_err(|error| CompilationError {
offset: error.offset,
line: error.line,
column: error.column,

View File

@ -4,8 +4,6 @@ use brev::OutputError;
use crate::misc::{maybe_s, ticks, write_error_context, And, Or, Tick};
pub type RunResult<'a, T> = Result<T, RuntimeError<'a>>;
fn write_token_error_context(f: &mut Formatter, token: &Token) -> Result<(), fmt::Error> {
write_error_context(
f,