Skip to content

Commit

Permalink
Merge pull request #465 from bblancha/master
Browse files Browse the repository at this point in the history
Implement simple form of associative arrays
  • Loading branch information
mmstick committed Jul 25, 2017
2 parents 6523fde + 4dade3c commit f7a560d
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 54 deletions.
7 changes: 5 additions & 2 deletions src/parser/assignments.rs
@@ -1,11 +1,11 @@
use shell::variables::Variables;
use types::{Identifier, Value as VString, Array};
use types::{Identifier, Value as VString, Array, Key};

#[derive(Debug, PartialEq, Clone)]
// TODO: Have the expand_string function return the `Value` type.
pub enum Value {
String(VString),
Array(Array)
Array(Array),
}

#[derive(Debug, PartialEq, Clone)]
Expand All @@ -14,6 +14,7 @@ pub enum Binding {
ListEntries,
KeyOnly(Identifier),
KeyValue(Identifier, VString),
MapKeyValue(Identifier, Key, VString),
Math(Identifier, Operator, VString),
MultipleKeys(Vec<Identifier>, VString)
}
Expand Down Expand Up @@ -108,6 +109,8 @@ pub fn parse_assignment(arguments: &str) -> Binding {
let value = char_iter.skip_while(|&x| x == ' ').collect::<VString>();
if value.is_empty() {
Binding::KeyOnly(key.into())
} else if let Some((key, inner_key)) = Variables::is_hashmap_reference(&key) {
Binding::MapKeyValue(key.into(), inner_key.into(), value)
} else if !Variables::is_valid_variable_name(&key) {
Binding::InvalidKey(key.into())
} else {
Expand Down
27 changes: 25 additions & 2 deletions src/parser/mod.rs
Expand Up @@ -7,8 +7,7 @@ macro_rules! get_expanders {
array: &|array: &str, selection : Select| {
use std::iter::FromIterator;
use $crate::types::*;

match $vars.get_array(array) {
let mut found = match $vars.get_array(array) {
Some(array) => match selection {
Select::None => None,
Select::All => Some(array.clone()),
Expand All @@ -32,10 +31,34 @@ macro_rules! get_expanders {
} else {
None
}
},
Select::Key(_) => {
None
}
},
None => None
};
if found.is_none() {
found = match $vars.get_map(array) {
Some(map) => match selection {
Select::All => {
let mut arr = Array::new();
for (_, value) in map {
arr.push(value.clone());
}
Some(arr)
}
Select::Key(ref key) => {
Some(array![
map.get(key.get()).unwrap_or(&"".into()).clone()
])
},
_ => None
},
None => None
}
}
found
},
variable: &|variable: &str, quoted: bool| {
use ascii_helpers::AsciiReplace;
Expand Down
59 changes: 32 additions & 27 deletions src/parser/shell_expand/mod.rs
Expand Up @@ -88,6 +88,7 @@ fn array_expand(elements : &[&str], expand_func: &ExpanderFunctions, selection :
Select::All => elements.iter().flat_map(|e| expand_string(e, expand_func, false)).collect(),
Select::Index(index) => array_nth(elements, expand_func, index).into_iter().collect(),
Select::Range(range) => array_range(elements, expand_func, range),
Select::Key(_) => Array::new(),
}
}

Expand Down Expand Up @@ -138,6 +139,7 @@ fn slice<S: AsRef<str>>(output: &mut String, expanded: S, selection: Select) {
output.push_str(&substring);
}
},
Select::Key(_) => ()
}
}

Expand Down Expand Up @@ -206,16 +208,16 @@ pub fn expand_tokens<'a>(token_buffer: &[WordToken], expand_func: &'a ExpanderFu

