Compare commits

..

2 Commits

Author SHA1 Message Date
Greg Shuflin
9adae9c262 Disallow empty import groups 2021-11-21 02:30:45 -08:00
Greg Shuflin
91985df449 Fix various parser bugs 2021-11-21 02:26:30 -08:00
3 changed files with 13 additions and 17 deletions

View File

@ -197,7 +197,7 @@ fn import(input: Span) -> ParseResult<ImportSpecifier> {
map( map(
preceded( preceded(
tag("::"), tag("::"),
delimited(char('{'), separated_list0(tok(char(',')), identifier), char('}')), delimited(char('{'), cut(separated_list1(tok(char(',')), identifier)), char('}')),
), ),
|names| ImportedNames::List(names.into_iter().map(|n| rc_string(n.fragment())).collect()), |names| ImportedNames::List(names.into_iter().map(|n| rc_string(n.fragment())).collect()),
), ),

View File

@ -37,7 +37,7 @@ peg::parser! {
//Note - this is a hack, ideally the rule `rule block() -> Block = "{" _ items:(statement() ** //Note - this is a hack, ideally the rule `rule block() -> Block = "{" _ items:(statement() **
//delimiter()) _ "}" { items.into() }` would've worked, but it doesn't. //delimiter()) _ "}" { items.into() }` would've worked, but it doesn't.
pub rule block(parser: &mut Parser) -> Block = pub rule block(parser: &mut Parser) -> Block =
"{" __ items:block_item(parser)* __ "}" { items.into() } / "{" __ items:(statement(parser) ** delimiter()) delimiter()? __ "}" { items.into() } /
"{" __ stmt:statement(parser) __ "}" { vec![stmt].into() } "{" __ stmt:statement(parser) __ "}" { vec![stmt].into() }
rule block_item(parser: &mut Parser) -> Statement = rule block_item(parser: &mut Parser) -> Statement =
@ -78,7 +78,13 @@ peg::parser! {
rule import_suffix() -> ImportedNames = rule import_suffix() -> ImportedNames =
"::*" { ImportedNames::All } / "::*" { ImportedNames::All } /
"::{" __ names:(identifier() ** (_ "," _)) __ "}" { ImportedNames::List(names.into_iter().map(rc_string).collect()) } "::{" __ names:(identifier() ** (_ "," _)) __ "}" {?
if names.is_empty() {
Err("import groups must have at least one item")
} else {
Ok(ImportedNames::List(names.into_iter().map(rc_string).collect()))
}
}
rule declaration(parser: &mut Parser) -> Declaration = rule declaration(parser: &mut Parser) -> Declaration =
binding(parser) / type_decl(parser) / annotation(parser) / func(parser) / interface(parser) / binding(parser) / type_decl(parser) / annotation(parser) / func(parser) / interface(parser) /
@ -97,7 +103,7 @@ peg::parser! {
} }
rule decl_block(parser: &mut Parser) -> Vec<Declaration> = rule decl_block(parser: &mut Parser) -> Vec<Declaration> =
"{" __ decls:(func_declaration(parser) ** (delimiter()+)) __ "}" { decls } "{" __ decls:(func_declaration(parser) ** (delimiter()+)) delimiter()? __ "}" { decls }
rule interface(parser: &mut Parser) -> Declaration = rule interface(parser: &mut Parser) -> Declaration =
"interface" _ name:identifier() _ signatures:signature_block(parser) { Declaration::Interface { name: rc_string(name), signatures } } "interface" _ name:identifier() _ signatures:signature_block(parser) { Declaration::Interface { name: rc_string(name), signatures } }

View File

@ -519,9 +519,8 @@ fn single_param_lambda() {
fn complex_lambdas() { fn complex_lambdas() {
use ExpressionKind::*; use ExpressionKind::*;
//TODO support this without the semicolon after the lambda
assert_ast! { assert_ast! {
r#"fn wahoo() { let a = 10; \(x) { x + a }; } r#"fn wahoo() { let a = 10; \(x) { x + a } }
wahoo()(3) "#, wahoo()(3) "#,
vec![ vec![
fn_decl(Signature { name: rc("wahoo"), operator: false, type_anno: None, params: vec![] }, fn_decl(Signature { name: rc("wahoo"), operator: false, type_anno: None, params: vec![] },
@ -991,9 +990,8 @@ fn impls() {
vec![decl(Impl { type_name: ty_simple("Heh"), interface_name: None, block: block.clone() })] vec![decl(Impl { type_name: ty_simple("Heh"), interface_name: None, block: block.clone() })]
); );
//TODO `"impl Heh<X> { fn yolo() { }; fn swagg() { }; }"` ought to work
assert_ast!( assert_ast!(
"impl Heh<X> { fn yolo() { }; fn swagg() { } }", "impl Heh<X> { fn yolo() { }; fn swagg() { }; }",
vec![decl(Impl { vec![decl(Impl {
type_name: TypeIdentifier::Singleton(TypeSingletonName { type_name: TypeIdentifier::Singleton(TypeSingletonName {
name: rc("Heh"), name: rc("Heh"),
@ -1108,15 +1106,7 @@ fn imports() {
}))] }))]
}; };
//TODO this shouldn't be legal assert_fail!("import bespouri::{}");
assert_ast! {
"import bespouri::{}",
vec![stmt(StatementKind::Import(ImportSpecifier {
id: Default::default(),
path_components: vec![rc("bespouri")],
imported_names: ImportedNames::List(vec![]),
}))]
};
assert_ast! { assert_ast! {
"import bespouri::*", "import bespouri::*",