Skip to content

Commit 4547c1b

Browse files
authored
Support | as the disjunction token (#64)
1 parent 7f9747a commit 4547c1b

File tree

7 files changed

+43
-19
lines changed

7 files changed

+43
-19
lines changed

ascent/examples/ascent_disjunction_clause.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ ascent! {
1919

2020
relation even_or_square(i32);
2121

22-
even_or_square(x) <-- (even(x) || square(x));
22+
even_or_square(x) <-- (even(x) | square(x));
2323
}
2424

2525
fn main() {

ascent/src/exps.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// TODO delete this file
12
#![cfg(all(test, feature = "par"))]
23
#![allow(dead_code)]
34

ascent_macro/src/ascent_hir.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,9 @@ pub(crate) fn prog_get_relation<'a>(
520520
Err(Error::new(
521521
name.span(),
522522
format!(
523-
"wrong arity for relation `{name}` (expected {expected}, found {actual})",
524-
expected = arity,
525-
actual = rel.field_types.len()
523+
"wrong arity for relation `{name}` (expected {expected}, found {found})",
524+
expected = rel.field_types.len(),
525+
found = arity,
526526
),
527527
))
528528
} else {

ascent_macro/src/ascent_syntax.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -177,21 +177,34 @@ fn peek_macro_invocation(parse_stream: ParseStream) -> bool {
177177

178178
fn peek_if_or_let(parse_stream: ParseStream) -> bool { parse_stream.peek(Token![if]) || parse_stream.peek(Token![let]) }
179179

180+
#[derive(Parse, Clone)]
181+
enum DisjunctionToken {
182+
#[allow(unused)]
183+
#[peek(Token![||], name = "||")]
184+
OrOr(Token![||]),
185+
#[allow(unused)]
186+
#[peek(Token![|], name = "|")]
187+
Or(Token![|]),
188+
}
189+
180190
#[derive(Clone)]
181191
pub struct DisjunctionNode {
182192
paren: syn::token::Paren,
183-
disjuncts: Punctuated<Punctuated<BodyItemNode, Token![,]>, Token![||]>,
193+
disjuncts: Punctuated<Punctuated<BodyItemNode, Token![,]>, DisjunctionToken>,
184194
}
185195

186196
impl Parse for DisjunctionNode {
187197
fn parse(input: ParseStream) -> Result<Self> {
188198
let content;
189199
let paren = parenthesized!(content in input);
190-
let res: Punctuated<Punctuated<BodyItemNode, Token![,]>, Token![||]> =
191-
Punctuated::<Punctuated<BodyItemNode, Token![,]>, Token![||]>::parse_terminated_with(
200+
let res: Punctuated<Punctuated<BodyItemNode, Token![,]>, DisjunctionToken> =
201+
Punctuated::<Punctuated<BodyItemNode, Token![,]>, DisjunctionToken>::parse_terminated_with(
192202
&content,
193203
Punctuated::<BodyItemNode, Token![,]>::parse_separated_nonempty,
194204
)?;
205+
if res.pairs().any(|pair| matches!(pair.punct(), Some(DisjunctionToken::OrOr(_)))) {
206+
eprintln!("WARNING: In Ascent rules, use `|` as the disjunction token instead of `||`")
207+
}
195208
Ok(DisjunctionNode { paren, disjuncts: res })
196209
}
197210
}

ascent_tests/src/analysis_exp.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ ascent! {
166166

167167
ς(v.clone(), ρ2, a, tick(e, ρ, a, t, k)) <--
168168
ς(?e@Ref(x), ρ, a, t),
169-
(σ(ρ[x], ?Value(v, ρ2)) ||
169+
(σ(ρ[x], ?Value(v, ρ2)) |
170170
σnum(ρ[x], lit), let v = Lit(*lit), let ρ2 = ρ),
171171
σ(a, ?Kont(k));
172172

ascent_tests/src/macros_tests.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ fn test_macro_in_macro() {
1818
foo2(12, 11);
1919

2020
macro foo($x: ident, $y: ident){
21-
(foo1($x, $y) || foo2($x, $y)), if $x < $y,
21+
(foo1($x, $y) | foo2($x, $y)), if $x < $y,
2222
}
2323

2424
bar(x, y) <-- foo!(x, y);
@@ -51,7 +51,7 @@ fn test_macro_in_macro2() {
5151
relation res(Atomic);
5252

5353
macro ae($x: ident) {
54-
(res(?Atomic::Var(_var)), σ(_var, $x) ||
54+
(res(?Atomic::Var(_var)), σ(_var, $x) |
5555
res(?Atomic::Val($x)))
5656
}
5757

@@ -201,7 +201,7 @@ fn test_macro_in_macro7() {
201201
macro bar($x: ident, $y: expr) { bar(?Some($x), $y) }
202202

203203
macro foo2($x: expr, $y: expr) {
204-
foo!($x, $y), let x = $x, for x2 in [1, 2], ((foo(x, x2), let y = $y, let _ = println!("{}", y)) || if true, for y in [$y, $y]),
204+
foo!($x, $y), let x = $x, for x2 in [1, 2], ((foo(x, x2), let y = $y, let _ = println!("{}", y)) | if true, for y in [$y, $y]),
205205
foo!(x + 0, y - 0), foo(x, y), foo!(x, y),
206206
let z = |x: i32| {x}, foo(z(*x), z(*y))
207207
}

ascent_tests/src/tests.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -402,24 +402,34 @@ fn test_dl_disjunctions() {
402402
relation bar(i32, i32);
403403

404404
small(x) <-- for x in 0..5;
405-
foo1(0, 4);
406-
foo1(1, 4);
407-
foo1(2, 6);
405+
foo1(0, 4); foo1(1, 4); foo1(2, 6);
408406

409-
foo2(3, 30);
410-
foo2(2, 20);
411-
foo2(8, 21);
412-
foo2(9, 21);
407+
foo2(3, 30); foo2(2, 20); foo2(8, 21); foo2(9, 21);
413408

414409
bar(x.clone(), y.clone()) <-- ((for x in 3..10), small(x) || foo1(x,_y)), (foo2(x,y));
415-
416410
};
417411
let mut prog = AscentProgram::default();
418412
prog.run();
419413
println!("bar: {:?}", prog.bar);
420414
assert_rels_eq!([(3, 30), (2, 20)], prog.bar);
421415
}
422416

417+
#[test]
418+
fn test_dl_disjunctions2() {
419+
let res = ascent_run! {
420+
relation road(&'static str, &'static str);
421+
relation rail(&'static str, &'static str);
422+
423+
road("A", "B"); road("B", "C"); rail("C", "D");
424+
425+
relation connected(&'static str, &'static str);
426+
427+
connected(x, y) <-- (road(x, y) | rail(x, y));
428+
connected(x, z) <-- connected(x, y), (road(y, z) | rail(y, z));
429+
};
430+
assert!(res.connected.contains(&("A", "D")));
431+
}
432+
423433
#[test]
424434
fn test_dl_repeated_vars() {
425435
ascent_m_par! {

0 commit comments

Comments
 (0)