scope gazelle_addVarDiscriminators. sclass #MechListContains extends F1 { S list; *() {} *(S *list) {} Bool get(S s) { bool ok = mechCISetContains(list, s); print("MechListContains: " + list + " / " + s + " => " + ok); ret ok; } } sclass #VarDiscriminator { S var; O discriminator; // func(S value) -> bool bool debug; *() {} *(S *var, O *discriminator, bool *debug) {} SS get(SS map, LS tokC, LS tokI, RuleEngine2_MatchedRule matched) { if (map == null) null; S value = map.get(var); if (value != null && !isTrue(callAndMake_orF1(discriminator, value))) { if (debug) print("Rejecting var: " + var + " -> " + value + " because of " + discriminator); null; } ret map; } } svoid gazelle_addVarDiscriminators(RuleEngine2 engine, O... _) { bool debug = boolPar debug(_) || boolPar debugVarDiscriminators(_); for (final RuleEngine2.Rule r : engine.rules) { for (Matches m : getJMatches_all("var * should satisfy *", r.comments)) { S var = $1, discriminator = $2; if (debug) print("Made discriminator for: " + var); r.addMapMassager(new VarDiscriminator(var, discriminator, debug)); } for (Matches m : getJMatches_all("var * should be in list *", r.comments)) { S var = $1, list = $2; r.addMapMassager(new VarDiscriminator(var, MechListContains(list), debug)); } for (Matches m : getJMatches_all("* has to be between * and *", r.comments)) { S var = $1; double min = parseDouble($2), max = parseDouble($3); if (debug) print("Made discriminator for: " + var); r.addMapMassager(new VarDiscriminator(var, func(S value) -> bool { pcall-silent { ret isBetween_double(parseDouble(or(value, var)), min, max); } false; }, debug)); } for (Matches m : getJMatches_all("* has to be * or *", r.comments)) { S var = $1; Set values = litciset($2, $3); if (debug) print("Made discriminator for: " + var); r.addMapMassager(new VarDiscriminator(var, func(S value) -> bool { contains(values, or(value, var)) }, debug)); } } } end scope