Add discrete list/table
This commit is contained in:
parent
74bb2af3e1
commit
5e33b8536b
|
@ -42,6 +42,22 @@ impl Command for Each {
|
||||||
match input {
|
match input {
|
||||||
Value::List { val, .. } => Ok(Value::List {
|
Value::List { val, .. } => Ok(Value::List {
|
||||||
val: val
|
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| {
|
.map(move |x| {
|
||||||
let engine_state = context.engine_state.borrow();
|
let engine_state = context.engine_state.borrow();
|
||||||
let block = engine_state.get_block(block);
|
let block = engine_state.get_block(block);
|
||||||
|
|
|
@ -53,8 +53,8 @@ impl Command for For {
|
||||||
let context = context.clone();
|
let context = context.clone();
|
||||||
|
|
||||||
match values {
|
match values {
|
||||||
Value::List { val, .. } => Ok(Value::List {
|
Value::ValueStream { stream, .. } => Ok(Value::ValueStream {
|
||||||
val: val
|
stream: stream
|
||||||
.map(move |x| {
|
.map(move |x| {
|
||||||
let engine_state = context.engine_state.borrow();
|
let engine_state = context.engine_state.borrow();
|
||||||
let block = engine_state.get_block(block);
|
let block = engine_state.get_block(block);
|
||||||
|
@ -68,6 +68,22 @@ impl Command for For {
|
||||||
.into_value_stream(),
|
.into_value_stream(),
|
||||||
span: call.head,
|
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()),
|
_ => Ok(Value::nothing()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ impl Command for Length {
|
||||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||||
match input {
|
match input {
|
||||||
Value::List { val, .. } => {
|
Value::List { val, .. } => {
|
||||||
let length = val.count();
|
let length = val.len();
|
||||||
|
|
||||||
Ok(Value::Int {
|
Ok(Value::Int {
|
||||||
val: length as i64,
|
val: length as i64,
|
||||||
|
@ -33,7 +33,23 @@ impl Command for Length {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Value::Table { val, .. } => {
|
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 {
|
Ok(Value::Int {
|
||||||
val: length as i64,
|
val: length as i64,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use nu_protocol::ast::{Block, Call, Expr, Expression, Operator, Statement};
|
use nu_protocol::ast::{Block, Call, Expr, Expression, Operator, Statement};
|
||||||
use nu_protocol::engine::EvaluationContext;
|
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> {
|
pub fn eval_operator(op: &Expression) -> Result<Operator, ShellError> {
|
||||||
match op {
|
match op {
|
||||||
|
@ -99,7 +99,7 @@ pub fn eval_expression(
|
||||||
output.push(eval_expression(context, expr)?);
|
output.push(eval_expression(context, expr)?);
|
||||||
}
|
}
|
||||||
Ok(Value::List {
|
Ok(Value::List {
|
||||||
val: output.into_iter().into_value_stream(),
|
val: output,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ pub fn eval_expression(
|
||||||
}
|
}
|
||||||
Ok(Value::Table {
|
Ok(Value::Table {
|
||||||
headers: output_headers,
|
headers: output_headers,
|
||||||
val: output_rows.into_row_stream(),
|
val: output_rows,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1688,7 +1688,14 @@ pub fn parse_value(
|
||||||
} else if bytes.starts_with(b"(") {
|
} else if bytes.starts_with(b"(") {
|
||||||
return parse_full_column_path(working_set, span);
|
return parse_full_column_path(working_set, span);
|
||||||
} else if bytes.starts_with(b"{") {
|
} 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"[") {
|
} else if bytes.starts_with(b"[") {
|
||||||
match shape {
|
match shape {
|
||||||
SyntaxShape::Any
|
SyntaxShape::Any
|
||||||
|
|
|
@ -15,6 +15,8 @@ pub enum Type {
|
||||||
Number,
|
Number,
|
||||||
Nothing,
|
Nothing,
|
||||||
Table,
|
Table,
|
||||||
|
RowStream,
|
||||||
|
ValueStream,
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +36,8 @@ impl Display for Type {
|
||||||
Type::Number => write!(f, "number"),
|
Type::Number => write!(f, "number"),
|
||||||
Type::String => write!(f, "string"),
|
Type::String => write!(f, "string"),
|
||||||
Type::Table => write!(f, "table"),
|
Type::Table => write!(f, "table"),
|
||||||
|
Type::ValueStream => write!(f, "value stream"),
|
||||||
|
Type::RowStream => write!(f, "row stream"),
|
||||||
Type::Unknown => write!(f, "unknown"),
|
Type::Unknown => write!(f, "unknown"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,13 +125,22 @@ pub enum Value {
|
||||||
val: String,
|
val: String,
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
|
ValueStream {
|
||||||
|
stream: ValueStream,
|
||||||
|
span: Span,
|
||||||
|
},
|
||||||
|
RowStream {
|
||||||
|
headers: Vec<String>,
|
||||||
|
stream: RowStream,
|
||||||
|
span: Span,
|
||||||
|
},
|
||||||
List {
|
List {
|
||||||
val: ValueStream,
|
val: Vec<Value>,
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
Table {
|
Table {
|
||||||
headers: Vec<String>,
|
headers: Vec<String>,
|
||||||
val: RowStream,
|
val: Vec<Vec<Value>>,
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
Block {
|
Block {
|
||||||
|
@ -160,6 +169,8 @@ impl Value {
|
||||||
Value::List { span, .. } => *span,
|
Value::List { span, .. } => *span,
|
||||||
Value::Table { span, .. } => *span,
|
Value::Table { span, .. } => *span,
|
||||||
Value::Block { span, .. } => *span,
|
Value::Block { span, .. } => *span,
|
||||||
|
Value::RowStream { span, .. } => *span,
|
||||||
|
Value::ValueStream { span, .. } => *span,
|
||||||
Value::Nothing { span, .. } => *span,
|
Value::Nothing { span, .. } => *span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,6 +181,8 @@ impl Value {
|
||||||
Value::Int { span, .. } => *span = new_span,
|
Value::Int { span, .. } => *span = new_span,
|
||||||
Value::Float { span, .. } => *span = new_span,
|
Value::Float { span, .. } => *span = new_span,
|
||||||
Value::String { 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::List { span, .. } => *span = new_span,
|
||||||
Value::Table { span, .. } => *span = new_span,
|
Value::Table { span, .. } => *span = new_span,
|
||||||
Value::Block { span, .. } => *span = new_span,
|
Value::Block { span, .. } => *span = new_span,
|
||||||
|
@ -189,6 +202,8 @@ impl Value {
|
||||||
Value::Table { .. } => Type::Table, // FIXME
|
Value::Table { .. } => Type::Table, // FIXME
|
||||||
Value::Nothing { .. } => Type::Nothing,
|
Value::Nothing { .. } => Type::Nothing,
|
||||||
Value::Block { .. } => Type::Block,
|
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::Int { val, .. } => val.to_string(),
|
||||||
Value::Float { val, .. } => val.to_string(),
|
Value::Float { val, .. } => val.to_string(),
|
||||||
Value::String { val, .. } => val,
|
Value::String { val, .. } => val,
|
||||||
Value::List { val, .. } => val.into_string(),
|
Value::ValueStream { stream, .. } => stream.into_string(),
|
||||||
Value::Table { headers, val, .. } => val.into_string(headers),
|
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::Block { val, .. } => format!("<Block {}>", val),
|
||||||
Value::Nothing { .. } => String::new(),
|
Value::Nothing { .. } => String::new(),
|
||||||
}
|
}
|
||||||
|
@ -517,6 +549,25 @@ impl Value {
|
||||||
val: lhs == rhs,
|
val: lhs == rhs,
|
||||||
span,
|
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 {
|
_ => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
|
@ -553,6 +604,26 @@ impl Value {
|
||||||
val: lhs != rhs,
|
val: lhs != rhs,
|
||||||
span,
|
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 {
|
_ => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user