Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 41 additions & 2 deletions compiler/pipec-ast/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:#?}");
Expand All @@ -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();
Expand Down Expand Up @@ -317,7 +350,7 @@ impl<'this> ASTGenerator<'this> {
v => todo!("{v:#?}"),
}
}
Some(Token::RightSquare) => {
Some(Token::RightSquare) | Some(Token::RightCurly) => {
break;
}
_ => todo!(),
Expand All @@ -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:#?}"),
Expand Down Expand Up @@ -1288,6 +1321,12 @@ pub enum ASTNode {
generics: Generics,
subtype: SubType,
},
TraitDeclaration {
name: Span,
generics: Generics,
supertraits: Traits,
tree: ASTTree,
},
Public(Box<Self>),
Attributed(Vec<Attribute>, Box<Self>),
EOF,
Expand Down
3 changes: 3 additions & 0 deletions compiler/pipec-ast/src/tokenizer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ impl<'chars> Tokenizer<'chars> {
"immutable" => ImmutableKeyword,
"switch" => SwitchKeyword,
"type" => TypeKeyword,
"trait" => TraitKeyword,
_ => Token::Ident(input),
}
}
Expand Down Expand Up @@ -562,6 +563,8 @@ pub enum Token {
SwitchKeyword,
/// type
TypeKeyword,
/// trait
TraitKeyword,
/// 21213
Digit { val: Span, digittype: DigitType },
/// things_like_this or this_2
Expand Down
1 change: 1 addition & 0 deletions compiler/pipec-tests/src/ast/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod functiondeclaration;
mod generics;
mod traits;
mod variablemutability;
mod viewportdeclaration;
4 changes: 4 additions & 0 deletions compiler/pipec-tests/src/ast/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#[test]
fn test_traits() {
crate::test_file_generation!("traits.pipec");
}
144 changes: 144 additions & 0 deletions compiler/pipec-tests/src/ast/traits/traits.pipec
Original file line number Diff line number Diff line change
@@ -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 {}
}