Back to working state

This commit is contained in:
JT 2021-09-03 06:21:37 +12:00
parent e1be8f61fc
commit 94687a7603
28 changed files with 170 additions and 116 deletions

View File

@ -1,6 +1,9 @@
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
use nu_protocol::{EngineState, Signature, StateWorkingSet, SyntaxShape}; use nu_protocol::{
engine::{EngineState, StateWorkingSet},
Signature, SyntaxShape,
};
pub fn create_default_context() -> Rc<RefCell<EngineState>> { pub fn create_default_context() -> Rc<RefCell<EngineState>> {
let engine_state = Rc::new(RefCell::new(EngineState::new())); let engine_state = Rc::new(RefCell::new(EngineState::new()));
@ -10,7 +13,7 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
let sig = let sig =
Signature::build("where").required("cond", SyntaxShape::RowCondition, "condition"); Signature::build("where").required("cond", SyntaxShape::RowCondition, "condition");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("if") let sig = Signature::build("if")
.required("cond", SyntaxShape::Expression, "condition") .required("cond", SyntaxShape::Expression, "condition")
@ -20,7 +23,7 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
SyntaxShape::Keyword(b"else".to_vec(), Box::new(SyntaxShape::Expression)), SyntaxShape::Keyword(b"else".to_vec(), Box::new(SyntaxShape::Expression)),
"optional else followed by else block", "optional else followed by else block",
); );
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("let") let sig = Signature::build("let")
.required("var_name", SyntaxShape::VarWithOptType, "variable name") .required("var_name", SyntaxShape::VarWithOptType, "variable name")
@ -29,7 +32,7 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::Expression)), SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::Expression)),
"equals sign followed by value", "equals sign followed by value",
); );
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("let-env") let sig = Signature::build("let-env")
.required("var_name", SyntaxShape::String, "variable name") .required("var_name", SyntaxShape::String, "variable name")
@ -38,7 +41,7 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::String)), SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::String)),
"equals sign followed by value", "equals sign followed by value",
); );
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("alias") let sig = Signature::build("alias")
.required("name", SyntaxShape::String, "name of the alias") .required("name", SyntaxShape::String, "name of the alias")
@ -47,16 +50,16 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::Expression)), SyntaxShape::Keyword(b"=".to_vec(), Box::new(SyntaxShape::Expression)),
"equals sign followed by value", "equals sign followed by value",
); );
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("build-string").rest(SyntaxShape::String, "list of string"); let sig = Signature::build("build-string").rest(SyntaxShape::String, "list of string");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("def") let sig = Signature::build("def")
.required("def_name", SyntaxShape::String, "definition name") .required("def_name", SyntaxShape::String, "definition name")
.required("params", SyntaxShape::Signature, "parameters") .required("params", SyntaxShape::Signature, "parameters")
.required("block", SyntaxShape::Block, "body of the definition"); .required("block", SyntaxShape::Block, "body of the definition");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("for") let sig = Signature::build("for")
.required( .required(
@ -70,11 +73,11 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
"range of the loop", "range of the loop",
) )
.required("block", SyntaxShape::Block, "the block to run"); .required("block", SyntaxShape::Block, "the block to run");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = let sig =
Signature::build("benchmark").required("block", SyntaxShape::Block, "the block to run"); Signature::build("benchmark").required("block", SyntaxShape::Block, "the block to run");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
// let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); // let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
// working_set.add_decl(sig.into()); // working_set.add_decl(sig.into());
@ -84,25 +87,25 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
// .switch("--rock", "rock!!", Some('r')); // .switch("--rock", "rock!!", Some('r'));
// working_set.add_decl(sig.into()); // working_set.add_decl(sig.into());
let sig = Signature::build("exit"); let sig = Signature::build("exit");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("vars"); let sig = Signature::build("vars");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("decls"); let sig = Signature::build("decls");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("blocks"); let sig = Signature::build("blocks");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("stack"); let sig = Signature::build("stack");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("add"); let sig = Signature::build("add");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("add it"); let sig = Signature::build("add it");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let sig = Signature::build("add it together") let sig = Signature::build("add it together")
.required("x", SyntaxShape::Int, "x value") .required("x", SyntaxShape::Int, "x value")
.required("y", SyntaxShape::Int, "y value"); .required("y", SyntaxShape::Int, "y value");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
working_set.render() working_set.render()
}; };

