Get unary negation working.
This commit is contained in:
@@ -8,6 +8,7 @@ use proptest::{
|
||||
use std::collections::HashMap;
|
||||
|
||||
const VALID_VARIABLE_NAMES: &str = r"[a-z][a-zA-Z0-9_]*";
|
||||
const OPERATORS: &[(&str, usize)] = &[("+", 2), ("-", 1), ("-", 2), ("*", 2), ("/", 2)];
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Name(String);
|
||||
@@ -26,40 +27,34 @@ impl Arbitrary for Program {
|
||||
type Strategy = BoxedStrategy<Self>;
|
||||
|
||||
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
|
||||
let optionals = Vec::<Option<(Name, ConstantType)>>::arbitrary();
|
||||
let optionals = Vec::<(Name, ConstantType, u8)>::arbitrary();
|
||||
|
||||
optionals
|
||||
.prop_flat_map(|mut possible_names| {
|
||||
let mut statements = Vec::new();
|
||||
let mut defined_variables: HashMap<String, ConstantType> = HashMap::new();
|
||||
|
||||
for possible_name in possible_names.drain(..) {
|
||||
match possible_name {
|
||||
None if defined_variables.is_empty() => continue,
|
||||
None => statements.push(
|
||||
for (possible_name, possible_type, dice_roll) in possible_names.drain(..) {
|
||||
if !defined_variables.is_empty() && dice_roll < 100 {
|
||||
statements.push(
|
||||
Union::new(defined_variables.keys().map(|name| {
|
||||
Just(Statement::Print(Location::manufactured(), name.to_string()))
|
||||
}))
|
||||
.boxed(),
|
||||
),
|
||||
Some((new_name, new_type)) => {
|
||||
let closures_name = new_name.0.clone();
|
||||
let retval = Expression::arbitrary_with((
|
||||
Some(defined_variables.clone()),
|
||||
Some(new_type),
|
||||
))
|
||||
.prop_map(move |exp| {
|
||||
Statement::Binding(
|
||||
Location::manufactured(),
|
||||
closures_name.clone(),
|
||||
exp,
|
||||
)
|
||||
})
|
||||
.boxed();
|
||||
);
|
||||
} else {
|
||||
let closures_name = possible_name.0.clone();
|
||||
let retval = Expression::arbitrary_with((
|
||||
Some(defined_variables.clone()),
|
||||
Some(possible_type),
|
||||
))
|
||||
.prop_map(move |exp| {
|
||||
Statement::Binding(Location::manufactured(), closures_name.clone(), exp)
|
||||
})
|
||||
.boxed();
|
||||
|
||||
defined_variables.insert(new_name.0, new_type);
|
||||
statements.push(retval);
|
||||
}
|
||||
defined_variables.insert(possible_name.0, possible_type);
|
||||
statements.push(retval);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,13 +126,28 @@ impl Arbitrary for Expression {
|
||||
|
||||
leaf_strategy
|
||||
.prop_recursive(3, 64, 2, move |inner| {
|
||||
(
|
||||
select(super::BINARY_OPERATORS),
|
||||
proptest::collection::vec(inner, 2),
|
||||
(select(OPERATORS), proptest::collection::vec(inner, 2)).prop_map(
|
||||
move |((operator, arg_count), mut exprs)| {
|
||||
if arg_count == 1 && operator == "-" {
|
||||
if target_type.map(|x| x.is_signed()).unwrap_or(false) {
|
||||
Expression::Primitive(
|
||||
Location::manufactured(),
|
||||
operator.to_string(),
|
||||
exprs,
|
||||
)
|
||||
} else {
|
||||
exprs.pop().unwrap()
|
||||
}
|
||||
} else {
|
||||
exprs.truncate(arg_count);
|
||||
Expression::Primitive(
|
||||
Location::manufactured(),
|
||||
operator.to_string(),
|
||||
exprs,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
.prop_map(move |(operator, exprs)| {
|
||||
Expression::Primitive(Location::manufactured(), operator.to_string(), exprs)
|
||||
})
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user