From e127ccfc38fca89af3db0204b77c6e7eeccc9322 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Sun, 17 Oct 2021 15:58:16 +0900 Subject: [PATCH] Apply assignment to special built-in --- .../src/command_impl/simple_command.rs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/yash-semantics/src/command_impl/simple_command.rs b/yash-semantics/src/command_impl/simple_command.rs index 916b02f6..ec593613 100644 --- a/yash-semantics/src/command_impl/simple_command.rs +++ b/yash-semantics/src/command_impl/simple_command.rs @@ -169,7 +169,9 @@ impl Command for syntax::SimpleCommand { use crate::command_search::Target::{Builtin, External, Function}; if let Some(name) = fields.get(0) { match search(env, &name.value) { - Some(Builtin(builtin)) => execute_builtin(env, builtin, fields, &self.redirs).await, + Some(Builtin(builtin)) => { + execute_builtin(env, builtin, &self.assigns, fields, &self.redirs).await + } Some(Function(function)) => { execute_function(env, function, &self.assigns, &self.redirs).await } @@ -246,13 +248,18 @@ async fn execute_absent_target( async fn execute_builtin( env: &mut Env, builtin: Builtin, + assigns: &[Assign], fields: Vec, redirs: &[Redir], ) -> Result { let mut env = RedirEnv::new(env); perform_redirs(&mut env, redirs).await?; - // TODO expand and perform assignments + match perform_assignments(env.deref_mut(), assigns, Scope::Global, false).await { + Ok(()) => (), + Err(error) => return error.handle(&mut env).await, + } + let (exit_status, abort) = (builtin.execute)(&mut env, fields).await; env.exit_status = exit_status; abort @@ -473,6 +480,17 @@ mod tests { assert_eq!(file.content, "hello\n".as_bytes()); } + #[test] + fn simple_command_assigns_permanently_for_special_builtin() { + let mut env = Env::new_virtual(); + env.builtins.insert("return", return_builtin()); + let command: syntax::SimpleCommand = "v=42 return -n 0".parse().unwrap(); + block_on(command.execute(&mut env)); + let v = env.variables.get("v").unwrap(); + assert_eq!(v.value, Value::Scalar("42".to_string())); + assert!(!v.is_exported); + } + #[test] fn simple_command_returns_exit_status_from_function() { use yash_env::function::HashEntry;