This commit is contained in:
JT 2021-10-25 17:24:10 +13:00
parent b6d269e90a
commit 397a31e69c
8 changed files with 241 additions and 195 deletions

View File

@ -39,7 +39,7 @@ impl Command for Do {
let block = context.engine_state.get_block(block_id); let block = context.engine_state.get_block(block_id);
let state = context.enter_scope(); let mut state = context.enter_scope();
let params: Vec<_> = block let params: Vec<_> = block
.signature .signature

View File

@ -62,7 +62,7 @@ impl Command for For {
.map(move |x| { .map(move |x| {
let block = context.engine_state.get_block(block); let block = context.engine_state.get_block(block);
let state = context.enter_scope(); let mut state = context.enter_scope();
state.add_var(var_id, x); state.add_var(var_id, x);
@ -75,6 +75,33 @@ impl Command for For {
} }
}) })
.into_pipeline_data()), .into_pipeline_data()),
Value::Range { val, span } => Ok(val
.into_range_iter()?
.map(move |x| {
let block = context.engine_state.get_block(block);
let mut state = context.enter_scope();
state.add_var(var_id, x);
match eval_block(&state, block, PipelineData::new()) {
Ok(value) => Value::List {
vals: value.collect(),
span,
},
Err(error) => Value::Error { error },
}
})
.into_pipeline_data()),
x => {
let block = context.engine_state.get_block(block);
let mut state = context.enter_scope();
state.add_var(var_id, x);
eval_block(&state, block, PipelineData::new())
}
} }
} }

View File

