refactor how default variables are evaluated

This commit is contained in:
Connor Skees 2020-08-17 06:16:18 -04:00
parent 44ecd82454
commit 8d1e8a99c5
4 changed files with 66 additions and 33 deletions

View File

@ -39,29 +39,42 @@ impl<'a> Parser<'a> {
} = self.parse_variable_value()?; } = self.parse_variable_value()?;
if default { if default {
let config_val = self.module_config.get(ident); let config_val = self.module_config.get(ident).filter(|v| !v.is_null());
if self.at_root && !self.flags.in_control_flow() {
if !self.global_scope.default_var_exists(ident) { let value = if (self.at_root && !self.flags.in_control_flow()) || global {
let value = if let Some(config_val) = config_val { if self.global_scope.default_var_exists(ident) {
config_val return Ok(());
} else if let Some(value) = config_val {
value
} else { } else {
self.parse_value_from_vec(val_toks, true)?.node self.parse_value_from_vec(val_toks, true)?.node
};
self.global_scope.insert_var(ident, value);
} }
} else { } else if self.at_root && self.flags.in_control_flow() {
let value = if let Some(config_val) = config_val { if self.global_scope.default_var_exists(ident) {
config_val return Ok(());
}
self.parse_value_from_vec(val_toks, true)?.node
} else if !self.at_root {
if self.scopes.default_var_exists(ident) {
return Ok(());
}
self.parse_value_from_vec(val_toks, true)?.node
} else { } else {
self.parse_value_from_vec(val_toks, true)?.node self.parse_value_from_vec(val_toks, true)?.node
}; };
if global && !self.global_scope.default_var_exists(ident) { if self.at_root && !self.flags.in_control_flow() {
self.global_scope.insert_var(ident, value);
return Ok(());
}
if global {
self.global_scope.insert_var(ident, value.clone()); self.global_scope.insert_var(ident, value.clone());
} }
self.scopes.insert_default_var(ident, value);
} self.scopes.insert_var(ident, value);
return Ok(()); return Ok(());
} }

View File

@ -88,21 +88,13 @@ impl Scope {
self.merge(other.scope); self.merge(other.scope);
} }
pub fn default_var_exists(&mut self, s: Identifier) -> bool { pub fn default_var_exists(&self, s: Identifier) -> bool {
if let Some(default_var) = self.get_var_no_err(s) { if let Some(default_var) = self.get_var_no_err(s) {
!default_var.is_null() !default_var.is_null()
} else { } else {
false false
} }
} }
pub fn insert_default_var(&mut self, s: Identifier, v: Value) -> Option<Value> {
if self.default_var_exists(s) {
None
} else {
self.insert_var(s, v)
}
}
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -171,14 +163,16 @@ impl Scopes {
} }
} }
pub fn insert_default_var(&mut self, s: Identifier, v: Value) -> Option<Value> { pub fn default_var_exists(&self, name: Identifier) -> bool {
if let Some(scope) = self.0.last_mut() { for scope in self.0.iter().rev() {
scope.insert_default_var(s, v) if scope.default_var_exists(name) {
} else { return true;
panic!()
} }
} }
false
}
pub fn get_var<'a>( pub fn get_var<'a>(
&'a self, &'a self,
name: Spanned<Identifier>, name: Spanned<Identifier>,

View File

@ -682,7 +682,7 @@ test!(
"null {\n color: null;\n}\n" "null {\n color: null;\n}\n"
); );
test!( test!(
#[ignore = "we do not yet have a good way of consuming a string without converting \a to a newline"] #[ignore = "we do not yet have a good way of consuming a string without converting \\a to a newline"]
silent_comment_in_quoted_attribute_value, silent_comment_in_quoted_attribute_value,
".foo bar[val=\"//\"] {\n color: &;\n}\n", ".foo bar[val=\"//\"] {\n color: &;\n}\n",
".foo bar[val=\"//\"] {\n color: .foo bar[val=\"//\"];\n}\n" ".foo bar[val=\"//\"] {\n color: .foo bar[val=\"//\"];\n}\n"

View File

@ -182,6 +182,32 @@ test!(
}", }",
"a {\n color: red;\n}\n" "a {\n color: red;\n}\n"
); );
test!(
default_at_root_inside_control_flow,
"$a: initial;
@if true {
$a: outer !default;
}
a {
color: $a;
}",
"a {\n color: initial;\n}\n"
);
test!(
default_at_root_inside_control_flow_outer_is_null,
"$a: null;
@if true {
$a: outer !default;
}
a {
color: $a;
}",
"a {\n color: outer;\n}\n"
);
// https://github.com/Kixiron/lasso/issues/7 // https://github.com/Kixiron/lasso/issues/7
test!( test!(
regression_test_for_lasso_0_3_0, regression_test_for_lasso_0_3_0,