diff --git a/compiler/pipec-ast/src/ast/mod.rs b/compiler/pipec-ast/src/ast/mod.rs index 9c5cfd4..6b72655 100644 --- a/compiler/pipec-ast/src/ast/mod.rs +++ b/compiler/pipec-ast/src/ast/mod.rs @@ -78,6 +78,7 @@ impl<'this> ASTGenerator<'this> { Token::FunctionKeyword => self.consume_function_keyword(), Token::PublicKeyword => self.consume_public_keyword(), Token::TypeKeyword => self.consume_type_keyword(), + Token::TraitKeyword => self.consume_trait_keyword(), Token::AtSign => self.consume_attributes(), _v => { println!("{_v:#?}"); @@ -88,6 +89,38 @@ impl<'this> ASTGenerator<'this> { } } + #[inline] + pub(crate) fn consume_trait_keyword(&mut self) -> ASTNode { + self.advance_stream(); + self.consume_whitespace(); + let name = self.must_ident(); + let generics = self.consume_generics(); + self.consume_whitespace(); + let mut supertraits = Traits::default(); + if self.next_is(Token::Colon) { + self.advance_stream(); + supertraits = self.consume_traits(); + } + self.consume_whitespace(); + self.must(Token::LeftCurly); + let mut nodes = Vec::new(); + loop { + self.consume_whitespace(); + if self.peek_stream() == &Some(Token::RightCurly) { + self.advance_stream(); + break; + } + nodes.push(self.parse_value()); + } + let tree = ASTTree::new(nodes, self.src); + ASTNode::TraitDeclaration { + name, + generics, + supertraits, + tree, + } + } + #[inline] pub(crate) fn consume_attributes(&mut self) -> ASTNode { let mut attributes = Vec::new(); @@ -317,7 +350,7 @@ impl<'this> ASTGenerator<'this> { v => todo!("{v:#?}"), } } - Some(Token::RightSquare) => { + Some(Token::RightSquare) | Some(Token::RightCurly) => { break; } _ => todo!(), @@ -342,7 +375,7 @@ impl<'this> ASTGenerator<'this> { continue; } } - Some(Token::Comma) | Some(Token::RightSquare) => { + Some(Token::Comma) | Some(Token::RightSquare) | Some(Token::LeftCurly) => { break; } v => todo!("{v:#?}"), @@ -1288,6 +1321,12 @@ pub enum ASTNode { generics: Generics, subtype: SubType, }, + TraitDeclaration { + name: Span, + generics: Generics, + supertraits: Traits, + tree: ASTTree, + }, Public(Box), Attributed(Vec, Box), EOF, diff --git a/compiler/pipec-ast/src/tokenizer/mod.rs b/compiler/pipec-ast/src/tokenizer/mod.rs index 5563a30..2586643 100644 --- a/compiler/pipec-ast/src/tokenizer/mod.rs +++ b/compiler/pipec-ast/src/tokenizer/mod.rs @@ -435,6 +435,7 @@ impl<'chars> Tokenizer<'chars> { "immutable" => ImmutableKeyword, "switch" => SwitchKeyword, "type" => TypeKeyword, + "trait" => TraitKeyword, _ => Token::Ident(input), } } @@ -562,6 +563,8 @@ pub enum Token { SwitchKeyword, /// type TypeKeyword, + /// trait + TraitKeyword, /// 21213 Digit { val: Span, digittype: DigitType }, /// things_like_this or this_2 diff --git a/compiler/pipec-tests/src/ast/mod.rs b/compiler/pipec-tests/src/ast/mod.rs index e50318f..5b6b87a 100644 --- a/compiler/pipec-tests/src/ast/mod.rs +++ b/compiler/pipec-tests/src/ast/mod.rs @@ -1,4 +1,5 @@ mod functiondeclaration; mod generics; +mod traits; mod variablemutability; mod viewportdeclaration; diff --git a/compiler/pipec-tests/src/ast/traits/mod.rs b/compiler/pipec-tests/src/ast/traits/mod.rs new file mode 100644 index 0000000..14a198f --- /dev/null +++ b/compiler/pipec-tests/src/ast/traits/mod.rs @@ -0,0 +1,4 @@ +#[test] +fn test_traits() { + crate::test_file_generation!("traits.pipec"); +} diff --git a/compiler/pipec-tests/src/ast/traits/traits.pipec b/compiler/pipec-tests/src/ast/traits/traits.pipec new file mode 100644 index 0000000..6903ffd --- /dev/null +++ b/compiler/pipec-tests/src/ast/traits/traits.pipec @@ -0,0 +1,144 @@ +trait Basic { + function new() => unsigned32 {} +} + +trait WithGeneric[T] { + function new() => unsigned32 {} +} + +trait WithGenericWithTrait[T : Trait] { + function new() => unsigned32 {} +} + +trait WithGenericWithMultipleTraits[T : Trait1 + Trait2 + Trait3] { + function new() => unsigned32 {} +} + +trait WithMultipleGenerics[T,U] { + function new() => unsigned32 {} +} + +trait WithMultipleGenericsWithMultipleTraits[T : Trait1 + Trait2 + Trait3 , U : Trait1 + Trait2 + Trait3] { + function new() => unsigned32 {} +} + +trait WithGenericWithGenericTrait[T : Trait[T]] { + function new() => unsigned32 {} +} + +trait WithGenericWithMultipleGenericTrait[T : Trait1[T] + Trait2[T] + Trait3[T]] { + function new() => unsigned32 {} +} + +trait WithMultipleGenericWithMultipleGenericTrait[T : Trait1[T] + Trait2[T] + Trait3[T] , U : Trait1[U] + Trait2[U] + Trait3[U]] { + function new() => unsigned32 {} +} + +trait BasicWithSuperTrait : Trait1 { + function new() => unsigned32 {} +} + +trait WithGenericWithSuperTrait[T] : Trait1 { + function new() => unsigned32 {} +} + +trait WithGenericWithTraitWithSuperTrait[T : Trait] : Trait1 { + function new() => unsigned32 {} +} + +trait WithGenericWithMultipleTraitsWithSuperTrait[T : Trait1 + Trait2 + Trait3] : Trait1 { + function new() => unsigned32 {} +} + +trait WithMultipleGenericsWithSuperTrait[T,U] : Trait1 { + function new() => unsigned32 {} +} + +trait WithMultipleGenericsWithMultipleTraitsWithSuperTrait[T : Trait1 + Trait2 + Trait3 , U : Trait1 + Trait2 + Trait3] : Trait1 { + function new() => unsigned32 {} +} + +trait WithGenericWithGenericTraitWithSuperTrait[T : Trait[T]] : Trait1 { + function new() => unsigned32 {} +} + +trait WithGenericWithMultipleGenericTraitWithSuperTrait[T : Trait1[T] + Trait2[T] + Trait3[T]] : Trait1 { + function new() => unsigned32 {} +} + +trait WithMultipleGenericWithMultipleGenericTraitWithSuperTrait[T : Trait1[T] + Trait2[T] + Trait3[T] , U : Trait1[U] + Trait2[U] + Trait3[U]] : Trait1 { + function new() => unsigned32 {} +} + +trait BasicWithMultiSuperTrait : Trait1 + Trait2 + Trait3 { + function new() => unsigned32 {} +} + +trait WithGenericWithMultiSuperTrait[T] : Trait1 + Trait2 + Trait3 { + function new() => unsigned32 {} +} + +trait WithGenericWithTraitWithMultiSuperTrait[T : Trait] : Trait1 + Trait2 + Trait3 { + function new() => unsigned32 {} +} + +trait WithGenericWithMultipleTraitsWithMultiSuperTrait[T : Trait1 + Trait2 + Trait3] : Trait1 + Trait2 + Trait3 { + function new() => unsigned32 {} +} + +trait WithMultipleGenericsWithMultiSuperTrait[T,U] : Trait1 + Trait2 + Trait3 { + function new() => unsigned32 {} +} + +trait WithMultipleGenericsWithMultipleTraitsWithMultiSuperTrait[T : Trait1 + Trait2 + Trait3 , U : Trait1 + Trait2 + Trait3] : Trait1 + Trait2 + Trait3 { + function new() => unsigned32 {} +} + +trait WithGenericWithGenericTraitWithMultiSuperTrait[T : Trait[T]] : Trait1 + Trait2 + Trait3 { + function new() => unsigned32 {} +} + +trait WithGenericWithMultipleGenericTraitWithMultiSuperTrait[T : Trait1[T] + Trait2[T] + Trait3[T]] : Trait1 + Trait2 + Trait3 { + function new() => unsigned32 {} +} + +trait WithMultipleGenericWithMultipleGenericTraitWithMultiSuperTrait[T : Trait1[T] + Trait2[T] + Trait3[T] , U : Trait1[U] + Trait2[U] + Trait3[U]] : Trait1 + Trait2 + Trait3 { + function new() => unsigned32 {} +} + +trait BasicWithMultiSuperTraitWithGenerics : Trait1[T] + Trait2[T] + Trait3[T] { + function new() => unsigned32 {} +} + +trait WithGenericWithMultiSuperTraitWithGenerics[T] : Trait1[T] + Trait2[T] + Trait3[T] { + function new() => unsigned32 {} +} + +trait WithGenericWithTraitWithMultiSuperTraitWithGenerics[T : Trait] : Trait1[T] + Trait2[T] + Trait3[T] { + function new() => unsigned32 {} +} + +trait WithGenericWithMultipleTraitsWithMultiSuperTraitWithGenerics[T : Trait1 + Trait2 + Trait3] : Trait1[T] + Trait2[T] + Trait3[T] { + function new() => unsigned32 {} +} + +trait WithMultipleGenericsWithMultiSuperTraitWithGenerics[T,U] : Trait1[T] + Trait2[T] + Trait3[T] { + function new() => unsigned32 {} +} + +trait WithMultipleGenericsWithMultipleTraitsWithMultiSuperTraitWithGenerics[T : Trait1 + Trait2 + Trait3 , U : Trait1 + Trait2 + Trait3] : Trait1[T] + Trait2[T] + Trait3[T] { + function new() => unsigned32 {} +} + +trait WithGenericWithGenericTraitWithMultiSuperTraitWithGenerics[T : Trait[T]] : Trait1[T] + Trait2[T] + Trait3[T] { + function new() => unsigned32 {} +} + +trait WithGenericWithMultipleGenericTraitWithMultiSuperTraitWithGenerics[T : Trait1[T] + Trait2[T] + Trait3[T]] : Trait1[T] + Trait2[T] + Trait3[T] { + function new() => unsigned32 {} +} + +trait WithMultipleGenericWithMultipleGenericTraitWithMultiSuperTraitWithGenerics[T : Trait1[T] + Trait2[T] + Trait3[T] , U : Trait1[U] + Trait2[U] + Trait3[U]] : Trait1[T] + Trait2[T] + Trait3[T] { + function new() => unsigned32 {} +} +