add specific error for match guard bool
This commit is contained in:
parent
f026a07fe3
commit
6a8169e8ba
|
@ -227,6 +227,7 @@ impl BlockBuilder {
|
|||
src,
|
||||
index: _,
|
||||
} => allocate(&[*src], &[*src]),
|
||||
Instruction::CheckMatchGuard { src } => allocate(&[*src], &[*src]),
|
||||
Instruction::Iterate {
|
||||
dst,
|
||||
stream,
|
||||
|
|
|
@ -149,6 +149,7 @@ pub(crate) fn compile_match(
|
|||
// drop %match_reg
|
||||
// jump END
|
||||
// PAT1: %guard_reg <- <guard_expr>
|
||||
// check-match-guard %guard_reg
|
||||
// not %guard_reg
|
||||
// branch-if %guard_reg, MATCH2
|
||||
// drop %match_reg
|
||||
|
@ -224,6 +225,8 @@ pub(crate) fn compile_match(
|
|||
None,
|
||||
guard_reg,
|
||||
)?;
|
||||
builder
|
||||
.push(Instruction::CheckMatchGuard { src: guard_reg }.into_spanned(guard.span))?;
|
||||
builder.push(Instruction::Not { src_dst: guard_reg }.into_spanned(guard.span))?;
|
||||
// Branch to the next match instruction if the branch fails to match
|
||||
builder.push(
|
||||
|
|
|
@ -116,6 +116,12 @@ impl<'a> EvalContext<'a> {
|
|||
self.registers[reg_id.0 as usize] = new_value;
|
||||
}
|
||||
|
||||
/// Borrow the contents of a register.
|
||||
#[inline]
|
||||
fn borrow_reg(&self, reg_id: RegId) -> &PipelineData {
|
||||
&self.registers[reg_id.0 as usize]
|
||||
}
|
||||
|
||||
/// Replace the contents of a register with `Empty` and then return the value that it contained
|
||||
#[inline]
|
||||
fn take_reg(&mut self, reg_id: RegId) -> PipelineData {
|
||||
|
@ -422,24 +428,20 @@ fn eval_instruction<D: DebugContext>(
|
|||
ctx.redirect_err = eval_redirection(ctx, mode, *span, RedirectionStream::Err)?;
|
||||
Ok(Continue)
|
||||
}
|
||||
Instruction::CheckErrRedirected { src } => {
|
||||
let data = ctx.take_reg(*src);
|
||||
match &data {
|
||||
PipelineData::ByteStream(stream, _)
|
||||
if matches!(stream.source(), ByteStreamSource::Child(_)) =>
|
||||
{
|
||||
ctx.put_reg(*src, data);
|
||||
Ok(Continue)
|
||||
}
|
||||
_ => Err(ShellError::GenericError {
|
||||
error: "Can't redirect stderr of internal command output".into(),
|
||||
msg: "piping stderr only works on external commands".into(),
|
||||
span: Some(*span),
|
||||
help: None,
|
||||
inner: vec![],
|
||||
}),
|
||||
Instruction::CheckErrRedirected { src } => match ctx.borrow_reg(*src) {
|
||||
PipelineData::ByteStream(stream, _)
|
||||
if matches!(stream.source(), ByteStreamSource::Child(_)) =>
|
||||
{
|
||||
Ok(Continue)
|
||||
}
|
||||
}
|
||||
_ => Err(ShellError::GenericError {
|
||||
error: "Can't redirect stderr of internal command output".into(),
|
||||
msg: "piping stderr only works on external commands".into(),
|
||||
span: Some(*span),
|
||||
help: None,
|
||||
inner: vec![],
|
||||
}),
|
||||
},
|
||||
Instruction::OpenFile {
|
||||
file_num,
|
||||
path,
|
||||
|
@ -656,12 +658,10 @@ fn eval_instruction<D: DebugContext>(
|
|||
}
|
||||
}
|
||||
Instruction::BranchIfEmpty { src, index } => {
|
||||
let data = ctx.take_reg(*src);
|
||||
let is_empty = matches!(
|
||||
data,
|
||||
ctx.borrow_reg(*src),
|
||||
PipelineData::Empty | PipelineData::Value(Value::Nothing { .. }, _)
|
||||
);
|
||||
ctx.put_reg(*src, data);
|
||||
|
||||
if is_empty {
|
||||
Ok(Branch(*index))
|
||||
|
@ -688,6 +688,16 @@ fn eval_instruction<D: DebugContext>(
|
|||
Ok(Continue)
|
||||
}
|
||||
}
|
||||
Instruction::CheckMatchGuard { src } => {
|
||||
if matches!(
|
||||
ctx.borrow_reg(*src),
|
||||
PipelineData::Value(Value::Bool { .. }, _)
|
||||
) {
|
||||
Ok(Continue)
|
||||
} else {
|
||||
Err(ShellError::MatchGuardNotBool { span: *span })
|
||||
}
|
||||
}
|
||||
Instruction::Iterate {
|
||||
dst,
|
||||
stream,
|
||||
|
|
|
@ -216,6 +216,9 @@ impl<'a> fmt::Display for FmtInstruction<'a> {
|
|||
};
|
||||
write!(f, "{:WIDTH$} ({pattern}), {src}, {index}", "match")
|
||||
}
|
||||
Instruction::CheckMatchGuard { src } => {
|
||||
write!(f, "{:WIDTH$} {src}", "check-match-guard")
|
||||
}
|
||||
Instruction::Iterate {
|
||||
dst,
|
||||
stream,
|
||||
|
|
|
@ -223,6 +223,9 @@ pub enum Instruction {
|
|||
src: RegId,
|
||||
index: usize,
|
||||
},
|
||||
/// Check that a match guard is a boolean, throwing
|
||||
/// [`MatchGuardNotBool`](crate::ShellError::MatchGuardNotBool) if it isn't. Preserves `src`.
|
||||
CheckMatchGuard { src: RegId },
|
||||
/// Iterate on register `stream`, putting the next value in `dst` if present, or jumping to
|
||||
/// `end_index` if the iterator is finished
|
||||
Iterate {
|
||||
|
|
Loading…
Reference in New Issue
Block a user