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::Move { dst, src } => allocate(&[*src], &[*dst]),
|
||||||
Instruction::Clone { dst, src } => allocate(&[*src], &[*dst, *src]),
|
Instruction::Clone { dst, src } => allocate(&[*src], &[*dst, *src]),
|
||||||
Instruction::Collect { src_dst } => allocate(&[*src_dst], &[*src_dst]),
|
Instruction::Collect { src_dst } => allocate(&[*src_dst], &[*src_dst]),
|
||||||
|
Instruction::Span { src_dst } => allocate(&[*src_dst], &[*src_dst]),
|
||||||
Instruction::Drop { src } => allocate(&[*src], &[]),
|
Instruction::Drop { src } => allocate(&[*src], &[]),
|
||||||
Instruction::Drain { src } => allocate(&[*src], &[]),
|
Instruction::Drain { src } => allocate(&[*src], &[]),
|
||||||
Instruction::LoadVariable { dst, var_id: _ } => allocate(&[], &[*dst]),
|
Instruction::LoadVariable { dst, var_id: _ } => allocate(&[], &[*dst]),
|
||||||
|
|
|
@ -164,6 +164,7 @@ pub(crate) fn compile_expression(
|
||||||
lhs,
|
lhs,
|
||||||
operator.clone().into_spanned(op.span),
|
operator.clone().into_spanned(op.span),
|
||||||
rhs,
|
rhs,
|
||||||
|
expr.span,
|
||||||
out_reg,
|
out_reg,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub(crate) fn compile_binary_op(
|
||||||
lhs: &Expression,
|
lhs: &Expression,
|
||||||
op: Spanned<Operator>,
|
op: Spanned<Operator>,
|
||||||
rhs: &Expression,
|
rhs: &Expression,
|
||||||
|
span: Span,
|
||||||
out_reg: RegId,
|
out_reg: RegId,
|
||||||
) -> Result<(), CompileError> {
|
) -> Result<(), CompileError> {
|
||||||
if let Operator::Assignment(assign_op) = op.item {
|
if let Operator::Assignment(assign_op) = op.item {
|
||||||
|
@ -25,6 +26,7 @@ pub(crate) fn compile_binary_op(
|
||||||
lhs,
|
lhs,
|
||||||
decomposed_op.into_spanned(op.span),
|
decomposed_op.into_spanned(op.span),
|
||||||
rhs,
|
rhs,
|
||||||
|
span,
|
||||||
out_reg,
|
out_reg,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -136,6 +138,8 @@ pub(crate) fn compile_binary_op(
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.push(Instruction::Span { src_dst: out_reg }.into_spanned(span))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,6 +284,8 @@ fn eval_instruction<D: DebugContext>(
|
||||||
) -> Result<InstructionResult, ShellError> {
|
) -> Result<InstructionResult, ShellError> {
|
||||||
use self::InstructionResult::*;
|
use self::InstructionResult::*;
|
||||||
|
|
||||||
|
// See the docs for `Instruction` for more information on what these instructions are supposed
|
||||||
|
// to do.
|
||||||
match instruction {
|
match instruction {
|
||||||
Instruction::Unreachable => Err(ShellError::IrEvalError {
|
Instruction::Unreachable => Err(ShellError::IrEvalError {
|
||||||
msg: "Reached unreachable code".into(),
|
msg: "Reached unreachable code".into(),
|
||||||
|
@ -310,6 +312,12 @@ fn eval_instruction<D: DebugContext>(
|
||||||
ctx.put_reg(*src_dst, value);
|
ctx.put_reg(*src_dst, value);
|
||||||
Ok(Continue)
|
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 } => {
|
Instruction::Drop { src } => {
|
||||||
ctx.take_reg(*src);
|
ctx.take_reg(*src);
|
||||||
Ok(Continue)
|
Ok(Continue)
|
||||||
|
@ -893,7 +901,8 @@ fn binary_op(
|
||||||
return Err(*error);
|
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 op_span = span;
|
||||||
|
|
||||||
let result = match op {
|
let result = match op {
|
||||||
|
|
|
@ -80,6 +80,9 @@ impl<'a> fmt::Display for FmtInstruction<'a> {
|
||||||
Instruction::Collect { src_dst } => {
|
Instruction::Collect { src_dst } => {
|
||||||
write!(f, "{:WIDTH$} {src_dst}", "collect")
|
write!(f, "{:WIDTH$} {src_dst}", "collect")
|
||||||
}
|
}
|
||||||
|
Instruction::Span { src_dst } => {
|
||||||
|
write!(f, "{:WIDTH$} {src_dst}", "span")
|
||||||
|
}
|
||||||
Instruction::Drop { src } => {
|
Instruction::Drop { src } => {
|
||||||
write!(f, "{:WIDTH$} {src}", "drop")
|
write!(f, "{:WIDTH$} {src}", "drop")
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,9 @@ pub enum Instruction {
|
||||||
Clone { dst: RegId, src: RegId },
|
Clone { dst: RegId, src: RegId },
|
||||||
/// Collect a stream in a register to a value
|
/// Collect a stream in a register to a value
|
||||||
Collect { src_dst: RegId },
|
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 },
|
Drop { src: RegId },
|
||||||
/// Drain the value/stream in a register and discard (e.g. semicolon).
|
/// Drain the value/stream in a register and discard (e.g. semicolon).
|
||||||
///
|
///
|
||||||
|
|
|
@ -357,6 +357,12 @@ impl ByteStream {
|
||||||
self.span
|
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`].
|
/// Returns the [`ByteStreamType`] associated with the [`ByteStream`].
|
||||||
pub fn type_(&self) -> ByteStreamType {
|
pub fn type_(&self) -> ByteStreamType {
|
||||||
self.type_
|
self.type_
|
||||||
|
|
|
@ -34,6 +34,12 @@ impl ListStream {
|
||||||
self.span
|
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`.
|
/// Convert a [`ListStream`] into its inner [`Value`] `Iterator`.
|
||||||
pub fn into_inner(self) -> ValueIterator {
|
pub fn into_inner(self) -> ValueIterator {
|
||||||
self.stream
|
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`.
|
/// 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
|
/// 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