Get unary negation working.

This commit is contained in:
2023-06-07 21:38:18 -07:00
parent 469fe35e46
commit b4ad24030f
10 changed files with 138 additions and 74 deletions

View File

@@ -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()
}