@@ -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());
|
||||
if let Some(expr) = expr {
|
||||
cg.add(": ");
|
||||
expr.gen_rust(ctx, cg);
|
||||
}
|
||||
cg.add(",");
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ");
|
||||
ctx.expr_ensure_semicolon = false;
|
||||
else_if_branch.condition.gen_rust(ctx, cg);
|
||||
cg.add(" ");
|
||||
cg.ensure_brackets_body(ctx, &else_if_branch.body);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()?,
|
||||
))
|
||||
}))),
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user