@ -1,7 +1,7 @@
use nu_engine::eval_block; use nu_engine::eval_block;
use nu_protocol::ast::Call; use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EvaluationContext}; use nu_protocol::engine::{Command, EvaluationContext};
use nu_protocol::{Example, PipelineData, Signature, Span, SyntaxShape, Value}; use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value};
#[derive(Clone)] #[derive(Clone)]
pub struct Each; pub struct Each;
@ -65,186 +65,180 @@ impl Command for Each {
let context = context.clone(); let context = context.clone();
let span = call.head; let span = call.head;
// match input { match input {
// Value::Range { val, .. } => Ok(val PipelineData::Value(Value::Range { val, .. }) => Ok(val
// .into_range_iter()? .into_range_iter()?
// .enumerate() .enumerate()
// .map(move |(idx, x)| { .map(move |(idx, x)| {
// let block = context.engine_state.get_block(block_id); let block = context.engine_state.get_block(block_id);
// let state = context.enter_scope(); let state = context.enter_scope();
// if let Some(var) = block.signature.get_positional(0) { if let Some(var) = block.signature.get_positional(0) {
// if let Some(var_id) = &var.var_id { if let Some(var_id) = &var.var_id {
// if numbered { if numbered {
// state.add_var( state.add_var(
// *var_id, *var_id,
// Value::Record { Value::Record {
// cols: vec!["index".into(), "item".into()], cols: vec!["index".into(), "item".into()],
// vals: vec![ vals: vec![
// Value::Int { Value::Int {
// val: idx as i64, val: idx as i64,
// span, span,
// }, },
// x, x,
// ], ],
// span, span,
// }, },
// ); );
// } else { } else {
// state.add_var(*var_id, x); state.add_var(*var_id, x);
// } }
// } }
// } }
// match eval_block(&state, block, Value::nothing()) { match eval_block(&state, block, PipelineData::new()) {
// Ok(v) => v, Ok(v) => v,
// Err(error) => Value::Error { error }, Err(error) => Value::Error { error }.into_pipeline_data(),
// } }
// }) })
// .into_pipeline_data()), .flatten()
// Value::List { vals: val, .. } => Ok(Value::Stream { .into_pipeline_data()),
// stream: val PipelineData::Value(Value::List { vals: val, .. }) => Ok(val
// .into_iter() .into_iter()
// .enumerate() .enumerate()
// .map(move |(idx, x)| { .map(move |(idx, x)| {
// let engine_state = context.engine_state.borrow(); let block = context.engine_state.get_block(block_id);
// let block = engine_state.get_block(block_id);
// let state = context.enter_scope(); let state = context.enter_scope();
// if let Some(var) = block.signature.get_positional(0) { if let Some(var) = block.signature.get_positional(0) {
// if let Some(var_id) = &var.var_id { if let Some(var_id) = &var.var_id {
// if numbered { if numbered {
// state.add_var( state.add_var(
// *var_id, *var_id,
// Value::Record { Value::Record {
// cols: vec!["index".into(), "item".into()], cols: vec!["index".into(), "item".into()],
// vals: vec![ vals: vec![
// Value::Int { Value::Int {
// val: idx as i64, val: idx as i64,
// span, span,
// }, },
// x, x,
// ], ],
// span, span,
// }, },
// ); );
// } else { } else {
// state.add_var(*var_id, x); state.add_var(*var_id, x);
// } }
// } }
// } }
// match eval_block(&state, block, Value::nothing()) { match eval_block(&state, block, PipelineData::new()) {
// Ok(v) => v, Ok(v) => v,
// Err(error) => Value::Error { error }, Err(error) => Value::Error { error }.into_pipeline_data(),
// } }
// }) })
// .into_value_stream(), .flatten()
// span: call.head, .into_pipeline_data()),
// }), PipelineData::Stream(stream) => Ok(stream
// Value::Stream { stream, .. } => Ok(Value::Stream { .enumerate()
// stream: stream .map(move |(idx, x)| {
// .enumerate() let block = context.engine_state.get_block(block_id);
// .map(move |(idx, x)| {
// let engine_state = context.engine_state.borrow();
// let block = engine_state.get_block(block_id);
// let state = context.enter_scope(); let state = context.enter_scope();
// if let Some(var) = block.signature.get_positional(0) { if let Some(var) = block.signature.get_positional(0) {
// if let Some(var_id) = &var.var_id { if let Some(var_id) = &var.var_id {
// if numbered { if numbered {
// state.add_var( state.add_var(
// *var_id, *var_id,
// Value::Record { Value::Record {
// cols: vec!["index".into(), "item".into()], cols: vec!["index".into(), "item".into()],
// vals: vec![ vals: vec![
// Value::Int { Value::Int {
// val: idx as i64, val: idx as i64,
// span, span,
// }, },
// x, x,
// ], ],
// span, span,
// }, },
// ); );
// } else { } else {
// state.add_var(*var_id, x); state.add_var(*var_id, x);
// } }
// } }
// } }
// match eval_block(&state, block, Value::nothing()) { match eval_block(&state, block, PipelineData::new()) {
// Ok(v) => v, Ok(v) => v,
// Err(error) => Value::Error { error }, Err(error) => Value::Error { error }.into_pipeline_data(),
// } }
// }) })
// .into_value_stream(), .flatten()
// span: call.head, .into_pipeline_data()),
// }), PipelineData::Value(Value::Record { cols, vals, .. }) => {
// Value::Record { cols, vals, .. } => { let mut output_cols = vec![];
// let mut output_cols = vec![]; let mut output_vals = vec![];
// let mut output_vals = vec![];
// for (col, val) in cols.into_iter().zip(vals.into_iter()) { for (col, val) in cols.into_iter().zip(vals.into_iter()) {
// let engine_state = context.engine_state.borrow(); let block = context.engine_state.get_block(block_id);
// let block = engine_state.get_block(block_id);
// let state = context.enter_scope(); let state = context.enter_scope();
// if let Some(var) = block.signature.get_positional(0) { if let Some(var) = block.signature.get_positional(0) {
// if let Some(var_id) = &var.var_id { if let Some(var_id) = &var.var_id {
// state.add_var( state.add_var(
// *var_id, *var_id,
// Value::Record { Value::Record {
// cols: vec!["column".into(), "value".into()], cols: vec!["column".into(), "value".into()],
// vals: vec![ vals: vec![
// Value::String { Value::String {
// val: col.clone(), val: col.clone(),
// span: call.head, span: call.head,
// }, },
// val, val,
// ], ],
// span: call.head, span: call.head,
// }, },
// ); );
// } }
// } }
// match eval_block(&state, block, Value::nothing())? { match eval_block(&state, block, PipelineData::new())? {
// Value::Record { PipelineData::Value(Value::Record {
// mut cols, mut vals, .. mut cols, mut vals, ..
// } => { }) => {
// // TODO check that the lengths match when traversing record // TODO check that the lengths match when traversing record
// output_cols.append(&mut cols); output_cols.append(&mut cols);
// output_vals.append(&mut vals); output_vals.append(&mut vals);
// } }
// x => { x => {
// output_cols.push(col); output_cols.push(col);
// output_vals.push(x); output_vals.push(x.into_value());
// } }
// } }
// } }
// Ok(Value::Record { Ok(Value::Record {
// cols: output_cols, cols: output_cols,
// vals: output_vals, vals: output_vals,
// span: call.head, span: call.head,
// }) }
// } .into_pipeline_data())
// x => { }
// let engine_state = context.engine_state.borrow(); PipelineData::Value(x) => {
// let block = engine_state.get_block(block_id); let block = context.engine_state.get_block(block_id);
// let state = context.enter_scope(); let state = context.enter_scope();
// if let Some(var) = block.signature.get_positional(0) { if let Some(var) = block.signature.get_positional(0) {
// if let Some(var_id) = &var.var_id { if let Some(var_id) = &var.var_id {
// state.add_var(*var_id, x); state.add_var(*var_id, x);
// } }
// } }
// eval_block(&state, block, Value::nothing()) eval_block(&state, block, PipelineData::new())
// } }
// } }
} }
} }