View File

@ -3,7 +3,7 @@ use core::ops::Range;
use codespan_reporting::diagnostic::{Diagnostic, Label}; use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
use nu_parser::ParseError; use nu_parser::ParseError;
use nu_protocol::{ShellError, Span, StateWorkingSet}; use nu_protocol::{engine::StateWorkingSet, ShellError, Span};
fn convert_span_to_diag( fn convert_span_to_diag(
working_set: &StateWorkingSet, working_set: &StateWorkingSet,

View File

@ -1,6 +1,6 @@
use nu_ansi_term::Style; use nu_ansi_term::Style;
use nu_parser::FlatShape; use nu_parser::{flatten_block, parse_source, FlatShape};
use nu_protocol::{EngineState, StateWorkingSet}; use nu_protocol::engine::{EngineState, StateWorkingSet};
use reedline::{Highlighter, StyledText}; use reedline::{Highlighter, StyledText};
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
@ -13,9 +13,9 @@ impl Highlighter for NuHighlighter {
let (shapes, global_span_offset) = { let (shapes, global_span_offset) = {
let engine_state = self.engine_state.borrow(); let engine_state = self.engine_state.borrow();
let mut working_set = StateWorkingSet::new(&*engine_state); let mut working_set = StateWorkingSet::new(&*engine_state);
let (block, _) = working_set.parse_source(line.as_bytes(), false); let (block, _) = parse_source(&mut working_set, line.as_bytes(), false);
let shapes = working_set.flatten_block(&block); let shapes = flatten_block(&working_set, &block);
(shapes, engine_state.next_span_start()) (shapes, engine_state.next_span_start())
}; };

View File

@ -1,7 +1,7 @@
use std::time::Instant; use std::time::Instant;
use crate::state::State; use nu_protocol::ast::{Block, Call, Expr, Expression, Operator, Statement};
use nu_protocol::{Block, Call, Expr, Expression, Operator, Statement}; use nu_protocol::engine::EvaluationContext;
use nu_protocol::{IntoRowStream, IntoValueStream, ShellError, Span, Value}; use nu_protocol::{IntoRowStream, IntoValueStream, ShellError, Span, Value};
pub fn eval_operator(op: &Expression) -> Result<Operator, ShellError> { pub fn eval_operator(op: &Expression) -> Result<Operator, ShellError> {
@ -14,16 +14,16 @@ pub fn eval_operator(op: &Expression) -> Result<Operator, ShellError> {
} }
} }
fn eval_call(state: &State, call: &Call) -> Result<Value, ShellError> { fn eval_call(state: &EvaluationContext, call: &Call) -> Result<Value, ShellError> {
let engine_state = state.engine_state.borrow(); let engine_state = state.engine_state.borrow();
let decl = engine_state.get_decl(call.decl_id); let decl = engine_state.get_decl(call.decl_id);
if let Some(block_id) = decl.body { if let Some(block_id) = decl.get_custom_command() {
let state = state.enter_scope(); let state = state.enter_scope();
for (arg, param) in call.positional.iter().zip( for (arg, param) in call.positional.iter().zip(
decl.signature decl.signature()
.required_positional .required_positional
.iter() .iter()
.chain(decl.signature.optional_positional.iter()), .chain(decl.signature().optional_positional.iter()),
) { ) {
let result = eval_expression(&state, arg)?; let result = eval_expression(&state, arg)?;
let var_id = param let var_id = param
@ -35,7 +35,7 @@ fn eval_call(state: &State, call: &Call) -> Result<Value, ShellError> {
let engine_state = state.engine_state.borrow(); let engine_state = state.engine_state.borrow();
let block = engine_state.get_block(block_id); let block = engine_state.get_block(block_id);
eval_block(&state, block) eval_block(&state, block)
} else if decl.signature.name == "let" { } else if decl.signature().name == "let" {
let var_id = call.positional[0] let var_id = call.positional[0]
.as_var() .as_var()
.expect("internal error: missing variable"); .expect("internal error: missing variable");
@ -52,7 +52,7 @@ fn eval_call(state: &State, call: &Call) -> Result<Value, ShellError> {
Ok(Value::Nothing { Ok(Value::Nothing {
span: call.positional[0].span, span: call.positional[0].span,
}) })
} else if decl.signature.name == "let-env" { } else if decl.signature().name == "let-env" {
let env_var = call.positional[0] let env_var = call.positional[0]
.as_string() .as_string()
.expect("internal error: missing variable"); .expect("internal error: missing variable");
@ -70,7 +70,7 @@ fn eval_call(state: &State, call: &Call) -> Result<Value, ShellError> {
Ok(Value::Nothing { Ok(Value::Nothing {
span: call.positional[0].span, span: call.positional[0].span,
}) })
} else if decl.signature.name == "if" { } else if decl.signature().name == "if" {
let cond = &call.positional[0]; let cond = &call.positional[0];
let then_block = call.positional[1] let then_block = call.positional[1]
.as_block() .as_block()
@ -103,7 +103,7 @@ fn eval_call(state: &State, call: &Call) -> Result<Value, ShellError> {
} }
_ => Err(ShellError::CantConvert("bool".into(), result.span())), _ => Err(ShellError::CantConvert("bool".into(), result.span())),
} }
} else if decl.signature.name == "build-string" { } else if decl.signature().name == "build-string" {
let mut output = vec![]; let mut output = vec![];
for expr in &call.positional { for expr in &call.positional {
@ -115,7 +115,7 @@ fn eval_call(state: &State, call: &Call) -> Result<Value, ShellError> {
val: output.join(""), val: output.join(""),
span: call.head, span: call.head,
}) })
} else if decl.signature.name == "benchmark" { } else if decl.signature().name == "benchmark" {
let block = call.positional[0] let block = call.positional[0]
.as_block() .as_block()
.expect("internal error: expected block"); .expect("internal error: expected block");
@ -130,7 +130,7 @@ fn eval_call(state: &State, call: &Call) -> Result<Value, ShellError> {
Ok(Value::Nothing { Ok(Value::Nothing {
span: call.positional[0].span, span: call.positional[0].span,
}) })
} else if decl.signature.name == "for" { } else if decl.signature().name == "for" {
let var_id = call.positional[0] let var_id = call.positional[0]
.as_var() .as_var()
.expect("internal error: missing variable"); .expect("internal error: missing variable");
@ -167,26 +167,26 @@ fn eval_call(state: &State, call: &Call) -> Result<Value, ShellError> {
Ok(Value::Nothing { Ok(Value::Nothing {
span: call.positional[0].span, span: call.positional[0].span,
}) })
} else if decl.signature.name == "vars" { } else if decl.signature().name == "vars" {
state.engine_state.borrow().print_vars(); state.engine_state.borrow().print_vars();
Ok(Value::Nothing { span: call.head }) Ok(Value::Nothing { span: call.head })
} else if decl.signature.name == "decls" { } else if decl.signature().name == "decls" {
state.engine_state.borrow().print_decls(); state.engine_state.borrow().print_decls();
Ok(Value::Nothing { span: call.head }) Ok(Value::Nothing { span: call.head })
} else if decl.signature.name == "blocks" { } else if decl.signature().name == "blocks" {
state.engine_state.borrow().print_blocks(); state.engine_state.borrow().print_blocks();
Ok(Value::Nothing { span: call.head }) Ok(Value::Nothing { span: call.head })
} else if decl.signature.name == "stack" { } else if decl.signature().name == "stack" {
state.print_stack(); state.print_stack();
Ok(Value::Nothing { span: call.head }) Ok(Value::Nothing { span: call.head })
} else if decl.signature.name == "def" || decl.signature.name == "alias" { } else if decl.signature().name == "def" || decl.signature().name == "alias" {
Ok(Value::Nothing { span: call.head }) Ok(Value::Nothing { span: call.head })
} else { } else {
Err(ShellError::Unsupported(call.head)) Err(ShellError::Unsupported(call.head))
} }
} }
pub fn eval_expression(state: &State, expr: &Expression) -> Result<Value, ShellError> { pub fn eval_expression(state: &EvaluationContext, expr: &Expression) -> Result<Value, ShellError> {
match &expr.expr { match &expr.expr {
Expr::Bool(b) => Ok(Value::Bool { Expr::Bool(b) => Ok(Value::Bool {
val: *b, val: *b,
@ -278,7 +278,7 @@ pub fn eval_expression(state: &State, expr: &Expression) -> Result<Value, ShellE
} }
} }
pub fn eval_block(state: &State, block: &Block) -> Result<Value, ShellError> { pub fn eval_block(state: &EvaluationContext, block: &Block) -> Result<Value, ShellError> {
let mut last = Ok(Value::Nothing { let mut last = Ok(Value::Nothing {
span: Span { start: 0, end: 0 }, span: Span { start: 0, end: 0 },
}); });

View File

@ -1,9 +1,3 @@
mod command;
mod eval; mod eval;
mod example;
mod state;
pub use command::Command;
pub use eval::{eval_block, eval_expression, eval_operator}; pub use eval::{eval_block, eval_expression, eval_operator};
pub use example::Example;
pub use state::{Stack, State};

View File

@ -1,4 +1,4 @@
use nu_protocol::{Span, StateWorkingSet, Type}; use nu_protocol::{engine::StateWorkingSet, Span, Type};
use std::ops::Range; use std::ops::Range;
#[derive(Debug)] #[derive(Debug)]

View File

@ -1,5 +1,5 @@
use nu_protocol::Span; use nu_protocol::ast::{Block, Expr, Expression, Pipeline, Statement};
use nu_protocol::{Block, Expr, Expression, Pipeline, StateWorkingSet, Statement}; use nu_protocol::{engine::StateWorkingSet, Span};
#[derive(Debug)] #[derive(Debug)]
pub enum FlatShape { pub enum FlatShape {

View File

@ -6,7 +6,7 @@ mod parser;
mod type_check; mod type_check;
pub use errors::ParseError; pub use errors::ParseError;
pub use flatten::FlatShape; pub use flatten::{flatten_block, FlatShape};
pub use lex::{lex, Token, TokenContents}; pub use lex::{lex, Token, TokenContents};
pub use lite_parse::{lite_parse, LiteBlock}; pub use lite_parse::{lite_parse, LiteBlock};
pub use parser::{Import, VarDecl}; pub use parser::{parse_file, parse_source, Import, VarDecl};

View File

@ -5,8 +5,9 @@ use crate::{
}; };
use nu_protocol::{ use nu_protocol::{
span, Block, BlockId, Call, DeclId, Expr, Expression, Flag, Operator, Pipeline, PositionalArg, ast::{Block, Call, Expr, Expression, Operator, Pipeline, Statement},
Signature, Span, StateWorkingSet, Statement, SyntaxShape, Type, VarId, engine::StateWorkingSet,
span, BlockId, DeclId, Flag, PositionalArg, Signature, Span, SyntaxShape, Type, VarId,
}; };
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

View File

@ -1,5 +1,9 @@
use crate::ParseError; use crate::ParseError;
use nu_protocol::{Expr, Expression, Operator, StateWorkingSet, Type}; use nu_protocol::{
ast::{Expr, Expression, Operator},
engine::StateWorkingSet,
Type,
};
pub fn type_compatible(lhs: &Type, rhs: &Type) -> bool { pub fn type_compatible(lhs: &Type, rhs: &Type) -> bool {
match (lhs, rhs) { match (lhs, rhs) {

View File

@ -1,13 +1,17 @@
use nu_parser::ParseError; use nu_parser::ParseError;
use nu_parser::*; use nu_parser::*;
use nu_protocol::{EngineState, Signature, SyntaxShape}; use nu_protocol::{
ast::{Expr, Expression, Statement},
engine::{EngineState, StateWorkingSet},
Signature, SyntaxShape,
};
#[test] #[test]
pub fn parse_int() { pub fn parse_int() {
let engine_state = EngineState::new(); let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let (block, err) = working_set.parse_source(b"3", true); let (block, err) = parse_source(&mut working_set, b"3", true);
assert!(err.is_none()); assert!(err.is_none());
assert!(block.len() == 1); assert!(block.len() == 1);
@ -26,9 +30,9 @@ pub fn parse_call() {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let (block, err) = working_set.parse_source(b"foo", true); let (block, err) = parse_source(&mut working_set, b"foo", true);
assert!(err.is_none()); assert!(err.is_none());
assert!(block.len() == 1); assert!(block.len() == 1);
@ -50,9 +54,9 @@ pub fn parse_call_missing_flag_arg() {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let (_, err) = working_set.parse_source(b"foo --jazz", true); let (_, err) = parse_source(&mut working_set, b"foo --jazz", true);
assert!(matches!(err, Some(ParseError::MissingFlagParam(..)))); assert!(matches!(err, Some(ParseError::MissingFlagParam(..))));
} }
@ -62,9 +66,9 @@ pub fn parse_call_missing_short_flag_arg() {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'));
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let (_, err) = working_set.parse_source(b"foo -j", true); let (_, err) = parse_source(&mut working_set, b"foo -j", true);
assert!(matches!(err, Some(ParseError::MissingFlagParam(..)))); assert!(matches!(err, Some(ParseError::MissingFlagParam(..))));
} }
@ -76,8 +80,8 @@ pub fn parse_call_too_many_shortflag_args() {
let sig = Signature::build("foo") let sig = Signature::build("foo")
.named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')) .named("--jazz", SyntaxShape::Int, "jazz!!", Some('j'))
.named("--math", SyntaxShape::Int, "math!!", Some('m')); .named("--math", SyntaxShape::Int, "math!!", Some('m'));
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let (_, err) = working_set.parse_source(b"foo -mj", true); let (_, err) = parse_source(&mut working_set, b"foo -mj", true);
assert!(matches!( assert!(matches!(
err, err,
Some(ParseError::ShortFlagBatchCantTakeArg(..)) Some(ParseError::ShortFlagBatchCantTakeArg(..))
@ -90,8 +94,8 @@ pub fn parse_call_unknown_shorthand() {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j')); let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let (_, err) = working_set.parse_source(b"foo -mj", true); let (_, err) = parse_source(&mut working_set, b"foo -mj", true);
assert!(matches!(err, Some(ParseError::UnknownFlag(..)))); assert!(matches!(err, Some(ParseError::UnknownFlag(..))));
} }
@ -101,8 +105,8 @@ pub fn parse_call_extra_positional() {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j')); let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j'));
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let (_, err) = working_set.parse_source(b"foo -j 100", true); let (_, err) = parse_source(&mut working_set, b"foo -j 100", true);
assert!(matches!(err, Some(ParseError::ExtraPositional(..)))); assert!(matches!(err, Some(ParseError::ExtraPositional(..))));
} }
@ -112,8 +116,8 @@ pub fn parse_call_missing_req_positional() {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let sig = Signature::build("foo").required("jazz", SyntaxShape::Int, "jazz!!"); let sig = Signature::build("foo").required("jazz", SyntaxShape::Int, "jazz!!");
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let (_, err) = working_set.parse_source(b"foo", true); let (_, err) = parse_source(&mut working_set, b"foo", true);
assert!(matches!(err, Some(ParseError::MissingPositional(..)))); assert!(matches!(err, Some(ParseError::MissingPositional(..))));
} }
@ -123,7 +127,7 @@ pub fn parse_call_missing_req_flag() {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let sig = Signature::build("foo").required_named("--jazz", SyntaxShape::Int, "jazz!!", None); let sig = Signature::build("foo").required_named("--jazz", SyntaxShape::Int, "jazz!!", None);
working_set.add_decl(sig.into()); working_set.add_decl(sig.predeclare());
let (_, err) = working_set.parse_source(b"foo", true); let (_, err) = parse_source(&mut working_set, b"foo", true);
assert!(matches!(err, Some(ParseError::MissingRequiredFlag(..)))); assert!(matches!(err, Some(ParseError::MissingRequiredFlag(..))));
} }

View File

@ -1,6 +1,6 @@
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
use crate::Statement; use super::Statement;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Block { pub struct Block {

View File

@ -1,4 +1,5 @@
use crate::{DeclId, Expression, Span}; use super::Expression;
use crate::{DeclId, Span};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Call { pub struct Call {

View File

@ -1,4 +1,5 @@
use crate::{BlockId, Call, Expression, Operator, Signature, Span, VarId}; use super::{Call, Expression, Operator};
use crate::{BlockId, Signature, Span, VarId};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Expr { pub enum Expr {

View File

@ -1,4 +1,5 @@
use crate::{BlockId, Expr, Operator, Signature, Span, Type, VarId}; use super::{Expr, Operator};
use crate::{BlockId, Signature, Span, Type, VarId};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Expression { pub struct Expression {

View File

@ -0,0 +1,15 @@
mod block;
mod call;
mod expr;
mod expression;
mod operator;
mod pipeline;
mod statement;
pub use block::*;
pub use call::*;
pub use expr::*;
pub use expression::*;
pub use operator::*;
pub use pipeline::*;
pub use statement::*;

View File

@ -1,4 +1,4 @@
use crate::Expression; use crate::ast::Expression;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Pipeline { pub struct Pipeline {

View File

@ -1,4 +1,5 @@
use crate::{DeclId, Expression, Pipeline}; use super::{Expression, Pipeline};
use crate::DeclId;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Statement { pub enum Statement {

View File

@ -0,0 +1,8 @@
use crate::ast::Call;
use crate::Span;
#[derive(Debug, Clone)]
pub struct UnevaluatedCallInfo {
pub args: Call,
pub name_span: Span,
}

View File

@ -1,4 +1,6 @@
use crate::{Example, Signature}; use crate::{BlockId, Example, ShellError, Signature, Value};
use super::CommandArgs;
pub trait Command { pub trait Command {
fn name(&self) -> &str; fn name(&self) -> &str;
@ -13,6 +15,8 @@ pub trait Command {
"" ""
} }
fn run(&self, args: CommandArgs) -> Result<Value, ShellError>;
// fn run(&self, args: CommandArgs) -> Result<InputStream, ShellError> { // fn run(&self, args: CommandArgs) -> Result<InputStream, ShellError> {
// let context = args.context.clone(); // let context = args.context.clone();
// let stream = self.run_with_actions(args)?; // let stream = self.run_with_actions(args)?;
@ -53,8 +57,8 @@ pub trait Command {
false false
} }
// Is a custom command i.e. def blah [] { } // If command is a custom command i.e. def blah [] { }, get the block id
fn is_custom(&self) -> bool { fn get_custom_command(&self) -> Option<BlockId> {
false None
} }
} }

View File

@ -0,0 +1,7 @@
use super::{EvaluationContext, UnevaluatedCallInfo};
pub struct CommandArgs {
pub context: EvaluationContext,
pub call_info: UnevaluatedCallInfo,
pub input: crate::Value,
}

View File

@ -1,4 +1,5 @@
use crate::{Block, BlockId, Command, DeclId, Span, Type, VarId}; use super::Command;
use crate::{ast::Block, BlockId, DeclId, Span, Type, VarId};
use core::panic; use core::panic;
use std::{collections::HashMap, ops::Range, slice::Iter}; use std::{collections::HashMap, ops::Range, slice::Iter};

View File

@ -1,19 +1,19 @@
use nu_protocol::EngineState; use super::EngineState;
use std::{cell::RefCell, collections::HashMap, rc::Rc}; use std::{cell::RefCell, collections::HashMap, rc::Rc};
use nu_protocol::{ShellError, Value, VarId}; use crate::{ShellError, Value, VarId};
pub struct State { pub struct EvaluationContext {
pub engine_state: Rc<RefCell<EngineState>>, pub engine_state: Rc<RefCell<EngineState>>,
pub stack: Stack, pub stack: Stack,
} }
impl State { impl EvaluationContext {
pub fn get_var(&self, var_id: VarId) -> Result<Value, ShellError> { pub fn get_var(&self, var_id: VarId) -> Result<Value, ShellError> {
self.stack.get_var(var_id) self.stack.get_var(var_id)
} }
pub fn enter_scope(&self) -> State { pub fn enter_scope(&self) -> EvaluationContext {
Self { Self {
engine_state: self.engine_state.clone(), engine_state: self.engine_state.clone(),
stack: self.stack.clone().enter_scope(), stack: self.stack.clone().enter_scope(),

View File

@ -0,0 +1,11 @@
mod call_info;
mod command;
mod command_args;
mod engine_state;
mod evaluation_context;
pub use call_info::*;
pub use command::*;
pub use command_args::*;
pub use engine_state::*;
pub use evaluation_context::*;

View File

@ -1,35 +1,19 @@
mod block; pub mod ast;
mod call; pub mod engine;
mod command;
mod engine_state;
mod example; mod example;
mod expr;
mod expression;
mod id; mod id;
mod operator;
mod pipeline;
mod shell_error; mod shell_error;
mod signature; mod signature;
mod span; mod span;
mod statement;
mod syntax_shape; mod syntax_shape;
mod ty; mod ty;
mod value; mod value;
pub use block::*;
pub use call::*;
pub use command::*;
pub use engine_state::*;
pub use example::*; pub use example::*;
pub use expr::*;
pub use expression::*;
pub use id::*; pub use id::*;
pub use operator::*;
pub use pipeline::*;
pub use shell_error::*; pub use shell_error::*;
pub use signature::*; pub use signature::*;
pub use span::*; pub use span::*;
pub use statement::*;
pub use syntax_shape::*; pub use syntax_shape::*;
pub use ty::*; pub use ty::*;
pub use value::*; pub use value::*;

View File

@ -1,5 +1,5 @@
use crate::engine::Command;
use crate::BlockId; use crate::BlockId;
use crate::Command;
use crate::SyntaxShape; use crate::SyntaxShape;
use crate::VarId; use crate::VarId;
@ -314,6 +314,10 @@ impl Command for Predeclaration {
fn usage(&self) -> &str { fn usage(&self) -> &str {
&self.signature.usage &self.signature.usage
} }
fn run(&self, _args: crate::engine::CommandArgs) -> Result<crate::Value, crate::ShellError> {
panic!("Internal error: can't run a predeclaration without a body")
}
} }
struct BlockCommand { struct BlockCommand {
@ -333,4 +337,12 @@ impl Command for BlockCommand {
fn usage(&self) -> &str { fn usage(&self) -> &str {
&self.signature.usage &self.signature.usage
} }
fn run(&self, _args: crate::engine::CommandArgs) -> Result<crate::Value, crate::ShellError> {
panic!("Internal error: can't run custom command with 'run', use block_id");
}
fn get_custom_command(&self) -> Option<BlockId> {
Some(self.block_id)
}
} }

View File

@ -1,6 +1,7 @@
use nu_cli::{create_default_context, report_parsing_error, report_shell_error, NuHighlighter}; use nu_cli::{create_default_context, report_parsing_error, report_shell_error, NuHighlighter};
use nu_engine::eval_block; use nu_engine::eval_block;
use nu_protocol::{EngineState, StateWorkingSet}; use nu_parser::parse_file;
use nu_protocol::engine::{EngineState, EvaluationContext, StateWorkingSet};
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
@ -14,7 +15,7 @@ fn main() -> std::io::Result<()> {
let (block, delta) = { let (block, delta) = {
let engine_state = engine_state.borrow(); let engine_state = engine_state.borrow();
let mut working_set = StateWorkingSet::new(&*engine_state); let mut working_set = StateWorkingSet::new(&*engine_state);
let (output, err) = working_set.parse_file(&path, &file, false); let (output, err) = parse_file(&mut working_set, &path, &file, false);
if let Some(err) = err { if let Some(err) = err {
let _ = report_parsing_error(&working_set, &err); let _ = report_parsing_error(&working_set, &err);
@ -25,9 +26,9 @@ fn main() -> std::io::Result<()> {
EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta); EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta);
let state = nu_engine::State { let state = EvaluationContext {
engine_state: engine_state.clone(), engine_state: engine_state.clone(),
stack: nu_engine::Stack::new(), stack: nu_protocol::engine::Stack::new(),
}; };
match eval_block(&state, &block) { match eval_block(&state, &block) {
@ -59,7 +60,7 @@ fn main() -> std::io::Result<()> {
let prompt = DefaultPrompt::new(1); let prompt = DefaultPrompt::new(1);
let mut current_line = 1; let mut current_line = 1;
let stack = nu_engine::Stack::new(); let stack = nu_protocol::engine::Stack::new();
loop { loop {
let input = line_editor.read_line(&prompt); let input = line_editor.read_line(&prompt);
@ -73,7 +74,8 @@ fn main() -> std::io::Result<()> {
let (block, delta) = { let (block, delta) = {
let engine_state = engine_state.borrow(); let engine_state = engine_state.borrow();
let mut working_set = StateWorkingSet::new(&*engine_state); let mut working_set = StateWorkingSet::new(&*engine_state);
let (output, err) = working_set.parse_file( let (output, err) = parse_file(
&mut working_set,
&format!("line_{}", current_line), &format!("line_{}", current_line),
s.as_bytes(), s.as_bytes(),
false, false,
@ -87,7 +89,7 @@ fn main() -> std::io::Result<()> {
EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta); EngineState::merge_delta(&mut *engine_state.borrow_mut(), delta);
let state = nu_engine::State { let state = nu_protocol::engine::EvaluationContext {
engine_state: engine_state.clone(), engine_state: engine_state.clone(),
stack: stack.clone(), stack: stack.clone(),
}; };