diff --git a/crates/nu-engine/src/compile/builder.rs b/crates/nu-engine/src/compile/builder.rs index aaabec764b..89bda46535 100644 --- a/crates/nu-engine/src/compile/builder.rs +++ b/crates/nu-engine/src/compile/builder.rs @@ -147,6 +147,7 @@ impl BlockBuilder { Instruction::AppendRest { src } => self.free_register(*src)?, Instruction::PushFlag { name: _ } => (), Instruction::PushNamed { name: _, src } => self.free_register(*src)?, + Instruction::PushParserInfo { name: _, info: _ } => (), Instruction::RedirectOut { mode } | Instruction::RedirectErr { mode } => match mode { RedirectMode::File { path, .. } => self.free_register(*path)?, _ => (), diff --git a/crates/nu-engine/src/compile/call.rs b/crates/nu-engine/src/compile/call.rs index 992969d544..b8d8e0f4ac 100644 --- a/crates/nu-engine/src/compile/call.rs +++ b/crates/nu-engine/src/compile/call.rs @@ -119,6 +119,13 @@ pub(crate) fn compile_call( } } + // Add any parser info from the call + for (name, info) in &call.parser_info { + let name = builder.data(name)?; + let info = Box::new(info.clone()); + builder.push(Instruction::PushParserInfo { name, info }.into_spanned(call.head))?; + } + if let Some(mode) = redirect_modes.out { builder.push(mode.map(|mode| Instruction::RedirectOut { mode }))?; } diff --git a/crates/nu-engine/src/eval_ir.rs b/crates/nu-engine/src/eval_ir.rs index 16dade5712..0bf46e32e8 100644 --- a/crates/nu-engine/src/eval_ir.rs +++ b/crates/nu-engine/src/eval_ir.rs @@ -319,6 +319,14 @@ fn eval_instruction( }); Ok(Continue) } + Instruction::PushParserInfo { name, info } => { + ctx.stack.arguments.push(Argument::ParserInfo { + data: ctx.data.clone(), + name: *name, + info: info.clone(), + }); + Ok(Continue) + } Instruction::RedirectOut { mode } => { let out_dest = eval_redirection(ctx, mode, *span)?; ctx.redirect_out = Some(out_dest); diff --git a/crates/nu-protocol/src/engine/argument.rs b/crates/nu-protocol/src/engine/argument.rs index c2c816d2e5..ea5eab8fef 100644 --- a/crates/nu-protocol/src/engine/argument.rs +++ b/crates/nu-protocol/src/engine/argument.rs @@ -28,7 +28,7 @@ pub enum Argument { name: DataSlice, // TODO: rather than `Expression`, this would probably be best served by a specific enum // type for this purpose. - expr: Box, + info: Box, }, } diff --git a/crates/nu-protocol/src/ir/call.rs b/crates/nu-protocol/src/ir/call.rs index 75794f9000..bf24ae36e3 100644 --- a/crates/nu-protocol/src/ir/call.rs +++ b/crates/nu-protocol/src/ir/call.rs @@ -192,7 +192,7 @@ impl Call { Argument::ParserInfo { data, name: name_slice, - expr, + info: expr, } if &data[*name_slice] == name.as_bytes() => Some(expr.as_ref()), _ => None, }) diff --git a/crates/nu-protocol/src/ir/display.rs b/crates/nu-protocol/src/ir/display.rs index 981c6ad324..efbdb98a67 100644 --- a/crates/nu-protocol/src/ir/display.rs +++ b/crates/nu-protocol/src/ir/display.rs @@ -105,6 +105,10 @@ impl<'a> fmt::Display for FmtInstruction<'a> { let name = FmtData(self.data, *name); write!(f, "{:WIDTH$} {name}, {src}", "push-named") } + Instruction::PushParserInfo { name, info } => { + let name = FmtData(self.data, *name); + write!(f, "{:WIDTH$} {name}, {info:?}", "push-parser-info") + } Instruction::RedirectOut { mode } => { write!(f, "{:WIDTH$} {mode}", "redirect-out") } diff --git a/crates/nu-protocol/src/ir/mod.rs b/crates/nu-protocol/src/ir/mod.rs index 3156911577..43f0e640c0 100644 --- a/crates/nu-protocol/src/ir/mod.rs +++ b/crates/nu-protocol/src/ir/mod.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use crate::{ - ast::{CellPath, Operator, RangeInclusion}, + ast::{CellPath, Expression, Operator, RangeInclusion}, engine::EngineState, BlockId, DeclId, RegId, Span, VarId, }; @@ -90,6 +90,11 @@ pub enum Instruction { PushFlag { name: DataSlice }, /// Add a named arg with a value to the next call. PushNamed { name: DataSlice, src: RegId }, + /// Add parser info to the next call. + PushParserInfo { + name: DataSlice, + info: Box, + }, /// Set the redirection for stdout for the next call (only) RedirectOut { mode: RedirectMode }, /// Set the redirection for stderr for the next call (only)