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) => {
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)?;
Diagnostic::error()
.with_message("Variable not found")

View File

@ -101,7 +101,7 @@ pub fn eval_expression(
}
Expr::Var(var_id) => context
.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::ExternalCall(_, _) => Err(ShellError::ExternalNotSupported(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, &[], &[]);
error = error.or(err);
working_set.enter_scope();
// Check to see if we have parameters
let (signature, amt_to_skip): (Option<Box<Signature>>, usize) = match output.first() {
Some(Token {
@ -1818,12 +1819,25 @@ pub fn parse_block_expression(
let (output, err) = lite_parse(&output[amt_to_skip..]);
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);
if let Some(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);

View File

@ -13,7 +13,7 @@ pub struct EngineState {
}
#[derive(Debug)]
struct ScopeFrame {
pub struct ScopeFrame {
vars: HashMap<Vec<u8>, VarId>,
decls: HashMap<Vec<u8>, DeclId>,
aliases: HashMap<Vec<u8>, Vec<Span>>,
@ -27,6 +27,16 @@ impl ScopeFrame {
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 {
@ -188,7 +198,7 @@ pub struct StateDelta {
vars: Vec<Type>, // indexed by VarId
decls: Vec<Box<dyn Command>>, // indexed by DeclId
blocks: Vec<Block>, // indexed by BlockId
scope: Vec<ScopeFrame>,
pub scope: Vec<ScopeFrame>,
}
impl StateDelta {

View File

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

View File

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

View File

@ -203,3 +203,13 @@ fn alias_2() -> TestResult {
"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")
}