Merge pull request #64 from mist-go/syntax-patches

Syntax patches
This commit is contained in:
2026-06-04 19:24:40 +02:00
committed by GitHub
11 changed files with 72 additions and 63 deletions
+10
View File
@@ -153,6 +153,14 @@ impl GenRust for Vec<Prefix> {
impl GenRust for Postfix { impl GenRust for Postfix {
fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
match self { match self {
Postfix::TupleFieldAccess(field, generics) => cg.add(&format!(
".{}{}",
field,
generics
.iter()
.map(|v| format!("::{}", v.get_rust()))
.collect::<String>()
)),
Postfix::FieldAccess(field, generics) => cg.add(&format!( Postfix::FieldAccess(field, generics) => cg.add(&format!(
".{}{}", ".{}{}",
field.get_rust(), field.get_rust(),
@@ -192,8 +200,10 @@ impl GenRust for Postfix {
for (name, expr) in fields { for (name, expr) in fields {
cg.add(&name.get_rust()); cg.add(&name.get_rust());
if let Some(expr) = expr {
cg.add(": "); cg.add(": ");
expr.gen_rust(ctx, cg); expr.gen_rust(ctx, cg);
}
cg.add(","); cg.add(",");
} }
+7 -12
View File
@@ -208,19 +208,14 @@ pub fn get_static_type_path(path: &Path) -> String {
impl GetRust for TypeExprKind { impl GetRust for TypeExprKind {
fn get_rust(&self) -> String { fn get_rust(&self) -> String {
match self { match self {
TypeExprKind::Path(path) => get_static_type_path(path), TypeExprKind::Path(path, generics) => {
TypeExprKind::Lifetime(name) => format!("'{}", name.get_rust()), if let Some(generics) = generics {
TypeExprKind::PathParams(path, params) => { format!("{}{}", get_static_type_path(path), generics.get_rust())
format!( } else {
"{}<{}>", get_static_type_path(path)
get_static_type_path(path),
params
.into_iter()
.map(|t| t.get_rust())
.collect::<Vec<_>>()
.join(", ")
)
} }
}
TypeExprKind::Lifetime(name) => format!("'{}", name.get_rust()),
TypeExprKind::Tuple(types) => format!( TypeExprKind::Tuple(types) => format!(
"({})", "({})",
types types
+2
View File
@@ -90,12 +90,14 @@ impl GenRust for Statement {
else_branch, else_branch,
} => { } => {
cg.add("if "); cg.add("if ");
ctx.expr_ensure_semicolon = false;
initial.condition.gen_rust(ctx, cg); initial.condition.gen_rust(ctx, cg);
cg.add(" "); cg.add(" ");
cg.ensure_brackets_body(ctx, &initial.body); cg.ensure_brackets_body(ctx, &initial.body);
for else_if_branch in else_if { 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); else_if_branch.condition.gen_rust(ctx, cg);
cg.add(" "); cg.add(" ");
cg.ensure_brackets_body(ctx, &else_if_branch.body); cg.ensure_brackets_body(ctx, &else_if_branch.body);
+5 -3
View File
@@ -235,7 +235,7 @@ impl GenRust for (&Vec<Spanned<FieldDeclStmt>>, &Spanned<ClassConstructor>) {
let mut constructor_params = vec![VarDecl { let mut constructor_params = vec![VarDecl {
name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])), name: Pattern::Path(false, Path(vec![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"))]), None),
vec![TypePostfix::RefMut], vec![TypePostfix::RefMut],
)), )),
}]; }];
@@ -423,8 +423,10 @@ impl GenRust for TopLevelKind {
let mut impl_ = impl_.clone(); let mut impl_ = impl_.clone();
impl_.item.trait_ = Some(impl_.item.target); impl_.item.trait_ = Some(impl_.item.target);
impl_.item.target = impl_.item.target = TypeExpr(
TypeExpr(TypeExprKind::Path(Path(vec![name.clone()])), Vec::new()); TypeExprKind::Path(Path(vec![name.clone()]), None),
Vec::new(),
);
impl_.gen_rust(ctx, cg); impl_.gen_rust(ctx, cg);
} }
+2 -1
View File
@@ -50,12 +50,13 @@ pub enum MacroDelimiter {
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub enum Postfix { pub enum Postfix {
FieldAccess(Identifier, Option<Generics>), FieldAccess(Identifier, Option<Generics>),
TupleFieldAccess(u8, Option<Generics>),
Call(Vec<Expression>), Call(Vec<Expression>),
MacroCall { MacroCall {
inner: String, inner: String,
delimiter: MacroDelimiter, delimiter: MacroDelimiter,
}, },
StructCall(Vec<(Identifier, Expression)>), StructCall(Vec<(Identifier, Option<Expression>)>),
Assign(String, Box<Expression>), Assign(String, Box<Expression>),
Index(Expression), Index(Expression),
As(TypeExpr), As(TypeExpr),
+5 -5
View File
@@ -31,8 +31,7 @@ pub enum TypePostfix {
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub enum TypeExprKind { pub enum TypeExprKind {
Path(Path), Path(Path, Option<Generics>),
PathParams(Path, Vec<TypeExpr>),
Tuple(Vec<TypeExpr>), Tuple(Vec<TypeExpr>),
Lifetime(Identifier), Lifetime(Identifier),
} }
@@ -54,9 +53,10 @@ impl From<GenericDecl> for Generic {
fn from(value: GenericDecl) -> Self { fn from(value: GenericDecl) -> Self {
match value { match value {
GenericDecl::Lifetime(life) => Generic::Lifetime(life), GenericDecl::Lifetime(life) => Generic::Lifetime(life),
GenericDecl::Type(ty, _) => { GenericDecl::Type(ty, _) => Generic::Type(TypeExpr(
Generic::Type(TypeExpr(TypeExprKind::Path(Path(vec![ty])), Vec::new())) TypeExprKind::Path(Path(vec![ty]), None),
} Vec::new(),
)),
} }
} }
} }
+20 -25
View File
@@ -80,10 +80,10 @@ let_kw = { "let" }
// ====================================================== // ======================================================
// GENERICS // GENERICS
// ====================================================== // ======================================================
generic_decl = { lifetime | (identifier ~ (":" ~ type_expr_param ~ ("+" ~ type_expr_param)*)?) } generic_decl = { lifetime | (identifier ~ (":" ~ generic ~ ("+" ~ generic)*)?) }
generics_decl = { "<" ~ (generic_decl ~ ("," ~ generic_decl)*)? ~ ">" } generics_decl = { "<" ~ (generic_decl ~ ("," ~ generic_decl)*)? ~ ">" }
generic = { lifetime | type_expr_param } generic = { lifetime | type_expr }
generics = { "<" ~ (generic ~ ("," ~ generic)*)? ~ ">" } generics = { "<" ~ (generic ~ ("," ~ generic)*)? ~ ">" }
// ====================================================== // ======================================================
@@ -95,7 +95,7 @@ tuple_type = {
} }
path_type = { path_type = {
static_path ~ ("<" ~ (type_expr_param ~ ("," ~ type_expr_param)*)? ~ ">")? static_path ~ generics?
} }
ref_type = { ref_type = {
@@ -114,11 +114,6 @@ lifetime = {
"'" ~ identifier "'" ~ identifier
} }
type_expr_param = {
type_expr
| lifetime
}
// ====================================================== // ======================================================
// LITERALS // LITERALS
// ====================================================== // ======================================================
@@ -281,13 +276,13 @@ self_param = {
"self" ~ mutable? ~ deref_px? "self" ~ mutable? ~ deref_px?
} }
method = { method_args = _{
visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list)? ~ ")" ~ block ((self_param ~ ("," ~ param_list)?) | param_list) ~ ","?
} }
class_item = _{ class_item = _{
impl_decl impl_decl
| method | function_decl
} }
class_decl = { class_decl = {
@@ -298,25 +293,20 @@ class_decl = {
// IMPL // IMPL
// ====================================================== // ======================================================
impl_for_decl = { 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_decl = {
"impl" ~ generics_decl? ~ type_expr ~ "{" ~ method* ~ "}" "impl" ~ generics_decl? ~ type_expr ~ "{" ~ function_decl* ~ "}"
} }
// ====================================================== // ======================================================
// Traits // Traits
// ====================================================== // ======================================================
trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* } trait_requirements = { ":" ~ generic ~ ("+" ~ generic)* }
method_no_body = {
visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list)? ~ ")" ~ semicolon
}
trait_item = _{ trait_item = _{
method function_decl
| method_no_body
} }
trait_decl = { trait_decl = {
@@ -328,7 +318,7 @@ trait_decl = {
// ====================================================== // ======================================================
function_decl = { function_decl = {
visibility? ~ type_expr ~ identifier ~ "(" ~ param_list ~ ")" ~ block visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ (block | semicolon)
} }
// ====================================================== // ======================================================
@@ -404,7 +394,7 @@ control_flow = {
statement_branch = { "(" ~ expr ~ ")" ~ statement_body } statement_branch = { "(" ~ expr ~ ")" ~ statement_body }
else_if = { else_if = _{
"else" ~ "if" ~ statement_branch "else" ~ "if" ~ statement_branch
} }
@@ -491,7 +481,7 @@ macro_inner_v = @{
// ------------------------------------------------------ // ------------------------------------------------------
expr_path_segment = { expr_path_segment = {
identifier ~ ("::" ~ generics)? identifier ~ generics?
} }
expr_path = { expr_path = {
@@ -512,7 +502,11 @@ primary = {
// ------------------------------------------------------ // ------------------------------------------------------
field_px = { field_px = {
"." ~ identifier ~ ("::" ~ generics)? "." ~ identifier ~ generics?
}
tuple_field_px = {
"." ~ integer ~ generics?
} }
call_px = { call_px = {
@@ -524,7 +518,7 @@ macro_call_bracket = { "!" ~ "[" ~ macro_inner_v* ~ "]" }
macro_call_brace = { "!" ~ "{" ~ macro_inner_v* ~ "}" } macro_call_brace = { "!" ~ "{" ~ macro_inner_v* ~ "}" }
struct_field_decl = { struct_field_decl = {
identifier ~ ":" ~ expr identifier ~ (":" ~ expr)?
} }
struct_px = { struct_px = {
@@ -553,6 +547,7 @@ decrement = {
postfix = { postfix = {
field_px field_px
| tuple_field_px
| call_px | call_px
| macro_call_paren | macro_call_paren
| macro_call_bracket | macro_call_bracket
+9 -1
View File
@@ -141,13 +141,21 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> 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::call_px => ast_expr!(Postfix::Call(collect_recovered(inner))),
Rule::struct_px => ast_expr!(Postfix::StructCall(collect_recovered_map(inner, |p| { Rule::struct_px => ast_expr!(Postfix::StructCall(collect_recovered_map(inner, |p| {
let mut pi = p.into_inner(); let mut pi = p.into_inner();
Ok(( Ok((
Identifier::try_from(pi.next().unwrap())?, Identifier::try_from(pi.next().unwrap())?,
Expression::try_from(pi.next().unwrap()).get()?, pi.next().map(Expression::try_from).transpose().get()?,
)) ))
}))), }))),
+6 -10
View File
@@ -2,7 +2,7 @@ use crate::{
Rule, Rule,
ast::*, ast::*,
ast_ensure, ast_expr, ast_ensure, ast_expr,
error::{AstError, GetLength, IntoErr, collect_recovered}, error::{AstError, IntoErr, collect_recovered},
parser::{consume_rule, listen_rule}, parser::{consume_rule, listen_rule},
}; };
@@ -53,14 +53,10 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExprKind {
match rule { match rule {
Rule::tuple_type => ast_expr!(TypeExprKind::Tuple(collect_recovered(inner))), Rule::tuple_type => ast_expr!(TypeExprKind::Tuple(collect_recovered(inner))),
Rule::path_type => { Rule::path_type => {
let path = Path::try_from(inner.next().unwrap()); ast_expr!(TypeExprKind::Path(
let params = collect_recovered(inner); Path::try_from(inner.next().unwrap()),
inner.next().map(Generics::try_from).transpose()
if params.len() == 0 { ))
ast_expr!(TypeExprKind::Path(path))
} else {
ast_expr!(TypeExprKind::PathParams(path, params))
}
} }
_ => AstError::bug_unimplemented(pair), _ => AstError::bug_unimplemented(pair),
} }
@@ -75,11 +71,11 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TypeExpr {
let mut inner = pair.clone().into_inner(); let mut inner = pair.clone().into_inner();
match rule { match rule {
Rule::generic => Self::try_from(inner.next().unwrap()),
Rule::type_expr => ast_expr!(TypeExpr( Rule::type_expr => ast_expr!(TypeExpr(
inner.next().unwrap().try_into(), inner.next().unwrap().try_into(),
collect_recovered(inner), collect_recovered(inner),
)), )),
Rule::type_expr_param => Self::try_from(inner.next().unwrap()),
Rule::lifetime => ast_expr!(TypeExprKind::Lifetime(inner.next().unwrap().try_into())) Rule::lifetime => ast_expr!(TypeExprKind::Lifetime(inner.next().unwrap().try_into()))
.get_map(TypeExpr::no_px) .get_map(TypeExpr::no_px)
.map(TypeExpr::no_px), .map(TypeExpr::no_px),
+1 -1
View File
@@ -42,7 +42,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for ClassItem {
Ok(ClassItem::ImplDecl(pair.try_into().get()?)) 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), _ => AstError::bug_unimplemented(pair),
} }
+2 -2
View File
@@ -10,7 +10,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
type Error = AstError<'a, Self>; type Error = AstError<'a, Self>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> { fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
ast_ensure!(pair, Rule::function_decl, Rule::method, Rule::method_no_body => { ast_ensure!(pair, Rule::function_decl => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
let visibility = Visibility::try_from(&mut inner); let visibility = Visibility::try_from(&mut inner);
let return_type = TypeExpr::try_from(inner.next().unwrap()); let return_type = TypeExpr::try_from(inner.next().unwrap());
@@ -30,7 +30,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for FunctionDecl {
VarDecl { VarDecl {
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())]), None),
if is_ref { if is_ref {
vec![if mutable { vec![if mutable {
TypePostfix::RefMut TypePostfix::RefMut