Skip to content

Commit

Permalink
Merge pull request #2 from vakaras/new-generator
Browse files Browse the repository at this point in the history
syn based generator + proc macro
  • Loading branch information
lqd authored Feb 4, 2020
2 parents 93a5741 + 7e55f9c commit a77fe1b
Show file tree
Hide file tree
Showing 29 changed files with 1,454 additions and 71 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/target
target
**/*.rs.bk
Cargo.lock
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2018"

[dependencies]
rustc-hash = "1.0.0"
syn = "1.0.8"
syn = { version = "1.0.8", features = ["extra-traits"] }
proc-macro2 = { version = "1.0.6", features = ["span-locations"] }
quote = "1.0.2"
log = "0.4.8"
Expand Down
13 changes: 13 additions & 0 deletions datapond-derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "datapond-derive"
version = "0.1.0"
authors = ["Vytautas Astrauskas <[email protected]>"]
edition = "2018"

[dependencies]
proc-macro-hack = "0.5"
datapond-macro = { path = "../datapond-macro" }

[dev-dependencies]
trybuild = "1.0"
datafrog = "2"
4 changes: 4 additions & 0 deletions datapond-derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use proc_macro_hack::proc_macro_hack;

#[proc_macro_hack]
pub use datapond_macro::datapond;
11 changes: 11 additions & 0 deletions datapond-derive/tests/fail/arg_mismatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use datapond_derive::datapond;

fn main() {
let inp = vec![(1, 2), (2, 3)];
let out;
datapond! {
input inp(x: u32, y: u32, z: u32)
output out(x: u32, y: u32)
out(x, y) :- inp(y, x).
};
}
11 changes: 11 additions & 0 deletions datapond-derive/tests/fail/arg_mismatch.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: Wrong number of arguments for inp: expected 2, found 3.
--> $DIR/arg_mismatch.rs:9:22
|
9 | out(x, y) :- inp(y, x).
| ^^^

error: The predicate inp was declared here.
--> $DIR/arg_mismatch.rs:7:15
|
7 | input inp(x: u32, y: u32, z: u32)
| ^^^
28 changes: 28 additions & 0 deletions datapond-derive/tests/fail/kwargs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use datapond_derive::datapond;

fn test1() {
let inp = vec![(1, 2, 0), (2, 3, 0)];
let out;
datapond! {
input inp(x: u32, y: u32, z: u32)
output out(x: u32, y: u32)
out(x, y) :- inp(.y=y, .y=x).
};
assert_eq!(out.len(), 2);
}

fn test2() {
let inp = vec![(1, 2, 0), (2, 3, 0)];
let out;
datapond! {
input inp(x: u32, y: u32, z: u32)
output out(x: u32, y: u32)
out(x, y) :- inp(.a=y, .y=x).
};
assert_eq!(out.len(), 2);
}

fn main() {
test1();
test2();
}
11 changes: 11 additions & 0 deletions datapond-derive/tests/fail/kwargs.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: Parameter already bound: y
--> $DIR/kwargs.rs:9:33
|
9 | out(x, y) :- inp(.y=y, .y=x).
| ^

error: Unknown parameter a in predicate inp. Available parameters are: x,y,z.
--> $DIR/kwargs.rs:20:27
|
20 | out(x, y) :- inp(.a=y, .y=x).
| ^
81 changes: 81 additions & 0 deletions datapond-derive/tests/pass/example1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use datapond_derive::datapond;

#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy)]
struct Origin(u64);
#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy)]
struct Loan(u64);
#[derive(PartialOrd, Ord, PartialEq, Eq, Clone, Copy)]
struct Point(u64);


fn main() {
let borrow_region = vec![];
let cfg_edge = vec![];
let killed = vec![];
let outlives = vec![];
let region_live_at = vec![];
let invalidates = vec![];
let errors;
datapond! {
input borrow_region(O: Origin, L: Loan, P: Point)
input cfg_edge(P: Point, Q: Point)
input killed(L: Loan, P: Point)
input outlives(O1: Origin, O2: Origin, P: Point)
input region_live_at(O: Origin, P: Point)
input invalidates(L: Loan, P: Point)
internal subset(O1: Origin, O2: Origin, P: Point)
internal requires(O: Origin, L: Loan, P: Point)
internal borrow_live_at(L: Loan, P: Point)
internal equals(O1: Origin, O2: Origin, P: Point)
output errors(L: Loan, P: Point)

// R1
subset(O1, O2, P) :- outlives(O1, O2, P).

// R2
subset(O1, O3, P) :-
subset(O1, O2, P),
outlives(O2, O3, P).

// R3: this is the transitive relation
equals(O1, O2, P) :-
subset(O1, O2, P),
subset(O2, O1, P).

// R4
equals(O1, O2, Q) :-
equals(O1, O2, P),
cfg_edge(P, Q).

// R5
requires(O2, L, P) :-
requires(O1, L, P),
equals(O1, O2, P).

// R6
requires(O, L, P) :- borrow_region(O, L, P).

// R7
requires(O2, L, P) :-
requires(O1, L, P),
subset(O1, O2, P).

// R8
requires(O, L, Q) :-
requires(O, L, P),
!killed(L, P),
cfg_edge(P, Q),
region_live_at(O, Q).

// R9
borrow_live_at(L, P) :-
requires(O, L, P),
region_live_at(O, P).

// R10
errors(L, P) :-
borrow_live_at(L, P),
invalidates(L, P).
};
assert!(errors.is_empty());
}
23 changes: 23 additions & 0 deletions datapond-derive/tests/pass/kwargs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use datapond_derive::datapond;

fn main() {
let inp = vec![(1, 2, 0), (2, 3, 0)];
let out;
let out2;
datapond! {
input inp(x: u32, y: u32, z: u32)

output out(x: u32, y: u32)
out(x, y) :- inp(.y=y, .x=x).

output out2(x: u32, y: u32)
out2(a, b) :- inp(.y=a, .x=b).
};
assert_eq!(out.len(), 2);
assert_eq!(out[0], (1, 2));
assert_eq!(out[1], (2, 3));

assert_eq!(out2.len(), 2);
assert_eq!(out2[0], (2, 1));
assert_eq!(out2[1], (3, 2));
}
31 changes: 31 additions & 0 deletions datapond-derive/tests/pass/missing_args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use datapond_derive::datapond;

fn test1() {
let inp = vec![(1, 2), (2, 3)];
let out;
datapond! {
input inp(x: u32, y: u32)
output out(x: u32)
out(x) :- inp(x, _).
};
assert!(out.len() == 2);
assert!(out[0] == (1,));
assert!(out[1] == (2,));
}

fn test2() {
let inp = vec![(1, 2), (2, 3)];
let out;
datapond! {
input inp(x: u32, y: u32)
output out(x: u32)
out(x) :- inp(x, _), inp(_, x).
};
assert!(out.len() == 1);
assert!(out[0] == (2,));
}

fn main() {
test1();
test2();
}
15 changes: 15 additions & 0 deletions datapond-derive/tests/pass/negation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use datapond_derive::datapond;

fn main() {
let inp = vec![(1, 2), (2, 3)];
let kill = vec![(3,), (4,), (5,)];
let out;
datapond! {
input inp(x: u32, y: u32)
input kill(y: u32)
output out(x: u32, y: u32)
out(x, y) :- inp(x, y), !kill(y).
};
assert!(out.len() == 1);
assert!(out[0] == (1, 2));
}
14 changes: 14 additions & 0 deletions datapond-derive/tests/pass/simple1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use datapond_derive::datapond;

fn main() {
let inp = vec![(1, 2), (2, 3)];
let out;
datapond! {
input inp(x: u32, y: u32)
output out(x: u32, y: u32)
out(x, y) :- inp(y, x).
};
assert!(out.len() == 2);
assert!(out[0] == (2, 1));
assert!(out[1] == (3, 2));
}
16 changes: 16 additions & 0 deletions datapond-derive/tests/pass/transitive_closure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use datapond_derive::datapond;

fn main() {
let inp = vec![(1, 2), (2, 3)];
let out;
datapond! {
input inp(x: u32, y: u32)
output out(x: u32, y: u32)
out(x, y) :- inp(x, y).
out(x, y) :- out(x, z), out(z, y).
};
assert!(out.len() == 3);
assert!(out[0] == (1, 2));
assert!(out[1] == (1, 3));
assert!(out[2] == (2, 3));
}
6 changes: 6 additions & 0 deletions datapond-derive/tests/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#[test]
fn tests() {
let runner = trybuild::TestCases::new();
runner.pass("tests/pass/*.rs");
runner.compile_fail("tests/fail/*.rs");
}
12 changes: 12 additions & 0 deletions datapond-macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "datapond-macro"
version = "0.1.0"
authors = ["Vytautas Astrauskas <[email protected]>"]
edition = "2018"

[lib]
proc-macro = true

[dependencies]
datapond = { path = ".." }
proc-macro-hack = "0.5"
7 changes: 7 additions & 0 deletions datapond-macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use proc_macro::TokenStream;
use proc_macro_hack::proc_macro_hack;

#[proc_macro_hack]
pub fn datapond(input: TokenStream) -> TokenStream {
datapond::generate_datafrog(input.into()).into()
}
2 changes: 1 addition & 1 deletion examples/generate_skeleton.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::env;
use datapond;
use std::env;

fn main() {
if env::var("RUST_LOG").is_ok() {
Expand Down
19 changes: 17 additions & 2 deletions src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! This file contains the typed AST.
use crate::data_structures::OrderedMap;
use proc_macro2::Ident;
use quote::ToTokens;
use std::collections::HashMap;
use std::fmt;

/// The predicate kind regarding IO.
Expand Down Expand Up @@ -98,6 +98,21 @@ pub enum Arg {
Wildcard,
}

impl Arg {
pub fn to_ident(&self) -> syn::Ident {
match self {
Arg::Ident(ident) => ident.clone(),
Arg::Wildcard => syn::Ident::new("_", proc_macro2::Span::call_site()),
}
}
pub fn is_wildcard(&self) -> bool {
match self {
Arg::Ident(_) => false,
Arg::Wildcard => true,
}
}
}

impl fmt::Display for Arg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Expand Down Expand Up @@ -188,6 +203,6 @@ impl fmt::Display for Rule {
/// A Datalog program.
#[derive(Debug, Clone)]
pub struct Program {
pub decls: HashMap<String, PredicateDecl>,
pub decls: OrderedMap<String, PredicateDecl>,
pub rules: Vec<Rule>,
}
Loading

0 comments on commit a77fe1b

Please sign in to comment.