sinterface ISearchVar {
bool set(O o);
O get();
}
sclass MatchVar implements IRef, ISearchVar {
A value;
Class type;
public A get() { ret value; }
public S toString() { ret str(value); }
bool canHold(O o) { ret type == null || isInstance(type, o); }
public bool set(O o) { if (canHold(o)) { value = (A) o; true; } else false; }
}
sclass Subsearch {
Class c;
O[] params;
*(Class *c, O[] params) {
this.params = expandParams(c, params);
}
}
static Subsearch some(Class extends Concept> c, O... params) {
ret new Subsearch(c, params);
}
static A searchConcept(MatchVar var, O... params) {
assertNotNull(var.type); // must be typed to use in place of class
ret var.value = searchConcept(var.type, params);
}
static A searchConcept(Class c, O... params) {
params = expandParams(c, params);
// First, go through all the concepts of the primary type.
for (A concept : list(c))
if (searchConcept_checkParams(concept, params))
ret concept; // Success!
null;
}
static L searchConcept_all(Class c, O... params) {
params = expandParams(c, params);
new L l;
// First, go through all the concepts of the primary type.
for (A concept : list(c))
if (searchConcept_checkParams(concept, params))
l.add(concept); // Success!
ret l;
}
static bool searchConcept_checkParams(Concept c, O... params) {
for (int i = 0; i+1 < l(params); i += 2) {
S field = cast params[i];
O val = derefRef(params[i+1]);
O actual = cget(c, field);
if (val instanceof Subsearch) {
Subsearch s = cast val;
if (!isInstance(s.c, actual)) false; // wrong type
if (!searchConcept_checkParams((Concept) actual, s.params)) false; // bad params
} else if (val instanceof ISearchVar) {
ISearchVar v = cast val;
if (!v.set(actual)) false;
} else
if (neq(actual, val)) false;
}
true; // all params match
}
sbool actually(Class c, O... params) {
ret searchConcept(Actually, some(c, params)) != null;
}
/*sbool actually(MatchVar var, O... params) {
ret searchConcept(Actually, some(var, params)) != null;
}*/
/*static L listActually(MatchVar var, O... params) {
ret map(func(Actually a) { a.what.get() }, searchConcept_all(Actually, some(var, params)));
}*/
static L listActually(Class c, O... params) {
ret map(func(Actually a) { a.what.get() }, searchConcept_all(Actually, some(c, params)));
}
static MatchVar typedVar(Class c) {
new MatchVar var;
var.type = c;
ret var;
}