explicitly set span of binary op output
This commit is contained in:
parent
dcbfff8eb8
commit
9e00e8ab2d
|
@ -161,6 +161,7 @@ impl BlockBuilder {
|
|||
Instruction::Move { dst, src } => allocate(&[*src], &[*dst]),
|
||||
Instruction::Clone { dst, src } => allocate(&[*src], &[*dst, *src]),
|
||||
Instruction::Collect { src_dst } => allocate(&[*src_dst], &[*src_dst]),
|
||||
Instruction::Span { src_dst } => allocate(&[*src_dst], &[*src_dst]),
|
||||
Instruction::Drop { src } => allocate(&[*src], &[]),
|
||||
Instruction::Drain { src } => allocate(&[*src], &[]),
|
||||
Instruction::LoadVariable { dst, var_id: _ } => allocate(&[], &[*dst]),
|
||||
|
|
|
@ -164,6 +164,7 @@ pub(crate) fn compile_expression(
|
|||
lhs,
|
||||
operator.clone().into_spanned(op.span),
|
||||
rhs,
|
||||
expr.span,
|
||||
out_reg,
|
||||
)
|
||||
} else {
|
||||
|
|
|
@ -14,6 +14,7 @@ pub(crate) fn compile_binary_op(
|
|||
lhs: &Expression,
|
||||
op: Spanned<Operator>,
|
||||
rhs: &Expression,
|
||||
span: Span,
|
||||
out_reg: RegId,
|
||||
) -> Result<(), CompileError> {
|
||||
if let Operator::Assignment(assign_op) = op.item {
|
||||
|
@ -25,6 +26,7 @@ pub(crate) fn compile_binary_op(
|
|||
lhs,
|
||||
decomposed_op.into_spanned(op.span),
|
||||
rhs,
|
||||
span,
|
||||
out_reg,
|
||||
)?;
|
||||
} else {
|
||||
|
@ -136,6 +138,8 @@ pub(crate) fn compile_binary_op(
|
|||
)?;
|
||||
}
|
||||
|
||||
builder.push(Instruction::Span { src_dst: out_reg }.into_spanned(span))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -284,6 +284,8 @@ fn eval_instruction<D: DebugContext>(
|
|||
) -> Result<InstructionResult, ShellError> {
|
||||
use self::InstructionResult::*;
|
||||
|
||||
// See the docs for `Instruction` for more information on what these instructions are supposed
|
||||
// to do.
|
||||
match instruction {
|
||||
Instruction::Unreachable => Err(ShellError::IrEvalError {
|
||||
msg: "Reached unreachable code".into(),
|
||||
|
@ -310,6 +312,12 @@ fn eval_instruction<D: DebugContext>(
|
|||
ctx.put_reg(*src_dst, value);
|
||||
Ok(Continue)
|
||||
}
|
||||
Instruction::Span { src_dst } => {
|
||||
let data = ctx.take_reg(*src_dst);
|
||||
let spanned = data.with_span(*span);
|
||||
ctx.put_reg(*src_dst, spanned);
|
||||
Ok(Continue)
|
||||
}
|
||||
Instruction::Drop { src } => {
|
||||
ctx.take_reg(*src);
|
||||
Ok(Continue)
|
||||
|
@ -893,7 +901,8 @@ fn binary_op(
|
|||
return Err(*error);
|
||||
}
|
||||
|
||||
// FIXME: there should be a span for both the operator and for the expr?
|
||||
// We only have access to one span here, but the generated code usually adds a `span`
|
||||
// instruction to set the output span to the right span.
|
||||
let op_span = span;
|
||||
|
||||
let result = match op {
|
||||
|
|
|
@ -80,6 +80,9 @@ impl<'a> fmt::Display for FmtInstruction<'a> {
|
|||
Instruction::Collect { src_dst } => {
|
||||
write!(f, "{:WIDTH$} {src_dst}", "collect")
|
||||
}
|
||||
Instruction::Span { src_dst } => {
|
||||
write!(f, "{:WIDTH$} {src_dst}", "span")
|
||||
}
|
||||
Instruction::Drop { src } => {
|
||||
write!(f, "{:WIDTH$} {src}", "drop")
|
||||
}
|
||||
|
|
|
@ -110,7 +110,9 @@ pub enum Instruction {
|
|||
Clone { dst: RegId, src: RegId },
|
||||
/// Collect a stream in a register to a value
|
||||
Collect { src_dst: RegId },
|
||||
/// Drop the value/straem in a register, without draining
|
||||
/// Change the span of the contents of a register to the span of this instruction.
|
||||
Span { src_dst: RegId },
|
||||
/// Drop the value/stream in a register, without draining
|
||||
Drop { src: RegId },
|
||||
/// Drain the value/stream in a register and discard (e.g. semicolon).
|
||||
///
|
||||
|
|
|
@ -357,6 +357,12 @@ impl ByteStream {
|
|||
self.span
|
||||
}
|
||||
|
||||
/// Changes the [`Span`] associated with the [`ByteStream`].
|
||||
pub fn with_span(mut self, span: Span) -> Self {
|
||||
self.span = span;
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns the [`ByteStreamType`] associated with the [`ByteStream`].
|
||||
pub fn type_(&self) -> ByteStreamType {
|
||||
self.type_
|
||||
|
|
|
@ -34,6 +34,12 @@ impl ListStream {
|
|||
self.span
|
||||
}
|
||||
|
||||
/// Changes the [`Span`] associated with this [`ListStream`].
|
||||
pub fn with_span(mut self, span: Span) -> Self {
|
||||
self.span = span;
|
||||
self
|
||||
}
|
||||
|
||||
/// Convert a [`ListStream`] into its inner [`Value`] `Iterator`.
|
||||
pub fn into_inner(self) -> ValueIterator {
|
||||
self.stream
|
||||
|
|
|
@ -99,6 +99,24 @@ impl PipelineData {
|
|||
}
|
||||
}
|
||||
|
||||
/// Change the span of the [`PipelineData`].
|
||||
///
|
||||
/// Returns `Value(Nothing)` with the given span if it was [`PipelineData::Empty`].
|
||||
pub fn with_span(self, span: Span) -> Self {
|
||||
match self {
|
||||
PipelineData::Empty => PipelineData::Value(Value::nothing(span), None),
|
||||
PipelineData::Value(value, metadata) => {
|
||||
PipelineData::Value(value.with_span(span), metadata)
|
||||
}
|
||||
PipelineData::ListStream(stream, metadata) => {
|
||||
PipelineData::ListStream(stream.with_span(span), metadata)
|
||||
}
|
||||
PipelineData::ByteStream(stream, metadata) => {
|
||||
PipelineData::ByteStream(stream.with_span(span), metadata)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a type that is representative of the `PipelineData`.
|
||||
///
|
||||
/// The type returned here makes no effort to collect a stream, so it may be a different type
|
||||
|
|
Loading…
Reference in New Issue
Block a user