From 1d945d8ce3681d93021a1e1fdb898647729db69d Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Sat, 11 Sep 2021 00:54:24 -0400 Subject: [PATCH 01/13] added source command --- crates/nu-command/Cargo.toml | 3 +- crates/nu-command/src/default_context.rs | 4 +- crates/nu-command/src/lib.rs | 2 + crates/nu-command/src/source.rs | 117 +++++++++++++++++++++++ 4 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 crates/nu-command/src/source.rs diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index 6cc6ae2f63..1d64aca4d4 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -7,4 +7,5 @@ edition = "2018" [dependencies] nu-protocol = { path = "../nu-protocol" } -nu-engine = { path = "../nu-engine" } \ No newline at end of file +nu-engine = { path = "../nu-engine" } +nu-parser = {path = "../nu-parser"} \ No newline at end of file diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index fbaaaf537b..a9278dcc08 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -5,7 +5,7 @@ use nu_protocol::{ Signature, SyntaxShape, }; -use crate::{Alias, Benchmark, BuildString, Def, Do, Each, For, If, Length, Let, LetEnv}; +use crate::{Alias, Benchmark, BuildString, Def, Do, Each, For, If, Length, Let, LetEnv, Source}; pub fn create_default_context() -> Rc> { let engine_state = Rc::new(RefCell::new(EngineState::new())); @@ -39,6 +39,8 @@ pub fn create_default_context() -> Rc> { working_set.add_decl(Box::new(Length)); + working_set.add_decl(Box::new(Source)); + let sig = Signature::build("exit"); working_set.add_decl(sig.predeclare()); let sig = Signature::build("vars"); diff --git a/crates/nu-command/src/lib.rs b/crates/nu-command/src/lib.rs index 3e7d99e7d7..dad3122926 100644 --- a/crates/nu-command/src/lib.rs +++ b/crates/nu-command/src/lib.rs @@ -10,6 +10,7 @@ mod if_; mod length; mod let_; mod let_env; +mod source; pub use alias::Alias; pub use benchmark::Benchmark; @@ -23,3 +24,4 @@ pub use if_::If; pub use length::Length; pub use let_::Let; pub use let_env::LetEnv; +pub use source::Source; diff --git a/crates/nu-command/src/source.rs b/crates/nu-command/src/source.rs new file mode 100644 index 0000000000..b50c7bfca9 --- /dev/null +++ b/crates/nu-command/src/source.rs @@ -0,0 +1,117 @@ +use nu_engine::{eval_block, eval_expression}; +use nu_parser::parse; +use nu_protocol::ast::{Block, Call}; +use nu_protocol::engine::{Command, EngineState, EvaluationContext, StateWorkingSet}; +use nu_protocol::{ShellError, Signature, SyntaxShape, Value}; +use std::task::Context; +use std::{borrow::Cow, path::Path, path::PathBuf}; + +/// Source a file for environment variables. +pub struct Source; + +impl Command for Source { + fn name(&self) -> &str { + "source" + } + + fn signature(&self) -> Signature { + Signature::build("source").required( + "filename", + SyntaxShape::FilePath, + "the filepath to the script file to source", + ) + } + + fn usage(&self) -> &str { + "Runs a script file in the current context." + } + + fn run( + &self, + _context: &EvaluationContext, + call: &Call, + input: Value, + ) -> Result { + source(_context, call, input) + } +} + +pub fn source(ctx: &EvaluationContext, call: &Call, input: Value) -> Result { + let filename = call.positional[0] + .as_string() + .expect("internal error: missing file name"); + + let source_file = Path::new(&filename); + + // This code is in the current Nushell version + // ...Not entirely sure what it's doing or if there's an equivalent in engine-q + + // Note: this is a special case for setting the context from a command + // In this case, if we don't set it now, we'll lose the scope that this + // variable should be set into. + + // let lib_dirs = &ctx + // .configs() + // .lock() + // .global_config + // .as_ref() + // .map(|configuration| match configuration.var("lib_dirs") { + // Some(paths) => paths + // .table_entries() + // .cloned() + // .map(|path| path.as_string()) + // .collect(), + // None => vec![], + // }); + + // if let Some(dir) = lib_dirs { + // for lib_path in dir { + // match lib_path { + // Ok(name) => { + // let path = PathBuf::from(name).join(source_file); + + // if let Ok(contents) = + // std::fs::read_to_string(&expand_path(Cow::Borrowed(path.as_path()))) + // { + // let result = script::run_script_standalone(contents, true, ctx, false); + + // if let Err(err) = result { + // ctx.error(err); + // } + // return Ok(OutputStream::empty()); + // } + // } + // Err(reason) => { + // ctx.error(reason.clone()); + // } + // } + // } + // } + + // 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 engine_state = EngineState::new(); + let mut working_set = StateWorkingSet::new(&engine_state); + + let (block, err) = parse(&mut working_set, None, &contents, true); + if let Some(e) = err { + // Be more specific here: need to convert parse error to string + Err(ShellError::InternalError("Parse error in file".to_string())) + } else { + let result = eval_block(ctx, &block, input); + match result { + Err(e) => Err(e), + _ => Ok(Value::nothing()), + } + } + } + Err(_) => Err(ShellError::InternalError( + "Can't load file to source".to_string(), + )), + } +} From 719920fa37ee9bd9210f5a46eeaf32a2292c706c Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Mon, 27 Sep 2021 08:10:18 -0400 Subject: [PATCH 02/13] tried to move source command into parser (still doesn't compile) --- Cargo.lock | 1 + crates/nu-command/src/source.rs | 2 +- crates/nu-engine/src/eval.rs | 15 +++- crates/nu-parser/src/parser.rs | 108 +++++++++++++++++++++++++- crates/nu-protocol/src/value/mod.rs | 1 + crates/nu-protocol/src/value/range.rs | 1 + example.nu | 1 + 7 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 example.nu diff --git a/Cargo.lock b/Cargo.lock index 8948993d4c..acfbf68bc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -277,6 +277,7 @@ name = "nu-command" version = "0.1.0" dependencies = [ "nu-engine", + "nu-parser", "nu-protocol", ] diff --git a/crates/nu-command/src/source.rs b/crates/nu-command/src/source.rs index b50c7bfca9..1997bbea82 100644 --- a/crates/nu-command/src/source.rs +++ b/crates/nu-command/src/source.rs @@ -101,7 +101,7 @@ pub fn source(ctx: &EvaluationContext, call: &Call, input: Value) -> Result Result { @@ -239,3 +240,15 @@ pub fn eval_block( Ok(input) } + +// pub fn eval(context: &EvaluationContext, script: &str) -> Result { +// 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()) +// } +// } diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 86271281be..cab66c3e8d 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -1,3 +1,5 @@ +use std::path::Path; + use crate::{ lex, lite_parse, type_check::{math_result_type, type_compatible}, @@ -10,7 +12,7 @@ use nu_protocol::{ RangeInclusion, RangeOperator, Statement, }, engine::StateWorkingSet, - span, Flag, PositionalArg, Signature, Span, SyntaxShape, Type, VarId, + span, Flag, PositionalArg, ShellError, Signature, Span, SyntaxShape, Type, VarId, }; #[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( working_set: &mut StateWorkingSet, spans: &[Span], @@ -2381,6 +2384,7 @@ pub fn parse_def( } } +/// Parser for the alias command pub fn parse_alias( working_set: &mut StateWorkingSet, spans: &[Span], @@ -2436,6 +2440,7 @@ pub fn parse_alias( ) } +/// Parse let command pub fn parse_let( working_set: &mut StateWorkingSet, 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) { + 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( working_set: &mut StateWorkingSet, spans: &[Span], @@ -2491,6 +2595,8 @@ pub fn parse_statement( (stmt, None) } else if let (stmt, None) = parse_alias(working_set, spans) { (stmt, None) + } else if let (decl, None) = parse_source(working_set, spans) { + (decl, None) } else { let (expr, err) = parse_expression(working_set, spans); (Statement::Pipeline(Pipeline::from_vec(vec![expr])), err) diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index d02f1ce2d4..815a0fabfd 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -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 { let mut current = self; for member in column_path { diff --git a/crates/nu-protocol/src/value/range.rs b/crates/nu-protocol/src/value/range.rs index 54d836de16..6c7de36166 100644 --- a/crates/nu-protocol/src/value/range.rs +++ b/crates/nu-protocol/src/value/range.rs @@ -1,5 +1,6 @@ use crate::{ast::RangeInclusion, *}; +/// A Range is an iterator over integers. #[derive(Debug, Clone, PartialEq)] pub struct Range { pub from: Value, diff --git a/example.nu b/example.nu new file mode 100644 index 0000000000..a157d1a3ce --- /dev/null +++ b/example.nu @@ -0,0 +1 @@ +length [1,2,3,4] \ No newline at end of file From 2b5ef1b2d7bbc4c68ac686578994bd5518361a7a Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Mon, 27 Sep 2021 08:10:45 -0400 Subject: [PATCH 03/13] Removed extra file --- crates/nu-command/src/source.rs | 139 ++++++++++++++++---------------- example.nu | 1 - 2 files changed, 70 insertions(+), 70 deletions(-) delete mode 100644 example.nu diff --git a/crates/nu-command/src/source.rs b/crates/nu-command/src/source.rs index 1997bbea82..566c898ef5 100644 --- a/crates/nu-command/src/source.rs +++ b/crates/nu-command/src/source.rs @@ -32,86 +32,87 @@ impl Command for Source { call: &Call, input: Value, ) -> Result { - source(_context, call, input) + Ok(Value::Nothing { span: call.head }) + // source(_context, call, input) } } -pub fn source(ctx: &EvaluationContext, call: &Call, input: Value) -> Result { - let filename = call.positional[0] - .as_string() - .expect("internal error: missing file name"); +// pub fn source(ctx: &EvaluationContext, call: &Call, input: Value) -> Result { +// let filename = call.positional[0] +// .as_string() +// .expect("internal error: missing file name"); - let source_file = Path::new(&filename); +// let source_file = Path::new(&filename); - // This code is in the current Nushell version - // ...Not entirely sure what it's doing or if there's an equivalent in engine-q +// // This code is in the current Nushell version +// // ...Not entirely sure what it's doing or if there's an equivalent in engine-q - // Note: this is a special case for setting the context from a command - // In this case, if we don't set it now, we'll lose the scope that this - // variable should be set into. +// // Note: this is a special case for setting the context from a command +// // In this case, if we don't set it now, we'll lose the scope that this +// // variable should be set into. - // let lib_dirs = &ctx - // .configs() - // .lock() - // .global_config - // .as_ref() - // .map(|configuration| match configuration.var("lib_dirs") { - // Some(paths) => paths - // .table_entries() - // .cloned() - // .map(|path| path.as_string()) - // .collect(), - // None => vec![], - // }); +// // let lib_dirs = &ctx +// // .configs() +// // .lock() +// // .global_config +// // .as_ref() +// // .map(|configuration| match configuration.var("lib_dirs") { +// // Some(paths) => paths +// // .table_entries() +// // .cloned() +// // .map(|path| path.as_string()) +// // .collect(), +// // None => vec![], +// // }); - // if let Some(dir) = lib_dirs { - // for lib_path in dir { - // match lib_path { - // Ok(name) => { - // let path = PathBuf::from(name).join(source_file); +// // if let Some(dir) = lib_dirs { +// // for lib_path in dir { +// // match lib_path { +// // Ok(name) => { +// // let path = PathBuf::from(name).join(source_file); - // if let Ok(contents) = - // std::fs::read_to_string(&expand_path(Cow::Borrowed(path.as_path()))) - // { - // let result = script::run_script_standalone(contents, true, ctx, false); +// // if let Ok(contents) = +// // std::fs::read_to_string(&expand_path(Cow::Borrowed(path.as_path()))) +// // { +// // let result = script::run_script_standalone(contents, true, ctx, false); - // if let Err(err) = result { - // ctx.error(err); - // } - // return Ok(OutputStream::empty()); - // } - // } - // Err(reason) => { - // ctx.error(reason.clone()); - // } - // } - // } - // } +// // if let Err(err) = result { +// // ctx.error(err); +// // } +// // return Ok(OutputStream::empty()); +// // } +// // } +// // Err(reason) => { +// // ctx.error(reason.clone()); +// // } +// // } +// // } +// // } - // This is to stay consistent w/ the code taken from nushell - let path = source_file; +// // This is to stay consistent w/ the code taken from nushell +// let path = source_file; - let contents = std::fs::read(path); +// let contents = std::fs::read(path); - match contents { - Ok(contents) => { - let engine_state = EngineState::new(); - let mut working_set = StateWorkingSet::new(&engine_state); +// match contents { +// Ok(contents) => { +// let engine_state = EngineState::new(); +// let mut working_set = StateWorkingSet::new(&engine_state); - let (block, err) = parse(&mut working_set, None, &contents, true); - if let Some(e) = err { - // Be more specific here: need to convert parse error to string - Err(e.into()) - } else { - let result = eval_block(ctx, &block, input); - match result { - Err(e) => Err(e), - _ => Ok(Value::nothing()), - } - } - } - Err(_) => Err(ShellError::InternalError( - "Can't load file to source".to_string(), - )), - } -} +// let (block, err) = parse(&mut working_set, None, &contents, true); +// if let Some(e) = err { +// // Be more specific here: need to convert parse error to string +// Err(e.into()) +// } else { +// let result = eval_block(ctx, &block, input); +// match result { +// Err(e) => Err(e), +// _ => Ok(Value::nothing()), +// } +// } +// } +// Err(_) => Err(ShellError::InternalError( +// "Can't load file to source".to_string(), +// )), +// } +// } diff --git a/example.nu b/example.nu deleted file mode 100644 index a157d1a3ce..0000000000 --- a/example.nu +++ /dev/null @@ -1 +0,0 @@ -length [1,2,3,4] \ No newline at end of file From e00755a2e9dac3679f5ab6c1fa701d584d545251 Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Thu, 30 Sep 2021 23:04:56 -0400 Subject: [PATCH 04/13] fix compile errors --- Cargo.lock | 24 +++---- crates/nu-parser/src/parser.rs | 128 +++++++++++++-------------------- 2 files changed, 63 insertions(+), 89 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index acfbf68bc9..a9b6b51227 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,9 +39,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bstr" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "lazy_static", "memchr", @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" dependencies = [ "cfg-if", ] @@ -190,9 +190,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.101" +version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" [[package]] name = "lock_api" @@ -477,8 +477,8 @@ dependencies = [ [[package]] name = "reedline" -version = "0.1.0" -source = "git+https://github.com/jntrnr/reedline?branch=main#cd87851ad9f238b491062bb854d65489ca2c4c1c" +version = "0.2.0" +source = "git+https://github.com/jntrnr/reedline?branch=main#93c2146fcf4257c40426bc2f0c6903d4115caaf1" dependencies = [ "chrono", "crossterm", @@ -567,9 +567,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "syn" -version = "1.0.76" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" +checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0" dependencies = [ "proc-macro2", "quote", @@ -624,9 +624,9 @@ checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index cab66c3e8d..38b5123763 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -2490,97 +2490,71 @@ pub fn parse_source( working_set: &mut StateWorkingSet, spans: &[Span], ) -> (Statement, Option) { - 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(decl_id) = working_set.find_decl(b"source") { + let (call, call_span, _) = + parse_internal_call(working_set, spans[0], &spans[1..], decl_id); - 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; + // Command and one file name + if spans.len() >= 2 { + let name_expr = working_set.get_span_contents(spans[1]); + if let Ok(filename) = String::from_utf8(name_expr.to_vec()) { + let source_file = Path::new(&filename); - let contents = std::fs::read(path); + 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, - ) + if let Ok(contents) = contents { + let (block, err) = parse( + working_set, + path.file_name().and_then(|x| x.to_str()), + &contents, + true, + ); + if let None = err { + // Successful parse + // What should I be doing here? + let block_id = working_set.add_block(block); + // return ( + // // Successful parse + // // 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 { - ( + + return ( Statement::Pipeline(Pipeline::from_vec(vec![Expression { - expr: Expr::Garbage, - span: span(spans), + expr: Expr::Call(call), + span: call_span, ty: Type::Unknown, }])), - Some(ParseError::Mismatch( - "string".into(), - // Can this be better? - "incompatible string".into(), - spans[1], - )), - ) + None, + ); } - } 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), - // )), - // ) + + ( + Statement::Pipeline(Pipeline::from_vec(vec![Expression { + expr: Expr::Garbage, + span: span(spans), + ty: Type::Unknown, + }])), + Some(ParseError::UnknownState( + "internal error: source statement unparseable".into(), + span(spans), + )), + ) } /// Parse a statement. Check if def, let, alias, or source command can process it properly From adb92b970e3ddf6975f735f04d8898a874ff06dd Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Fri, 1 Oct 2021 22:07:17 -0400 Subject: [PATCH 05/13] nothing --- crates/nu-parser/src/parser.rs | 19 ++++++++----------- example.nu | 1 + 2 files changed, 9 insertions(+), 11 deletions(-) create mode 100644 example.nu diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 38b5123763..76e5c88037 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -2507,24 +2507,21 @@ pub fn parse_source( let contents = std::fs::read(path); if let Ok(contents) = contents { + // This will load the defs from the file into the + // working set, if it was a successful parse. let (block, err) = parse( working_set, path.file_name().and_then(|x| x.to_str()), &contents, - true, + false, ); - if let None = err { - // Successful parse - // What should I be doing here? - let block_id = working_set.add_block(block); + if let Some(_) = err { + // Unsuccessful parse of file // return ( - // // Successful parse - // // 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 + // expr: Expr::Call(call), + // span: call_span, + // ty: Type::Unknown, // }])), // None, // ); diff --git a/example.nu b/example.nu new file mode 100644 index 0000000000..75138d409f --- /dev/null +++ b/example.nu @@ -0,0 +1 @@ +alias x = 4 \ No newline at end of file From 2d4e471052d01124214de41c41766910749dc889 Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Fri, 1 Oct 2021 22:17:32 -0400 Subject: [PATCH 06/13] fix more merge conflicts --- Cargo.lock | 32 +++++++------------ crates/nu-command/Cargo.toml | 5 --- crates/nu-command/src/core_commands/mod.rs | 2 ++ .../src/{ => core_commands}/source.rs | 10 ++---- crates/nu-command/src/default_context.rs | 7 ++-- crates/nu-command/src/lib.rs | 25 --------------- crates/nu-engine/src/eval.rs | 5 --- 7 files changed, 18 insertions(+), 68 deletions(-) rename crates/nu-command/src/{ => core_commands}/source.rs (91%) diff --git a/Cargo.lock b/Cargo.lock index cf0b7954ab..f8afa23836 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -350,11 +350,6 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -<<<<<<< HEAD -version = "0.2.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" -======= version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" @@ -368,7 +363,6 @@ dependencies = [ "serde", "serde_test", ] ->>>>>>> 3567bbbf32302dbc3cbf97a39b03efa3bd3e8bb5 [[package]] name = "lock_api" @@ -405,9 +399,9 @@ dependencies = [ [[package]] name = "miette" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b98aebb9d23c72cb22c089834ea59be059c6f462e844fd9fd18dd0168ad149c" +checksum = "4786c5b04c6f73e96d88444e7f37e241d99479ea5dd88a4887363ab2e03b4e53" dependencies = [ "atty", "backtrace", @@ -424,9 +418,9 @@ dependencies = [ [[package]] name = "miette-derive" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a7cd3347eb52480d4ba59d71ce2b48b8b128034e17068c7e2ff3766c2e87a3" +checksum = "0ee63a981bc9cde5f26665ffd756b624963bf0b5956e0df51e52ef8f6b5466d6" dependencies = [ "proc-macro2", "quote", @@ -504,11 +498,7 @@ version = "0.1.0" dependencies = [ "glob", "nu-engine", -<<<<<<< HEAD - "nu-parser", -======= "nu-json", ->>>>>>> 3567bbbf32302dbc3cbf97a39b03efa3bd3e8bb5 "nu-protocol", "nu-table", "sysinfo", @@ -812,7 +802,7 @@ dependencies = [ [[package]] name = "reedline" version = "0.2.0" -source = "git+https://github.com/jntrnr/reedline?branch=main#93c2146fcf4257c40426bc2f0c6903d4115caaf1" +source = "git+https://github.com/jntrnr/reedline?branch=main#bfddc5870ca2d8301694b4211bdcdb29e647c6f3" dependencies = [ "chrono", "crossterm", @@ -944,9 +934,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "smawk" @@ -956,9 +946,9 @@ checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" [[package]] name = "supports-color" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f5b0f9e689dd52e27228469dd68b7416b60d75b7571ae9060a5f4c50048fee" +checksum = "3f3cef55878ee693bb9f6765515f52910ec20b776d222fce5d11fbb9f5368028" dependencies = [ "atty", "is_ci", @@ -975,9 +965,9 @@ dependencies = [ [[package]] name = "supports-unicode" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5fa283a620b255940913bd962cda2e6320e3799041f96ac0d7191ff2b4622f" +checksum = "a8b945e45b417b125a8ec51f1b7df2f8df7920367700d1f98aedd21e5735f8b2" dependencies = [ "atty", ] diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index beca24e6ee..eb8e8303ba 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -9,14 +9,9 @@ edition = "2018" nu-engine = { path = "../nu-engine" } nu-json = { path = "../nu-json" } nu-protocol = { path = "../nu-protocol" } -<<<<<<< HEAD -nu-engine = { path = "../nu-engine" } -nu-parser = {path = "../nu-parser"} -======= nu-table = { path = "../nu-table" } # Potential dependencies for extras glob = "0.3.0" thiserror = "1.0.29" sysinfo = "0.20.4" ->>>>>>> 3567bbbf32302dbc3cbf97a39b03efa3bd3e8bb5 diff --git a/crates/nu-command/src/core_commands/mod.rs b/crates/nu-command/src/core_commands/mod.rs index 4d909467d6..43a5165fc8 100644 --- a/crates/nu-command/src/core_commands/mod.rs +++ b/crates/nu-command/src/core_commands/mod.rs @@ -5,6 +5,7 @@ mod help; mod if_; mod let_; mod module; +mod source; mod use_; pub use alias::Alias; @@ -14,4 +15,5 @@ pub use help::Help; pub use if_::If; pub use let_::Let; pub use module::Module; +pub use source::Source; pub use use_::Use; diff --git a/crates/nu-command/src/source.rs b/crates/nu-command/src/core_commands/source.rs similarity index 91% rename from crates/nu-command/src/source.rs rename to crates/nu-command/src/core_commands/source.rs index 566c898ef5..677c6f5eda 100644 --- a/crates/nu-command/src/source.rs +++ b/crates/nu-command/src/core_commands/source.rs @@ -1,10 +1,6 @@ -use nu_engine::{eval_block, eval_expression}; -use nu_parser::parse; -use nu_protocol::ast::{Block, Call}; -use nu_protocol::engine::{Command, EngineState, EvaluationContext, StateWorkingSet}; -use nu_protocol::{ShellError, Signature, SyntaxShape, Value}; -use std::task::Context; -use std::{borrow::Cow, path::Path, path::PathBuf}; +use nu_protocol::ast::Call; +use nu_protocol::engine::{Command, EvaluationContext}; +use nu_protocol::{Signature, SyntaxShape, Value}; /// Source a file for environment variables. pub struct Source; diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index d2041573f7..6bc8726adc 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -5,14 +5,11 @@ use nu_protocol::{ Signature, }; -<<<<<<< HEAD -use crate::{Alias, Benchmark, BuildString, Def, Do, Each, For, If, Length, Let, LetEnv, Source}; -======= use crate::{ Alias, Benchmark, BuildString, Def, Do, Each, External, For, From, FromJson, Git, GitCheckout, - Help, If, Length, Let, LetEnv, Lines, ListGitBranches, Ls, Module, Ps, Sys, Table, Use, Where, + Help, If, Length, Let, LetEnv, Lines, ListGitBranches, Ls, Module, Ps, Source, Sys, Table, Use, + Where, }; ->>>>>>> 3567bbbf32302dbc3cbf97a39b03efa3bd3e8bb5 pub fn create_default_context() -> Rc> { let engine_state = Rc::new(RefCell::new(EngineState::new())); diff --git a/crates/nu-command/src/lib.rs b/crates/nu-command/src/lib.rs index 35b71cfd30..da1fd1a680 100644 --- a/crates/nu-command/src/lib.rs +++ b/crates/nu-command/src/lib.rs @@ -1,29 +1,5 @@ mod core_commands; mod default_context; -<<<<<<< HEAD -mod do_; -mod each; -mod for_; -mod if_; -mod length; -mod let_; -mod let_env; -mod source; - -pub use alias::Alias; -pub use benchmark::Benchmark; -pub use build_string::BuildString; -pub use def::Def; -pub use default_context::create_default_context; -pub use do_::Do; -pub use each::Each; -pub use for_::For; -pub use if_::If; -pub use length::Length; -pub use let_::Let; -pub use let_env::LetEnv; -pub use source::Source; -======= mod env; mod experimental; mod filesystem; @@ -43,4 +19,3 @@ pub use formats::*; pub use strings::*; pub use system::*; pub use viewers::*; ->>>>>>> 3567bbbf32302dbc3cbf97a39b03efa3bd3e8bb5 diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index 0abb4efbc4..f8b7c633f4 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -1,12 +1,7 @@ use nu_parser::parse; use nu_protocol::ast::{Block, Call, Expr, Expression, Operator, Statement}; -<<<<<<< HEAD -use nu_protocol::engine::{EngineState, EvaluationContext, StateWorkingSet}; -use nu_protocol::{Range, ShellError, Span, Value}; -======= use nu_protocol::engine::EvaluationContext; use nu_protocol::{Range, ShellError, Span, Type, Value}; ->>>>>>> 3567bbbf32302dbc3cbf97a39b03efa3bd3e8bb5 pub fn eval_operator(op: &Expression) -> Result { match op { From 8ef16c6da66f4804e10e495735631ea66ec06626 Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Fri, 1 Oct 2021 22:25:35 -0400 Subject: [PATCH 07/13] add source command --- crates/nu-parser/src/parser.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index d88c3f73d7..2dd9714cc2 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -1,5 +1,6 @@ use crate::{ lex, lite_parse, + parse_keywords::parse_source, type_check::{math_result_type, type_compatible}, LiteBlock, ParseError, Token, TokenContents, }; @@ -2585,7 +2586,7 @@ pub fn parse_statement( b"alias" => parse_alias(working_set, spans), b"module" => parse_module(working_set, spans), b"use" => parse_use(working_set, spans), - b"source" => parse_use(working_set, spans), + b"source" => parse_source(working_set, spans), _ => { let (expr, err) = parse_expression(working_set, spans); (Statement::Pipeline(Pipeline::from_vec(vec![expr])), err) From 9e7285ad46a28d34f59d1067f80f5d29f544d79e Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Fri, 1 Oct 2021 22:26:52 -0400 Subject: [PATCH 08/13] Delete example.nu --- example.nu | 1 - 1 file changed, 1 deletion(-) delete mode 100644 example.nu diff --git a/example.nu b/example.nu deleted file mode 100644 index 75138d409f..0000000000 --- a/example.nu +++ /dev/null @@ -1 +0,0 @@ -alias x = 4 \ No newline at end of file From 909b7d2160ffbc4289b82c8090a196cb136ec712 Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Sun, 3 Oct 2021 14:23:23 -0400 Subject: [PATCH 09/13] no-op --- crates/nu-command/src/core_commands/source.rs | 6 ++++-- crates/nu-parser/src/parse_keywords.rs | 2 ++ example.nu | 5 +++++ 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 example.nu diff --git a/crates/nu-command/src/core_commands/source.rs b/crates/nu-command/src/core_commands/source.rs index 677c6f5eda..76bcc461bb 100644 --- a/crates/nu-command/src/core_commands/source.rs +++ b/crates/nu-command/src/core_commands/source.rs @@ -1,6 +1,8 @@ +use std::path::Path; + use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EvaluationContext}; -use nu_protocol::{Signature, SyntaxShape, Value}; +use nu_protocol::{ShellError, Signature, SyntaxShape, Value}; /// Source a file for environment variables. pub struct Source; @@ -27,7 +29,7 @@ impl Command for Source { _context: &EvaluationContext, call: &Call, input: Value, - ) -> Result { + ) -> Result { Ok(Value::Nothing { span: call.head }) // source(_context, call, input) } diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index 1700a71ce8..ffce2acc40 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -581,6 +581,8 @@ pub fn parse_source( // None, // ); } + } else { + // Source file couldn't be parsed correctly } } } diff --git a/example.nu b/example.nu new file mode 100644 index 0000000000..6a1392318a --- /dev/null +++ b/example.nu @@ -0,0 +1,5 @@ +def greet [name] { + echo "hello" $name +} + +greet "world" \ No newline at end of file From d6d0bad7aafb620ddd8ab6f2eafa66649a976522 Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Tue, 5 Oct 2021 21:59:16 -0400 Subject: [PATCH 10/13] reverted --- crates/nu-cli/src/syntax_highlight.rs | 4 +- crates/nu-command/src/core_commands/source.rs | 7 ++- crates/nu-parser/src/parse_keywords.rs | 48 ++++++++++++++----- example.nu | 6 +-- 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/crates/nu-cli/src/syntax_highlight.rs b/crates/nu-cli/src/syntax_highlight.rs index 87ec535ed0..67198959ba 100644 --- a/crates/nu-cli/src/syntax_highlight.rs +++ b/crates/nu-cli/src/syntax_highlight.rs @@ -34,7 +34,9 @@ impl Highlighter for NuHighlighter { .to_string(); output.push((Style::new(), gap)); } - + // println!("line: \n{}", line); + // println!("shape: \n{:#?}\n", shape); + // println!("global_span_offset: \n{:#?}\n", global_span_offset); let next_token = line [(shape.0.start - global_span_offset)..(shape.0.end - global_span_offset)] .to_string(); diff --git a/crates/nu-command/src/core_commands/source.rs b/crates/nu-command/src/core_commands/source.rs index 76bcc461bb..c154566c22 100644 --- a/crates/nu-command/src/core_commands/source.rs +++ b/crates/nu-command/src/core_commands/source.rs @@ -1,5 +1,7 @@ +use std::borrow::Borrow; use std::path::Path; +use nu_engine::{eval_block, eval_expression}; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EvaluationContext}; use nu_protocol::{ShellError, Signature, SyntaxShape, Value}; @@ -30,8 +32,9 @@ impl Command for Source { call: &Call, input: Value, ) -> Result { - Ok(Value::Nothing { span: call.head }) - // source(_context, call, input) + let block = &call.positional[0]; + + Ok(eval_expression(_context, block)?) } } diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index ffce2acc40..44dd96ae26 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -549,8 +549,9 @@ pub fn parse_source( if name == b"source" { if let Some(decl_id) = working_set.find_decl(b"source") { - let (call, call_span, _) = + let (call, call_span, err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id); + // println!("\nSpans: {:#?}", spans); // Command and one file name if spans.len() >= 2 { @@ -570,19 +571,44 @@ pub fn parse_source( &contents, false, ); + if let Some(_) = err { // Unsuccessful parse of file - // return ( - // Statement::Pipeline(Pipeline::from_vec(vec![Expression { - // expr: Expr::Call(call), - // span: call_span, - // ty: Type::Unknown, - // }])), - // None, - // ); + return ( + Statement::Pipeline(Pipeline::from_vec(vec![Expression { + expr: Expr::Call(call), + span: span(&spans[1..]), + ty: Type::Unknown, + custom_completion: None, + }])), + // Return the file parse error + err, + ); + } else { + // Save the block into the working set + let block_id = working_set.add_block(block); + // println!("CALL:{:?}", call); + + let mut call_with_block = call.clone(); + // println!("CALL_WITH_BLOCK: {:?}", call_with_block); + + call_with_block.positional.push(Expression { + expr: Expr::Block(block_id), + span: span(&spans[1..]), + ty: Type::Unknown, + custom_completion: None, + }); + + return ( + Statement::Pipeline(Pipeline::from_vec(vec![Expression { + expr: Expr::Call(call_with_block), + span: call_span, + ty: Type::Unknown, + custom_completion: None, + }])), + None, + ); } - } else { - // Source file couldn't be parsed correctly } } } diff --git a/example.nu b/example.nu index 6a1392318a..a4f40bac8a 100644 --- a/example.nu +++ b/example.nu @@ -1,5 +1,5 @@ -def greet [name] { - echo "hello" $name +def inc [x] { + $x + 1 } -greet "world" \ No newline at end of file +inc 5 \ No newline at end of file From 996ee363b774cc9291371c4fcd18bfd9669ef03d Mon Sep 17 00:00:00 2001 From: Tanishq Kancharla Date: Tue, 5 Oct 2021 22:03:18 -0400 Subject: [PATCH 11/13] comments --- crates/nu-parser/src/parse_keywords.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index e0e72f1807..1069c3c706 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -697,6 +697,8 @@ pub fn parse_source( if name == b"source" { if let Some(decl_id) = working_set.find_decl(b"source") { + // Is this the right call to be using here? + // Some of the others (`parse_let`) use it, some of them (`parse_hide`) don't. let (call, call_span, err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id); // println!("\nSpans: {:#?}", spans); @@ -740,6 +742,8 @@ pub fn parse_source( let mut call_with_block = call.clone(); // println!("CALL_WITH_BLOCK: {:?}", call_with_block); + // Adding this expression to the positional creates a syntax highlighting error + // after writing `source example.nu` call_with_block.positional.push(Expression { expr: Expr::Block(block_id), span: span(&spans[1..]), From 7eb022b58cad2a8fdbfe4ff9ef6dc5d9769a9a64 Mon Sep 17 00:00:00 2001 From: JT Date: Wed, 6 Oct 2021 15:29:05 +1300 Subject: [PATCH 12/13] Adapt tk's work for a source command --- crates/nu-cli/src/syntax_highlight.rs | 3 - crates/nu-command/src/core_commands/source.rs | 98 +++---------------- crates/nu-engine/src/eval.rs | 1 - crates/nu-parser/src/parse_keywords.rs | 17 ++-- 4 files changed, 18 insertions(+), 101 deletions(-) diff --git a/crates/nu-cli/src/syntax_highlight.rs b/crates/nu-cli/src/syntax_highlight.rs index fccc0e9544..161801e261 100644 --- a/crates/nu-cli/src/syntax_highlight.rs +++ b/crates/nu-cli/src/syntax_highlight.rs @@ -34,9 +34,6 @@ impl Highlighter for NuHighlighter { .to_string(); output.push((Style::new(), gap)); } - // println!("line: \n{}", line); - // println!("shape: \n{:#?}\n", shape); - // println!("global_span_offset: \n{:#?}\n", global_span_offset); let next_token = line [(shape.0.start - global_span_offset)..(shape.0.end - global_span_offset)] .to_string(); diff --git a/crates/nu-command/src/core_commands/source.rs b/crates/nu-command/src/core_commands/source.rs index 73f5425d27..aacd3564cd 100644 --- a/crates/nu-command/src/core_commands/source.rs +++ b/crates/nu-command/src/core_commands/source.rs @@ -1,7 +1,4 @@ -use std::borrow::Borrow; -use std::path::Path; - -use nu_engine::{eval_block, eval_expression}; +use nu_engine::{eval_block, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EvaluationContext}; use nu_protocol::{ShellError, Signature, SyntaxShape, Value}; @@ -28,92 +25,19 @@ impl Command for Source { fn run( &self, - _context: &EvaluationContext, + context: &EvaluationContext, call: &Call, input: Value, ) -> Result { - let block = &call.positional[0]; + // Note: this hidden positional is the block_id that corresponded to the 0th position + // it is put here by the parser + let block_id: i64 = call.req(context, 1)?; - Ok(eval_expression(_context, block)?) + let block = context + .engine_state + .borrow() + .get_block(block_id as usize) + .clone(); + eval_block(context, &block, input) } } - -// pub fn source(ctx: &EvaluationContext, call: &Call, input: Value) -> Result { -// let filename = call.positional[0] -// .as_string() -// .expect("internal error: missing file name"); - -// let source_file = Path::new(&filename); - -// // This code is in the current Nushell version -// // ...Not entirely sure what it's doing or if there's an equivalent in engine-q - -// // Note: this is a special case for setting the context from a command -// // In this case, if we don't set it now, we'll lose the scope that this -// // variable should be set into. - -// // let lib_dirs = &ctx -// // .configs() -// // .lock() -// // .global_config -// // .as_ref() -// // .map(|configuration| match configuration.var("lib_dirs") { -// // Some(paths) => paths -// // .table_entries() -// // .cloned() -// // .map(|path| path.as_string()) -// // .collect(), -// // None => vec![], -// // }); - -// // if let Some(dir) = lib_dirs { -// // for lib_path in dir { -// // match lib_path { -// // Ok(name) => { -// // let path = PathBuf::from(name).join(source_file); - -// // if let Ok(contents) = -// // std::fs::read_to_string(&expand_path(Cow::Borrowed(path.as_path()))) -// // { -// // let result = script::run_script_standalone(contents, true, ctx, false); - -// // if let Err(err) = result { -// // ctx.error(err); -// // } -// // return Ok(OutputStream::empty()); -// // } -// // } -// // Err(reason) => { -// // ctx.error(reason.clone()); -// // } -// // } -// // } -// // } - -// // 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 engine_state = EngineState::new(); -// let mut working_set = StateWorkingSet::new(&engine_state); - -// let (block, err) = parse(&mut working_set, None, &contents, true); -// if let Some(e) = err { -// // Be more specific here: need to convert parse error to string -// Err(e.into()) -// } else { -// let result = eval_block(ctx, &block, input); -// match result { -// Err(e) => Err(e), -// _ => Ok(Value::nothing()), -// } -// } -// } -// Err(_) => Err(ShellError::InternalError( -// "Can't load file to source".to_string(), -// )), -// } -// } diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index 7408cf2cc9..d59ff4b3e0 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -1,4 +1,3 @@ -use nu_parser::parse; use nu_protocol::ast::{Block, Call, Expr, Expression, Operator, Statement}; use nu_protocol::engine::EvaluationContext; use nu_protocol::{Range, ShellError, Span, Type, Unit, Value}; diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index c1510edbb7..3abad8e122 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -1,7 +1,7 @@ use nu_protocol::{ ast::{Block, Call, Expr, Expression, ImportPatternMember, Pipeline, Statement}, engine::StateWorkingSet, - span, DeclId, ShellError, Span, SyntaxShape, Type, + span, DeclId, Span, SyntaxShape, Type, }; use std::path::Path; @@ -779,7 +779,6 @@ pub fn parse_source( // Some of the others (`parse_let`) use it, some of them (`parse_hide`) don't. let (call, call_span, err) = parse_internal_call(working_set, spans[0], &spans[1..], decl_id); - // println!("\nSpans: {:#?}", spans); // Command and one file name if spans.len() >= 2 { @@ -800,7 +799,7 @@ pub fn parse_source( false, ); - if let Some(_) = err { + if err.is_some() { // Unsuccessful parse of file return ( Statement::Pipeline(Pipeline::from_vec(vec![Expression { @@ -815,16 +814,14 @@ pub fn parse_source( } else { // Save the block into the working set let block_id = working_set.add_block(block); - // println!("CALL:{:?}", call); - let mut call_with_block = call.clone(); - // println!("CALL_WITH_BLOCK: {:?}", call_with_block); + let mut call_with_block = call; // Adding this expression to the positional creates a syntax highlighting error // after writing `source example.nu` call_with_block.positional.push(Expression { - expr: Expr::Block(block_id), - span: span(&spans[1..]), + expr: Expr::Int(block_id as i64), + span: spans[1], ty: Type::Unknown, custom_completion: None, }); @@ -849,14 +846,14 @@ pub fn parse_source( ty: Type::Unknown, custom_completion: None, }])), - None, + err, ); } } ( garbage_statement(spans), Some(ParseError::UnknownState( - "internal error: let statement unparseable".into(), + "internal error: source statement unparseable".into(), span(spans), )), ) From 2500f23fcbed079d41c4a6566bc81c3df413dace Mon Sep 17 00:00:00 2001 From: JT <547158+jntrnr@users.noreply.github.com> Date: Wed, 6 Oct 2021 15:30:36 +1300 Subject: [PATCH 13/13] Delete example.nu --- example.nu | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 example.nu diff --git a/example.nu b/example.nu deleted file mode 100644 index a4f40bac8a..0000000000 --- a/example.nu +++ /dev/null @@ -1,5 +0,0 @@ -def inc [x] { - $x + 1 -} - -inc 5 \ No newline at end of file