Refactor: Finish converting all the enum types to tuple around struct pattern.

This commit is contained in:
Jeremy Wall 2017-11-29 19:07:36 -06:00
parent 2b01e8611b
commit fffdad589c
4 changed files with 65 additions and 42 deletions

View File

@ -16,7 +16,6 @@ organiztion for a given configuration structure. Some options here could be
# Minor Fixes and Polish # Minor Fixes and Polish
* Full selector support. (i.e. expressions in the selector parts) * Full selector support. (i.e. expressions in the selector parts)
* Error Reporting with Line, Column, and File information.
* JSON export * JSON export
* YAML export * YAML export
* Error Reporting with Line, Column, and File information.
* All enums should use the tuple wrapping a concrete type pattern.

View File

@ -395,6 +395,18 @@ pub enum Expression {
Select(SelectDef), Select(SelectDef),
} }
#[derive(Debug,PartialEq)]
pub struct LetDef {
pub name: Token,
pub value: Expression,
}
#[derive(Debug,PartialEq)]
pub struct ImportDef {
pub path: Token,
pub name: Token,
}
/// Statement encodes a parsed Statement in the UCG AST. /// Statement encodes a parsed Statement in the UCG AST.
#[derive(Debug,PartialEq)] #[derive(Debug,PartialEq)]
pub enum Statement { pub enum Statement {
@ -402,16 +414,10 @@ pub enum Statement {
Expression(Expression), Expression(Expression),
// Named bindings // Named bindings
Let { Let(LetDef),
name: Token,
value: Expression,
},
// Include a file. // Include a file.
Import { Import(ImportDef),
path: String,
name: Token,
},
} }
#[cfg(test)] #[cfg(test)]

View File

@ -355,7 +355,7 @@ impl Builder {
fn build_stmt(&mut self, stmt: &Statement) -> BuildResult { fn build_stmt(&mut self, stmt: &Statement) -> BuildResult {
match stmt { match stmt {
&Statement::Let { name: ref sym, value: ref expr } => { &Statement::Let(LetDef{ name: ref sym, value: ref expr }) => {
let val = try!(self.eval_expr(expr)); let val = try!(self.eval_expr(expr));
self.last = Some(val.clone()); self.last = Some(val.clone());
match self.out.entry(sym.into()) { match self.out.entry(sym.into()) {
@ -370,17 +370,17 @@ impl Builder {
} }
} }
} }
&Statement::Import { path: ref val, name: ref sym } => { &Statement::Import(ImportDef{ path: ref val, name: ref sym }) => {
if !self.files.contains(val) { if !self.files.contains(&val.fragment) {
// Only parse the file once on import. // Only parse the file once on import.
let positioned_sym = sym.into(); let positioned_sym = sym.into();
if self.assets.get(&positioned_sym).is_none() { if self.assets.get(&positioned_sym).is_none() {
let mut b = Self::new(); let mut b = Self::new();
try!(b.build_file(&val)); try!(b.build_file(&val.fragment));
let fields: Vec<(Positioned<String>, Rc<Val>)> = b.out.drain().collect(); let fields: Vec<(Positioned<String>, Rc<Val>)> = b.out.drain().collect();
let result = Rc::new(Val::Tuple(fields)); let result = Rc::new(Val::Tuple(fields));
self.assets.entry(positioned_sym).or_insert(result.clone()); self.assets.entry(positioned_sym).or_insert(result.clone());
self.files.insert(val.clone()); self.files.insert(val.fragment.clone());
self.last = Some(result); self.last = Some(result);
} }
} }
@ -1241,14 +1241,14 @@ mod test {
#[test] #[test]
fn test_let_statement() { fn test_let_statement() {
let mut b = Builder::new(); let mut b = Builder::new();
let stmt = Statement::Let { let stmt = Statement::Let(LetDef {
name: Token::new("foo", name: Token::new("foo",
Position { Position {
line: 1, line: 1,
column: 1, column: 1,
}), }),
value: Expression::Simple(Value::String(make_value_node("bar".to_string(), 1, 1))), value: Expression::Simple(Value::String(make_value_node("bar".to_string(), 1, 1))),
}; });
b.build_stmt(&stmt).unwrap(); b.build_stmt(&stmt).unwrap();
test_expr_to_val(vec![ test_expr_to_val(vec![
(Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1))), (Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1))),

View File

@ -501,10 +501,10 @@ named!(expression_statement( Span ) -> Statement,
); );
fn tuple_to_let(t: (Token, Expression)) -> ParseResult<Statement> { fn tuple_to_let(t: (Token, Expression)) -> ParseResult<Statement> {
Ok(Statement::Let { Ok(Statement::Let(LetDef {
name: t.0, name: t.0,
value: t.1, value: t.1,
}) }))
} }
named!(let_statement( Span ) -> Statement, named!(let_statement( Span ) -> Statement,
@ -521,10 +521,10 @@ named!(let_statement( Span ) -> Statement,
); );
fn tuple_to_import(t: (Token, Token)) -> ParseResult<Statement> { fn tuple_to_import(t: (Token, Token)) -> ParseResult<Statement> {
Ok(Statement::Import { Ok(Statement::Import(ImportDef {
name: t.0, name: t.0,
path: t.1.fragment.to_string(), path: t.1,
}) }))
} }
named!(import_statement( Span ) -> Statement, named!(import_statement( Span ) -> Statement,
@ -645,8 +645,14 @@ mod test {
line: 1, line: 1,
fragment: "", fragment: "",
}, },
Statement::Import{ Statement::Import(ImportDef{
path: "foo".to_string(), path: Token{
fragment: "foo".to_string(),
pos: Position {
line: 1,
column: 8,
}
},
name: Token{ name: Token{
fragment: "foo".to_string(), fragment: "foo".to_string(),
pos: Position{ pos: Position{
@ -654,7 +660,7 @@ mod test {
column: 17, column: 17,
}, },
} }
} })
) )
); );
@ -669,7 +675,7 @@ mod test {
line: 1, line: 1,
fragment: "", fragment: "",
}, },
Statement::Let{ Statement::Let(LetDef{
name: Token{ name: Token{
fragment: "foo".to_string(), fragment: "foo".to_string(),
pos: Position { pos: Position {
@ -678,7 +684,7 @@ mod test {
}, },
}, },
value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 11}))) value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 11})))
})); })));
stmt = "1.0;"; stmt = "1.0;";
let input = LocatedSpan::new(stmt); let input = LocatedSpan::new(stmt);
assert_eq!(statement(input), assert_eq!(statement(input),
@ -706,8 +712,14 @@ mod test {
line: 1, line: 1,
offset: import_stmt.len(), offset: import_stmt.len(),
}, },
Statement::Import{ Statement::Import(ImportDef{
path: "foo".to_string(), path: Token{
fragment: "foo".to_string(),
pos: Position{
line: 1,
column: 8,
},
},
name: Token{ name: Token{
fragment: "foo".to_string(), fragment: "foo".to_string(),
pos: Position{ pos: Position{
@ -715,7 +727,7 @@ mod test {
column: 17, column: 17,
}, },
} }
} })
) )
); );
} }
@ -738,7 +750,7 @@ mod test {
offset: let_stmt.len(), offset: let_stmt.len(),
line: 1, line: 1,
}, },
Statement::Let{name: Token{ Statement::Let(LetDef{name: Token{
fragment: "foo".to_string(), fragment: "foo".to_string(),
pos: Position{ pos: Position{
line: 1, line: 1,
@ -746,7 +758,7 @@ mod test {
}, },
}, },
value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 11}))) value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 11})))
})); })));
let_stmt = "let foo= 1.0;"; let_stmt = "let foo= 1.0;";
assert_eq!(let_statement(LocatedSpan::new(let_stmt)), assert_eq!(let_statement(LocatedSpan::new(let_stmt)),
@ -755,14 +767,14 @@ mod test {
offset: let_stmt.len(), offset: let_stmt.len(),
line: 1, line: 1,
}, },
Statement::Let{name: Token{ Statement::Let(LetDef{name: Token{
fragment: "foo".to_string(), fragment: "foo".to_string(),
pos: Position{ pos: Position{
line: 1, line: 1,
column: 5, column: 5,
} }
}, },
value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))})); value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))})));
let_stmt = "let foo =1.0;"; let_stmt = "let foo =1.0;";
assert_eq!(let_statement(LocatedSpan::new(let_stmt)), assert_eq!(let_statement(LocatedSpan::new(let_stmt)),
IResult::Done(LocatedSpan{ IResult::Done(LocatedSpan{
@ -770,14 +782,14 @@ mod test {
offset: let_stmt.len(), offset: let_stmt.len(),
line: 1, line: 1,
}, },
Statement::Let{name: Token{ Statement::Let(LetDef{name: Token{
fragment: "foo".to_string(), fragment: "foo".to_string(),
pos: Position{ pos: Position{
line: 1, line: 1,
column: 5, column: 5,
} }
}, },
value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))})); value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))})));
} }
#[test] #[test]
@ -1444,8 +1456,14 @@ mod test {
assert_eq!(tpl.0.fragment, ""); assert_eq!(tpl.0.fragment, "");
assert_eq!(tpl.1, assert_eq!(tpl.1,
vec![ vec![
Statement::Import{ Statement::Import(ImportDef{
path: "mylib".to_string(), path: Token{
fragment: "mylib".to_string(),
pos: Position{
line: 1,
column: 8,
}
},
name: Token{ name: Token{
fragment: "lib".to_string(), fragment: "lib".to_string(),
pos: Position{ pos: Position{
@ -1453,8 +1471,8 @@ mod test {
column: 19, column: 19,
} }
} }
}, }),
Statement::Let{ Statement::Let(LetDef{
name: Token{ name: Token{
fragment: "foo".to_string(), fragment: "foo".to_string(),
pos: Position{ pos: Position{
@ -1463,7 +1481,7 @@ mod test {
} }
}, },
value: Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 33}))) value: Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 33})))
}, }),
Statement::Expression( Statement::Expression(
Expression::Binary( Expression::Binary(
BinaryOpDef{ BinaryOpDef{