Implemented scoping for expansions
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use crate::{parse::lex::Token, prelude::*};
|
||||
|
||||
use super::cmdsub::expand_cmdsub_string;
|
||||
|
||||
pub fn expand_var(var_sub: Token, shenv: &mut ShEnv) -> Vec<Token> {
|
||||
let var_name = var_sub.as_raw(shenv);
|
||||
let var_name = var_name.trim_start_matches('$').trim_matches(['{','}']);
|
||||
@@ -8,7 +10,7 @@ pub fn expand_var(var_sub: Token, shenv: &mut ShEnv) -> Vec<Token> {
|
||||
shenv.expand_input(&value, var_sub.span())
|
||||
}
|
||||
|
||||
pub fn expand_string(s: &str, shenv: &mut ShEnv) -> String {
|
||||
pub fn expand_string(s: &str, shenv: &mut ShEnv) -> ShResult<String> {
|
||||
let mut result = String::new();
|
||||
let mut var_name = String::new();
|
||||
let mut chars = s.chars().peekable();
|
||||
@@ -38,6 +40,30 @@ pub fn expand_string(s: &str, shenv: &mut ShEnv) -> String {
|
||||
expanded = true;
|
||||
break
|
||||
}
|
||||
'(' if var_name.is_empty() => {
|
||||
let mut paren_count = 1;
|
||||
var_name.push_str("$(");
|
||||
while let Some(ch) = chars.next() {
|
||||
match ch {
|
||||
'(' => {
|
||||
paren_count += 1;
|
||||
var_name.push(ch);
|
||||
}
|
||||
')' => {
|
||||
paren_count -= 1;
|
||||
var_name.push(ch);
|
||||
if paren_count == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
_ => var_name.push(ch)
|
||||
}
|
||||
}
|
||||
let value = expand_cmdsub_string(&var_name, shenv)?;
|
||||
result.push_str(&value);
|
||||
expanded = true;
|
||||
break
|
||||
}
|
||||
_ if ch.is_ascii_digit() && var_name.is_empty() && !in_brace => {
|
||||
var_name.push(ch);
|
||||
let value = shenv.vars().get_var(&var_name);
|
||||
@@ -72,5 +98,5 @@ pub fn expand_string(s: &str, shenv: &mut ShEnv) -> String {
|
||||
_ => result.push(ch)
|
||||
}
|
||||
}
|
||||
result
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user