Merge pull request #26 from mist-go/impl-traits

Impl traits
This commit is contained in:
2026-05-10 18:19:07 +02:00
committed by GitHub
5 changed files with 332 additions and 54 deletions
+33 -3
View File
@@ -1,9 +1,33 @@
use <std::fmt>;
public trait TestLogging<T: fmt::Display>: fmt::Display {
String get();
}
public enum LogLevel { public enum LogLevel {
Info, Info,
Warning, Warning,
Error, Error,
} }
impl fmt::Display for LogLevel {
std::fmt::Result fmt(self*, std::fmt::Formatter<'_> mut* f) {
match (self) {
LogLevel::Info => {
return write!(f, "[INFO]");
}
LogLevel::Warning => {
return write!(f, "[WARN]");
}
LogLevel::Error => {
return write!(f, "[ERROR]");
}
}
}
}
public class Logger { public class Logger {
String prefix; String prefix;
@@ -26,16 +50,22 @@ public class Logger {
void log(self*, LogLevel level, str* message) { void log(self*, LogLevel level, str* message) {
match(level) { match(level) {
LogLevel::Info => { LogLevel::Info => {
println!("[INFO] {} {}", self.prefix, message); println!("{level} {} {}", self.prefix, message);
} }
LogLevel::Warning => { LogLevel::Warning => {
println!("[WARN] {} {}", self.prefix, message); println!("{level} {} {}", self.prefix, message);
} }
LogLevel::Error => { LogLevel::Error => {
println!("[ERROR] {} {}", self.prefix, message); println!("{level} {} {}", self.prefix, message);
} }
} }
} }
impl fmt::Display {
std::fmt::Result fmt(self*, std::fmt::Formatter<'_> mut* f) {
return write!(f, "logger ({})", self.prefix);
}
}
} }
+41 -9
View File
@@ -3,9 +3,6 @@ use serde::Serialize;
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct Identifier(pub String); pub struct Identifier(pub String);
#[derive(Debug, Clone, Serialize, Default)]
pub struct FieldList(pub Vec<(Identifier, Visibility, TypeExpr)>);
#[derive(Debug, Clone, Serialize, Default)] #[derive(Debug, Clone, Serialize, Default)]
pub struct ParamList(pub Vec<VarDecl>); pub struct ParamList(pub Vec<VarDecl>);
@@ -77,6 +74,14 @@ pub enum TopLevelKind {
ModAttribute, ModAttribute,
Import(Path), Import(Path),
Mod(Identifier), Mod(Identifier),
ImplDecl(ImplDecl),
TraitDecl {
visibility: Visibility,
name: Identifier,
generics: Generics,
requirements: Vec<TypeExpr>,
items: Vec<FunctionDecl>,
},
EnumDecl { EnumDecl {
visibility: Visibility, visibility: Visibility,
name: Identifier, name: Identifier,
@@ -85,21 +90,27 @@ pub enum TopLevelKind {
}, },
StructDecl { StructDecl {
visibility: Visibility, visibility: Visibility,
generics: Generics,
name: Identifier, name: Identifier,
fields: FieldList, generics: Generics,
fields: Vec<FieldDecl>,
}, },
FunctionDecl(FunctionDecl), FunctionDecl(FunctionDecl),
ClassDecl { ClassDecl {
visibility: Visibility, visibility: Visibility,
name: Identifier, name: Identifier,
generics: Generics, generics: Generics,
fields: Vec<VarDeclStmt>, fields: Vec<FieldDeclStmt>,
constructor: ClassConstructor, constructor: ClassConstructor,
methods: Vec<FunctionDecl>, items: Vec<ClassItem>,
}, },
} }
#[derive(Debug, Clone, Serialize)]
pub enum ClassItem {
Method(FunctionDecl),
ImplDecl(ImplDecl),
}
#[derive(Debug, Clone, Serialize, Default)] #[derive(Debug, Clone, Serialize, Default)]
pub struct Generics(pub Vec<Generic>); pub struct Generics(pub Vec<Generic>);
@@ -123,7 +134,7 @@ pub enum Pattern {
pub enum EnumItem { pub enum EnumItem {
Named(Identifier), Named(Identifier),
Tuple(Identifier, Vec<TypeExpr>), Tuple(Identifier, Vec<TypeExpr>),
Struct(Identifier, FieldList), Struct(Identifier, Vec<FieldDecl>),
} }
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
@@ -141,7 +152,7 @@ pub struct FunctionDecl {
pub generics: Generics, pub generics: Generics,
pub params: ParamList, pub params: ParamList,
pub return_type: TypeExpr, pub return_type: TypeExpr,
pub body: Block, pub body: Option<Block>,
} }
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
@@ -195,6 +206,14 @@ pub enum Statement {
Continue, Continue,
} }
#[derive(Debug, Clone, Serialize)]
pub struct ImplDecl {
pub generics: Generics,
pub target: TypeExpr,
pub trait_: Option<TypeExpr>,
pub methods: Vec<FunctionDecl>,
}
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct VarDecl { pub struct VarDecl {
pub mutable: bool, pub mutable: bool,
@@ -208,6 +227,19 @@ pub struct VarDeclStmt {
pub init: Option<Expression>, pub init: Option<Expression>,
} }
#[derive(Debug, Clone, Serialize)]
pub struct FieldDecl {
pub visibility: Visibility,
pub type_: TypeExpr,
pub name: Identifier,
}
#[derive(Debug, Clone, Serialize)]
pub struct FieldDeclStmt {
pub decl: FieldDecl,
pub init: Option<Expression>,
}
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct VarAssignStmt { pub struct VarAssignStmt {
pub target: Expression, pub target: Expression,
+41 -4
View File
@@ -149,7 +149,6 @@ attributes = {
// ====================================================== // ======================================================
// DECLARATION HELPERS // DECLARATION HELPERS
// ====================================================== // ======================================================
var_decl = { var_decl = {
(var | type_expr) ~ mutable? ~ pattern (var | type_expr) ~ mutable? ~ pattern
} }
@@ -225,7 +224,11 @@ class_constructor = {
} }
class_fields = { class_fields = {
var_decl_statement* class_field*
}
class_field = {
field ~ ("=" ~ expr)? ~ semicolon
} }
self_param = { self_param = {
@@ -236,8 +239,42 @@ method = {
export? ~ type_expr ~ identifier ~ generics? ~ "(" ~ self_param? ~ ("," ~ param_list?)? ~ ")" ~ block export? ~ type_expr ~ identifier ~ generics? ~ "(" ~ self_param? ~ ("," ~ param_list?)? ~ ")" ~ block
} }
class_item = _{
impl_decl
| method
}
class_decl = { class_decl = {
export? ~ "class" ~ identifier ~ generics? ~ "{" ~ class_fields ~ class_constructor ~ method* ~ "}" export? ~ "class" ~ identifier ~ generics? ~ "{" ~ class_fields ~ class_constructor ~ class_item* ~ "}"
}
// ======================================================
// IMPL
// ======================================================
impl_for_decl = {
"impl" ~ generics? ~ type_expr ~ "for" ~ type_expr ~ "{" ~ method* ~ "}"
}
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?)? ~ ")" ~ semicolon
}
trait_item = _{
method
| method_no_body
}
trait_decl = {
export? ~ "trait" ~ identifier ~ generics? ~ trait_requirements? ~ "{" ~ trait_item* ~ "}"
} }
// ====================================================== // ======================================================
@@ -253,7 +290,7 @@ function_decl = {
// ====================================================== // ======================================================
top_level = { top_level = {
(attributes ~ (import | 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 | mod_attribute
} }
+108 -22
View File
@@ -107,23 +107,6 @@ impl From<pest::iterators::Pair<'_, Rule>> for Path {
} }
} }
impl From<pest::iterators::Pair<'_, Rule>> for FieldList {
fn from(pair: pest::iterators::Pair<Rule>) -> Self {
let params = pair
.into_inner()
.map(|p| {
let mut param_inner = p.into_inner();
let visibility = Visibility::from(&mut param_inner);
let param_type = TypeExpr::from(param_inner.next().unwrap());
let param_name = Identifier::from(param_inner.next().unwrap());
(param_name, visibility, param_type)
})
.collect();
FieldList(params)
}
}
impl From<pest::iterators::Pair<'_, Rule>> for ParamList { impl From<pest::iterators::Pair<'_, Rule>> for ParamList {
fn from(pair: pest::iterators::Pair<Rule>) -> Self { fn from(pair: pest::iterators::Pair<Rule>) -> Self {
ParamList(pair.into_inner().map(VarDecl::from).collect()) ParamList(pair.into_inner().map(VarDecl::from).collect())
@@ -287,7 +270,10 @@ impl From<pest::iterators::Pair<'_, Rule>> for TopLevelKind {
generics: consume_rule(&mut inner, Rule::generics) generics: consume_rule(&mut inner, Rule::generics)
.map(Generics::from) .map(Generics::from)
.unwrap_or_default(), .unwrap_or_default(),
fields: inner.next().map(FieldList::from).unwrap_or_default(), fields: inner
.next()
.map(|pair| pair.into_inner().map(FieldDecl::from).collect())
.unwrap_or_default(),
}, },
Rule::class_decl => TopLevelKind::ClassDecl { Rule::class_decl => TopLevelKind::ClassDecl {
@@ -300,10 +286,10 @@ impl From<pest::iterators::Pair<'_, Rule>> for TopLevelKind {
.next() .next()
.unwrap() .unwrap()
.into_inner() .into_inner()
.map(VarDeclStmt::from) .map(FieldDeclStmt::from)
.collect(), .collect(),
constructor: ClassConstructor::from(inner.next().unwrap()), constructor: ClassConstructor::from(inner.next().unwrap()),
methods: inner.into_iter().map(FunctionDecl::from).collect(), items: inner.into_iter().map(ClassItem::from).collect(),
}, },
Rule::enum_decl => TopLevelKind::EnumDecl { Rule::enum_decl => TopLevelKind::EnumDecl {
@@ -317,6 +303,63 @@ impl From<pest::iterators::Pair<'_, Rule>> for TopLevelKind {
Rule::mod_package => TopLevelKind::Mod(Identifier::from(inner.next().unwrap())), Rule::mod_package => TopLevelKind::Mod(Identifier::from(inner.next().unwrap())),
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(FunctionDecl::from).collect(),
},
_ => unimplemented!("{rule:#?}"),
}
}
}
impl From<pest::iterators::Pair<'_, Rule>> for ClassItem {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
let rule = pair.as_rule();
match rule {
Rule::impl_decl | Rule::impl_for_decl => ClassItem::ImplDecl(ImplDecl::from(pair)),
Rule::method => ClassItem::Method(FunctionDecl::from(pair)),
_ => unimplemented!("{rule:#?}"),
}
}
}
impl From<pest::iterators::Pair<'_, Rule>> for ImplDecl {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
let rule = pair.as_rule();
let mut inner = pair.clone().into_inner();
match rule {
Rule::impl_for_decl => ImplDecl {
generics: consume_rule(&mut inner, Rule::generics)
.map(Generics::from)
.unwrap_or_default(),
trait_: Some(TypeExpr::from(inner.next().unwrap())),
target: TypeExpr::from(inner.next().unwrap()),
methods: inner.map(FunctionDecl::from).collect(),
},
Rule::impl_decl => ImplDecl {
generics: consume_rule(&mut inner, Rule::generics)
.map(Generics::from)
.unwrap_or_default(),
trait_: None,
target: TypeExpr::from(inner.next().unwrap()),
methods: inner.map(FunctionDecl::from).collect(),
},
_ => unimplemented!("{rule:#?}"), _ => unimplemented!("{rule:#?}"),
} }
} }
@@ -342,7 +385,10 @@ impl From<pest::iterators::Pair<'_, Rule>> for EnumItem {
Rule::enum_struct => EnumItem::Struct( Rule::enum_struct => EnumItem::Struct(
Identifier::from(inner.next().unwrap()), Identifier::from(inner.next().unwrap()),
FieldList::from(inner.next().unwrap()), inner
.next()
.map(|pair| pair.into_inner().map(FieldDecl::from).collect())
.unwrap_or_default(),
), ),
_ => unimplemented!("{rule:#?}"), _ => unimplemented!("{rule:#?}"),
@@ -583,6 +629,24 @@ impl From<pest::iterators::Pair<'_, Rule>> for VarDeclStmt {
} }
} }
impl From<pest::iterators::Pair<'_, Rule>> for FieldDeclStmt {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
match pair.as_rule() {
Rule::class_field => {
let mut inner = pair.into_inner();
let decl = FieldDecl::from(inner.next().unwrap());
let init = inner.next().map(Expression::from);
FieldDeclStmt { decl, init }
}
_ => unimplemented!(),
}
}
}
impl From<pest::iterators::Pair<'_, Rule>> for Pattern { impl From<pest::iterators::Pair<'_, Rule>> for Pattern {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self { fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
let rule = pair.as_rule(); let rule = pair.as_rule();
@@ -641,6 +705,28 @@ impl From<pest::iterators::Pair<'_, Rule>> for VarDecl {
} }
} }
impl From<pest::iterators::Pair<'_, Rule>> for FieldDecl {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
match pair.as_rule() {
Rule::field => {
let mut inner = pair.into_inner();
let visibility = Visibility::from(&mut inner);
let type_ = TypeExpr::from(inner.next().unwrap());
let name = Identifier::from(inner.next().unwrap());
FieldDecl {
visibility,
type_,
name,
}
}
_ => unimplemented!("{:?}", pair.as_rule()),
}
}
}
impl From<pest::iterators::Pair<'_, Rule>> for FunctionDecl { impl From<pest::iterators::Pair<'_, Rule>> for FunctionDecl {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self { fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
@@ -690,7 +776,7 @@ impl From<pest::iterators::Pair<'_, Rule>> for FunctionDecl {
}) })
.unwrap_or_else(|| ParamList(self_param.into_iter().collect())); .unwrap_or_else(|| ParamList(self_param.into_iter().collect()));
let body = Block::from(inner.next().unwrap()); let body = inner.next().map(Block::from);
Self { Self {
visibility, visibility,
+109 -16
View File
@@ -1,7 +1,8 @@
use parser::ast::{ use parser::ast::{
Attribute, BinaryOp, Block, EnumItem, Expression, FunctionDecl, Generic, Generics, Identifier, Attribute, BinaryOp, Block, ClassItem, EnumItem, Expression, FieldDecl, FunctionDecl, Generic,
Literal, Path, Pattern, Postfix, Prefix, Statement, StatementBranch, TopLevel, TopLevelKind, Generics, Identifier, ImplDecl, Literal, Path, Pattern, Postfix, Prefix, Statement,
TypeExpr, TypeExprKind, TypePostfix, VarAssignStmt, VarDecl, VarDeclStmt, Visibility, StatementBranch, TopLevel, TopLevelKind, TypeExpr, TypeExprKind, TypePostfix, VarAssignStmt,
VarDecl, VarDeclStmt, Visibility,
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -314,6 +315,7 @@ impl ToRust for TopLevelKind {
Self::Import(path) => cg.addln(&format!("use {};", path.get_rust())), Self::Import(path) => cg.addln(&format!("use {};", path.get_rust())),
Self::Mod(id) => cg.addln(&format!("mod {};", id.get_rust())), Self::Mod(id) => cg.addln(&format!("mod {};", id.get_rust())),
Self::FunctionDecl(decl) => decl.to_rust(cg), Self::FunctionDecl(decl) => decl.to_rust(cg),
Self::ImplDecl(impl_) => impl_.to_rust(cg),
Self::StructDecl { Self::StructDecl {
visibility, visibility,
name, name,
@@ -328,9 +330,8 @@ impl ToRust for TopLevelKind {
)); ));
cg.indent += 1; cg.indent += 1;
for (field_name, _, ty) in &fields.0 { for field in fields {
let ty = ty.get_rust(); cg.add_indentedln(&field.get_rust());
cg.add_indentedln(&format!("pub {}: {},", field_name.get_rust(), ty));
} }
cg.indent -= 1; cg.indent -= 1;
@@ -357,13 +358,45 @@ impl ToRust for TopLevelKind {
cg.indent -= 1; cg.indent -= 1;
cg.addln("}\n"); cg.addln("}\n");
} }
Self::TraitDecl {
visibility,
name,
generics,
requirements,
items,
} => {
cg.addln(&format!(
"{}trait {}{}{} {{",
visibility.get_rust(),
name.get_rust(),
generics.get_rust(),
if requirements.len() != 0 {
String::from(": ")
+ &requirements
.iter()
.map(TypeExpr::get_rust)
.collect::<Vec<_>>()
.join("+")
} else {
String::new()
},
));
cg.indent += 1;
for item in items {
item.to_rust(cg);
}
cg.indent -= 1;
cg.addln("}\n");
}
Self::ClassDecl { Self::ClassDecl {
visibility, visibility,
name, name,
generics, generics,
fields, fields,
constructor, constructor,
methods, items,
} => { } => {
// Struct decl // Struct decl
cg.addln(&format!( cg.addln(&format!(
@@ -375,8 +408,7 @@ impl ToRust for TopLevelKind {
cg.indent += 1; cg.indent += 1;
for field in fields { for field in fields {
let ty = field.decl.type_.clone().unwrap().get_rust(); cg.add_indentedln(&field.decl.get_rust());
cg.add_indentedln(&format!("pub {}: {},", field.decl.name.get_rust(), ty));
} }
cg.indent -= 1; cg.indent -= 1;
@@ -458,12 +490,30 @@ impl ToRust for TopLevelKind {
cg.indent -= 1; cg.indent -= 1;
cg.add_indentedln("}\n"); cg.add_indentedln("}\n");
for method in methods { for item in items {
method.to_rust(cg); match item {
ClassItem::ImplDecl(_) => {}
ClassItem::Method(method) => method.to_rust(cg),
}
} }
cg.indent -= 1; cg.indent -= 1;
cg.addln("}\n"); cg.addln("}\n");
for item in items {
match item {
ClassItem::ImplDecl(impl_) => {
let mut impl_ = impl_.clone();
impl_.trait_ = Some(impl_.target);
impl_.target =
TypeExpr(TypeExprKind::Path(Path(vec![name.clone()])), Vec::new());
impl_.to_rust(cg);
}
ClassItem::Method(_) => {}
}
}
} }
} }
} }
@@ -602,17 +652,49 @@ impl ToRust for FunctionDecl {
.join(", "); .join(", ");
cg.add_indentedln(&format!( cg.add_indentedln(&format!(
"{}fn {}{}({}) -> {} {{", "{}fn {}{}({}) -> {}",
self.visibility.get_rust(), self.visibility.get_rust(),
self.name.get_rust(), self.name.get_rust(),
self.generics.get_rust(), self.generics.get_rust(),
params_str, params_str,
self.return_type.get_rust() self.return_type.get_rust()
)); ));
if let Some(body) = &self.body {
cg.add_indentedln("{\n");
cg.indent += 1;
body.to_rust(cg);
cg.indent -= 1;
cg.add_indentedln("}\n");
} else {
cg.add(";");
}
}
}
impl ToRust for ImplDecl {
fn to_rust(&self, cg: &mut RustCodegen) {
if let Some(trait_) = &self.trait_ {
cg.add_indentedln(&format!(
"impl{} {} for {} {{",
self.generics.get_rust(),
trait_.get_rust(),
self.target.get_rust()
));
} else {
cg.add_indentedln(&format!(
"impl{} {} {{",
self.generics.get_rust(),
self.target.get_rust()
));
}
cg.indent += 1; cg.indent += 1;
self.body.to_rust(cg);
for method in &self.methods {
method.to_rust(cg);
}
cg.indent -= 1; cg.indent -= 1;
cg.add_indentedln("}\n"); cg.add_indentedln("}");
} }
} }
@@ -677,8 +759,8 @@ impl GetRust for EnumItem {
Self::Struct(id, s) => format!( Self::Struct(id, s) => format!(
"{} {{{}}}", "{} {{{}}}",
id.get_rust(), id.get_rust(),
s.0.iter() s.iter()
.map(|(id, _, ty)| format!("{}: {}", id.get_rust(), ty.get_rust())) .map(|field| format!("{}: {}", field.name.get_rust(), field.type_.get_rust()))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .join(", ")
), ),
@@ -769,6 +851,17 @@ impl GetRust for (bool, &Generic) {
} }
} }
impl GetRust for FieldDecl {
fn get_rust(&self) -> String {
format!(
"{}{}: {},",
self.visibility.get_rust(),
self.name.get_rust(),
self.type_.get_rust()
)
}
}
pub fn get_static_type_path(path: &Path) -> String { pub fn get_static_type_path(path: &Path) -> String {
let rust_path = path.get_rust(); let rust_path = path.get_rust();