Merge pull request #52 from mist-go/parser-patches

Parser patches
This commit is contained in:
2026-05-28 15:47:44 +02:00
committed by GitHub
10 changed files with 80 additions and 73 deletions
+16 -15
View File
@@ -4,10 +4,6 @@ pub mod top_level;
use mist_parser::ast::*; use mist_parser::ast::*;
pub fn get_mutable(mutable: bool) -> String {
if mutable { "mut " } else { "" }.to_string()
}
pub struct Context { pub struct Context {
pub expr_ensure_semicolon: bool, pub expr_ensure_semicolon: bool,
} }
@@ -238,34 +234,39 @@ impl GetRust for TypeExprKind {
impl GenRust for Pattern { impl GenRust for Pattern {
fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
match self { match self {
Self::Id(id) => cg.add(&id.get_rust()), Self::Path(mutable, path) => {
Self::Path(path) => cg.add(&path.get_rust()), if *mutable {
cg.add("mut ");
};
cg.add(&path.get_rust())
}
Self::Literal(lit) => lit.gen_rust(ctx, cg), Self::Literal(lit) => lit.gen_rust(ctx, cg),
Self::Struct(path, ids) => { Self::Struct(path, inner) => {
cg.add(&path.get_rust()); cg.add(&path.get_rust());
cg.add(" {"); cg.add(" {");
for id in ids { for pat in inner {
cg.add(&id.get_rust()); pat.gen_rust(ctx, cg);
cg.add(","); cg.add(",");
} }
cg.add("}"); cg.add("}");
} }
Self::NamedTuple(path, ids) => { Self::NamedTuple(path, inner) => {
cg.add(&path.get_rust()); cg.add(&path.get_rust());
cg.add(" ("); cg.add(" (");
for id in ids { for pat in inner {
cg.add(&id.get_rust()); pat.gen_rust(ctx, cg);
cg.add(","); cg.add(",");
} }
cg.add(")"); cg.add(")");
} }
Self::Tuple(ids) => { Self::Tuple(inner) => {
cg.add("("); cg.add("(");
for id in ids { for pat in inner {
cg.add(&id.get_rust()); pat.gen_rust(ctx, cg);
cg.add(","); cg.add(",");
} }
cg.add(")"); cg.add(")");
+6 -6
View File
@@ -1,6 +1,6 @@
use mist_parser::ast::*; use mist_parser::ast::*;
use crate::{Context, get_mutable}; use crate::Context;
use crate::{GenRust, GetRust, RustCodegen}; use crate::{GenRust, GetRust, RustCodegen};
@@ -59,7 +59,11 @@ impl GenRust for Statement {
cg.add(" {"); cg.add(" {");
cg.indent += 1; cg.indent += 1;
for (pat, body) in match_items { for match_item in match_items {
cg.add_indentedln(&match_item.get_comment());
let MatchItem(pat, body) = &match_item.item;
for (i, p) in pat.iter().enumerate() { for (i, p) in pat.iter().enumerate() {
cg.addln(""); cg.addln("");
cg.add_indented(""); cg.add_indented("");
@@ -158,13 +162,11 @@ impl GenRust for Statement {
} }
Statement::For { Statement::For {
mutable,
pattern, pattern,
iterator, iterator,
body, body,
} => { } => {
cg.add("for "); cg.add("for ");
cg.add(&get_mutable(*mutable));
pattern.gen_rust(ctx, cg); pattern.gen_rust(ctx, cg);
cg.add(" in "); cg.add(" in ");
iterator.gen_rust(ctx, cg); iterator.gen_rust(ctx, cg);
@@ -186,8 +188,6 @@ impl GenRust for Statement {
impl GenRust for VarDecl { impl GenRust for VarDecl {
fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
cg.add(&get_mutable(self.mutable));
self.name.gen_rust(ctx, cg); self.name.gen_rust(ctx, cg);
cg.add( cg.add(
+1 -2
View File
@@ -212,8 +212,7 @@ impl GenRust for (&Vec<Spanned<FieldDeclStmt>>, &Spanned<ClassConstructor>) {
cg.add_indentedln("}\n"); cg.add_indentedln("}\n");
let mut constructor_params = vec![VarDecl { let mut constructor_params = vec![VarDecl {
mutable: false, name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])),
name: Pattern::Id(Identifier(String::from("self"))),
type_: Some(TypeExpr( type_: Some(TypeExpr(
TypeExprKind::Path(Path(vec![Identifier(String::from("Self"))])), TypeExprKind::Path(Path(vec![Identifier(String::from("Self"))])),
vec![TypePostfix::RefMut], vec![TypePostfix::RefMut],
+4 -5
View File
@@ -32,12 +32,11 @@ pub enum Literal {
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub enum Pattern { pub enum Pattern {
NamedTuple(Path, Vec<Identifier>), NamedTuple(Path, Vec<Box<Pattern>>),
Struct(Path, Vec<Identifier>), Struct(Path, Vec<Box<Pattern>>),
Tuple(Vec<Identifier>), Tuple(Vec<Box<Pattern>>),
Literal(Literal), Literal(Literal),
Path(Path), Path(bool, Path),
Id(Identifier),
} }
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
+4 -3
View File
@@ -31,12 +31,11 @@ pub enum Statement {
body: StatementBody, body: StatementBody,
}, },
For { For {
mutable: bool,
pattern: Pattern, pattern: Pattern,
iterator: Expression, iterator: Expression,
body: StatementBody, body: StatementBody,
}, },
Match(Expression, Vec<(Vec<Pattern>, Expression)>), Match(Expression, Vec<Spanned<MatchItem>>),
VarDecl(VarDeclStmt), VarDecl(VarDeclStmt),
Return(Option<Expression>), Return(Option<Expression>),
@@ -44,9 +43,11 @@ pub enum Statement {
Continue, Continue,
} }
#[derive(Debug, Clone, Serialize)]
pub struct MatchItem(pub Vec<Pattern>, pub Expression);
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct VarDecl { pub struct VarDecl {
pub mutable: bool,
pub name: Pattern, pub name: Pattern,
pub type_: Option<TypeExpr>, pub type_: Option<TypeExpr>,
} }
+21 -13
View File
@@ -134,16 +134,24 @@ literal = {
// PATTERNS // PATTERNS
// ====================================================== // ======================================================
multi_pat_template = _{
(pattern ~ ("," ~ pattern)*)?
}
tuple_pattern = { tuple_pattern = {
"[" ~ (identifier ~ ("," ~ identifier)*) ~ "]" "[" ~ multi_pat_template ~ "]"
} }
named_tuple_pattern = { named_tuple_pattern = {
static_path ~ "[" ~ (identifier ~ ("," ~ identifier)*)? ~ "]" static_path ~ "[" ~ multi_pat_template ~ "]"
} }
struct_pattern = { struct_pattern = {
static_path ~ "{" ~ (identifier ~ ("," ~ identifier)*)? ~ "}" static_path ~ "{" ~ multi_pat_template ~ "}"
}
path_pattern = {
mutable? ~ static_path
} }
pattern = _{ pattern = _{
@@ -151,7 +159,7 @@ pattern = _{
| tuple_pattern | tuple_pattern
| struct_pattern | struct_pattern
| literal | literal
| static_path | path_pattern
} }
// ====================================================== // ======================================================
@@ -171,7 +179,7 @@ meta = {
} }
meta_list = { meta_list = {
meta ~ ("," ~ meta)* ~ ","? (meta ~ ("," ~ meta)* ~ ","?)?
} }
attributes = { attributes = {
@@ -182,7 +190,7 @@ attributes = {
// DECLARATION HELPERS // DECLARATION HELPERS
// ====================================================== // ======================================================
var_decl = { var_decl = {
(var | type_expr) ~ mutable? ~ pattern (var | type_expr) ~ pattern
} }
field = { field = {
@@ -190,11 +198,11 @@ field = {
} }
field_list = { field_list = {
field ~ ("," ~ field)* ~ ","? (field ~ ("," ~ field)* ~ ","?)?
} }
param_list = { param_list = {
var_decl ~ ("," ~ var_decl)* ~ ","? (var_decl ~ ("," ~ var_decl)* ~ ","?)?
} }
// ====================================================== // ======================================================
@@ -252,7 +260,7 @@ enum_decl = {
// ====================================================== // ======================================================
class_constructor = { class_constructor = {
visibility? ~ "constructor" ~ generics_decl? ~ "(" ~ param_list? ~ ")" ~ block visibility? ~ "constructor" ~ generics_decl? ~ "(" ~ param_list ~ ")" ~ block
} }
class_fields = { class_fields = {
@@ -268,7 +276,7 @@ self_param = {
} }
method = { method = {
visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list?)? ~ ")" ~ block visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list)? ~ ")" ~ block
} }
class_item = _{ class_item = _{
@@ -297,7 +305,7 @@ impl_decl = {
trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* } trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* }
method_no_body = { method_no_body = {
visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list?)? ~ ")" ~ semicolon visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list)? ~ ")" ~ semicolon
} }
trait_item = _{ trait_item = _{
@@ -314,7 +322,7 @@ trait_decl = {
// ====================================================== // ======================================================
function_decl = { function_decl = {
visibility? ~ type_expr ~ identifier ~ "(" ~ param_list? ~ ")" ~ block visibility? ~ type_expr ~ identifier ~ "(" ~ param_list ~ ")" ~ block
} }
// ====================================================== // ======================================================
@@ -415,7 +423,7 @@ c_for_stmt = {
} }
for_stmt = { for_stmt = {
"for" ~ "(" ~ mutable? ~ pattern ~ ":" ~ expr ~ ")" ~ statement_body "for" ~ "(" ~ pattern ~ ":" ~ expr ~ ")" ~ statement_body
} }
loop_stmt = { loop_stmt = {
+1 -5
View File
@@ -2,8 +2,7 @@ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_expr, ast_expr,
error::{AstError, AstResult, IntoErr}, error::{AstError, IntoErr},
parser::listen_rule,
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for VarDeclStmt { impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for VarDeclStmt {
@@ -63,13 +62,10 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for VarDecl {
}) })
.transpose(); .transpose();
let mutable: AstResult<'_, bool> = Ok(listen_rule(&mut inner, Rule::mutable));
let name = Pattern::try_from(inner.next().unwrap()); let name = Pattern::try_from(inner.next().unwrap());
ast_expr!(VarDecl { ast_expr!(VarDecl {
type_: type_, type_: type_,
mutable: mutable,
name: name, name: name,
}) })
} }
+11 -8
View File
@@ -7,8 +7,8 @@ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure, ast_expr,
error::{AstError, IntoErr, collect_recovered}, error::{AstError, AstResult, IntoErr, collect_recovered, collect_recovered_map},
parser::consume_rule, parser::{consume_rule, listen_rule},
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Identifier { impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Identifier {
@@ -60,23 +60,26 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Pattern {
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
match rule { match rule {
Rule::tuple_pattern => ast_expr!(Pattern::Tuple(collect_recovered(pair.into_inner()))), Rule::tuple_pattern => ast_expr!(Pattern::Tuple(collect_recovered_map(inner, |v| {
Self::try_from(v).map(Box::new)
}))),
Rule::named_tuple_pattern => ast_expr!(Pattern::NamedTuple( Rule::named_tuple_pattern => ast_expr!(Pattern::NamedTuple(
Path::try_from(inner.next().unwrap()), Path::try_from(inner.next().unwrap()),
collect_recovered(inner), collect_recovered_map(inner, |v| Self::try_from(v).map(Box::new)),
)), )),
Rule::struct_pattern => ast_expr!(Pattern::Struct( Rule::struct_pattern => ast_expr!(Pattern::Struct(
Path::try_from(inner.next().unwrap()), Path::try_from(inner.next().unwrap()),
collect_recovered(inner), collect_recovered_map(inner, |v| Self::try_from(v).map(Box::new)),
)), )),
Rule::literal => ast_expr!(Pattern::Literal(pair.try_into())), Rule::literal => ast_expr!(Pattern::Literal(pair.try_into())),
Rule::identifier => ast_expr!(Pattern::Id(pair.try_into())), Rule::path_pattern => ast_expr!(Pattern::Path(
Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<'_, bool>,
Rule::static_path => ast_expr!(Pattern::Path(pair.try_into())), inner.next().unwrap().try_into()
)),
_ => AstError::bug_unimplemented(pair), _ => AstError::bug_unimplemented(pair),
} }
+15 -12
View File
@@ -2,8 +2,7 @@ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure, ast_expr,
error::{AstError, AstResult, IntoErr, collect_recovered}, error::{AstError, IntoErr, collect_recovered},
parser::listen_rule,
}; };
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block { impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block {
@@ -97,7 +96,6 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
}), }),
Rule::for_stmt => ast_expr!(Statement::For { Rule::for_stmt => ast_expr!(Statement::For {
mutable: Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<'_, bool>,
pattern: inner.next().unwrap().try_into(), pattern: inner.next().unwrap().try_into(),
iterator: inner.next().unwrap().try_into(), iterator: inner.next().unwrap().try_into(),
body: inner.next().unwrap().try_into(), body: inner.next().unwrap().try_into(),
@@ -105,18 +103,23 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
Rule::match_stmt => ast_expr!(Statement::Match( Rule::match_stmt => ast_expr!(Statement::Match(
inner.next().unwrap().try_into(), inner.next().unwrap().try_into(),
inner collect_recovered(inner),
.map(|match_itms| {
let mut match_inner = match_itms.into_inner();
Ok((
collect_recovered(match_inner.next().unwrap().into_inner()).get()?,
Expression::try_from(match_inner.next().unwrap()).get()?,
))
})
.collect::<AstResult<'a, Vec<_>>>(),
)), )),
_ => AstError::bug_unimplemented(pair), _ => AstError::bug_unimplemented(pair),
} }
} }
} }
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for MatchItem {
type Error = AstError<'a, Self>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
let mut match_inner = pair.into_inner();
Ok(MatchItem(
collect_recovered(match_inner.next().unwrap().into_inner()).get()?,
Expression::try_from(match_inner.next().unwrap()).get()?,
))
}
}
+1 -4
View File
@@ -23,14 +23,11 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| { let self_param = consume_rule(&mut inner, Rule::self_param).map(|param| {
let mut param_inner = param.into_inner(); let mut param_inner = param.into_inner();
let name = Pattern::Id(Identifier(String::from("self")));
let mutable = listen_rule(&mut param_inner, Rule::mutable); let mutable = listen_rule(&mut param_inner, Rule::mutable);
let is_ref = listen_rule(&mut param_inner, Rule::deref_px); let is_ref = listen_rule(&mut param_inner, Rule::deref_px);
let name = Pattern::Path(mutable && !is_ref, Path(vec![Identifier(String::from("self"))]));
VarDecl { VarDecl {
mutable: mutable && !is_ref,
name: name.clone(), name: name.clone(),
type_: Some(TypeExpr( type_: Some(TypeExpr(
TypeExprKind::Path(Path(vec![Identifier("Self".to_string())])), TypeExprKind::Path(Path(vec![Identifier("Self".to_string())])),