Improve external output in subexprs (#294)

This commit is contained in:
JT
2021-11-06 18:50:33 +13:00
committed by GitHub
parent c7d159a0f3
commit 02b8027749
50 changed files with 320 additions and 136 deletions

View File

@ -178,7 +178,11 @@ pub fn eval_expression(
}),
Expr::ValueWithUnit(e, unit) => match eval_expression(engine_state, stack, e)? {
Value::Int { val, .. } => Ok(compute(val, unit.item, unit.span)),
_ => Err(ShellError::CantConvert("unit value".into(), e.span)),
x => Err(ShellError::CantConvert(
"unit value".into(),
x.get_type().to_string(),
e.span,
)),
},
Expr::Range(from, next, to, operator) => {
let from = if let Some(f) = from {
@ -224,7 +228,10 @@ pub fn eval_expression(
Expr::RowCondition(_, expr) => eval_expression(engine_state, stack, expr),
Expr::Call(call) => {
// FIXME: protect this collect with ctrl-c
Ok(eval_call(engine_state, stack, call, PipelineData::new())?.into_value())
Ok(
eval_call(engine_state, stack, call, PipelineData::new(call.head))?
.into_value(call.head),
)
}
Expr::ExternalCall(name, span, args) => {
// FIXME: protect this collect with ctrl-c
@ -234,10 +241,10 @@ pub fn eval_expression(
name,
span,
args,
PipelineData::new(),
PipelineData::new(*span),
true,
)?
.into_value())
.into_value(*span))
}
Expr::Operator(_) => Ok(Value::Nothing { span: expr.span }),
Expr::BinaryOp(lhs, op, rhs) => {
@ -271,7 +278,10 @@ pub fn eval_expression(
let block = engine_state.get_block(*block_id);
// FIXME: protect this collect with ctrl-c
Ok(eval_block(engine_state, stack, block, PipelineData::new())?.into_value())
Ok(
eval_subexpression(engine_state, stack, block, PipelineData::new(expr.span))?
.into_value(expr.span),
)
}
Expr::Block(block_id) => Ok(Value::Block {
val: *block_id,
@ -370,6 +380,64 @@ pub fn eval_block(
Ok(input)
}
pub fn eval_subexpression(
engine_state: &EngineState,
stack: &mut Stack,
block: &Block,
mut input: PipelineData,
) -> Result<PipelineData, ShellError> {
for stmt in block.stmts.iter() {
if let Statement::Pipeline(pipeline) = stmt {
for (i, elem) in pipeline.expressions.iter().enumerate() {
match elem {
Expression {
expr: Expr::Call(call),
..
} => {
input = eval_call(engine_state, stack, call, input)?;
}
Expression {
expr: Expr::ExternalCall(name, name_span, args),
..
} => {
input = eval_external(
engine_state,
stack,
name,
name_span,
args,
input,
false,
)?;
if i == pipeline.expressions.len() - 1 {
// We're at the end, so drain as a string for the value
// to be used later
// FIXME: the trimming of the end probably needs to live in a better place
let mut s = input.collect_string();
if s.ends_with('\n') {
s.pop();
}
input = Value::String {
val: s.to_string(),
span: *name_span,
}
.into_pipeline_data()
}
}
elem => {
input = eval_expression(engine_state, stack, elem)?.into_pipeline_data();
}
}
}
}
}
Ok(input)
}
pub fn eval_variable(
engine_state: &EngineState,
stack: &Stack,

View File

@ -32,7 +32,11 @@ impl FromValue for Spanned<i64> {
span: *span,
}),
v => Err(ShellError::CantConvert("integer".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"integer".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}
@ -44,7 +48,11 @@ impl FromValue for i64 {
Value::Filesize { val, .. } => Ok(*val as i64),
Value::Duration { val, .. } => Ok(*val as i64),
v => Err(ShellError::CantConvert("integer".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"integer".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}
@ -61,7 +69,11 @@ impl FromValue for Spanned<f64> {
span: *span,
}),
v => Err(ShellError::CantConvert("float".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"float".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}
@ -71,7 +83,11 @@ impl FromValue for f64 {
match v {
Value::Float { val, .. } => Ok(*val),
Value::Int { val, .. } => Ok(*val as f64),
v => Err(ShellError::CantConvert("float".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"float".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}
@ -109,7 +125,11 @@ impl FromValue for CellPath {
span,
}],
}),
_ => Err(ShellError::CantConvert("cell path".into(), span)),
x => Err(ShellError::CantConvert(
"cell path".into(),
x.get_type().to_string(),
span,
)),
}
}
}
@ -118,7 +138,11 @@ impl FromValue for bool {
fn from_value(v: &Value) -> Result<Self, ShellError> {
match v {
Value::Bool { val, .. } => Ok(*val),
v => Err(ShellError::CantConvert("bool".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"bool".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}
@ -130,7 +154,11 @@ impl FromValue for Spanned<bool> {
item: *val,
span: *span,
}),
v => Err(ShellError::CantConvert("bool".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"bool".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}
@ -139,7 +167,11 @@ impl FromValue for DateTime<FixedOffset> {
fn from_value(v: &Value) -> Result<Self, ShellError> {
match v {
Value::Date { val, .. } => Ok(*val),
v => Err(ShellError::CantConvert("date".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"date".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}
@ -151,7 +183,11 @@ impl FromValue for Spanned<DateTime<FixedOffset>> {
item: *val,
span: *span,
}),
v => Err(ShellError::CantConvert("date".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"date".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}
@ -160,7 +196,11 @@ impl FromValue for Range {
fn from_value(v: &Value) -> Result<Self, ShellError> {
match v {
Value::Range { val, .. } => Ok((**val).clone()),
v => Err(ShellError::CantConvert("range".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"range".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}
@ -172,7 +212,11 @@ impl FromValue for Spanned<Range> {
item: (**val).clone(),
span: *span,
}),
v => Err(ShellError::CantConvert("range".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"range".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}
@ -182,7 +226,11 @@ impl FromValue for Vec<u8> {
match v {
Value::Binary { val, .. } => Ok(val.clone()),
Value::String { val, .. } => Ok(val.bytes().collect()),
v => Err(ShellError::CantConvert("binary data".into(), v.span()?)),
v => Err(ShellError::CantConvert(
"binary data".into(),
v.get_type().to_string(),
v.span()?,
)),
}
}
}