for word in token_buffer {
match *word {
WordToken::Array(ref elements, index) => {
output.push_str(&array_expand(elements, expand_func, index).join(" "));
WordToken::Array(ref elements, ref index) => {
output.push_str(&array_expand(elements, expand_func, index.clone()).join(" "));
},
WordToken::ArrayVariable(array, _, index) => {
if let Some(array) = (expand_func.array)(array, index) {
WordToken::ArrayVariable(array, _, ref index) => {
if let Some(array) = (expand_func.array)(array, index.clone()) {
output.push_str(&array.join(" "));
}
},
WordToken::ArrayProcess(command, _, index) => {
match index {
WordToken::ArrayProcess(command, _, ref index) => {
match *index {
Select::None => (),
Select::All => {
let mut temp = String::new();
Expand Down Expand Up @@ -247,7 +249,8 @@ pub fn expand_tokens<'a>(token_buffer: &[WordToken], expand_func: &'a ExpanderFu
.collect::<Vec<&str>>();
output.push_str(&res.join(" "));
}
}
},
Select::Key(_) => (),
}
},
WordToken::ArrayMethod(ref method) => {
Expand All @@ -259,17 +262,17 @@ pub fn expand_tokens<'a>(token_buffer: &[WordToken], expand_func: &'a ExpanderFu
WordToken::Brace(ref nodes) =>
expand_brace(&mut output, &mut expanders, &mut tokens, nodes, expand_func, reverse_quoting),
WordToken::Whitespace(_) => unreachable!(),
WordToken::Process(command, _, index) => {
expand_process(&mut output, command, index, expand_func);
WordToken::Process(command, _, ref index) => {
expand_process(&mut output, command, index.clone(), expand_func);
},
WordToken::Variable(text, quoted, index) => {
WordToken::Variable(text, quoted, ref index) => {
let quoted = if reverse_quoting { !quoted } else { quoted };
let expanded = match (expand_func.variable)(text, quoted) {
Some(var) => var,
None => continue
};

slice(&mut output, expanded, index);
slice(&mut output, expanded, index.clone());
},
WordToken::Normal(text, do_glob, tilde) => {
expand!(text, do_glob, tilde);
Expand All @@ -292,19 +295,19 @@ pub fn expand_tokens<'a>(token_buffer: &[WordToken], expand_func: &'a ExpanderFu
return expanded_words;
} else if token_buffer.len() == 1 {
match token_buffer[0] {
WordToken::Array(ref elements, index) => {
return array_expand(elements, expand_func, index);
WordToken::Array(ref elements, ref index) => {
return array_expand(elements, expand_func, index.clone());
},
WordToken::ArrayVariable(array, quoted, index) => {
return match (expand_func.array)(array, index) {
WordToken::ArrayVariable(array, quoted, ref index) => {
return match (expand_func.array)(array, index.clone()) {
Some(ref array) if quoted =>
Some(array.join(" ").into()).into_iter().collect(),
Some(array) => array,
None => Array::new(),
};
},
WordToken::ArrayProcess(command, _, index) => {
match index {
WordToken::ArrayProcess(command, _, ref index) => {
match *index {
Select::None => return Array::new(),
Select::All => {
expand_process(&mut output, command, Select::All, expand_func);
Expand Down Expand Up @@ -342,6 +345,7 @@ pub fn expand_tokens<'a>(token_buffer: &[WordToken], expand_func: &'a ExpanderFu
return Array::new();
}
},
Select::Key(_) => ()
}
},
WordToken::ArrayMethod(ref array_method) => {
Expand All @@ -360,16 +364,16 @@ pub fn expand_tokens<'a>(token_buffer: &[WordToken], expand_func: &'a ExpanderFu

for word in token_buffer {
match *word {
WordToken::Array(ref elements, index) => {
output.push_str(&array_expand(elements, expand_func, index).join(" "));
WordToken::Array(ref elements, ref index) => {
output.push_str(&array_expand(elements, expand_func, index.clone()).join(" "));
},
WordToken::ArrayVariable(array, _, index) => {
if let Some(array) = (expand_func.array)(array, index) {
WordToken::ArrayVariable(array, _, ref index) => {
if let Some(array) = (expand_func.array)(array, index.clone()) {
output.push_str(&array.join(" "));
}
},
WordToken::ArrayProcess(command, _, index) => {
match index {
WordToken::ArrayProcess(command, _, ref index) => {
match index.clone() {
Select::None => (),
Select::All => {
let mut temp = String::new();
Expand Down Expand Up @@ -401,6 +405,7 @@ pub fn expand_tokens<'a>(token_buffer: &[WordToken], expand_func: &'a ExpanderFu
output.push_str(&temp.join(" "))
}
},
Select::Key(_) => ()
}
},
WordToken::ArrayMethod(ref method) => {
Expand All @@ -416,17 +421,17 @@ pub fn expand_tokens<'a>(token_buffer: &[WordToken], expand_func: &'a ExpanderFu
WordToken::Whitespace(text) => {
output.push_str(text);
},
WordToken::Process(command, _, index) => {
expand_process(&mut output, command, index, expand_func);
WordToken::Process(command, _, ref index) => {
expand_process(&mut output, command, index.clone(), expand_func);
}
WordToken::Variable(text, quoted, index) => {
WordToken::Variable(text, quoted, ref index) => {
let quoted = if reverse_quoting { !quoted } else { quoted };
let expanded = match (expand_func.variable)(text, quoted) {
Some(var) => var,
None => continue
};

slice(&mut output, expanded, index);
slice(&mut output, expanded, index.clone());
},
WordToken::Arithmetic(s) => expand_arithmetic(&mut output, s, expand_func),
}
Expand Down

0 comments on commit f7a560d

Please sign in to comment.