View File

@ -1,7 +1,7 @@
use nu_engine::CallExt; use nu_engine::CallExt;
use nu_protocol::ast::{Call, CellPath}; use nu_protocol::ast::{Call, CellPath};
use nu_protocol::engine::{Command, EvaluationContext}; use nu_protocol::engine::{Command, EvaluationContext};
use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value};
#[derive(Clone)] #[derive(Clone)]
pub struct Get; pub struct Get;
@ -31,6 +31,8 @@ impl Command for Get {
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let cell_path: CellPath = call.req(context, 0)?; let cell_path: CellPath = call.req(context, 0)?;
input.follow_cell_path(&cell_path.members) input
.follow_cell_path(&cell_path.members)
.map(|x| x.into_pipeline_data())
} }
} }

View File

@ -72,7 +72,7 @@ impl Command for FromJson {
call: &Call, call: &Call,
input: PipelineData, input: PipelineData,
) -> Result<nu_protocol::PipelineData, ShellError> { ) -> Result<nu_protocol::PipelineData, ShellError> {
let span = input.span()?; let span = call.head;
let mut string_input = input.collect_string(); let mut string_input = input.collect_string();
string_input.push('\n'); string_input.push('\n');

View File

@ -3,7 +3,7 @@ use nu_engine::CallExt;
use nu_protocol::{ use nu_protocol::{
ast::{Call, PathMember}, ast::{Call, PathMember},
engine::{Command, EvaluationContext}, engine::{Command, EvaluationContext},
Signature, Span, SyntaxShape, Value, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value,
}; };
use nu_term_grid::grid::{Alignment, Cell, Direction, Filling, Grid, GridOptions}; use nu_term_grid::grid::{Alignment, Cell, Direction, Filling, Grid, GridOptions};
use terminal_size::{Height, Width}; use terminal_size::{Height, Width};
@ -50,14 +50,14 @@ prints out the list properly."#
&self, &self,
context: &EvaluationContext, context: &EvaluationContext,
call: &Call, call: &Call,
input: Value, input: PipelineData,
) -> Result<nu_protocol::Value, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let width_param: Option<String> = call.get_flag(context, "width")?; let width_param: Option<String> = call.get_flag(context, "width")?;
let color_param: bool = call.has_flag("color"); let color_param: bool = call.has_flag("color");
let separator_param: Option<String> = call.get_flag(context, "separator")?; let separator_param: Option<String> = call.get_flag(context, "separator")?;
match input { match input {
Value::List { vals, .. } => { PipelineData::Value(Value::List { vals, .. }) => {
// dbg!("value::list"); // dbg!("value::list");
let data = convert_to_list2(vals); let data = convert_to_list2(vals);
if let Some(items) = data { if let Some(items) = data {
@ -69,10 +69,10 @@ prints out the list properly."#
separator_param, separator_param,
)) ))
} else { } else {
Ok(Value::Nothing { span: call.head }) Ok(PipelineData::new())
} }
} }
Value::Stream { stream, .. } => { PipelineData::Stream(stream) => {
// dbg!("value::stream"); // dbg!("value::stream");
let data = convert_to_list2(stream); let data = convert_to_list2(stream);
if let Some(items) = data { if let Some(items) = data {
@ -85,10 +85,10 @@ prints out the list properly."#
)) ))
} else { } else {
// dbg!(data); // dbg!(data);
Ok(Value::Nothing { span: call.head }) Ok(PipelineData::new())
} }
} }
Value::Record { cols, vals, .. } => { PipelineData::Value(Value::Record { cols, vals, .. }) => {
// dbg!("value::record"); // dbg!("value::record");
let mut items = vec![]; let mut items = vec![];
@ -119,7 +119,7 @@ fn create_grid_output2(
width_param: Option<String>, width_param: Option<String>,
color_param: bool, color_param: bool,
separator_param: Option<String>, separator_param: Option<String>,
) -> Value { ) -> PipelineData {
let ls_colors = LsColors::from_env().unwrap_or_default(); let ls_colors = LsColors::from_env().unwrap_or_default();
let cols = if let Some(col) = width_param { let cols = if let Some(col) = width_param {
col.parse::<u16>().unwrap_or(80) col.parse::<u16>().unwrap_or(80)
@ -167,6 +167,7 @@ fn create_grid_output2(
span: call.head, span: call.head,
} }
} }
.into_pipeline_data()
} }
fn convert_to_list2(iter: impl IntoIterator<Item = Value>) -> Option<Vec<(usize, String, String)>> { fn convert_to_list2(iter: impl IntoIterator<Item = Value>) -> Option<Vec<(usize, String, String)>> {

View File

@ -1,6 +1,6 @@
use nu_protocol::ast::{Call, PathMember}; use nu_protocol::ast::{Call, PathMember};
use nu_protocol::engine::{Command, EvaluationContext}; use nu_protocol::engine::{Command, EvaluationContext};
use nu_protocol::{ShellError, Signature, Span, Value}; use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, Span, Value};
use nu_table::StyledString; use nu_table::StyledString;
use std::collections::HashMap; use std::collections::HashMap;
use terminal_size::{Height, Width}; use terminal_size::{Height, Width};
@ -26,8 +26,8 @@ impl Command for Table {
&self, &self,
_context: &EvaluationContext, _context: &EvaluationContext,
call: &Call, call: &Call,
input: Value, input: PipelineData,
) -> Result<nu_protocol::Value, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let term_width = if let Some((Width(w), Height(_h))) = terminal_size::terminal_size() { let term_width = if let Some((Width(w), Height(_h))) = terminal_size::terminal_size() {
w as usize w as usize
} else { } else {
@ -35,7 +35,7 @@ impl Command for Table {
}; };
match input { match input {
Value::List { vals, .. } => { PipelineData::Value(Value::List { vals, .. }) => {
let table = convert_to_table(vals)?; let table = convert_to_table(vals)?;
if let Some(table) = table { if let Some(table) = table {
@ -44,12 +44,13 @@ impl Command for Table {
Ok(Value::String { Ok(Value::String {
val: result, val: result,
span: call.head, span: call.head,
}) }
.into_pipeline_data())
} else { } else {
Ok(Value::Nothing { span: call.head }) Ok(PipelineData::new())
} }
} }
Value::Stream { stream, .. } => { PipelineData::Stream(stream) => {
let table = convert_to_table(stream)?; let table = convert_to_table(stream)?;
if let Some(table) = table { if let Some(table) = table {
@ -58,12 +59,13 @@ impl Command for Table {
Ok(Value::String { Ok(Value::String {
val: result, val: result,
span: call.head, span: call.head,
}) }
.into_pipeline_data())
} else { } else {
Ok(Value::Nothing { span: call.head }) Ok(PipelineData::new())
} }
} }
Value::Record { cols, vals, .. } => { PipelineData::Value(Value::Record { cols, vals, .. }) => {
let mut output = vec![]; let mut output = vec![];
for (c, v) in cols.into_iter().zip(vals.into_iter()) { for (c, v) in cols.into_iter().zip(vals.into_iter()) {
@ -90,9 +92,10 @@ impl Command for Table {
Ok(Value::String { Ok(Value::String {
val: result, val: result,
span: call.head, span: call.head,
})
} }
Value::Error { error } => Err(error), .into_pipeline_data())
}
PipelineData::Value(Value::Error { error }) => Err(error),
x => Ok(x), x => Ok(x),
} }
} }

View File

@ -1,4 +1,4 @@
use crate::{Span, Value, ValueStream}; use crate::{ast::PathMember, ShellError, Span, Value, ValueStream};
pub enum PipelineData { pub enum PipelineData {
Value(Value), Value(Value),
@ -19,6 +19,25 @@ impl PipelineData {
}, },
} }
} }
pub fn collect_string(self) -> String {
match self {
PipelineData::Value(v) => v.collect_string(),
PipelineData::Stream(s) => s.collect_string(),
}
}
pub fn follow_cell_path(self, cell_path: &[PathMember]) -> Result<Value, ShellError> {
match self {
// FIXME: there are probably better ways of doing this
PipelineData::Stream(stream) => Value::List {
vals: stream.collect(),
span: Span::unknown(),
}
.follow_cell_path(cell_path),
PipelineData::Value(v) => v.follow_cell_path(cell_path),
}
}
} }
impl Default for PipelineData { impl Default for PipelineData {