"Levels",
"Returns the level whose position in a hierarchy is specified by a numeric expression.",
"mlhn")
{
public Type getResultType(Validator validator, Exp[] args) {
final Type argType = args[0].getType();
return LevelType.forType(argType);
}
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler)
{
final HierarchyCalc hierarchyCalc =
compiler.compileHierarchy(call.getArg(0));
final IntegerCalc ordinalCalc =
compiler.compileInteger(call.getArg(1));
return new AbstractLevelCalc(
call, new Calc[] {hierarchyCalc, ordinalCalc})
{
public Level evaluateLevel(Evaluator evaluator) {
Hierarchy hierarchy =
hierarchyCalc.evaluateHierarchy(evaluator);
int ordinal = ordinalCalc.evaluateInteger(evaluator);
return nthLevel(hierarchy, ordinal);
}
};
}
Level nthLevel(Hierarchy hierarchy, int n) {
Level[] levels = hierarchy.getLevels();
if (n >= levels.length || n < 0) {
throw newEvalException(
this, "Index '" + n + "' out of bounds");
}
return levels[n];
}
});
// "<Hierarchy>.Levels(<String Expression>)"
builder.define(
new FunDefBase(
"Levels",
"Returns the level whose name is specified by a string expression.",
"mlhS")
{
public Type getResultType(Validator validator, Exp[] args) {
final Type argType = args[0].getType();
return LevelType.forType(argType);
}
public Calc compileCall(
final ResolvedFunCall call, ExpCompiler compiler)
{
final HierarchyCalc hierarchyCalc =
compiler.compileHierarchy(call.getArg(0));
final StringCalc nameCalc =
compiler.compileString(call.getArg(1));
return new AbstractLevelCalc(
call, new Calc[] {hierarchyCalc, nameCalc}) {
public Level evaluateLevel(Evaluator evaluator) {
Hierarchy hierarchy =
hierarchyCalc.evaluateHierarchy(evaluator);
String name = nameCalc.evaluateString(evaluator);
for (Level level : hierarchy.getLevels()) {
if (level.getName().equals(name)) {
return level;
}
}
throw newEvalException(
call.getFunDef(),
"Level '" + name + "' not found in hierarchy '"
+ hierarchy + "'");
}
};
}
});
// "Levels(<String Expression>)"
builder.define(
new FunDefBase(
"Levels",
"Returns the level whose name is specified by a string expression.",
"flS")
{
public Type getResultType(Validator validator, Exp[] args) {
final Type argType = args[0].getType();
return LevelType.forType(argType);
}
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler)
{
final StringCalc stringCalc =