// transformer can return null or input on no change svoid lambdaMapLike gazelle_deepTransform(IF1 transformer, S input, O... _) { if (transformer == null) ret input; // call transformer on whole input input = or(transformer.get(input), input); // tokenize (possibly transformed) input O tokenizer = optPar tokenizer(_, f javaTokWithBrackets); LS tok = callTokenizer(tokenizer, input); bool changes; for (int i = 1; i < l(tok); i += 2) { S t = tok.get(i); if (tok_isRoundOrCurlyBracketed(t)) { S unBracketed = tok_deRoundOrCurlyBracket(t); S transformed = gazelle_deepTransform(transformer, unBracketed, _); if (transformed != unBracketed) { if (!changes) tok = cloneList(tok); // in case a caching tokenizer was used // enclose in brackets & replace tok.set(i, startsWith(t, "(") ? roundOpt(transformed) : curlyOpt(transformed)); set changes; } } } ret changes ? join(tok) : input; }