Simplify handling of keyword arguments

This commit is contained in:
ConnorSkees 2020-01-19 12:10:35 -05:00
parent 1f1f43bf7c
commit 500b682739
2 changed files with 12 additions and 52 deletions

View File

@ -21,19 +21,7 @@ impl FuncArgs {
} }
#[derive(Debug, Clone, std::default::Default)] #[derive(Debug, Clone, std::default::Default)]
pub struct CallArgs(pub BTreeMap<String, CallArg>); pub struct CallArgs(pub BTreeMap<String, Vec<Token>>);
#[derive(Debug, Clone)]
pub struct CallArg {
pub name: Option<String>,
pub val: Vec<Token>,
}
impl CallArg {
pub fn is_named(&self) -> bool {
self.name.is_some()
}
}
impl CallArgs { impl CallArgs {
pub fn new() -> Self { pub fn new() -> Self {
@ -44,7 +32,7 @@ impl CallArgs {
self.0.is_empty() self.0.is_empty()
} }
pub fn get(&self, val: &str) -> Option<&CallArg> { pub fn get(&self, val: &str) -> Option<&Vec<Token>> {
self.0.get(val) self.0.get(val)
} }
} }
@ -125,7 +113,7 @@ pub fn eat_func_args<I: Iterator<Item = Token>>(toks: &mut Peekable<I>) -> FuncA
} }
pub fn eat_call_args<I: Iterator<Item = Token>>(toks: &mut Peekable<I>) -> CallArgs { pub fn eat_call_args<I: Iterator<Item = Token>>(toks: &mut Peekable<I>) -> CallArgs {
let mut args: BTreeMap<String, CallArg> = BTreeMap::new(); let mut args: BTreeMap<String, Vec<Token>> = BTreeMap::new();
devour_whitespace(toks); devour_whitespace(toks);
let mut name: Option<String> = None; let mut name: Option<String> = None;
let mut val = Vec::new(); let mut val = Vec::new();
@ -138,13 +126,7 @@ pub fn eat_call_args<I: Iterator<Item = Token>>(toks: &mut Peekable<I>) -> CallA
match &tok.kind { match &tok.kind {
TokenKind::Symbol(Symbol::Comma) => { TokenKind::Symbol(Symbol::Comma) => {
toks.next(); toks.next();
args.insert( args.insert(name.clone().unwrap(), val.clone());
name.clone().unwrap(),
CallArg {
name: name.clone(),
val: val.clone(),
},
);
if let Some(ref mut s) = name { if let Some(ref mut s) = name {
s.clear(); s.clear();
} }
@ -152,17 +134,7 @@ pub fn eat_call_args<I: Iterator<Item = Token>>(toks: &mut Peekable<I>) -> CallA
break; break;
} }
TokenKind::Symbol(Symbol::CloseParen) => { TokenKind::Symbol(Symbol::CloseParen) => {
args.insert( args.insert(name.clone().unwrap(), val.clone());
name.clone().unwrap(),
CallArg {
name: name.clone(),
val: val.clone(),
},
);
if let Some(ref mut s) = name {
s.clear();
}
val.clear();
break; break;
} }
_ => { _ => {
@ -173,30 +145,18 @@ pub fn eat_call_args<I: Iterator<Item = Token>>(toks: &mut Peekable<I>) -> CallA
} }
} }
TokenKind::Symbol(Symbol::CloseParen) => { TokenKind::Symbol(Symbol::CloseParen) => {
if name.is_some() { if let Some(name) = name {
args.insert(name.clone().unwrap(), CallArg { name, val }); args.insert(name, val);
} else { } else {
args.insert(format!("{}", args.len()), CallArg { name, val }); args.insert(format!("{}", args.len()), val);
} }
break; break;
} }
TokenKind::Symbol(Symbol::Comma) => { TokenKind::Symbol(Symbol::Comma) => {
if let Some(ref name) = name { if let Some(ref name) = name {
args.insert( args.insert(name.clone(), val.clone());
name.clone(),
CallArg {
name: Some(name.clone()),
val: val.clone(),
},
);
} else { } else {
args.insert( args.insert(format!("{}", args.len()), val.clone());
format!("{}", args.len()),
CallArg {
name: name.clone(),
val: val.clone(),
},
);
} }
if let Some(ref mut s) = name { if let Some(ref mut s) = name {
s.clear(); s.clear();

View File

@ -77,9 +77,9 @@ impl Mixin {
pub fn args(mut self, args: &CallArgs) -> Mixin { pub fn args(mut self, args: &CallArgs) -> Mixin {
for (idx, arg) in self.args.0.iter().enumerate() { for (idx, arg) in self.args.0.iter().enumerate() {
let val = match args.get(&format!("{}", idx)) { let val = match args.get(&format!("{}", idx)) {
Some(v) => v.val.clone(), Some(v) => v.clone(),
None => match args.get(&arg.name) { None => match args.get(&arg.name) {
Some(v) => v.val.clone(), Some(v) => v.clone(),
None => arg.default.clone().expect("missing variable!"), None => arg.default.clone().expect("missing variable!"),
}, },
}; };