Skip to content

Commit

Permalink
Refactor Context and PositionalParams (#317)
Browse files Browse the repository at this point in the history
  • Loading branch information
magicant committed Nov 5, 2023
2 parents 9f396f5 + 7f6aec3 commit fa5243e
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 246 deletions.
16 changes: 8 additions & 8 deletions yash-builtin/src/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ use yash_env::option::State;
use yash_env::option::{Interactive, Monitor};
use yash_env::semantics::ExitStatus;
use yash_env::semantics::Field;
use yash_env::variable::Array;
use yash_env::variable::Scope::Global;
use yash_env::Env;

Expand Down Expand Up @@ -167,10 +166,9 @@ fn modify(

// Modify positional parameters
if let Some(fields) = positional_params {
let location = env.stack.current_builtin().map(|b| b.name.origin.clone());
let params = env.variables.positional_params_mut();
params.value = Some(Array(fields.into_iter().map(|f| f.value).collect()));
params.last_assigned_location = location;
params.values = fields.into_iter().map(|f| f.value).collect();
params.last_modified_location = env.stack.current_builtin().map(|b| b.name.origin.clone());
}
}

Expand Down Expand Up @@ -366,10 +364,12 @@ xtrace off
let result = main(&mut env, args).now_or_never().unwrap();
assert_eq!(result, Result::new(ExitStatus::SUCCESS));

let v = env.variables.positional_params();
assert_eq!(v.value, Some(Value::array(["a", "b", "z"])));
assert_eq!(v.read_only_location, None);
assert_eq!(v.last_assigned_location.as_ref().unwrap(), &location);
let params = env.variables.positional_params();
assert_eq!(
params.values,
["a".to_string(), "b".to_string(), "z".to_string()],
);
assert_eq!(params.last_modified_location, Some(location));
}

#[test]
Expand Down
64 changes: 31 additions & 33 deletions yash-builtin/src/shift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ use std::borrow::Cow;
use yash_env::builtin::Result;
use yash_env::semantics::ExitStatus;
use yash_env::semantics::Field;
use yash_env::variable::Value;
use yash_env::Env;
use yash_syntax::source::pretty::Annotation;
use yash_syntax::source::pretty::AnnotationType;
Expand Down Expand Up @@ -99,13 +98,8 @@ pub async fn main(env: &mut Env, args: Vec<Field>) -> Result {
};

let params = env.variables.positional_params_mut();
let values = match params.value.as_mut() {
None => panic!("positional parameters are undefined"),
Some(Value::Scalar(value)) => panic!("positional parameters are not an array: {value:?}"),
Some(Value::Array(params)) => params,
};

if values.len() < count {
let len = params.values.len();
if len < count {
// Failure: cannot shift so many positional parameters
let (label, location) = match operand_location {
None => (
Expand All @@ -119,14 +113,14 @@ pub async fn main(env: &mut Env, args: Vec<Field>) -> Result {
format!(
"requested to shift {} but there {} only {}",
count,
if values.len() == 1 { "is" } else { "are" },
values.len(),
if len == 1 { "is" } else { "are" },
len,
)
.into(),
Cow::Borrowed(location),
),
};
let last_location = params.last_assigned_location.clone();
let last_location = params.last_modified_location.clone();
let mut annotations = vec![Annotation::new(AnnotationType::Error, label, &location)];
if let Some(last_location) = &last_location {
annotations.push(Annotation::new(
Expand All @@ -145,8 +139,8 @@ pub async fn main(env: &mut Env, args: Vec<Field>) -> Result {
return Result::with_exit_status_and_divert(ExitStatus::FAILURE, divert);
}

values.drain(..count);
params.last_assigned_location = env.stack.current_builtin().map(|b| b.name.origin.clone());
params.values.drain(..count);
params.last_modified_location = env.stack.current_builtin().map(|b| b.name.origin.clone());
Result::default()
}

Expand All @@ -172,28 +166,26 @@ mod tests {
name: Field::dummy("shift"),
is_special: true,
}));
env.variables.positional_params_mut().value = Some(Value::array(["1", "2", "3"]));
env.variables.positional_params_mut().values =
vec!["1".to_string(), "2".to_string(), "3".to_string()];

let result = main(&mut env, vec![]).now_or_never().unwrap();
assert_eq!(result, Result::default());
assert_eq!(
env.variables.positional_params().value,
Some(Value::array(["2", "3"])),
env.variables.positional_params().values,
["2".to_string(), "3".to_string()],
);

let result = main(&mut env, vec![]).now_or_never().unwrap();
assert_eq!(result, Result::default());
assert_eq!(
env.variables.positional_params().value,
Some(Value::array(["3"])),
);
assert_eq!(env.variables.positional_params().values, ["3".to_string()],);

let result = main(&mut env, vec![]).now_or_never().unwrap();
assert_eq!(result, Result::default());
let params = env.variables.positional_params();
assert_eq!(params.value, Some(Value::Array(vec![])));
assert_eq!(params.values, [] as [String; 0]);
assert_eq!(
params.last_assigned_location,
params.last_modified_location,
Some(Location::dummy("shift")),
);
}
Expand All @@ -205,32 +197,37 @@ mod tests {
name: Field::dummy("shift"),
is_special: true,
}));
env.variables.positional_params_mut().value =
Some(Value::array(["1", "2", "3", "4", "5", "6", "7"]));
env.variables.positional_params_mut().values = ["1", "2", "3", "4", "5", "6", "7"]
.into_iter()
.map(Into::into)
.collect();

let args = Field::dummies(["2"]);
let result = main(&mut env, args).now_or_never().unwrap();
assert_eq!(result, Result::default());
assert_eq!(
env.variables.positional_params().value,
Some(Value::array(["3", "4", "5", "6", "7"])),
env.variables.positional_params().values,
[
"3".to_string(),
"4".to_string(),
"5".to_string(),
"6".to_string(),
"7".to_string(),
],
);

let args = Field::dummies(["3"]);
let result = main(&mut env, args).now_or_never().unwrap();
assert_eq!(result, Result::default());
assert_eq!(
env.variables.positional_params().value,
Some(Value::array(["6", "7"])),
env.variables.positional_params().values,
["6".to_string(), "7".to_string(),],
);

let args = Field::dummies(["2"]);
let result = main(&mut env, args).now_or_never().unwrap();
assert_eq!(result, Result::default());
assert_eq!(
env.variables.positional_params().value,
Some(Value::Array(vec![])),
);
assert_eq!(env.variables.positional_params().values, [] as [String; 0]);
}

#[test]
Expand Down Expand Up @@ -266,7 +263,8 @@ mod tests {
name: Field::dummy("shift"),
is_special: true,
}));
env.variables.positional_params_mut().value = Some(Value::array(["1", "2", "3"]));
env.variables.positional_params_mut().values =
vec!["1".to_string(), "2".to_string(), "3".to_string()];

let args = Field::dummies(["4"]);
let actual_result = main(&mut env, args).now_or_never().unwrap();
Expand Down
Loading

0 comments on commit fa5243e

Please sign in to comment.