diff --git a/src/schala_lang/parsing.rs b/src/schala_lang/parsing.rs index d8536cb..a3e03e1 100644 --- a/src/schala_lang/parsing.rs +++ b/src/schala_lang/parsing.rs @@ -271,10 +271,11 @@ formal_param := IDENTIFIER type_anno+ binding_declaration: 'var' IDENTIFIER '=' expression | 'const' IDENTIFIER '=' expression -trait_declaration := 'trait' trait_name decl_block +trait_declaration := 'trait' trait_name signature_block impl_declaration := 'impl' IDENTIFIER decl_block | 'impl' trait_name 'for' IDENTIFIER decl_block decl_block := '{' (func_declaration)* '}' +signature_block := '{' (func_signature)* '}' trait_name := IDENTIFIER @@ -416,6 +417,9 @@ pub enum Declaration { trait_name: Option, block: Vec, }, + Trait { + signatures: Vec + } } #[derive(Debug, PartialEq, Clone)] @@ -696,7 +700,14 @@ impl Parser { }); parse_method!(trait_declaration(&mut self) -> ParseResult { - unimplemented!() + expect!(self, Keyword(Trait), "'trait'"); + let name = self.identifier()?; + let signatures = self.signature_block()?; + Ok(Declaration::Trait { signatures }) + }); + + parse_method!(signature_block(&mut self) -> ParseResult> { + Ok(delimited!(self, LCurlyBrace, '{', signature, Newline | Semicolon, RCurlyBrace, '}', nonstrict)) }); parse_method!(impl_declaration(&mut self) -> ParseResult { @@ -1299,6 +1310,17 @@ mod parse_tests { parse_error!("if A {a: 1} { b } else { c }"); } + #[test] + fn parsing_traits() { + parse_test!("trait Unglueable { fn unglue(a: Glue); fn mar(): Glue }", AST(vec![ + Declaration(Trait { + signatures: vec![ + Signature { name: rc!(unglue), params: vec![(rc!(a), Some(Singleton(TypeSingletonName { name: rc!(Glue), params: vec![] })))], type_anno: None }, + Signature { name: rc!(mar), params: vec![], type_anno: Some(Singleton(TypeSingletonName { name: rc!(Glue), params: vec![] })) }, + ] + }) + ])); + } #[test] fn parsing_impls() {