From a8717aa5c4cdb3b79f4ee651f6393bda0f8df745 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 4 Jun 2026 17:38:49 +0200 Subject: [PATCH 1/6] Fix methods #58 and #55 --- crates/parser/src/grammar.pest | 11 +++++------ crates/parser/src/parser/items/function.rs | 2 +- mist-test/src/main.mist | 8 ++++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 26a7994..549e5dc 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -281,8 +281,12 @@ self_param = { "self" ~ mutable? ~ deref_px? } +method_args = _{ + ((self_param ~ ("," ~ param_list)?) | param_list) ~ ","? +} + method = { - visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list)? ~ ")" ~ block + visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ (block | semicolon) } class_item = _{ @@ -310,13 +314,8 @@ impl_decl = { // ====================================================== trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* } -method_no_body = { - visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list)? ~ ")" ~ semicolon -} - trait_item = _{ method - | method_no_body } trait_decl = { diff --git a/crates/parser/src/parser/items/function.rs b/crates/parser/src/parser/items/function.rs index 2b52253..65da84f 100644 --- a/crates/parser/src/parser/items/function.rs +++ b/crates/parser/src/parser/items/function.rs @@ -10,7 +10,7 @@ impl<'a> TryFrom> for FunctionDecl { type Error = AstError<'a, Self>; fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result { - ast_ensure!(pair, Rule::function_decl, Rule::method, Rule::method_no_body => { + ast_ensure!(pair, Rule::function_decl, Rule::method => { let mut inner = pair.into_inner(); let visibility = Visibility::try_from(&mut inner); let return_type = TypeExpr::try_from(inner.next().unwrap()); diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 1a14ec9..759a8fe 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -1,3 +1,11 @@ +class Bro { + constructor() {} + + void idk_man(i32 bro) {} +} + void main() { test_package::hello(); + + let idk = Bro::new(); } From e571d98cd05088e025389efbee240dba999d83b3 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 4 Jun 2026 17:44:41 +0200 Subject: [PATCH 2/6] Fix undeclared lifetime and simplifed grammar #50 --- crates/parser/src/grammar.pest | 14 +++++--------- crates/parser/src/parser/items/class.rs | 2 +- crates/parser/src/parser/items/function.rs | 2 +- mist-test/src/main.mist | 6 ------ 4 files changed, 7 insertions(+), 17 deletions(-) diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 549e5dc..4e5bfa5 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -285,13 +285,9 @@ method_args = _{ ((self_param ~ ("," ~ param_list)?) | param_list) ~ ","? } -method = { - visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ (block | semicolon) -} - class_item = _{ impl_decl - | method + | function_decl } class_decl = { @@ -302,11 +298,11 @@ class_decl = { // IMPL // ====================================================== impl_for_decl = { - "impl" ~ generics_decl? ~ type_expr ~ "for" ~ type_expr ~ "{" ~ method* ~ "}" + "impl" ~ generics_decl? ~ type_expr ~ "for" ~ type_expr ~ "{" ~ function_decl* ~ "}" } impl_decl = { - "impl" ~ generics_decl? ~ type_expr ~ "{" ~ method* ~ "}" + "impl" ~ generics_decl? ~ type_expr ~ "{" ~ function_decl* ~ "}" } // ====================================================== @@ -315,7 +311,7 @@ impl_decl = { trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* } trait_item = _{ - method + function_decl } trait_decl = { @@ -327,7 +323,7 @@ trait_decl = { // ====================================================== function_decl = { - visibility? ~ type_expr ~ identifier ~ "(" ~ param_list ~ ")" ~ block + visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ (block | semicolon) } // ====================================================== diff --git a/crates/parser/src/parser/items/class.rs b/crates/parser/src/parser/items/class.rs index 4512d59..cab69ec 100644 --- a/crates/parser/src/parser/items/class.rs +++ b/crates/parser/src/parser/items/class.rs @@ -42,7 +42,7 @@ impl<'a> TryFrom> for ClassItem { Ok(ClassItem::ImplDecl(pair.try_into().get()?)) } - Rule::method => Ok(ClassItem::Method(pair.try_into().get()?)), + Rule::function_decl => Ok(ClassItem::Method(pair.try_into().get()?)), _ => AstError::bug_unimplemented(pair), } diff --git a/crates/parser/src/parser/items/function.rs b/crates/parser/src/parser/items/function.rs index 65da84f..1b2ff6c 100644 --- a/crates/parser/src/parser/items/function.rs +++ b/crates/parser/src/parser/items/function.rs @@ -10,7 +10,7 @@ impl<'a> TryFrom> for FunctionDecl { type Error = AstError<'a, Self>; fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result { - ast_ensure!(pair, Rule::function_decl, Rule::method => { + ast_ensure!(pair, Rule::function_decl => { let mut inner = pair.into_inner(); let visibility = Visibility::try_from(&mut inner); let return_type = TypeExpr::try_from(inner.next().unwrap()); diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 759a8fe..73abdcb 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -1,9 +1,3 @@ -class Bro { - constructor() {} - - void idk_man(i32 bro) {} -} - void main() { test_package::hello(); From d3b54b411436a25004b49d554f4a5576a9d7c9ff Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 4 Jun 2026 17:57:12 +0200 Subject: [PATCH 3/6] Fix else if statements #49 --- crates/codegen/src/statement.rs | 4 +++- crates/parser/src/grammar.pest | 2 +- mist-test/src/main.mist | 2 -- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/codegen/src/statement.rs b/crates/codegen/src/statement.rs index b3c6901..fb2d3aa 100644 --- a/crates/codegen/src/statement.rs +++ b/crates/codegen/src/statement.rs @@ -90,12 +90,14 @@ impl GenRust for Statement { else_branch, } => { cg.add("if "); + ctx.expr_ensure_semicolon = false; initial.condition.gen_rust(ctx, cg); cg.add(" "); cg.ensure_brackets_body(ctx, &initial.body); for else_if_branch in else_if { - cg.add("else if"); + cg.add(" else if "); + ctx.expr_ensure_semicolon = false; else_if_branch.condition.gen_rust(ctx, cg); cg.add(" "); cg.ensure_brackets_body(ctx, &else_if_branch.body); diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 4e5bfa5..4853f83 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -399,7 +399,7 @@ control_flow = { statement_branch = { "(" ~ expr ~ ")" ~ statement_body } -else_if = { +else_if = _{ "else" ~ "if" ~ statement_branch } diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index 73abdcb..1a14ec9 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -1,5 +1,3 @@ void main() { test_package::hello(); - - let idk = Bro::new(); } From d4dc1571b291d86b893a2c2255e20b547f06b576 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 4 Jun 2026 18:14:52 +0200 Subject: [PATCH 4/6] Tuple field access #59 --- crates/codegen/src/expr.rs | 8 ++++++++ crates/parser/src/ast/expr.rs | 1 + crates/parser/src/grammar.pest | 9 +++++++-- crates/parser/src/parser/common/expr.rs | 8 ++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/crates/codegen/src/expr.rs b/crates/codegen/src/expr.rs index 0de2c59..50641a9 100644 --- a/crates/codegen/src/expr.rs +++ b/crates/codegen/src/expr.rs @@ -153,6 +153,14 @@ impl GenRust for Vec { impl GenRust for Postfix { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { match self { + Postfix::TupleFieldAccess(field, generics) => cg.add(&format!( + ".{}{}", + field, + generics + .iter() + .map(|v| format!("::{}", v.get_rust())) + .collect::() + )), Postfix::FieldAccess(field, generics) => cg.add(&format!( ".{}{}", field.get_rust(), diff --git a/crates/parser/src/ast/expr.rs b/crates/parser/src/ast/expr.rs index 08c3af3..13365c3 100644 --- a/crates/parser/src/ast/expr.rs +++ b/crates/parser/src/ast/expr.rs @@ -50,6 +50,7 @@ pub enum MacroDelimiter { #[derive(Debug, Clone, Serialize)] pub enum Postfix { FieldAccess(Identifier, Option), + TupleFieldAccess(u8, Option), Call(Vec), MacroCall { inner: String, diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 4853f83..4a45207 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -486,7 +486,7 @@ macro_inner_v = @{ // ------------------------------------------------------ expr_path_segment = { - identifier ~ ("::" ~ generics)? + identifier ~ generics? } expr_path = { @@ -507,7 +507,11 @@ primary = { // ------------------------------------------------------ field_px = { - "." ~ identifier ~ ("::" ~ generics)? + "." ~ identifier ~ generics? +} + +tuple_field_px = { + "." ~ integer ~ generics? } call_px = { @@ -548,6 +552,7 @@ decrement = { postfix = { field_px + | tuple_field_px | call_px | macro_call_paren | macro_call_bracket diff --git a/crates/parser/src/parser/common/expr.rs b/crates/parser/src/parser/common/expr.rs index fd83e0e..12f076f 100644 --- a/crates/parser/src/parser/common/expr.rs +++ b/crates/parser/src/parser/common/expr.rs @@ -141,6 +141,14 @@ impl<'a> TryFrom> for Postfix { )) } + Rule::tuple_field_px => { + ast_expr!(Postfix::TupleFieldAccess( + Ok(inner.next().unwrap().as_str().parse().unwrap_or(255_u8)) + as AstResult<'_, u8>, + inner.next().map(Generics::try_from).transpose(), + )) + } + Rule::call_px => ast_expr!(Postfix::Call(collect_recovered(inner))), Rule::struct_px => ast_expr!(Postfix::StructCall(collect_recovered_map(inner, |p| { From 6cacfd71358fcf2416b7202dc7b5da464a4ecd93 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 4 Jun 2026 18:20:54 +0200 Subject: [PATCH 5/6] Identifier setting via struct #59 --- crates/codegen/src/expr.rs | 6 ++++-- crates/parser/src/ast/expr.rs | 2 +- crates/parser/src/grammar.pest | 2 +- crates/parser/src/parser/common/expr.rs | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/codegen/src/expr.rs b/crates/codegen/src/expr.rs index 50641a9..8cdbaca 100644 --- a/crates/codegen/src/expr.rs +++ b/crates/codegen/src/expr.rs @@ -200,8 +200,10 @@ impl GenRust for Postfix { for (name, expr) in fields { cg.add(&name.get_rust()); - cg.add(": "); - expr.gen_rust(ctx, cg); + if let Some(expr) = expr { + cg.add(": "); + expr.gen_rust(ctx, cg); + } cg.add(","); } diff --git a/crates/parser/src/ast/expr.rs b/crates/parser/src/ast/expr.rs index 13365c3..969cf21 100644 --- a/crates/parser/src/ast/expr.rs +++ b/crates/parser/src/ast/expr.rs @@ -56,7 +56,7 @@ pub enum Postfix { inner: String, delimiter: MacroDelimiter, }, - StructCall(Vec<(Identifier, Expression)>), + StructCall(Vec<(Identifier, Option)>), Assign(String, Box), Index(Expression), As(TypeExpr), diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 4a45207..cf4df27 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -523,7 +523,7 @@ macro_call_bracket = { "!" ~ "[" ~ macro_inner_v* ~ "]" } macro_call_brace = { "!" ~ "{" ~ macro_inner_v* ~ "}" } struct_field_decl = { - identifier ~ ":" ~ expr + identifier ~ (":" ~ expr)? } struct_px = { diff --git a/crates/parser/src/parser/common/expr.rs b/crates/parser/src/parser/common/expr.rs index 12f076f..b3236d8 100644 --- a/crates/parser/src/parser/common/expr.rs +++ b/crates/parser/src/parser/common/expr.rs @@ -155,7 +155,7 @@ impl<'a> TryFrom> for Postfix { let mut pi = p.into_inner(); Ok(( Identifier::try_from(pi.next().unwrap())?, - Expression::try_from(pi.next().unwrap()).get()?, + pi.next().map(Expression::try_from).transpose().get()?, )) }))), From 202f41c0e6aeb6620f7c6b417745fd3b146ece2e Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Thu, 4 Jun 2026 18:50:33 +0200 Subject: [PATCH 6/6] Fixed type/generics parsing --- crates/codegen/src/lib.rs | 19 +++++++------------ crates/codegen/src/top_level.rs | 8 +++++--- crates/parser/src/ast/mod.rs | 10 +++++----- crates/parser/src/grammar.pest | 13 ++++--------- crates/parser/src/parser/common/types.rs | 16 ++++++---------- crates/parser/src/parser/items/function.rs | 2 +- 6 files changed, 28 insertions(+), 40 deletions(-) diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index 6e397ce..a8f4433 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -208,19 +208,14 @@ pub fn get_static_type_path(path: &Path) -> String { impl GetRust for TypeExprKind { fn get_rust(&self) -> String { match self { - TypeExprKind::Path(path) => get_static_type_path(path), - TypeExprKind::Lifetime(name) => format!("'{}", name.get_rust()), - TypeExprKind::PathParams(path, params) => { - format!( - "{}<{}>", - get_static_type_path(path), - params - .into_iter() - .map(|t| t.get_rust()) - .collect::>() - .join(", ") - ) + TypeExprKind::Path(path, generics) => { + if let Some(generics) = generics { + format!("{}{}", get_static_type_path(path), generics.get_rust()) + } else { + get_static_type_path(path) + } } + TypeExprKind::Lifetime(name) => format!("'{}", name.get_rust()), TypeExprKind::Tuple(types) => format!( "({})", types diff --git a/crates/codegen/src/top_level.rs b/crates/codegen/src/top_level.rs index 79da978..bc4ef66 100644 --- a/crates/codegen/src/top_level.rs +++ b/crates/codegen/src/top_level.rs @@ -235,7 +235,7 @@ impl GenRust for (&Vec>, &Spanned) { let mut constructor_params = vec![VarDecl { name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])), type_: Some(TypeExpr( - TypeExprKind::Path(Path(vec![Identifier(String::from("Self"))])), + TypeExprKind::Path(Path(vec![Identifier(String::from("Self"))]), None), vec![TypePostfix::RefMut], )), }]; @@ -423,8 +423,10 @@ impl GenRust for TopLevelKind { let mut impl_ = impl_.clone(); impl_.item.trait_ = Some(impl_.item.target); - impl_.item.target = - TypeExpr(TypeExprKind::Path(Path(vec![name.clone()])), Vec::new()); + impl_.item.target = TypeExpr( + TypeExprKind::Path(Path(vec![name.clone()]), None), + Vec::new(), + ); impl_.gen_rust(ctx, cg); } diff --git a/crates/parser/src/ast/mod.rs b/crates/parser/src/ast/mod.rs index deff4e2..23e9ce6 100644 --- a/crates/parser/src/ast/mod.rs +++ b/crates/parser/src/ast/mod.rs @@ -31,8 +31,7 @@ pub enum TypePostfix { #[derive(Debug, Clone, Serialize)] pub enum TypeExprKind { - Path(Path), - PathParams(Path, Vec), + Path(Path, Option), Tuple(Vec), Lifetime(Identifier), } @@ -54,9 +53,10 @@ impl From for Generic { fn from(value: GenericDecl) -> Self { match value { GenericDecl::Lifetime(life) => Generic::Lifetime(life), - GenericDecl::Type(ty, _) => { - Generic::Type(TypeExpr(TypeExprKind::Path(Path(vec![ty])), Vec::new())) - } + GenericDecl::Type(ty, _) => Generic::Type(TypeExpr( + TypeExprKind::Path(Path(vec![ty]), None), + Vec::new(), + )), } } } diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index cf4df27..da34ad7 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -80,10 +80,10 @@ let_kw = { "let" } // ====================================================== // GENERICS // ====================================================== -generic_decl = { lifetime | (identifier ~ (":" ~ type_expr_param ~ ("+" ~ type_expr_param)*)?) } +generic_decl = { lifetime | (identifier ~ (":" ~ generic ~ ("+" ~ generic)*)?) } generics_decl = { "<" ~ (generic_decl ~ ("," ~ generic_decl)*)? ~ ">" } -generic = { lifetime | type_expr_param } +generic = { lifetime | type_expr } generics = { "<" ~ (generic ~ ("," ~ generic)*)? ~ ">" } // ====================================================== @@ -95,7 +95,7 @@ tuple_type = { } path_type = { - static_path ~ ("<" ~ (type_expr_param ~ ("," ~ type_expr_param)*)? ~ ">")? + static_path ~ generics? } ref_type = { @@ -114,11 +114,6 @@ lifetime = { "'" ~ identifier } -type_expr_param = { - type_expr - | lifetime -} - // ====================================================== // LITERALS // ====================================================== @@ -308,7 +303,7 @@ impl_decl = { // ====================================================== // Traits // ====================================================== -trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* } +trait_requirements = { ":" ~ generic ~ ("+" ~ generic)* } trait_item = _{ function_decl diff --git a/crates/parser/src/parser/common/types.rs b/crates/parser/src/parser/common/types.rs index c557e53..2bf19d6 100644 --- a/crates/parser/src/parser/common/types.rs +++ b/crates/parser/src/parser/common/types.rs @@ -2,7 +2,7 @@ use crate::{ Rule, ast::*, ast_ensure, ast_expr, - error::{AstError, GetLength, IntoErr, collect_recovered}, + error::{AstError, IntoErr, collect_recovered}, parser::{consume_rule, listen_rule}, }; @@ -53,14 +53,10 @@ impl<'a> TryFrom> for TypeExprKind { match rule { Rule::tuple_type => ast_expr!(TypeExprKind::Tuple(collect_recovered(inner))), Rule::path_type => { - let path = Path::try_from(inner.next().unwrap()); - let params = collect_recovered(inner); - - if params.len() == 0 { - ast_expr!(TypeExprKind::Path(path)) - } else { - ast_expr!(TypeExprKind::PathParams(path, params)) - } + ast_expr!(TypeExprKind::Path( + Path::try_from(inner.next().unwrap()), + inner.next().map(Generics::try_from).transpose() + )) } _ => AstError::bug_unimplemented(pair), } @@ -75,11 +71,11 @@ impl<'a> TryFrom> for TypeExpr { let mut inner = pair.clone().into_inner(); match rule { + Rule::generic => Self::try_from(inner.next().unwrap()), Rule::type_expr => ast_expr!(TypeExpr( inner.next().unwrap().try_into(), collect_recovered(inner), )), - Rule::type_expr_param => Self::try_from(inner.next().unwrap()), Rule::lifetime => ast_expr!(TypeExprKind::Lifetime(inner.next().unwrap().try_into())) .get_map(TypeExpr::no_px) .map(TypeExpr::no_px), diff --git a/crates/parser/src/parser/items/function.rs b/crates/parser/src/parser/items/function.rs index 1b2ff6c..8f75627 100644 --- a/crates/parser/src/parser/items/function.rs +++ b/crates/parser/src/parser/items/function.rs @@ -30,7 +30,7 @@ impl<'a> TryFrom> for FunctionDecl { VarDecl { name: name.clone(), type_: Some(TypeExpr( - TypeExprKind::Path(Path(vec![Identifier("Self".to_string())])), + TypeExprKind::Path(Path(vec![Identifier("Self".to_string())]), None), if is_ref { vec![if mutable { TypePostfix::RefMut