Convert Value::Tuple to Val::Tuple using the value_to_val method.

This commit is contained in:
Jeremy Wall 2017-07-29 12:05:39 -05:00
parent 20c360af67
commit a3b2b605a2

View File

@ -190,7 +190,6 @@ pub struct Builder {
// List of file paths we have already parsed. // List of file paths we have already parsed.
files: HashSet<String>, files: HashSet<String>,
/// out is our built output. /// out is our built output.
// TODO Okay Make the out a tuple itself
out: ValueMap, out: ValueMap,
} }
@ -211,7 +210,7 @@ macro_rules! eval_binary_expr {
impl Builder { impl Builder {
/// new_builder constructs Builder with initialized fields ready to parse. /// new_builder constructs Builder with initialized fields ready to parse.
fn from(&self, v: Value) -> Result<Rc<Val>, Box<Error>> { fn value_to_val(&self, v: Value) -> Result<Rc<Val>, Box<Error>> {
match v { match v {
Value::Int(i) => Ok(Rc::new(Val::Int(i))), Value::Int(i) => Ok(Rc::new(Val::Int(i))),
Value::Float(f) => Ok(Rc::new(Val::Float(f))), Value::Float(f) => Ok(Rc::new(Val::Float(f))),
@ -220,13 +219,14 @@ impl Builder {
self.lookup_sym(&s).ok_or(Box::new( self.lookup_sym(&s).ok_or(Box::new(
BuildError::NoSuchSymbol(format!("Unable to find {}", s)))) BuildError::NoSuchSymbol(format!("Unable to find {}", s))))
}, },
Value::Tuple(fields) => { Value::Tuple(mut fields) => {
// TODO(jwall): We need to resolve the expressions here. let mut new_fields = Vec::new();
// TODO(jwall): Don't forget we want a stable order for the fields for (name, expr) in fields.drain(0..) {
// in a tuple to make Vec comparisons easier later on. let val = try!(self.eval_expr(expr));
Err(Box::new( new_fields.push((name, val));
BuildError::TODO( }
"Value::Tuple to Val::Tuple is not yet impolemented.".to_string()))) new_fields.sort_by(|a, b| a.0.cmp(&b.0));
Ok(Rc::new(Val::Tuple(new_fields)))
}, },
Value::Selector(selector_list) => { Value::Selector(selector_list) => {
self.lookup_selector(selector_list) self.lookup_selector(selector_list)
@ -338,11 +338,11 @@ impl Builder {
// Take a reference instead? // Take a reference instead?
match expr { match expr {
Expression::Simple(val) => { Expression::Simple(val) => {
self.from(val) self.value_to_val(val)
}, },
Expression::Add(v, expr) => { Expression::Add(v, expr) => {
let expr_result = try!(self.eval_expr(*expr)); let expr_result = try!(self.eval_expr(*expr));
let v = try!(self.from(*v)); let v = try!(self.value_to_val(*v));
match *v { match *v {
Val::Int(i) => { Val::Int(i) => {
eval_binary_expr!(&Val::Int(ii), expr_result, eval_binary_expr!(&Val::Int(ii), expr_result,
@ -374,7 +374,7 @@ impl Builder {
}, },
Expression::Sub(v, expr) => { Expression::Sub(v, expr) => {
let expr_result = try!(self.eval_expr(*expr)); let expr_result = try!(self.eval_expr(*expr));
let v = try!(self.from(*v)); let v = try!(self.value_to_val(*v));
match *v { match *v {
Val::Int(i) => { Val::Int(i) => {
eval_binary_expr!(&Val::Int(ii), expr_result, eval_binary_expr!(&Val::Int(ii), expr_result,
@ -393,7 +393,7 @@ impl Builder {
}, },
Expression::Mul(v, expr) => { Expression::Mul(v, expr) => {
let expr_result = try!(self.eval_expr(*expr)); let expr_result = try!(self.eval_expr(*expr));
let v = try!(self.from(*v)); let v = try!(self.value_to_val(*v));
match *v { match *v {
Val::Int(i) => { Val::Int(i) => {
eval_binary_expr!(&Val::Int(ii), expr_result, eval_binary_expr!(&Val::Int(ii), expr_result,
@ -412,7 +412,7 @@ impl Builder {
}, },
Expression::Div(v, expr) => { Expression::Div(v, expr) => {
let expr_result = try!(self.eval_expr(*expr)); let expr_result = try!(self.eval_expr(*expr));
let v = try!(self.from(*v)); let v = try!(self.value_to_val(*v));
match *v { match *v {
Val::Int(i) => { Val::Int(i) => {
eval_binary_expr!(&Val::Int(ii), expr_result, eval_binary_expr!(&Val::Int(ii), expr_result,
@ -543,7 +543,7 @@ impl Builder {
BuildError::IncompleteParse(format!("Could not parse input from file: {}", name)))), BuildError::IncompleteParse(format!("Could not parse input from file: {}", name)))),
} }
} }
pub fn build_file(&mut self, name: &str) -> BuildResult { pub fn build_file(&mut self, name: &str) -> BuildResult {
let mut f = try!(File::open(name)); let mut f = try!(File::open(name));
let mut s = String::new(); let mut s = String::new();
@ -580,7 +580,7 @@ impl Builder {
} }
} }
Statement::Expression(ref expr) => { Statement::Expression(ref expr) => {
// TODO Is this just a noop? Maybe it's completely unnecessary? // TODO(jwall): Is this just a noop? Maybe it's completely unnecessary?
} }
}; };
Ok(()) Ok(())
@ -698,7 +698,11 @@ mod test {
test_expr_to_val(vec![ test_expr_to_val(vec![
(Expression::Simple(Value::Int(1)), Val::Int(1)), (Expression::Simple(Value::Int(1)), Val::Int(1)),
(Expression::Simple(Value::Float(2.0)), Val::Float(2.0)), (Expression::Simple(Value::Float(2.0)), Val::Float(2.0)),
(Expression::Simple(Value::String("foo".to_string())), Val::String("foo".to_string())), (Expression::Simple(Value::String("foo".to_string())),
Val::String("foo".to_string())),
(Expression::Simple(Value::Tuple(vec![("bar".to_string(),
Expression::Simple(Value::Int(1)))])),
Val::Tuple(vec![("bar".to_string(), Rc::new(Val::Int(1)))])),
], Builder::new()); ], Builder::new());
} }