FEATURE: Suppport quoting self and env when we need them as tuple fields.

This commit is contained in:
Jeremy Wall 2019-01-06 14:25:17 -06:00
parent 47163ef010
commit dbadfa1c4c
3 changed files with 53 additions and 8 deletions

View File

@ -85,4 +85,36 @@ let copy_maybe = base_maybe{
assert | assert |
copy_maybe.real == NULL; copy_maybe.real == NULL;
|; |;
let quotedself_tpl = {
"self" = "myself",
};
assert |
quotedself_tpl."self" == "myself";
|;
let quotedenv_tpl = {
"env" = "myenv",
};
assert |
quotedenv_tpl."env" == "myenv";
|;
let unquotedenv_tpl = {
env = "myenv",
};
assert |
unquotedenv_tpl."env" == "myenv";
|;
let unquotedself_tpl = {
self = "myself",
};
assert |
unquotedself_tpl."self" == "myself";
|;

View File

@ -235,7 +235,7 @@ impl<'a> FileBuilder<'a> {
&Value::Str(ref s) => Ok(Rc::new(Val::Str(s.val.to_string()))), &Value::Str(ref s) => Ok(Rc::new(Val::Str(s.val.to_string()))),
&Value::Symbol(ref s) => { &Value::Symbol(ref s) => {
scope scope
.lookup_sym(&(s.into())) .lookup_sym(&(s.into()), true)
.ok_or(Box::new(error::BuildError::new( .ok_or(Box::new(error::BuildError::new(
format!("Unable to find binding {}", s.val,), format!("Unable to find binding {}", s.val,),
error::ErrorType::NoSuchSymbol, error::ErrorType::NoSuchSymbol,
@ -253,7 +253,7 @@ impl<'a> FileBuilder<'a> {
pos: Position::new(0, 0, 0), pos: Position::new(0, 0, 0),
val: name.to_string(), val: name.to_string(),
}; };
self.scope.lookup_sym(&key) self.scope.lookup_sym(&key, true)
} }
/// Puts the builder in validation mode. /// Puts the builder in validation mode.
@ -741,14 +741,27 @@ impl<'a> FileBuilder<'a> {
right: &Expression, right: &Expression,
scope: &Scope, scope: &Scope,
) -> Result<Rc<Val>, Box<dyn Error>> { ) -> Result<Rc<Val>, Box<dyn Error>> {
let pos = right.pos().clone();
match right { match right {
Expression::Copy(_) => return self.eval_expr(right, scope), Expression::Copy(_) => return self.eval_expr(right, scope),
Expression::Call(_) => return self.eval_expr(right, scope), Expression::Call(_) => return self.eval_expr(right, scope),
Expression::Simple(Value::Symbol(ref s)) => { Expression::Simple(Value::Symbol(ref s)) => {
self.eval_value(&Value::Symbol(s.clone()), scope) scope
.lookup_sym(s, true)
.ok_or(Box::new(error::BuildError::new(
format!("Unable to find binding {}", s.val,),
error::ErrorType::NoSuchSymbol,
pos,
)))
} }
Expression::Simple(Value::Str(ref s)) => { Expression::Simple(Value::Str(ref s)) => {
self.eval_value(&Value::Symbol(s.clone()), scope) scope
.lookup_sym(s, false)
.ok_or(Box::new(error::BuildError::new(
format!("Unable to find binding {}", s.val,),
error::ErrorType::NoSuchSymbol,
pos,
)))
} }
Expression::Simple(Value::Int(ref i)) => { Expression::Simple(Value::Int(ref i)) => {
scope.lookup_idx(right.pos(), &Val::Int(i.val)) scope.lookup_idx(right.pos(), &Val::Int(i.val))

View File

@ -119,11 +119,11 @@ impl Scope {
/// valid when the current value is a tuple. /// valid when the current value is a tuple.
/// * everything else is looked up in the currently accumulated build output /// * everything else is looked up in the currently accumulated build output
/// for this execution context. /// for this execution context.
pub fn lookup_sym(&self, sym: &PositionedItem<String>) -> Option<Rc<Val>> { pub fn lookup_sym(&self, sym: &PositionedItem<String>, is_symbol: bool) -> Option<Rc<Val>> {
if &sym.val == "env" { if &sym.val == "env" && is_symbol {
return Some(self.env.clone()); return Some(self.env.clone());
} }
if &sym.val == "self" { if &sym.val == "self" && is_symbol {
return self.curr_val.clone(); return self.curr_val.clone();
} }
if self.build_output.contains_key(sym) { if self.build_output.contains_key(sym) {