Skip to content

Commit

Permalink
Fix a bug in typechecking and add regression tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
vakaras committed Jan 14, 2020
1 parent 75f5bbd commit e04fe26
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 16 deletions.
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).
| ^
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));
}
36 changes: 20 additions & 16 deletions src/typechecker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,42 +117,46 @@ fn check_body(
.collect()
}
past::ArgList::Named(named_args) => {
let kwargs: HashMap<_, _> = named_args
.into_iter()
.map(|named_arg| (named_arg.param.to_string(), named_arg.arg))
.collect();
let mut args = Vec::new();
let mut kwargs = HashMap::new();
let mut used_parameters = HashSet::new();
for named_arg in named_args {
let param_name = named_arg.param.to_string();
if used_parameters.contains(&param_name) {
return Err(Error::new(
format!("Parameter already bound: {}", param_name),
named_arg.param.span(),
));
}
used_parameters.insert(param_name.clone());
kwargs.insert(param_name, named_arg);
}
let mut args = Vec::new();
let mut available_parameters = HashSet::new();
for parameter in &decl.parameters {
let param_name = parameter.name.to_string();
let arg = match kwargs.get(&param_name) {
Some(ident) => {
Some(past::NamedArg { arg: ident, .. }) => {
let ident_str = ident.to_string();
if used_parameters.contains(&ident_str) {
return Err(Error::new(
format!("Parameter already bound: {}", ident_str),
ident.span(),
));
}
used_parameters.insert(ident_str);
ast::Arg::Ident(ident.clone())
}
None => ast::Arg::Wildcard,
};
available_parameters.insert(param_name);
args.push(arg);
}
for key in kwargs.keys() {
if !used_parameters.contains(key) {
let available_parameters: Vec<_> = used_parameters.iter().map(|parameter| parameter.to_string()).collect();
if !available_parameters.contains(key) {
let available_parameters: Vec<_> = available_parameters.into_iter().collect();
let parameter_span = kwargs[key].param.span();
return Err(Error::new(
format!("Unknown parameter {} in predicate {}. Available parameters are: {}.",
key, literal.predicate, available_parameters.join(","),
),
literal.predicate.span(),
parameter_span,
));
}
}
if kwargs.len() != used_parameters.len() {}
args
}
};
Expand Down

0 comments on commit e04fe26

Please sign in to comment.