@Override public RNode create(ASTNode call, RSymbol[] names, RNode[] exprs) { final ArgumentInfo ia = check(call, names, exprs); final int posText = ia.position("text"); final int posLast = ia.position("last"); final int posFirst = ia.position("first"); final RDouble defaultLast = RDouble.RDoubleFactory.getScalar(1000000); // FIXME slow, but perhaps the default is not used, anyway return new Builtin(call, names, exprs) { @Override public RAny doBuiltIn(Frame frame, RAny[] args) { RString text = args[posText].asString(); warn.naIntroduced = false; RDouble first = args[posFirst].asDouble(warn); RDouble last; last = posLast != -1 ? args[posLast].asDouble(warn) : defaultLast; RString res = substring(text, first, last, ast); if (warn.naIntroduced) { RContext.warning(ast, RError.NA_INTRODUCED_COERCION); } return res; } }; }
@Override public RNode create(ASTNode call, RSymbol[] names, RNode[] exprs) { ArgumentInfo ia = check(call, names, exprs); final int posExpr = ia.position("expr"); return new Builtin(call, names, exprs) { @Override public RAny doBuiltIn(Frame frame, RAny[] args) { return RString.RStringFactory.getScalar(AsBase.deparse(args[posExpr], false)); } }; }
@Override public RNode create(ASTNode call, RSymbol[] names, RNode[] exprs) { ArgumentInfo ia = check(call, names, exprs); boolean product = false; if (ia.provided("FUN")) { RNode fnode = exprs[ia.position("FUN")]; if (fnode instanceof Constant) { RAny value = ((Constant) fnode).execute(null); if (value instanceof RString) { RString str = (RString) value; if (str.size() == 1) { if (str.getString(0).equals("*")) { product = true; } } } } } else { product = true; } if (product) { return new MatrixOperation.OuterProduct(call, exprs[ia.position("X")], exprs[ia.position("Y")]); } int cnArgs = 2 + names.length - 3; // "-2" because both FUN, X, Y RSymbol[] cnNames = new RSymbol[cnArgs]; RNode[] cnExprs = new RNode[cnArgs]; cnNames[0] = null; ValueProvider xArgProvider = new ValueProvider(call); cnExprs[0] = xArgProvider; ValueProvider yArgProvider = new ValueProvider(call); cnExprs[1] = yArgProvider; ValueProvider[] constantArgProviders = new ValueProvider[cnArgs]; int j = 0; for (int i = 0; i < names.length; i++) { if (ia.position("X") == i || ia.position("Y") == i || ia.position("FUN") == i) { continue; } cnNames[2 + j] = names[i]; ValueProvider vp = new ValueProvider(call); cnExprs[2 + j] = vp; constantArgProviders[j] = vp; j++; } RNode funExpr = exprs[ia.position("FUN")]; final CallableProvider callableProvider = new CallableProvider(funExpr.getAST(), funExpr); final RNode callNode = FunctionCall.getFunctionCall(call, callableProvider, cnNames, cnExprs); final int posX = ia.position("X"); final int posY = ia.position("Y"); final int posFUN = ia.position("FUN"); return new OuterBuiltIn(call, names, exprs, callNode, callableProvider, xArgProvider, yArgProvider, constantArgProviders) { @Override public RAny doBuiltIn(Frame frame, RAny[] args) { RAny argx = null; RAny argy = null; RAny argfun = null; int k = 0; for (int i = 0; i < args.length; i++) { if (i == posX) { argx = args[i]; } else if (i == posY) { argy = args[i]; } else if (i == posFUN) { argfun = args[i]; } else { constantArgProviders[k].setValue(args[i]); k++; } } return outer(frame, argx, argy, argfun); } }; }