package com.googlecode.aviator.runtime.function.seq;
import java.util.Map;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.AbstractVariadicFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorBoolean;
import com.googlecode.aviator.runtime.type.AviatorFunction;
import com.googlecode.aviator.runtime.type.AviatorObject;
import com.googlecode.aviator.runtime.type.AviatorRuntimeJavaType;
/**
* Composite predicate function with && or ||
*
* @author dennis
*
*/
public class SeqCompsitePredFunFunction extends AbstractVariadicFunction {
public static enum LogicOp {
AND,
OR
}
@Override
public String getName() {
return this.name;
}
private LogicOp op;
private String name;
public SeqCompsitePredFunFunction(String name, LogicOp op) {
super();
this.op = op;
this.name = name;
}
@Override
public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
if (args == null || args.length == 0)
return AviatorBoolean.valueOf(op == LogicOp.AND);
return new AviatorRuntimeJavaType(createFunction(env, args, op));
}
private static AviatorFunction createFunction(final Map<String, Object> env, final AviatorObject[] args,
final LogicOp op) {
return new AbstractFunction() {
@Override
public AviatorObject call(Map<String, Object> env, AviatorObject arg1) {
switch (op) {
case AND:
boolean ret = true;
for (AviatorObject obj : args) {
AviatorFunction fn = FunctionUtils.getFunction(obj, env, 1);
if (fn == null)
throw new IllegalArgumentException("Expect " + obj.desc(env) + " as a function.");
ret = fn.call(env, arg1) == AviatorBoolean.TRUE;
if (!ret)
break;
}
return AviatorBoolean.valueOf(ret);
case OR:
ret = false;
for (AviatorObject obj : args) {
AviatorFunction fn = FunctionUtils.getFunction(obj, env, 1);
if (fn == null)
throw new IllegalArgumentException("Expect " + obj.desc(env) + " as a function.");
ret = fn.call(env, arg1) == AviatorBoolean.TRUE;
if (ret)
break;
}
return AviatorBoolean.valueOf(ret);
}
return AviatorBoolean.FALSE;
}
@Override
public String getName() {
return op == LogicOp.AND ? "seq.and" : "seq.or";
}
};
}
}