Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor a ton of redundant code by using macros
- Loading branch information
Showing
12 changed files
with
1,193 additions
and
1,795 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,73 @@ | ||
use types::*; | ||
use Parse; | ||
use common::*; | ||
use attribute::*; | ||
use attribute::ExtendedAttributeList; | ||
use common::{Default, Identifier, Punctuated}; | ||
use types::{AttributedType, Type}; | ||
|
||
/// Parses a list of argument. Ex: `double v1, double v2, double v3, optional double alpha` | ||
pub type ArgumentList = Punctuated<Argument, term!(,)>; | ||
|
||
/// Parses an argument. Ex: `double v1|double... v1s` | ||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)] | ||
pub enum Argument { | ||
Single(SingleArgument), | ||
Variadic(VariadicArgument) | ||
} | ||
|
||
impl Parse for Argument { | ||
named!(parse -> Self, alt!( | ||
weedle!(SingleArgument) => {|inner| Argument::Single(inner)} | | ||
weedle!(VariadicArgument) => {|inner| Argument::Variadic(inner)} | ||
)); | ||
} | ||
|
||
/// Parses `[attributes]? optional? attributedtype identifier ( = default )?` | ||
/// | ||
/// Note: `= default` is only allowed if `optional` is present | ||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)] | ||
pub struct SingleArgument { | ||
pub attributes: Option<ExtendedAttributeList>, | ||
pub optional: Option<term!(optional)>, | ||
pub type_: AttributedType, | ||
pub identifier: Identifier, | ||
pub default: Option<Default> | ||
} | ||
|
||
impl Parse for SingleArgument { | ||
named!(parse -> Self, do_parse!( | ||
attributes: weedle!(Option<ExtendedAttributeList>) >> | ||
optional: weedle!(Option<term!(optional)>) >> | ||
type_: weedle!(AttributedType) >> | ||
identifier: weedle!(Identifier) >> | ||
default: opt_flat!(cond_reduce!(optional.is_some(), weedle!(Option<Default>))) >> | ||
(SingleArgument { attributes, optional, type_, identifier, default }) | ||
)); | ||
} | ||
|
||
/// Parses `[attributes]? type... identifier` | ||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)] | ||
pub struct VariadicArgument { | ||
pub attributes: Option<ExtendedAttributeList>, | ||
pub type_: Type, | ||
pub ellipsis: term!(...), | ||
pub identifier: Identifier | ||
} | ||
|
||
impl Parse for VariadicArgument { | ||
named!(parse -> Self, do_parse!( | ||
attributes: weedle!(Option<ExtendedAttributeList>) >> | ||
type_: weedle!(Type) >> | ||
ellipsis: weedle!(term!(...)) >> | ||
identifier: weedle!(Identifier) >> | ||
(VariadicArgument { attributes, type_, ellipsis, identifier }) | ||
)); | ||
ast_types! { | ||
/// Parses an argument. Ex: `double v1|double... v1s` | ||
enum Argument { | ||
/// Parses `[attributes]? optional? attributedtype identifier ( = default )?` | ||
/// | ||
/// Note: `= default` is only allowed if `optional` is present | ||
Single(struct SingleArgument { | ||
attributes: Option<ExtendedAttributeList>, | ||
optional: Option<term!(optional)>, | ||
type_: AttributedType, | ||
identifier: Identifier, | ||
default: Option<Default> = map!(cond!(optional.is_some(), weedle!(Option<Default>)), |default| default.unwrap_or(None)), | ||
}), | ||
/// Parses `[attributes]? type... identifier` | ||
Variadic(struct VariadicArgument { | ||
attributes: Option<ExtendedAttributeList>, | ||
type_: Type, | ||
ellipsis: term!(...), | ||
identifier: Identifier, | ||
}), | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
use literal::{DecLit, DefaultValue, IntegerLit}; | ||
use Parse; | ||
|
||
test!(should_parse_single_argument { "optional short a" => | ||
test!(should_parse_single_argument { "short a" => | ||
""; | ||
SingleArgument; | ||
attributes.is_none(); | ||
optional.is_some(); | ||
identifier.name == "a"; | ||
optional.is_none(); | ||
identifier.0 == "a"; | ||
default.is_none(); | ||
}); | ||
|
||
test!(should_parse_variadic_argument { "short... a" => | ||
""; | ||
VariadicArgument; | ||
attributes.is_none(); | ||
identifier.name == "a"; | ||
identifier.0 == "a"; | ||
}); | ||
|
||
test!(should_parse_optional_single_argument { "optional short a" => | ||
""; | ||
SingleArgument; | ||
attributes.is_none(); | ||
optional.is_some(); | ||
identifier.0 == "a"; | ||
default.is_none(); | ||
}); | ||
|
||
test!(should_parse_optional_single_argument_with_default { "optional short a = 5" => | ||
""; | ||
SingleArgument; | ||
attributes.is_none(); | ||
optional.is_some(); | ||
identifier.0 == "a"; | ||
default == Some(Default { | ||
assign: term!(=), | ||
value: DefaultValue::Integer(IntegerLit::Dec(DecLit("5".to_string()))), | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,156 +1,89 @@ | ||
use Parse; | ||
use common::*; | ||
use argument::*; | ||
use argument::ArgumentList; | ||
use common::{Braced, Bracketed, Identifier, Punctuated}; | ||
|
||
/// Parses a list of attributes. Ex: `[ attribute1, attribute2 ]` | ||
pub type ExtendedAttributeList = Bracketed<Punctuated<ExtendedAttribute, term!(,)>>; | ||
|
||
/// Parses on of the forms of attribute | ||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)] | ||
pub enum ExtendedAttribute { | ||
ArgList(ExtendedAttributeArgList), | ||
NamedArgList(ExtendedAttributeNamedArgList), | ||
IdentList(ExtendedAttributeIdentList), | ||
Ident(ExtendedAttributeIdent), | ||
NoArgs(ExtendedAttributeNoArgs), | ||
} | ||
|
||
impl Parse for ExtendedAttribute { | ||
named!(parse -> Self, alt!( | ||
weedle!(ExtendedAttributeArgList) => {|inner| ExtendedAttribute::ArgList(inner)} | | ||
weedle!(ExtendedAttributeNamedArgList) => {|inner| ExtendedAttribute::NamedArgList(inner)} | | ||
weedle!(ExtendedAttributeIdentList) => {|inner| ExtendedAttribute::IdentList(inner)} | | ||
weedle!(ExtendedAttributeIdent) => {|inner| ExtendedAttribute::Ident(inner)} | | ||
weedle!(ExtendedAttributeNoArgs) => {|inner| ExtendedAttribute::NoArgs(inner)} | ||
)); | ||
} | ||
|
||
/// Parses a named argument list. Ex: `NamedConstructor=Image((DOMString src))` | ||
/// | ||
/// (( )) means ( ) chars | ||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)] | ||
pub struct ExtendedAttributeNamedArgList { | ||
pub lhs_identifier: Identifier, | ||
pub assign: term!(=), | ||
pub rhs_identifier: Identifier, | ||
pub args: Braced<ArgumentList>, | ||
} | ||
|
||
impl Parse for ExtendedAttributeNamedArgList { | ||
named!(parse -> Self, do_parse!( | ||
lhs_identifier: weedle!(Identifier) >> | ||
assign: weedle!(term!(=)) >> | ||
rhs_identifier: weedle!(Identifier) >> | ||
args: weedle!(Braced<ArgumentList>) >> | ||
(ExtendedAttributeNamedArgList { lhs_identifier, assign, rhs_identifier, args }) | ||
)); | ||
} | ||
|
||
/// Parses an identifier list. Ex: `Exposed=((Window,Worker))` | ||
/// | ||
/// (( )) means ( ) chars | ||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)] | ||
pub struct ExtendedAttributeIdentList { | ||
pub identifier: Identifier, | ||
pub assign: term!(=), | ||
pub list: Braced<IdentifierList> | ||
} | ||
|
||
impl Parse for ExtendedAttributeIdentList { | ||
named!(parse -> Self, do_parse!( | ||
identifier: weedle!(Identifier) >> | ||
assign: weedle!(term!(=)) >> | ||
list: weedle!(Braced<IdentifierList>) >> | ||
(ExtendedAttributeIdentList { identifier, assign, list }) | ||
)); | ||
} | ||
|
||
/// Matches comma separated identifier list | ||
pub type IdentifierList = Punctuated<Identifier, term!(,)>; | ||
|
||
/// Parses an attribute with an identifier. Ex: `PutForwards=name` | ||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)] | ||
pub struct ExtendedAttributeIdent { | ||
pub lhs_identifier: Identifier, | ||
pub assign: term!(=), | ||
pub rhs_identifier: Identifier | ||
} | ||
|
||
impl Parse for ExtendedAttributeIdent { | ||
named!(parse -> Self, do_parse!( | ||
lhs_identifier: weedle!(Identifier) >> | ||
assign: weedle!(term!(=)) >> | ||
rhs_identifier: weedle!(Identifier) >> | ||
(ExtendedAttributeIdent { lhs_identifier, assign, rhs_identifier }) | ||
)); | ||
} | ||
|
||
/// Parses an argument list. Ex: `Constructor((double x, double y))` | ||
/// | ||
/// (( )) means ( ) chars | ||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)] | ||
pub struct ExtendedAttributeArgList { | ||
pub identifier: Identifier, | ||
pub args: Braced<ArgumentList> | ||
} | ||
|
||
impl Parse for ExtendedAttributeArgList { | ||
named!(parse -> Self, do_parse!( | ||
identifier: weedle!(Identifier) >> | ||
args: weedle!(Braced<ArgumentList>) >> | ||
(ExtendedAttributeArgList { identifier, args }) | ||
)); | ||
} | ||
|
||
/// Parses a plain attribute. Ex: `Replaceable` | ||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone)] | ||
pub struct ExtendedAttributeNoArgs { | ||
pub identifier: Identifier | ||
} | ||
|
||
impl Parse for ExtendedAttributeNoArgs { | ||
named!(parse -> Self, do_parse!( | ||
identifier: weedle!(Identifier) >> | ||
(ExtendedAttributeNoArgs { identifier }) | ||
)); | ||
ast_types! { | ||
/// Parses on of the forms of attribute | ||
enum ExtendedAttribute { | ||
/// Parses an argument list. Ex: `Constructor((double x, double y))` | ||
/// | ||
/// (( )) means ( ) chars | ||
ArgList(struct ExtendedAttributeArgList { | ||
identifier: Identifier, | ||
args: Braced<ArgumentList>, | ||
}), | ||
/// Parses a named argument list. Ex: `NamedConstructor=Image((DOMString src))` | ||
/// | ||
/// (( )) means ( ) chars | ||
NamedArgList(struct ExtendedAttributeNamedArgList { | ||
lhs_identifier: Identifier, | ||
assign: term!(=), | ||
rhs_identifier: Identifier, | ||
args: Braced<ArgumentList>, | ||
|
||
}), | ||
/// Parses an identifier list. Ex: `Exposed=((Window,Worker))` | ||
/// | ||
/// (( )) means ( ) chars | ||
IdentList(struct ExtendedAttributeIdentList { | ||
identifier: Identifier, | ||
assign: term!(=), | ||
list: Braced<IdentifierList>, | ||
}), | ||
/// Parses an attribute with an identifier. Ex: `PutForwards=name` | ||
Ident(struct ExtendedAttributeIdent { | ||
lhs_identifier: Identifier, | ||
assign: term!(=), | ||
rhs_identifier: Identifier, | ||
}), | ||
/// Parses a plain attribute. Ex: `Replaceable` | ||
NoArgs(struct ExtendedAttributeNoArgs( | ||
Identifier, | ||
)), | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::*; | ||
use Parse; | ||
|
||
test!(should_parse_attribute_no_args { "Replaceable" => | ||
""; | ||
ExtendedAttributeNoArgs; | ||
identifier.name == "Replaceable"; | ||
ExtendedAttributeNoArgs => ExtendedAttributeNoArgs(Identifier("Replaceable".to_string())) | ||
}); | ||
|
||
test!(should_parse_attribute_arg_list { "Constructor(double x, double y)" => | ||
""; | ||
ExtendedAttributeArgList; | ||
identifier.name == "Constructor"; | ||
identifier.0 == "Constructor"; | ||
args.body.list.len() == 2; | ||
}); | ||
|
||
test!(should_parse_attribute_ident { "PutForwards=name" => | ||
""; | ||
ExtendedAttributeIdent; | ||
lhs_identifier.name == "PutForwards"; | ||
rhs_identifier.name == "name"; | ||
lhs_identifier.0 == "PutForwards"; | ||
rhs_identifier.0 == "name"; | ||
}); | ||
|
||
test!(should_parse_ident_list { "Exposed=(Window,Worker)" => | ||
""; | ||
ExtendedAttributeIdentList; | ||
identifier.name == "Exposed"; | ||
identifier.0 == "Exposed"; | ||
list.body.list.len() == 2; | ||
}); | ||
|
||
test!(should_parse_named_arg_list { "NamedConstructor=Image(DOMString src)" => | ||
""; | ||
ExtendedAttributeNamedArgList; | ||
lhs_identifier.name == "NamedConstructor"; | ||
rhs_identifier.name == "Image"; | ||
lhs_identifier.0 == "NamedConstructor"; | ||
rhs_identifier.0 == "Image"; | ||
args.body.list.len() == 1; | ||
}); | ||
} |
Oops, something went wrong.