tried to move source command into parser (still doesn't compile)
This commit is contained in:
parent
1d945d8ce3
commit
719920fa37
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -277,6 +277,7 @@ name = "nu-command"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-engine",
|
"nu-engine",
|
||||||
|
"nu-parser",
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ pub fn source(ctx: &EvaluationContext, call: &Call, input: Value) -> Result<Valu
|
||||||
let (block, err) = parse(&mut working_set, None, &contents, true);
|
let (block, err) = parse(&mut working_set, None, &contents, true);
|
||||||
if let Some(e) = err {
|
if let Some(e) = err {
|
||||||
// Be more specific here: need to convert parse error to string
|
// Be more specific here: need to convert parse error to string
|
||||||
Err(ShellError::InternalError("Parse error in file".to_string()))
|
Err(e.into())
|
||||||
} else {
|
} else {
|
||||||
let result = eval_block(ctx, &block, input);
|
let result = eval_block(ctx, &block, input);
|
||||||
match result {
|
match result {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
use nu_parser::parse;
|
||||||
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::{EngineState, EvaluationContext, StateWorkingSet};
|
||||||
use nu_protocol::{Range, ShellError, Span, Value};
|
use nu_protocol::{Range, ShellError, Span, Value};
|
||||||
|
|
||||||
pub fn eval_operator(op: &Expression) -> Result<Operator, ShellError> {
|
pub fn eval_operator(op: &Expression) -> Result<Operator, ShellError> {
|
||||||
|
@ -239,3 +240,15 @@ pub fn eval_block(
|
||||||
|
|
||||||
Ok(input)
|
Ok(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pub fn eval(context: &EvaluationContext, script: &str) -> Result<Value, ShellError> {
|
||||||
|
// let engine_state = EngineState::new();
|
||||||
|
// let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
|
||||||
|
// let (block, err) = parse(&mut working_set, None, b"3", true);
|
||||||
|
// if let Some(e) = err {
|
||||||
|
// Err(e)
|
||||||
|
// } else {
|
||||||
|
// eval_block(context, &block, Value::nothing())
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
lex, lite_parse,
|
lex, lite_parse,
|
||||||
type_check::{math_result_type, type_compatible},
|
type_check::{math_result_type, type_compatible},
|
||||||
|
@ -10,7 +12,7 @@ use nu_protocol::{
|
||||||
RangeInclusion, RangeOperator, Statement,
|
RangeInclusion, RangeOperator, Statement,
|
||||||
},
|
},
|
||||||
engine::StateWorkingSet,
|
engine::StateWorkingSet,
|
||||||
span, Flag, PositionalArg, Signature, Span, SyntaxShape, Type, VarId,
|
span, Flag, PositionalArg, ShellError, Signature, Span, SyntaxShape, Type, VarId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -2299,6 +2301,7 @@ pub fn parse_def_predecl(working_set: &mut StateWorkingSet, spans: &[Span]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parser for the def command
|
||||||
pub fn parse_def(
|
pub fn parse_def(
|
||||||
working_set: &mut StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
spans: &[Span],
|
spans: &[Span],
|
||||||
|
@ -2381,6 +2384,7 @@ pub fn parse_def(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parser for the alias command
|
||||||
pub fn parse_alias(
|
pub fn parse_alias(
|
||||||
working_set: &mut StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
spans: &[Span],
|
spans: &[Span],
|
||||||
|
@ -2436,6 +2440,7 @@ pub fn parse_alias(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse let command
|
||||||
pub fn parse_let(
|
pub fn parse_let(
|
||||||
working_set: &mut StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
spans: &[Span],
|
spans: &[Span],
|
||||||
|
@ -2480,6 +2485,105 @@ pub fn parse_let(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parser for the source command
|
||||||
|
pub fn parse_source(
|
||||||
|
working_set: &mut StateWorkingSet,
|
||||||
|
spans: &[Span],
|
||||||
|
) -> (Statement, Option<ParseError>) {
|
||||||
|
let mut error = None;
|
||||||
|
let name = working_set.get_span_contents(spans[0]);
|
||||||
|
|
||||||
|
if name == b"source" {
|
||||||
|
let (name_expr, err) = parse_string(working_set, spans[1]);
|
||||||
|
error = error.or(err);
|
||||||
|
|
||||||
|
if let Some(filename) = name_expr.as_string() {
|
||||||
|
let source_file = Path::new(&filename);
|
||||||
|
// This is to stay consistent w/ the code taken from nushell
|
||||||
|
let path = source_file;
|
||||||
|
|
||||||
|
let contents = std::fs::read(path);
|
||||||
|
|
||||||
|
match contents {
|
||||||
|
Ok(contents) => {
|
||||||
|
let (block, err) = parse(
|
||||||
|
&mut working_set,
|
||||||
|
path.file_name().and_then(|x| x.to_str()),
|
||||||
|
&contents,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
if let Some(e) = err {
|
||||||
|
(
|
||||||
|
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
expr: Expr::Garbage,
|
||||||
|
span: span(spans),
|
||||||
|
ty: Type::Unknown,
|
||||||
|
}])),
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
let block_id = working_set.add_block(block);
|
||||||
|
(
|
||||||
|
// Why creating a pipeline here for only one expression?
|
||||||
|
// Is there a way to only make this a declaration?
|
||||||
|
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
expr: Expr::Subexpression(block_id),
|
||||||
|
span: span(spans),
|
||||||
|
ty: Type::Unknown, // FIXME
|
||||||
|
}])),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => (
|
||||||
|
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
expr: Expr::Garbage,
|
||||||
|
span: span(spans),
|
||||||
|
ty: Type::Unknown,
|
||||||
|
}])),
|
||||||
|
Some(ParseError::UnknownState(e.into(), span(spans))),
|
||||||
|
), //(ShellError::InternalError("Can't load file to source".to_string())),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
expr: Expr::Garbage,
|
||||||
|
span: span(spans),
|
||||||
|
ty: Type::Unknown,
|
||||||
|
}])),
|
||||||
|
Some(ParseError::Mismatch(
|
||||||
|
"string".into(),
|
||||||
|
// Can this be better?
|
||||||
|
"incompatible string".into(),
|
||||||
|
spans[1],
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not source command?
|
||||||
|
(
|
||||||
|
Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
expr: Expr::Garbage,
|
||||||
|
span: span(spans),
|
||||||
|
ty: Type::Unknown,
|
||||||
|
}])),
|
||||||
|
error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// (
|
||||||
|
// Statement::Pipeline(Pipeline::from_vec(vec![Expression {
|
||||||
|
// expr: Expr::Garbage,
|
||||||
|
// span: span(spans),
|
||||||
|
// ty: Type::Unknown,
|
||||||
|
// }])),
|
||||||
|
// Some(ParseError::UnknownState(
|
||||||
|
// "internal error: let statement unparseable".into(),
|
||||||
|
// span(spans),
|
||||||
|
// )),
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a statement. Check if def, let, alias, or source command can process it properly
|
||||||
pub fn parse_statement(
|
pub fn parse_statement(
|
||||||
working_set: &mut StateWorkingSet,
|
working_set: &mut StateWorkingSet,
|
||||||
spans: &[Span],
|
spans: &[Span],
|
||||||
|
@ -2491,6 +2595,8 @@ pub fn parse_statement(
|
||||||
(stmt, None)
|
(stmt, None)
|
||||||
} else if let (stmt, None) = parse_alias(working_set, spans) {
|
} else if let (stmt, None) = parse_alias(working_set, spans) {
|
||||||
(stmt, None)
|
(stmt, None)
|
||||||
|
} else if let (decl, None) = parse_source(working_set, spans) {
|
||||||
|
(decl, None)
|
||||||
} else {
|
} else {
|
||||||
let (expr, err) = parse_expression(working_set, spans);
|
let (expr, err) = parse_expression(working_set, spans);
|
||||||
(Statement::Pipeline(Pipeline::from_vec(vec![expr])), err)
|
(Statement::Pipeline(Pipeline::from_vec(vec![expr])), err)
|
||||||
|
|
|
@ -179,6 +179,7 @@ impl Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Follow a given column path into the value: for example accessing nth elements in a stream or list
|
||||||
pub fn follow_cell_path(self, column_path: &[PathMember]) -> Result<Value, ShellError> {
|
pub fn follow_cell_path(self, column_path: &[PathMember]) -> Result<Value, ShellError> {
|
||||||
let mut current = self;
|
let mut current = self;
|
||||||
for member in column_path {
|
for member in column_path {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::{ast::RangeInclusion, *};
|
use crate::{ast::RangeInclusion, *};
|
||||||
|
|
||||||
|
/// A Range is an iterator over integers.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Range {
|
pub struct Range {
|
||||||
pub from: Value,
|
pub from: Value,
|
||||||
|
|
1
example.nu
Normal file
1
example.nu
Normal file
|
@ -0,0 +1 @@
|
||||||
|
length [1,2,3,4]
|
Loading…
Reference in New Issue
Block a user