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
+12 -2
View File
@@ -153,6 +153,14 @@ impl GenRust for Vec<Prefix> {
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::<String>()
)),
Postfix::FieldAccess(field, generics) => cg.add(&format!(
".{}{}",
field.get_rust(),
@@ -192,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(",");
}
+7 -12
View File
@@ -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::<Vec<_>>()
.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
+3 -1
View File
@@ -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);
+5 -3
View File
@@ -235,7 +235,7 @@ impl GenRust for (&Vec<Spanned<FieldDeclStmt>>, &Spanned<ClassConstructor>) {
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);
}
+2 -1
View File
@@ -50,12 +50,13 @@ pub enum MacroDelimiter {
#[derive(Debug, Clone, Serialize)]
pub enum Postfix {
FieldAccess(Identifier, Option<Generics>),
TupleFieldAccess(u8, Option<Generics>),
Call(Vec<Expression>),
MacroCall {
inner: String,
delimiter: MacroDelimiter,
},
StructCall(Vec<(Identifier, Expression)>),
StructCall(Vec<(Identifier, Option<Expression>)>),
Assign(String, Box<Expression>),
Index(Expression),
As(TypeExpr),
+5 -5
View File
@@ -31,8 +31,7 @@ pub enum TypePostfix {
#[derive(Debug, Clone, Serialize)]
pub enum TypeExprKind {
Path(Path),
PathParams(Path, Vec<TypeExpr>),
Path(Path, Option<Generics>),
Tuple(Vec<TypeExpr>),
Lifetime(Identifier),
}
@@ -54,9 +53,10 @@ impl From<GenericDecl> 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(),
)),
}
}
}
+20 -25
View File
@@ -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
// ======================================================
@@ -281,13 +276,13 @@ self_param = {
"self" ~ mutable? ~ deref_px?
}
method = {
visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list)? ~ ")" ~ block
method_args = _{
((self_param ~ ("," ~ param_list)?) | param_list) ~ ","?
}
class_item = _{
impl_decl
| method
| function_decl
}
class_decl = {
@@ -298,25 +293,20 @@ 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* ~ "}"
}
// ======================================================
// Traits
// ======================================================
trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* }
method_no_body = {
visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list)? ~ ")" ~ semicolon
}
trait_requirements = { ":" ~ generic ~ ("+" ~ generic)* }
trait_item = _{
method
| method_no_body
function_decl
}
trait_decl = {
@@ -328,7 +318,7 @@ trait_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 }
else_if = {
else_if = _{
"else" ~ "if" ~ statement_branch
}
@@ -491,7 +481,7 @@ macro_inner_v = @{
// ------------------------------------------------------
expr_path_segment = {
identifier ~ ("::" ~ generics)?
identifier ~ generics?
}
expr_path = {
@@ -512,7 +502,11 @@ primary = {
// ------------------------------------------------------
field_px = {
"." ~ identifier ~ ("::" ~ generics)?
"." ~ identifier ~ generics?
}
tuple_field_px = {
"." ~ integer ~ generics?
}
call_px = {
@@ -524,7 +518,7 @@ macro_call_bracket = { "!" ~ "[" ~ macro_inner_v* ~ "]" }
macro_call_brace = { "!" ~ "{" ~ macro_inner_v* ~ "}" }
struct_field_decl = {
identifier ~ ":" ~ expr
identifier ~ (":" ~ expr)?
}
struct_px = {
@@ -553,6 +547,7 @@ decrement = {
postfix = {
field_px
| tuple_field_px
| call_px
| macro_call_paren
| 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::struct_px => ast_expr!(Postfix::StructCall(collect_recovered_map(inner, |p| {
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()?,
))
}))),
+6 -10
View File
@@ -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<pest::iterators::Pair<'a, Rule>> 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<pest::iterators::Pair<'a, Rule>> 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),
+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()?))
}
Rule::method => Ok(ClassItem::Method(pair.try_into().get()?)),
Rule::function_decl => Ok(ClassItem::Method(pair.try_into().get()?)),
_ => 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>;
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 visibility = Visibility::try_from(&mut inner);
let return_type = TypeExpr::try_from(inner.next().unwrap());
@@ -30,7 +30,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> 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