From e063d4c68513936e2eb9a7e6031d77aab32a71b3 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 10 May 2026 17:55:08 +0200 Subject: [PATCH] Traits --- mist-test/src/logger.mist | 2 ++ parser/src/ast.rs | 15 ++++++++++++++- parser/src/grammar.pest | 20 +++++++++++++++++++- parser/src/lib.rs | 25 +++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/mist-test/src/logger.mist b/mist-test/src/logger.mist index f6b55c5..a1c5631 100644 --- a/mist-test/src/logger.mist +++ b/mist-test/src/logger.mist @@ -1,5 +1,7 @@ use ; +public trait TestLogging: Display {} + public enum LogLevel { Info, Warning, diff --git a/parser/src/ast.rs b/parser/src/ast.rs index 5f78fd4..18509dd 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -75,6 +75,13 @@ pub enum TopLevelKind { Import(Path), Mod(Identifier), ImplDecl(ImplDecl), + TraitDecl { + visibility: Visibility, + name: Identifier, + generics: Generics, + requirements: Vec, + items: Vec, + }, EnumDecl { visibility: Visibility, name: Identifier, @@ -83,8 +90,8 @@ pub enum TopLevelKind { }, StructDecl { visibility: Visibility, - generics: Generics, name: Identifier, + generics: Generics, fields: Vec, }, FunctionDecl(FunctionDecl), @@ -98,6 +105,12 @@ pub enum TopLevelKind { }, } +#[derive(Debug, Clone, Serialize)] +pub enum TraitItem { + WithBody(FunctionDecl), + NoBody(FunctionDecl), +} + #[derive(Debug, Clone, Serialize)] pub enum ClassItem { Method(FunctionDecl), diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index afc0ea4..b9f3bfb 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -259,6 +259,24 @@ impl_decl = { "impl" ~ generics? ~ type_expr ~ "{" ~ method* ~ "}" } +// ====================================================== +// Traits +// ====================================================== +trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* } + +method_no_body = { + export? ~ type_expr ~ identifier ~ generics? ~ "(" ~ self_param? ~ ("," ~ param_list?)? ~ ")" +} + +trait_item = _{ + method + | method_no_body +} + +trait_decl = { + export? ~ "trait" ~ identifier ~ generics? ~ trait_requirements? ~ "{" ~ trait_item* ~ "}" +} + // ====================================================== // FUNCTIONS // ====================================================== @@ -272,7 +290,7 @@ function_decl = { // ====================================================== top_level = { - (attributes ~ (import | impl_for_decl | impl_decl | function_decl | struct_decl | enum_decl | class_decl | mod_package)) + (attributes ~ (import | impl_for_decl | impl_decl | trait_decl | struct_decl | enum_decl | class_decl | mod_package | function_decl)) | mod_attribute } diff --git a/parser/src/lib.rs b/parser/src/lib.rs index d3861e2..fb0343e 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -305,6 +305,31 @@ impl From> for TopLevelKind { Rule::impl_for_decl | Rule::impl_decl => TopLevelKind::ImplDecl(ImplDecl::from(pair)), + Rule::trait_decl => TopLevelKind::TraitDecl { + visibility: Visibility::from(&mut inner), + name: Identifier::from(inner.next().unwrap()), + generics: consume_rule(&mut inner, Rule::generics) + .map(Generics::from) + .unwrap_or_default(), + requirements: consume_rule(&mut inner, Rule::trait_requirements) + .map(|pair| pair.into_inner().map(TypeExpr::from).collect()) + .unwrap_or_default(), + items: inner.map(TraitItem::from).collect(), + }, + + _ => unimplemented!("{rule:#?}"), + } + } +} + +impl From> for TraitItem { + fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self { + let rule = pair.as_rule(); + + match rule { + Rule::method => TraitItem::WithBody(FunctionDecl::from(pair)), + Rule::method_no_body => TraitItem::NoBody(FunctionDecl::from(pair)), + _ => unimplemented!("{rule:#?}"), } }