Skip to content

Commit 13fe33c

Browse files
committed
more thorough testing around associativity
1 parent 0b1120a commit 13fe33c

File tree

6 files changed

+479
-63
lines changed

6 files changed

+479
-63
lines changed

crates/formality-core/src/parse.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ pub type ParseResult<'t, T> = Result<SuccessfulParse<'t, T>, Set<ParseError<'t>>
168168
pub type TokenResult<'t, T> = Result<(T, &'t str), Set<ParseError<'t>>>;
169169

170170
/// Tracks the variables in scope at this point in parsing.
171-
#[derive(Clone, Debug)]
171+
#[derive(Clone, Debug, Default)]
172172
pub struct Scope<L: Language> {
173173
bindings: Vec<(String, CoreParameter<L>)>,
174174
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
use formality_core::{term, test};
2+
use std::sync::Arc;
3+
4+
#[term]
5+
pub enum Expr {
6+
#[cast]
7+
Id(Id),
8+
9+
#[grammar($v0 + $v1)]
10+
#[precedence(1)]
11+
Add(Arc<Expr>, Arc<Expr>),
12+
13+
#[grammar($v0 * $v1)]
14+
#[precedence(2)]
15+
Mul(Arc<Expr>, Arc<Expr>),
16+
}
17+
18+
formality_core::id!(Id);
19+
20+
#[test]
21+
fn add_mul() {
22+
let term: Expr = crate::ptt::term("a + b * c");
23+
expect_test::expect![[r#"
24+
Add(
25+
Id(
26+
a,
27+
),
28+
Mul(
29+
Id(
30+
b,
31+
),
32+
Id(
33+
c,
34+
),
35+
),
36+
)
37+
"#]]
38+
.assert_debug_eq(&term);
39+
}
40+
41+
#[test]
42+
fn mul_add() {
43+
let term: Expr = crate::ptt::term("a * b + c");
44+
expect_test::expect![[r#"
45+
Add(
46+
Mul(
47+
Id(
48+
a,
49+
),
50+
Id(
51+
b,
52+
),
53+
),
54+
Id(
55+
c,
56+
),
57+
)
58+
"#]]
59+
.assert_debug_eq(&term);
60+
}
61+
62+
#[test]
63+
fn add_add() {
64+
let term: Expr = crate::ptt::term("a + b + c");
65+
expect_test::expect![[r#"
66+
Add(
67+
Add(
68+
Id(
69+
a,
70+
),
71+
Id(
72+
b,
73+
),
74+
),
75+
Id(
76+
c,
77+
),
78+
)
79+
"#]]
80+
.assert_debug_eq(&term);
81+
}
82+
83+
#[test]
84+
fn mul_mul() {
85+
let term: Expr = crate::ptt::term("a * b * c");
86+
expect_test::expect![[r#"
87+
Mul(
88+
Mul(
89+
Id(
90+
a,
91+
),
92+
Id(
93+
b,
94+
),
95+
),
96+
Id(
97+
c,
98+
),
99+
)
100+
"#]]
101+
.assert_debug_eq(&term);
102+
}
103+
104+
#[test]
105+
fn mul_mul_mul() {
106+
let term: Expr = crate::ptt::term("a * b * c * d");
107+
expect_test::expect![[r#"
108+
Mul(
109+
Mul(
110+
Mul(
111+
Id(
112+
a,
113+
),
114+
Id(
115+
b,
116+
),
117+
),
118+
Id(
119+
c,
120+
),
121+
),
122+
Id(
123+
d,
124+
),
125+
)
126+
"#]]
127+
.assert_debug_eq(&term);
128+
}
129+
130+
#[test]
131+
fn add_add_mul_add() {
132+
let term: Expr = crate::ptt::term("a + b + c * d + e");
133+
expect_test::expect![[r#"
134+
Add(
135+
Add(
136+
Add(
137+
Id(
138+
a,
139+
),
140+
Id(
141+
b,
142+
),
143+
),
144+
Mul(
145+
Id(
146+
c,
147+
),
148+
Id(
149+
d,
150+
),
151+
),
152+
),
153+
Id(
154+
e,
155+
),
156+
)
157+
"#]]
158+
.assert_debug_eq(&term);
159+
}

tests/parser-torture-tests/main.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
mod ambiguity;
22
mod grammar;
3+
mod left_associative;
4+
mod none_associative;
35
mod path;
4-
mod precedence;
6+
mod right_associative;
57

68
formality_core::declare_language! {
79
mod ptt {
@@ -20,8 +22,26 @@ formality_core::declare_language! {
2022
}
2123
}
2224

25+
/// Used to parse `text` when we expect some remainder
26+
fn expect_remainder<T>(text: &str) -> (T, &str)
27+
where
28+
T: CoreParse<FormalityLang>,
29+
{
30+
match T::parse(&Default::default(), text) {
31+
Ok(parse) => {
32+
let (value, remainder) = parse.finish();
33+
assert!(
34+
!remainder.is_empty(),
35+
"expected to have remainder text, but parsed entire term `{text:?}`"
36+
);
37+
(value, remainder)
38+
}
39+
Err(errs) => panic!("encountered unexpected parse error: {errs:#?}"),
40+
}
41+
}
42+
2343
// Default language for our crate
24-
use formality_core::Fallible;
44+
use formality_core::{parse::CoreParse, Fallible};
2545
use ptt::FormalityLang;
2646

2747
fn main() -> Fallible<()> {
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
use formality_core::{term, test};
2+
use std::sync::Arc;
3+
4+
use crate::expect_remainder;
5+
6+
#[term]
7+
pub enum Expr {
8+
#[cast]
9+
Id(Id),
10+
11+
#[grammar($v0 + $v1)]
12+
#[precedence(1, none)]
13+
Add(Arc<Expr>, Arc<Expr>),
14+
15+
#[grammar($v0 * $v1)]
16+
#[precedence(2, none)]
17+
Mul(Arc<Expr>, Arc<Expr>),
18+
}
19+
20+
formality_core::id!(Id);
21+
22+
#[test]
23+
fn add_mul() {
24+
let term: Expr = crate::ptt::term("a + b * c");
25+
expect_test::expect![[r#"
26+
Add(
27+
Id(
28+
a,
29+
),
30+
Mul(
31+
Id(
32+
b,
33+
),
34+
Id(
35+
c,
36+
),
37+
),
38+
)
39+
"#]]
40+
.assert_debug_eq(&term);
41+
}
42+
43+
#[test]
44+
fn mul_add() {
45+
let term: Expr = crate::ptt::term("a * b + c");
46+
expect_test::expect![[r#"
47+
Add(
48+
Mul(
49+
Id(
50+
a,
51+
),
52+
Id(
53+
b,
54+
),
55+
),
56+
Id(
57+
c,
58+
),
59+
)
60+
"#]]
61+
.assert_debug_eq(&term);
62+
}
63+
64+
#[test]
65+
fn add_add() {
66+
let term = expect_remainder::<Expr>("a + b + c");
67+
expect_test::expect![[r#"
68+
(
69+
Add(
70+
Id(
71+
a,
72+
),
73+
Id(
74+
b,
75+
),
76+
),
77+
" + c",
78+
)
79+
"#]]
80+
.assert_debug_eq(&term);
81+
}
82+
83+
#[test]
84+
fn mul_mul() {
85+
let term = expect_remainder::<Expr>("a * b * c");
86+
expect_test::expect![[r#"
87+
(
88+
Mul(
89+
Id(
90+
a,
91+
),
92+
Id(
93+
b,
94+
),
95+
),
96+
" * c",
97+
)
98+
"#]]
99+
.assert_debug_eq(&term);
100+
}
101+
102+
#[test]
103+
fn mul_mul_mul() {
104+
let term = expect_remainder::<Expr>("a * b * c * d");
105+
expect_test::expect![[r#"
106+
(
107+
Mul(
108+
Id(
109+
a,
110+
),
111+
Id(
112+
b,
113+
),
114+
),
115+
" * c * d",
116+
)
117+
"#]]
118+
.assert_debug_eq(&term);
119+
}
120+
121+
#[test]
122+
fn add_add_mul_add() {
123+
let term = expect_remainder::<Expr>("a + b + c * d + e");
124+
expect_test::expect![[r#"
125+
(
126+
Add(
127+
Id(
128+
a,
129+
),
130+
Id(
131+
b,
132+
),
133+
),
134+
" + c * d + e",
135+
)
136+
"#]]
137+
.assert_debug_eq(&term);
138+
}

0 commit comments

Comments
 (0)