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 {
Info,
Warning,
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 {
String prefix;
@@ -26,16 +50,22 @@ public class Logger {
void log(self*, LogLevel level, str* message) {
match(level) {
LogLevel::Info => {
println!("[INFO] {} {}", self.prefix, message);
println!("{level} {} {}", self.prefix, message);
}
LogLevel::Warning => {
println!("[WARN] {} {}", self.prefix, message);
println!("{level} {} {}", self.prefix, message);
}
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)]
pub struct Identifier(pub String);
#[derive(Debug, Clone, Serialize, Default)]
pub struct FieldList(pub Vec<(Identifier, Visibility, TypeExpr)>);
#[derive(Debug, Clone, Serialize, Default)]
pub struct ParamList(pub Vec<VarDecl>);
@@ -77,6 +74,14 @@ pub enum TopLevelKind {
ModAttribute,
Import(Path),
Mod(Identifier),
ImplDecl(ImplDecl),
TraitDecl {
visibility: Visibility,
name: Identifier,
generics: Generics,
requirements: Vec<TypeExpr>,
items: Vec<FunctionDecl>,
},
EnumDecl {
visibility: Visibility,
name: Identifier,
@@ -85,21 +90,27 @@ pub enum TopLevelKind {
},
StructDecl {
visibility: Visibility,
generics: Generics,
name: Identifier,
fields: FieldList,
generics: Generics,
fields: Vec<FieldDecl>,
},
FunctionDecl(FunctionDecl),
ClassDecl {
visibility: Visibility,
name: Identifier,
generics: Generics,
fields: Vec<VarDeclStmt>,
fields: Vec<FieldDeclStmt>,
constructor: ClassConstructor,
methods: Vec<FunctionDecl>,
items: Vec<ClassItem>,
},
}
#[derive(Debug, Clone, Serialize)]
pub enum ClassItem {
Method(FunctionDecl),
ImplDecl(ImplDecl),
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct Generics(pub Vec<Generic>);
@@ -123,7 +134,7 @@ pub enum Pattern {
pub enum EnumItem {
Named(Identifier),
Tuple(Identifier, Vec<TypeExpr>),
Struct(Identifier, FieldList),
Struct(Identifier, Vec<FieldDecl>),
}
#[derive(Debug, Clone, Serialize)]
@@ -141,7 +152,7 @@ pub struct FunctionDecl {
pub generics: Generics,
pub params: ParamList,
pub return_type: TypeExpr,
pub body: Block,
pub body: Option<Block>,
}
#[derive(Debug, Clone, Serialize)]
@@ -195,6 +206,14 @@ pub enum Statement {
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)]
pub struct VarDecl {
pub mutable: bool,
@@ -208,6 +227,19 @@ pub struct VarDeclStmt {
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)]
pub struct VarAssignStmt {
pub target: Expression,
+41 -4
View File
@@ -149,7 +149,6 @@ attributes = {
// ======================================================
// DECLARATION HELPERS
// ======================================================
var_decl = {
(var | type_expr) ~ mutable? ~ pattern
}
@@ -225,7 +224,11 @@ class_constructor = {
}
class_fields = {
var_decl_statement*
class_field*
}
class_field = {
field ~ ("=" ~ expr)? ~ semicolon
}
self_param = {
@@ -236,8 +239,42 @@ method = {
export? ~ type_expr ~ identifier ~ generics? ~ "(" ~ self_param? ~ ("," ~ param_list?)? ~ ")" ~ block
}
class_item = _{
impl_decl
| method
}
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 = {
(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
}
+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 {
fn from(pair: pest::iterators::Pair<Rule>) -> Self {
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)
.map(Generics::from)
.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 {
@@ -300,10 +286,10 @@ impl From<pest::iterators::Pair<'_, Rule>> for TopLevelKind {
.next()
.unwrap()
.into_inner()
.map(VarDeclStmt::from)
.map(FieldDeclStmt::from)
.collect(),
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 {
@@ -317,6 +303,63 @@ impl From<pest::iterators::Pair<'_, Rule>> for TopLevelKind {
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:#?}"),
}
}
@@ -342,7 +385,10 @@ impl From<pest::iterators::Pair<'_, Rule>> for EnumItem {
Rule::enum_struct => EnumItem::Struct(
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:#?}"),
@@ -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 {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
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 {
fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self {
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()));
let body = Block::from(inner.next().unwrap());
let body = inner.next().map(Block::from);
Self {
visibility,
+108 -15
View File
@@ -1,7 +1,8 @@
use parser::ast::{
Attribute, BinaryOp, Block, EnumItem, Expression, FunctionDecl, Generic, Generics, Identifier,
Literal, Path, Pattern, Postfix, Prefix, Statement, StatementBranch, TopLevel, TopLevelKind,
TypeExpr, TypeExprKind, TypePostfix, VarAssignStmt, VarDecl, VarDeclStmt, Visibility,
Attribute, BinaryOp, Block, ClassItem, EnumItem, Expression, FieldDecl, FunctionDecl, Generic,
Generics, Identifier, ImplDecl, Literal, Path, Pattern, Postfix, Prefix, Statement,
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::Mod(id) => cg.addln(&format!("mod {};", id.get_rust())),
Self::FunctionDecl(decl) => decl.to_rust(cg),
Self::ImplDecl(impl_) => impl_.to_rust(cg),
Self::StructDecl {
visibility,
name,
@@ -328,9 +330,8 @@ impl ToRust for TopLevelKind {
));
cg.indent += 1;
for (field_name, _, ty) in &fields.0 {
let ty = ty.get_rust();
cg.add_indentedln(&format!("pub {}: {},", field_name.get_rust(), ty));
for field in fields {
cg.add_indentedln(&field.get_rust());
}
cg.indent -= 1;
@@ -357,13 +358,45 @@ impl ToRust for TopLevelKind {
cg.indent -= 1;
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 {
visibility,
name,
generics,
fields,
constructor,
methods,
items,
} => {
// Struct decl
cg.addln(&format!(
@@ -375,8 +408,7 @@ impl ToRust for TopLevelKind {
cg.indent += 1;
for field in fields {
let ty = field.decl.type_.clone().unwrap().get_rust();
cg.add_indentedln(&format!("pub {}: {},", field.decl.name.get_rust(), ty));
cg.add_indentedln(&field.decl.get_rust());
}
cg.indent -= 1;
@@ -458,12 +490,30 @@ impl ToRust for TopLevelKind {
cg.indent -= 1;
cg.add_indentedln("}\n");
for method in methods {
method.to_rust(cg);
for item in items {
match item {
ClassItem::ImplDecl(_) => {}
ClassItem::Method(method) => method.to_rust(cg),
}
}
cg.indent -= 1;
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(", ");
cg.add_indentedln(&format!(
"{}fn {}{}({}) -> {} {{",
"{}fn {}{}({}) -> {}",
self.visibility.get_rust(),
self.name.get_rust(),
self.generics.get_rust(),
params_str,
self.return_type.get_rust()
));
if let Some(body) = &self.body {
cg.add_indentedln("{\n");
cg.indent += 1;
self.body.to_rust(cg);
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;
for method in &self.methods {
method.to_rust(cg);
}
cg.indent -= 1;
cg.add_indentedln("}");
}
}
@@ -677,8 +759,8 @@ impl GetRust for EnumItem {
Self::Struct(id, s) => format!(
"{} {{{}}}",
id.get_rust(),
s.0.iter()
.map(|(id, _, ty)| format!("{}: {}", id.get_rust(), ty.get_rust()))
s.iter()
.map(|field| format!("{}: {}", field.name.get_rust(), field.type_.get_rust()))
.collect::<Vec<_>>()
.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 {
let rust_path = path.get_rust();