Add discrete list/table

This commit is contained in:
JT 2021-09-04 18:52:28 +12:00
parent 74bb2af3e1
commit 5e33b8536b
7 changed files with 142 additions and 12 deletions

View File

@ -42,6 +42,22 @@ impl Command for Each {
match input {
Value::List { val, .. } => Ok(Value::List {
val: val
.into_iter()
.map(move |x| {
let engine_state = context.engine_state.borrow();
let block = engine_state.get_block(block);
let state = context.enter_scope();
state.add_var(var_id, x.clone());
//FIXME: DON'T UNWRAP
eval_block(&state, block, Value::nothing()).unwrap()
})
.collect(),
span: call.head,
}),
Value::ValueStream { stream, .. } => Ok(Value::ValueStream {
stream: stream
.map(move |x| {
let engine_state = context.engine_state.borrow();
let block = engine_state.get_block(block);

View File

@ -53,8 +53,8 @@ impl Command for For {
let context = context.clone();
match values {
Value::List { val, .. } => Ok(Value::List {
val: val
Value::ValueStream { stream, .. } => Ok(Value::ValueStream {
stream: stream
.map(move |x| {
let engine_state = context.engine_state.borrow();
let block = engine_state.get_block(block);
@ -68,6 +68,22 @@ impl Command for For {
.into_value_stream(),
span: call.head,
}),
Value::List { val, .. } => Ok(Value::List {
val: val
.into_iter()
.map(move |x| {
let engine_state = context.engine_state.borrow();
let block = engine_state.get_block(block);
let state = context.enter_scope();
state.add_var(var_id, x.clone());
//FIXME: DON'T UNWRAP
eval_block(&state, block, Value::nothing()).unwrap()
})
.collect(),
span: call.head,
}),
_ => Ok(Value::nothing()),
}
}

View File

@ -25,7 +25,7 @@ impl Command for Length {
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
match input {
Value::List { val, .. } => {
let length = val.count();
let length = val.len();
Ok(Value::Int {
val: length as i64,
@ -33,7 +33,23 @@ impl Command for Length {
})
}
Value::Table { val, .. } => {
let length = val.count();
let length = val.len();
Ok(Value::Int {
val: length as i64,
span: call.head,
})
}
Value::ValueStream { stream, .. } => {
let length = stream.count();
Ok(Value::Int {
val: length as i64,
span: call.head,
})
}
Value::RowStream { stream, .. } => {
let length = stream.count();
Ok(Value::Int {
val: length as i64,

View File

@ -1,6 +1,6 @@
use nu_protocol::ast::{Block, Call, Expr, Expression, Operator, Statement};
use nu_protocol::engine::EvaluationContext;
use nu_protocol::{IntoRowStream, IntoValueStream, ShellError, Value};
use nu_protocol::{ShellError, Value};
pub fn eval_operator(op: &Expression) -> Result<Operator, ShellError> {
match op {
@ -99,7 +99,7 @@ pub fn eval_expression(
output.push(eval_expression(context, expr)?);
}
Ok(Value::List {
val: output.into_iter().into_value_stream(),
val: output,
span: expr.span,
})
}
@ -119,7 +119,7 @@ pub fn eval_expression(
}
Ok(Value::Table {
headers: output_headers,
val: output_rows.into_row_stream(),
val: output_rows,
span: expr.span,
})
}

View File

@ -1688,7 +1688,14 @@ pub fn parse_value(
} else if bytes.starts_with(b"(") {
return parse_full_column_path(working_set, span);
} else if bytes.starts_with(b"{") {
return parse_block_expression(working_set, span);
if matches!(shape, SyntaxShape::Block) || matches!(shape, SyntaxShape::Any) {
return parse_block_expression(working_set, span);
} else {
return (
Expression::garbage(span),
Some(ParseError::Expected("non-block value".into(), span)),
);
}
} else if bytes.starts_with(b"[") {
match shape {
SyntaxShape::Any

View File

@ -15,6 +15,8 @@ pub enum Type {
Number,
Nothing,
Table,
RowStream,
ValueStream,
Unknown,
}
@ -34,6 +36,8 @@ impl Display for Type {
Type::Number => write!(f, "number"),
Type::String => write!(f, "string"),
Type::Table => write!(f, "table"),
Type::ValueStream => write!(f, "value stream"),
Type::RowStream => write!(f, "row stream"),
Type::Unknown => write!(f, "unknown"),
}
}

View File

@ -125,13 +125,22 @@ pub enum Value {
val: String,
span: Span,
},
ValueStream {
stream: ValueStream,
span: Span,
},
RowStream {
headers: Vec<String>,
stream: RowStream,
span: Span,
},
List {
val: ValueStream,
val: Vec<Value>,
span: Span,
},
Table {
headers: Vec<String>,
val: RowStream,
val: Vec<Vec<Value>>,
span: Span,
},
Block {
@ -160,6 +169,8 @@ impl Value {
Value::List { span, .. } => *span,
Value::Table { span, .. } => *span,
Value::Block { span, .. } => *span,
Value::RowStream { span, .. } => *span,
Value::ValueStream { span, .. } => *span,
Value::Nothing { span, .. } => *span,
}
}
@ -170,6 +181,8 @@ impl Value {
Value::Int { span, .. } => *span = new_span,
Value::Float { span, .. } => *span = new_span,
Value::String { span, .. } => *span = new_span,
Value::RowStream { span, .. } => *span = new_span,
Value::ValueStream { span, .. } => *span = new_span,
Value::List { span, .. } => *span = new_span,
Value::Table { span, .. } => *span = new_span,
Value::Block { span, .. } => *span = new_span,
@ -189,6 +202,8 @@ impl Value {
Value::Table { .. } => Type::Table, // FIXME
Value::Nothing { .. } => Type::Nothing,
Value::Block { .. } => Type::Block,
Value::ValueStream { .. } => Type::ValueStream,
Value::RowStream { .. } => Type::RowStream,
}
}
@ -198,8 +213,25 @@ impl Value {
Value::Int { val, .. } => val.to_string(),
Value::Float { val, .. } => val.to_string(),
Value::String { val, .. } => val,
Value::List { val, .. } => val.into_string(),
Value::Table { headers, val, .. } => val.into_string(headers),
Value::ValueStream { stream, .. } => stream.into_string(),
Value::List { val, .. } => val
.into_iter()
.map(|x| x.into_string())
.collect::<Vec<_>>()
.join(", "),
Value::Table { val, .. } => val
.into_iter()
.map(|x| {
x.into_iter()
.map(|x| x.into_string())
.collect::<Vec<_>>()
.join(", ")
})
.collect::<Vec<_>>()
.join("\n"),
Value::RowStream {
headers, stream, ..
} => stream.into_string(headers),
Value::Block { val, .. } => format!("<Block {}>", val),
Value::Nothing { .. } => String::new(),
}
@ -517,6 +549,25 @@ impl Value {
val: lhs == rhs,
span,
}),
(Value::List { val: lhs, .. }, Value::List { val: rhs, .. }) => Ok(Value::Bool {
val: lhs == rhs,
span,
}),
(
Value::Table {
val: lhs,
headers: lhs_headers,
..
},
Value::Table {
val: rhs,
headers: rhs_headers,
..
},
) => Ok(Value::Bool {
val: lhs_headers == rhs_headers && lhs == rhs,
span,
}),
_ => Err(ShellError::OperatorMismatch {
op_span: op,
lhs_ty: self.get_type(),
@ -553,6 +604,26 @@ impl Value {
val: lhs != rhs,
span,
}),
(Value::List { val: lhs, .. }, Value::List { val: rhs, .. }) => Ok(Value::Bool {
val: lhs != rhs,
span,
}),
(
Value::Table {
val: lhs,
headers: lhs_headers,
..
},
Value::Table {
val: rhs,
headers: rhs_headers,
..
},
) => Ok(Value::Bool {
val: lhs_headers != rhs_headers || lhs != rhs,
span,
}),
_ => Err(ShellError::OperatorMismatch {
op_span: op,
lhs_ty: self.get_type(),