+16
-15
@@ -4,10 +4,6 @@ pub mod top_level;
|
||||
|
||||
use mist_parser::ast::*;
|
||||
|
||||
pub fn get_mutable(mutable: bool) -> String {
|
||||
if mutable { "mut " } else { "" }.to_string()
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
pub expr_ensure_semicolon: bool,
|
||||
}
|
||||
@@ -238,34 +234,39 @@ impl GetRust for TypeExprKind {
|
||||
impl GenRust for Pattern {
|
||||
fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
|
||||
match self {
|
||||
Self::Id(id) => cg.add(&id.get_rust()),
|
||||
Self::Path(path) => cg.add(&path.get_rust()),
|
||||
Self::Path(mutable, path) => {
|
||||
if *mutable {
|
||||
cg.add("mut ");
|
||||
};
|
||||
|
||||
cg.add(&path.get_rust())
|
||||
}
|
||||
Self::Literal(lit) => lit.gen_rust(ctx, cg),
|
||||
|
||||
Self::Struct(path, ids) => {
|
||||
Self::Struct(path, inner) => {
|
||||
cg.add(&path.get_rust());
|
||||
cg.add(" {");
|
||||
for id in ids {
|
||||
cg.add(&id.get_rust());
|
||||
for pat in inner {
|
||||
pat.gen_rust(ctx, cg);
|
||||
cg.add(",");
|
||||
}
|
||||
cg.add("}");
|
||||
}
|
||||
|
||||
Self::NamedTuple(path, ids) => {
|
||||
Self::NamedTuple(path, inner) => {
|
||||
cg.add(&path.get_rust());
|
||||
cg.add(" (");
|
||||
for id in ids {
|
||||
cg.add(&id.get_rust());
|
||||
for pat in inner {
|
||||
pat.gen_rust(ctx, cg);
|
||||
cg.add(",");
|
||||
}
|
||||
cg.add(")");
|
||||
}
|
||||
|
||||
Self::Tuple(ids) => {
|
||||
Self::Tuple(inner) => {
|
||||
cg.add("(");
|
||||
for id in ids {
|
||||
cg.add(&id.get_rust());
|
||||
for pat in inner {
|
||||
pat.gen_rust(ctx, cg);
|
||||
cg.add(",");
|
||||
}
|
||||
cg.add(")");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use mist_parser::ast::*;
|
||||
|
||||
use crate::{Context, get_mutable};
|
||||
use crate::Context;
|
||||
|
||||
use crate::{GenRust, GetRust, RustCodegen};
|
||||
|
||||
@@ -59,7 +59,11 @@ impl GenRust for Statement {
|
||||
cg.add(" {");
|
||||
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() {
|
||||
cg.addln("");
|
||||
cg.add_indented("");
|
||||
@@ -158,13 +162,11 @@ impl GenRust for Statement {
|
||||
}
|
||||
|
||||
Statement::For {
|
||||
mutable,
|
||||
pattern,
|
||||
iterator,
|
||||
body,
|
||||
} => {
|
||||
cg.add("for ");
|
||||
cg.add(&get_mutable(*mutable));
|
||||
pattern.gen_rust(ctx, cg);
|
||||
cg.add(" in ");
|
||||
iterator.gen_rust(ctx, cg);
|
||||
@@ -186,8 +188,6 @@ impl GenRust for Statement {
|
||||
|
||||
impl GenRust for VarDecl {
|
||||
fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
|
||||
cg.add(&get_mutable(self.mutable));
|
||||
|
||||
self.name.gen_rust(ctx, cg);
|
||||
|
||||
cg.add(
|
||||
|
||||
@@ -212,8 +212,7 @@ impl GenRust for (&Vec<Spanned<FieldDeclStmt>>, &Spanned<ClassConstructor>) {
|
||||
cg.add_indentedln("}\n");
|
||||
|
||||
let mut constructor_params = vec![VarDecl {
|
||||
mutable: false,
|
||||
name: Pattern::Id(Identifier(String::from("self"))),
|
||||
name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])),
|
||||
type_: Some(TypeExpr(
|
||||
TypeExprKind::Path(Path(vec![Identifier(String::from("Self"))])),
|
||||
vec![TypePostfix::RefMut],
|
||||
|
||||
@@ -32,12 +32,11 @@ pub enum Literal {
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub enum Pattern {
|
||||
NamedTuple(Path, Vec<Identifier>),
|
||||
Struct(Path, Vec<Identifier>),
|
||||
Tuple(Vec<Identifier>),
|
||||
NamedTuple(Path, Vec<Box<Pattern>>),
|
||||
Struct(Path, Vec<Box<Pattern>>),
|
||||
Tuple(Vec<Box<Pattern>>),
|
||||
Literal(Literal),
|
||||
Path(Path),
|
||||
Id(Identifier),
|
||||
Path(bool, Path),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
|
||||
@@ -31,12 +31,11 @@ pub enum Statement {
|
||||
body: StatementBody,
|
||||
},
|
||||
For {
|
||||
mutable: bool,
|
||||
pattern: Pattern,
|
||||
iterator: Expression,
|
||||
body: StatementBody,
|
||||
},
|
||||
Match(Expression, Vec<(Vec<Pattern>, Expression)>),
|
||||
Match(Expression, Vec<Spanned<MatchItem>>),
|
||||
|
||||
VarDecl(VarDeclStmt),
|
||||
Return(Option<Expression>),
|
||||
@@ -44,9 +43,11 @@ pub enum Statement {
|
||||
Continue,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct MatchItem(pub Vec<Pattern>, pub Expression);
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct VarDecl {
|
||||
pub mutable: bool,
|
||||
pub name: Pattern,
|
||||
pub type_: Option<TypeExpr>,
|
||||
}
|
||||
|
||||
@@ -134,16 +134,24 @@ literal = {
|
||||
// PATTERNS
|
||||
// ======================================================
|
||||
|
||||
multi_pat_template = _{
|
||||
(pattern ~ ("," ~ pattern)*)?
|
||||
}
|
||||
|
||||
tuple_pattern = {
|
||||
"[" ~ (identifier ~ ("," ~ identifier)*) ~ "]"
|
||||
"[" ~ multi_pat_template ~ "]"
|
||||
}
|
||||
|
||||
named_tuple_pattern = {
|
||||
static_path ~ "[" ~ (identifier ~ ("," ~ identifier)*)? ~ "]"
|
||||
static_path ~ "[" ~ multi_pat_template ~ "]"
|
||||
}
|
||||
|
||||
struct_pattern = {
|
||||
static_path ~ "{" ~ (identifier ~ ("," ~ identifier)*)? ~ "}"
|
||||
static_path ~ "{" ~ multi_pat_template ~ "}"
|
||||
}
|
||||
|
||||
path_pattern = {
|
||||
mutable? ~ static_path
|
||||
}
|
||||
|
||||
pattern = _{
|
||||
@@ -151,7 +159,7 @@ pattern = _{
|
||||
| tuple_pattern
|
||||
| struct_pattern
|
||||
| literal
|
||||
| static_path
|
||||
| path_pattern
|
||||
}
|
||||
|
||||
// ======================================================
|
||||
@@ -171,7 +179,7 @@ meta = {
|
||||
}
|
||||
|
||||
meta_list = {
|
||||
meta ~ ("," ~ meta)* ~ ","?
|
||||
(meta ~ ("," ~ meta)* ~ ","?)?
|
||||
}
|
||||
|
||||
attributes = {
|
||||
@@ -182,7 +190,7 @@ attributes = {
|
||||
// DECLARATION HELPERS
|
||||
// ======================================================
|
||||
var_decl = {
|
||||
(var | type_expr) ~ mutable? ~ pattern
|
||||
(var | type_expr) ~ pattern
|
||||
}
|
||||
|
||||
field = {
|
||||
@@ -190,11 +198,11 @@ field = {
|
||||
}
|
||||
|
||||
field_list = {
|
||||
field ~ ("," ~ field)* ~ ","?
|
||||
(field ~ ("," ~ field)* ~ ","?)?
|
||||
}
|
||||
|
||||
param_list = {
|
||||
var_decl ~ ("," ~ var_decl)* ~ ","?
|
||||
(var_decl ~ ("," ~ var_decl)* ~ ","?)?
|
||||
}
|
||||
|
||||
// ======================================================
|
||||
@@ -252,7 +260,7 @@ enum_decl = {
|
||||
// ======================================================
|
||||
|
||||
class_constructor = {
|
||||
visibility? ~ "constructor" ~ generics_decl? ~ "(" ~ param_list? ~ ")" ~ block
|
||||
visibility? ~ "constructor" ~ generics_decl? ~ "(" ~ param_list ~ ")" ~ block
|
||||
}
|
||||
|
||||
class_fields = {
|
||||
@@ -268,7 +276,7 @@ self_param = {
|
||||
}
|
||||
|
||||
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 = _{
|
||||
@@ -297,7 +305,7 @@ impl_decl = {
|
||||
trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* }
|
||||
|
||||
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 = _{
|
||||
@@ -314,7 +322,7 @@ trait_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" ~ "(" ~ mutable? ~ pattern ~ ":" ~ expr ~ ")" ~ statement_body
|
||||
"for" ~ "(" ~ pattern ~ ":" ~ expr ~ ")" ~ statement_body
|
||||
}
|
||||
|
||||
loop_stmt = {
|
||||
|
||||
@@ -2,8 +2,7 @@ use crate::{
|
||||
Rule,
|
||||
ast::*,
|
||||
ast_expr,
|
||||
error::{AstError, AstResult, IntoErr},
|
||||
parser::listen_rule,
|
||||
error::{AstError, IntoErr},
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
let mutable: AstResult<'_, bool> = Ok(listen_rule(&mut inner, Rule::mutable));
|
||||
|
||||
let name = Pattern::try_from(inner.next().unwrap());
|
||||
|
||||
ast_expr!(VarDecl {
|
||||
type_: type_,
|
||||
mutable: mutable,
|
||||
name: name,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ use crate::{
|
||||
Rule,
|
||||
ast::*,
|
||||
ast_ensure, ast_expr,
|
||||
error::{AstError, IntoErr, collect_recovered},
|
||||
parser::consume_rule,
|
||||
error::{AstError, AstResult, IntoErr, collect_recovered, collect_recovered_map},
|
||||
parser::{consume_rule, listen_rule},
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
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(
|
||||
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(
|
||||
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::identifier => ast_expr!(Pattern::Id(pair.try_into())),
|
||||
|
||||
Rule::static_path => ast_expr!(Pattern::Path(pair.try_into())),
|
||||
Rule::path_pattern => ast_expr!(Pattern::Path(
|
||||
Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<'_, bool>,
|
||||
inner.next().unwrap().try_into()
|
||||
)),
|
||||
|
||||
_ => AstError::bug_unimplemented(pair),
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@ use crate::{
|
||||
Rule,
|
||||
ast::*,
|
||||
ast_ensure, ast_expr,
|
||||
error::{AstError, AstResult, IntoErr, collect_recovered},
|
||||
parser::listen_rule,
|
||||
error::{AstError, IntoErr, collect_recovered},
|
||||
};
|
||||
|
||||
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 {
|
||||
mutable: Ok(listen_rule(&mut inner, Rule::mutable)) as AstResult<'_, bool>,
|
||||
pattern: inner.next().unwrap().try_into(),
|
||||
iterator: 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(
|
||||
inner.next().unwrap().try_into(),
|
||||
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<_>>>(),
|
||||
collect_recovered(inner),
|
||||
)),
|
||||
|
||||
_ => 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()?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 mut param_inner = param.into_inner();
|
||||
let name = Pattern::Id(Identifier(String::from("self")));
|
||||
|
||||
let mutable = listen_rule(&mut param_inner, Rule::mutable);
|
||||
|
||||
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 {
|
||||
mutable: mutable && !is_ref,
|
||||
name: name.clone(),
|
||||
type_: Some(TypeExpr(
|
||||
TypeExprKind::Path(Path(vec![Identifier("Self".to_string())])),
|
||||
|
||||
Reference in New Issue
Block a user