Skip to content

Commit 9713970

Browse files
committed
ExprJump wip
1 parent ee5fb5b commit 9713970

File tree

2 files changed

+43
-16
lines changed

2 files changed

+43
-16
lines changed

rust/rustell/src/decode.rs

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ use chumsky::prelude::*;
44
use chumsky::text::whitespace;
55

66
pub trait Decode<'a, T>:
7-
Parser<'a, &'a str, T, extra::Err<Rich<'a, char>>>
7+
Parser<'a, &'a str, T, extra::Err<Rich<'a, char>>> + Clone
88
{
99
}
1010

1111
impl<'a, T, U> Decode<'a, T> for U where
1212
U: Parser<'a, &'a str, T, extra::Err<Rich<'a, char>>>
13+
+ Clone
1314
{
1415
}
1516

@@ -20,22 +21,26 @@ pub fn expr<'a>() -> impl Decode<'a, Vec<Expr<'a>>> {
2021
}
2122

2223
fn expr_ast<'a>() -> impl Decode<'a, Expr<'a>> {
23-
choice((expr_mod(), expr_use()))
24+
recursive(|expr_ast| {
25+
choice((
26+
expr_mod(),
27+
expr_use(),
28+
expr_jump(expr_ast),
29+
))
30+
})
2431
}
2532

2633
fn expr_mod<'a>() -> impl Decode<'a, Expr<'a>> {
2734
let tok =
2835
token(text::ascii::ident()).and_is(keyword().not());
29-
just("mod")
30-
.then_ignore(whitespace().at_least(1))
36+
space_after(just("mod"))
3137
.ignore_then(tok)
3238
.then_ignore(lexeme(";").or_not())
3339
.map(Expr::Mod)
3440
}
3541

3642
fn expr_use<'a>() -> impl Decode<'a, Expr<'a>> {
37-
just("use")
38-
.then_ignore(whitespace().at_least(1))
43+
space_after(just("use"))
3944
.ignore_then(expr_use_rec())
4045
.then_ignore(lexeme(";").or_not())
4146
.map(Expr::Use)
@@ -75,13 +80,31 @@ fn expr_use_rec<'a>() -> impl Decode<'a, ExprUse<'a>> {
7580
})
7681
}
7782

78-
fn expr_use_tok<'a>() -> impl Decode<'a, &'a str> + Clone {
83+
fn expr_use_tok<'a>() -> impl Decode<'a, &'a str> {
7984
token(text::ascii::ident()).and_is(
8085
keyword_except(&["crate", "super", "self", "Self"])
8186
.not(),
8287
)
8388
}
8489

90+
fn expr_jump<'a>(
91+
expr_ast: impl Decode<'a, Expr<'a>>,
92+
) -> impl Decode<'a, Expr<'a>> {
93+
choice((
94+
space_after(just("break"))
95+
.then_ignore(lexeme(";").or_not())
96+
.map(|_| ExprJump::Break),
97+
space_after(just("continue"))
98+
.then_ignore(lexeme(";").or_not())
99+
.map(|_| ExprJump::Continue),
100+
space_after(just("return"))
101+
.ignore_then(expr_ast)
102+
.then_ignore(lexeme(";").or_not())
103+
.map(|x| ExprJump::Return(Box::new(x))),
104+
))
105+
.map(Expr::Jump)
106+
}
107+
85108
fn expr_raw<'a>() -> impl Decode<'a, Expr<'a>> {
86109
any()
87110
.and_is(expr_ast().not())
@@ -91,13 +114,13 @@ fn expr_raw<'a>() -> impl Decode<'a, Expr<'a>> {
91114
.map(Expr::Raw)
92115
}
93116

94-
fn keyword<'a>() -> impl Decode<'a, &'a str> + Clone {
117+
fn keyword<'a>() -> impl Decode<'a, &'a str> {
95118
keyword_except(&[])
96119
}
97120

98121
fn keyword_except<'a>(
99122
except: &[&str],
100-
) -> impl Decode<'a, &'a str> + Clone {
123+
) -> impl Decode<'a, &'a str> {
101124
choice(
102125
[
103126
"as", "break", "const", "continue", "crate",
@@ -121,14 +144,18 @@ fn keyword_except<'a>(
121144
)
122145
}
123146

147+
fn space_after<'a>(
148+
tok: impl Decode<'a, &'a str>,
149+
) -> impl Decode<'a, &'a str> {
150+
tok.then_ignore(whitespace().at_least(1))
151+
}
152+
124153
fn token<'a>(
125-
tok: impl Decode<'a, &'a str> + Clone,
126-
) -> impl Decode<'a, &'a str> + Clone {
154+
tok: impl Decode<'a, &'a str>,
155+
) -> impl Decode<'a, &'a str> {
127156
whitespace().or_not().ignore_then(tok)
128157
}
129158

130-
fn lexeme<'a>(
131-
seq: &'a str,
132-
) -> impl Decode<'a, &'a str> + Clone {
159+
fn lexeme<'a>(seq: &'a str) -> impl Decode<'a, &'a str> {
133160
token(just(seq))
134161
}

rust/rustell/src/encode.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub fn expr<'a>(
1313
fn expr_ast<'a>(
1414
last: bool,
1515
ast: &'a Expr<'a>,
16-
) -> IntoIter<&'a str> {
16+
) -> impl Iterator<Item = &'a str> + 'a {
1717
let end = if last { vec![] } else { vec![";"] };
1818
match ast {
1919
Expr::Mod(x) => vec!["mod ", x, ";"],
@@ -58,7 +58,7 @@ fn expr_use<'a>(
5858

5959
fn expr_jump<'a>(
6060
ast: &'a ExprJump<'a>,
61-
) -> IntoIter<&'a str> {
61+
) -> impl Iterator<Item = &'a str> + 'a {
6262
match ast {
6363
ExprJump::Break => vec!["break"],
6464
ExprJump::Continue => vec!["continue"],

0 commit comments

Comments
 (0)