From 851d72cdd58a51adcf93bcd9a5956d82d3b5417d Mon Sep 17 00:00:00 2001 From: bnewbold Date: Mon, 26 Dec 2016 00:43:58 -0800 Subject: parser: refactor vec operations into hashset --- modelica-parser-lalrpop/src/ast.rs | 44 +++++++++++++++++------------------- modelica-parser-lalrpop/tests/ast.rs | 41 +++++++++++++++------------------ 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/modelica-parser-lalrpop/src/ast.rs b/modelica-parser-lalrpop/src/ast.rs index 7eb9dda..f31681e 100644 --- a/modelica-parser-lalrpop/src/ast.rs +++ b/modelica-parser-lalrpop/src/ast.rs @@ -1,7 +1,8 @@ use std::clone::Clone; use std::fmt::{Debug, Formatter, Error}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; +use std::iter::FromIterator; #[derive(Clone, PartialEq)] @@ -146,7 +147,7 @@ impl ModelicaModel { // the sole element on the LHS of an equation. // Bugs: // if a var is on LHS and RHS of same equation - pub fn get_free_vars(&self) -> Vec { + pub fn get_free_vars(&self) -> HashSet { // Start with components, and remove constants and parameters let vars = self.components.iter().filter(|v| match v.prefix { Some(ComponentPrefix::Constant) | Some(ComponentPrefix::Parameter) => false, @@ -164,39 +165,34 @@ impl ModelicaModel { } let vars = vars.filter(|v| !outputs.contains(&v.name)); - vars.map(|c| c.name.clone()).collect() + HashSet::from_iter(vars.map(|c| c.name.clone())) } } -fn union_strings(a: &Vec, b: &Vec) -> Vec { - let mut u = a.clone(); - for e in b { - if !(u.contains(&e)) { - u.push(e.clone()); - } - } - u -} - impl Expr { // Order is undefined - // TODO: should return a HashSet, not a Vec - pub fn identifiers(&self) -> Vec { + pub fn identifiers(&self) -> HashSet { use self::Expr::*; match *self { - Integer(_) | Float(_) | Boolean(_) | StringLiteral(_) => vec![], - Ident(ref s) => vec![s.clone()], + Integer(_) | Float(_) | Boolean(_) | StringLiteral(_) => HashSet::new(), + Ident(ref s) => { + let mut hs = HashSet::new(); + hs.insert(s.to_string()); + hs + }, Der(ref e) | Sign(ref e) => e.identifiers(), MathUnaryExpr(_, ref e) => e.identifiers(), BinExpr(_, ref e1, ref e2) => { - union_strings(&e1.identifiers(), &e2.identifiers()) + let mut hs = e1.identifiers(); + hs.extend(e2.identifiers()); + hs }, Array(ref el) => { - let mut all: Vec = vec![]; + let mut all: HashSet = HashSet::new(); for e in el { - all.append(&mut e.identifiers()); + all.extend(e.identifiers()); } all } @@ -204,15 +200,17 @@ impl Expr { } pub fn contains(&self, ident: &str) -> bool{ - self.identifiers().contains(&ident.to_string()) + self.identifiers().contains(ident) } } impl SimpleEquation { // Order is undefined - pub fn identifiers(&self) -> Vec { - union_strings(&self.lhs.identifiers(), &self.rhs.identifiers()) + pub fn identifiers(&self) -> HashSet { + let mut hs = self.lhs.identifiers(); + hs.extend(self.rhs.identifiers()); + hs } pub fn contains(&self, ident: &str) -> bool{ diff --git a/modelica-parser-lalrpop/tests/ast.rs b/modelica-parser-lalrpop/tests/ast.rs index 51c1014..d551142 100644 --- a/modelica-parser-lalrpop/tests/ast.rs +++ b/modelica-parser-lalrpop/tests/ast.rs @@ -5,52 +5,47 @@ use std::collections::HashSet; use std::iter::FromIterator; use modelica_parser::*; -fn set_eq(a: Vec, b: Vec) -> bool { - let set_a: HashSet = HashSet::from_iter(a); - let set_b: HashSet = HashSet::from_iter(b); - return set_a == set_b; -} #[test] fn test_expr_identifiers() { use modelica_parser::Expr::*; - assert!(set_eq( - vec![], - Integer(0).identifiers())); - assert!(set_eq( - vec!["x".to_string()], - Ident("x".to_string()).identifiers())); - assert!(set_eq( - vec!["x".to_string(), "y".to_string(), "z".to_string()], + assert_eq!( + HashSet::new(), + Integer(0).identifiers()); + assert_eq!( + HashSet::from_iter(vec!["x".to_string()]), + Ident("x".to_string()).identifiers()); + assert_eq!( + HashSet::from_iter(vec!["x".to_string(), "y".to_string(), "z".to_string()]), BinExpr(BinOperator::Add, Box::new(Sign(Box::new(Ident("z".to_string())))), Box::new(BinExpr(BinOperator::Add, Box::new(Sign(Box::new(Ident("x".to_string())))), - Box::new(Sign(Box::new(Ident("y".to_string()))))))).identifiers())); - assert!(set_eq( - vec!["z".to_string()], + Box::new(Sign(Box::new(Ident("y".to_string()))))))).identifiers()); + assert_eq!( + HashSet::from_iter(vec!["z".to_string()]), BinExpr(BinOperator::Add, Box::new(Ident("z".to_string())), - Box::new(Ident("z".to_string()))).identifiers())); + Box::new(Ident("z".to_string()))).identifiers()); } #[test] fn test_eqn_identifiers() { use modelica_parser::Expr::*; - assert!(set_eq( - vec![], + assert_eq!( + HashSet::new(), SimpleEquation{ lhs: Integer(0), rhs: Integer(0), - }.identifiers())); - assert!(set_eq( - vec!["z".to_string()], + }.identifiers()); + assert_eq!( + HashSet::from_iter(vec!["z".to_string()]), SimpleEquation{ lhs: Ident("z".to_string()), rhs: BinExpr(BinOperator::Add, Box::new(Ident("z".to_string())), Box::new(Ident("z".to_string()))), - }.identifiers())); + }.identifiers()); } -- cgit v1.2.3