yash_semantics/expansion/initial.rs
1// This file is part of yash, an extended POSIX shell.
2// Copyright (C) 2022 WATANABE Yuki
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17//! Initial expansion
18//!
19//! The initial expansion evaluates a word to a phrase. This module defines the
20//! [`Expand`] trait and its implementors that perform the expansion.
21
22use super::Error;
23use super::phrase::Phrase;
24use std::fmt::Debug;
25use yash_env::semantics::ExitStatus;
26
27/// Environment in which initial expansion is performed
28///
29/// This sturct extends [`yash_env::Env`] with some properties.
30#[derive(Debug)]
31pub struct Env<'a> {
32 /// Main part of the environment
33 pub inner: &'a mut yash_env::Env,
34
35 /// Exit status of the last executed command substitution
36 ///
37 /// This value is `None` by default.
38 /// When performing a command substitution during expansion, you must set
39 /// its exit status to this field.
40 pub last_command_subst_exit_status: Option<ExitStatus>,
41
42 /// Whether the expansion result will be subjected to field splitting.
43 ///
44 /// This flag will affect the expansion of the `$*` special parameter.
45 pub will_split: bool,
46}
47
48impl<'a> Env<'a> {
49 /// Creates a new `Env` instance.
50 ///
51 /// The `last_command_subst_exit_status` and `will_split` field are
52 /// initialized to be `None` and `true`, respectively.
53 pub fn new(inner: &'a mut yash_env::Env) -> Self {
54 Env {
55 inner,
56 last_command_subst_exit_status: None,
57 will_split: true,
58 }
59 }
60}
61
62/// Syntactic construct that can be subjected to the word expansion.
63///
64/// Syntactic elements like [`TextUnit`](yash_syntax::syntax::TextUnit) and
65/// [`Word`](yash_syntax::syntax::Word) implement this trait to
66/// [`expand`](Self::expand) themselves to a [`Phrase`].
67pub trait Expand {
68 /// Performs initial expansion.
69 #[allow(async_fn_in_trait)] // We don't support Send
70 async fn expand(&self, env: &mut Env<'_>) -> Result<Phrase, Error>;
71}
72
73mod arith;
74mod command_subst;
75mod param;
76mod slice;
77mod text;
78mod tilde;
79mod word;
80
81pub use arith::ArithError;
82pub use param::NonassignableError;
83pub use param::Vacancy;
84pub use param::VacantError;