package org.basex.query.func; import org.basex.query.QueryContext; import org.basex.query.QueryException; import org.basex.query.expr.Expr; import org.basex.query.item.Item; import org.basex.query.item.QNm; import org.basex.query.item.Value; import org.basex.query.iter.Iter; import org.basex.query.util.Var; import org.basex.query.util.VarStack; import org.basex.util.InputInfo; /** * Function call for user-defined functions. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ final class BaseFuncCall extends UserFuncCall { /** * Function constructor. * @param ii input info * @param nm function name * @param arg arguments */ BaseFuncCall(final InputInfo ii, final QNm nm, final Expr... arg) { super(ii, nm, arg); } @Override public Item item(final QueryContext ctx, final InputInfo ii) throws QueryException { Expr fun = func; Var[] args = args(ctx); do { // cache arguments, evaluate function and reset variable scope final VarStack cs = addArgs(ctx, args); ctx.tailCalls = 0; try { return fun.item(ctx, ii); } catch(final Continuation c) { fun = c.getFunc(); args = c.getArgs(); } finally { ctx.vars.reset(cs); } } while(true); } @Override public Value value(final QueryContext ctx) throws QueryException { Expr fun = func; Var[] args = args(ctx); do { // cache arguments, evaluate function and reset variable scope final VarStack cs = addArgs(ctx, args); ctx.tailCalls = 0; try { return ctx.value(fun); } catch(final Continuation c) { fun = c.getFunc(); args = c.getArgs(); } finally { ctx.vars.reset(cs); } } while(true); } @Override public Iter iter(final QueryContext ctx) throws QueryException { // [LW] make result streamable return value(ctx).iter(); } @Override public Expr markTailCalls() { return new TailFuncCall(input, name, func, expr); } }