Block params

This commit is contained in:
JT 2021-09-06 14:20:02 +12:00
parent aaee3a8b61
commit 979faf853a
7 changed files with 41 additions and 7 deletions

View File

@ -297,7 +297,7 @@ pub fn report_shell_error(
ShellError::InternalError(s) => { ShellError::InternalError(s) => {
Diagnostic::error().with_message(format!("Internal error: {}", s)) Diagnostic::error().with_message(format!("Internal error: {}", s))
} }
ShellError::VariableNotFound(span) => { ShellError::VariableNotFoundAtRuntime(span) => {
let (diag_file_id, diag_range) = convert_span_to_diag(working_set, span)?; let (diag_file_id, diag_range) = convert_span_to_diag(working_set, span)?;
Diagnostic::error() Diagnostic::error()
.with_message("Variable not found") .with_message("Variable not found")

View File

@ -101,7 +101,7 @@ pub fn eval_expression(
} }
Expr::Var(var_id) => context Expr::Var(var_id) => context
.get_var(*var_id) .get_var(*var_id)
.map_err(move |_| ShellError::VariableNotFound(expr.span)), .map_err(move |_| ShellError::VariableNotFoundAtRuntime(expr.span)),
Expr::Call(call) => eval_call(context, call, Value::nothing()), Expr::Call(call) => eval_call(context, call, Value::nothing()),
Expr::ExternalCall(_, _) => Err(ShellError::ExternalNotSupported(expr.span)), Expr::ExternalCall(_, _) => Err(ShellError::ExternalNotSupported(expr.span)),
Expr::Operator(_) => Ok(Value::Nothing { span: expr.span }), Expr::Operator(_) => Ok(Value::Nothing { span: expr.span }),

View File

@ -1771,6 +1771,7 @@ pub fn parse_block_expression(
let (output, err) = lex(source, start, &[], &[]); let (output, err) = lex(source, start, &[], &[]);
error = error.or(err); error = error.or(err);
working_set.enter_scope();
// Check to see if we have parameters // Check to see if we have parameters
let (signature, amt_to_skip): (Option<Box<Signature>>, usize) = match output.first() { let (signature, amt_to_skip): (Option<Box<Signature>>, usize) = match output.first() {
Some(Token { Some(Token {
@ -1818,13 +1819,26 @@ pub fn parse_block_expression(
let (output, err) = lite_parse(&output[amt_to_skip..]); let (output, err) = lite_parse(&output[amt_to_skip..]);
error = error.or(err); error = error.or(err);
let (mut output, err) = parse_block(working_set, &output, true); let (mut output, err) = parse_block(working_set, &output, false);
error = error.or(err); error = error.or(err);
if let Some(signature) = signature { if let Some(signature) = signature {
output.signature = signature; output.signature = signature;
} else if let Some(last) = working_set.delta.scope.last() {
if let Some(var_id) = last.get_var(b"$it") {
let mut signature = Signature::new("");
signature.required_positional.push(PositionalArg {
var_id: Some(*var_id),
name: "$it".into(),
desc: String::new(),
shape: SyntaxShape::Any,
});
output.signature = Box::new(signature);
}
} }
working_set.exit_scope();
let block_id = working_set.add_block(output); let block_id = working_set.add_block(output);
( (

View File

@ -13,7 +13,7 @@ pub struct EngineState {
} }
#[derive(Debug)] #[derive(Debug)]
struct ScopeFrame { pub struct ScopeFrame {
vars: HashMap<Vec<u8>, VarId>, vars: HashMap<Vec<u8>, VarId>,
decls: HashMap<Vec<u8>, DeclId>, decls: HashMap<Vec<u8>, DeclId>,
aliases: HashMap<Vec<u8>, Vec<Span>>, aliases: HashMap<Vec<u8>, Vec<Span>>,
@ -27,6 +27,16 @@ impl ScopeFrame {
aliases: HashMap::new(), aliases: HashMap::new(),
} }
} }
pub fn get_var(&self, var_name: &[u8]) -> Option<&VarId> {
self.vars.get(var_name)
}
}
impl Default for ScopeFrame {
fn default() -> Self {
Self::new()
}
} }
impl Default for EngineState { impl Default for EngineState {
@ -188,7 +198,7 @@ pub struct StateDelta {
vars: Vec<Type>, // indexed by VarId vars: Vec<Type>, // indexed by VarId
decls: Vec<Box<dyn Command>>, // indexed by DeclId decls: Vec<Box<dyn Command>>, // indexed by DeclId
blocks: Vec<Block>, // indexed by BlockId blocks: Vec<Block>, // indexed by BlockId
scope: Vec<ScopeFrame>, pub scope: Vec<ScopeFrame>,
} }
impl StateDelta { impl StateDelta {

View File

@ -13,7 +13,7 @@ pub enum ShellError {
UnknownOperator(String, Span), UnknownOperator(String, Span),
ExternalNotSupported(Span), ExternalNotSupported(Span),
InternalError(String), InternalError(String),
VariableNotFound(Span), VariableNotFoundAtRuntime(Span),
CantConvert(String, Span), CantConvert(String, Span),
DivisionByZero(Span), DivisionByZero(Span),
} }

View File

@ -350,7 +350,7 @@ impl Command for BlockCommand {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
panic!("Internal error: can't get signature with 'signature', use block_id"); self.signature.clone()
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {

View File

@ -203,3 +203,13 @@ fn alias_2() -> TestResult {
"143", "143",
) )
} }
#[test]
fn block_param1() -> TestResult {
run_test("[3] | each { $it + 10 }", "13")
}
#[test]
fn block_param2() -> TestResult {
run_test("[3] | each { |y| $y + 10 }", "13")
}