diff --git a/schala-lang/language/src/parsing/new.rs b/schala-lang/language/src/parsing/new.rs index 2882d0d..b8dd5f4 100644 --- a/schala-lang/language/src/parsing/new.rs +++ b/schala-lang/language/src/parsing/new.rs @@ -37,15 +37,37 @@ peg::parser! { __ expr:expression() { StatementKind::Expression(expr) } rule declaration() -> Declaration = - binding() / type_decl() / annotation() / func() + binding() / type_decl() / annotation() / func() / interface() / implementation() + + + rule implementation() -> Declaration = + "impl" _ interface:type_singleton_name() _ "for" _ type_name:type_identifier() _ block:decl_block() { + Declaration::Impl { type_name, interface_name: Some(interface), block } + + } / + "impl" _ type_name:type_identifier() _ block:decl_block() { + Declaration::Impl { type_name, interface_name: None, block } + } + + rule decl_block() -> Vec = + "{" __ decls:(func_declaration() ** (delimiter()+)) __ "}" { decls } + + rule interface() -> Declaration = + "interface" _ name:identifier() _ signatures:signature_block() { Declaration::Interface { name: rc_string(name), signatures } } + + rule signature_block() -> Vec = + "{" __ signatures:(func_signature() ** (delimiter()+)) __ "}" { signatures } rule func() -> Declaration = - sig:func_signature() __ body:block() { Declaration::FuncDecl(sig, body) } / + decl:func_declaration() { decl } / sig:func_signature() { Declaration::FuncSig(sig) } + rule func_declaration() -> Declaration = + sig:func_signature() __ body:block() { Declaration::FuncDecl(sig, body) } + //TODO handle operators rule func_signature() -> Signature = - "fn" _ name:identifier() "(" _ params:formal_params() _ ")" _ type_anno:type_anno()? { Signature { + _ "fn" _ name:identifier() "(" _ params:formal_params() _ ")" _ type_anno:type_anno()? { Signature { name: rc_string(name), operator: false, params, type_anno } } diff --git a/schala-lang/language/src/parsing/test.rs b/schala-lang/language/src/parsing/test.rs index e505eae..a219830 100644 --- a/schala-lang/language/src/parsing/test.rs +++ b/schala-lang/language/src/parsing/test.rs @@ -904,7 +904,7 @@ fn functions_with_default_args() { #[test] fn interface() { let glue = TypeIdentifier::Singleton(TypeSingletonName { name: rc("Glue"), params: vec![] }); - assert_ast!( + assert_ast2!( "interface Unglueable { fn unglue(a: Glue); fn mar(): Glue }", vec![decl(Declaration::Interface { name: rc("Unglueable"), @@ -923,48 +923,48 @@ fn interface() { #[test] fn impls() { - use Declaration::{FuncSig, Impl}; + use Declaration::{FuncDecl, Impl}; - assert_ast!( - "impl Heh { fn yolo(); fn swagg(); }", + let block = vec![ + FuncDecl(Signature { name: rc("yolo"), operator: false, params: vec![], type_anno: None }, + vec![].into()), + FuncDecl(Signature { name: rc("swagg"), operator: false, params: vec![], type_anno: None }, + vec![].into() + ) + ]; + + assert_ast2!( + "impl Heh { fn yolo() { }; fn swagg() { } }", vec![decl(Impl { type_name: ty_simple("Heh"), interface_name: None, - block: vec![ - FuncSig(Signature { name: rc("yolo"), operator: false, params: vec![], type_anno: None }), - FuncSig(Signature { name: rc("swagg"), operator: false, params: vec![], type_anno: None }) - ] + block: block.clone(), })] ); - assert_ast!( - "impl Heh { fn yolo(); fn swagg(); }", + //TODO `"impl Heh { fn yolo() { }; fn swagg() { }; }"` ought to work + assert_ast2!( + "impl Heh { fn yolo() { }; fn swagg() { } }", vec![decl(Impl { type_name: TypeIdentifier::Singleton(TypeSingletonName { name: rc("Heh"), params: vec![ty_simple("X")] }), interface_name: None, - block: vec![ - FuncSig(Signature { name: rc("yolo"), operator: false, params: vec![], type_anno: None }), - FuncSig(Signature { name: rc("swagg"), operator: false, params: vec![], type_anno: None }) - ] + block: block.clone(), })] ); - assert_ast!( - "impl Heh for Saraz { fn yolo(); fn swagg(); }", + assert_ast2!( + "impl Heh for Saraz { fn yolo() {}; fn swagg() {} }", vec![decl(Impl { type_name: ty_simple("Saraz"), interface_name: Some(TypeSingletonName { name: rc("Heh"), params: vec![] }), - block: vec![ - FuncSig(Signature { name: rc("yolo"), operator: false, params: vec![], type_anno: None }), - FuncSig(Signature { name: rc("swagg"), operator: false, params: vec![], type_anno: None }) - ] + block: block.clone(), })] ); - assert_ast!( + assert_ast2!( "impl Heh for (Int, Codepoint) {}", vec![decl(Impl { type_name: TypeIdentifier::Tuple(vec![ty_simple("Int"), ty_simple("Codepoint")]),