makeFragment = parser => {
  // For fragments we must wrap the source in a function
  // otherwise the parser will fail as it's not a valid
  // place for an expression
  const parse = src => {
    try {
      // 1st node is a function.
      // 3rd node of a function is a block, containing a single expression
      return parser(`function fragment() {
        ${src}
      }`).params[0].params[2].params[0];
    } catch (e) {
      throw new Error(`PANIC - Invalid fragment input:

${src}

Parse Error: ${e.stack}`);
    }
  };

  return (template, ...replacements) => {
    let expandNodes = false;
    // Build out a placeholder source string which will be compiled
    const source = template.reduce((a, v, i) => {
      const rep = replacements[i];
      if (rep != null && typeof rep !== 'object') {
        return a += v + String(rep);
      }

      if (rep != null) {
        expandNodes = true;
        return a += v + `$$rep_${i}`;
      }

      return a += v;
    }, '');

    const node = parse(source);

    // Expand any Node objects if necessary
    if (expandNodes) {
      return mapNode_2({
        Identifier(id) {
          const { value: name } = id;
          if (!name.indexOf('$$rep_')) {
            return replacements[Number(name.replace('$$rep_', ''))];
          }
          return id;
        }
      })(node);
    }

    return node;
  };
}
Fragment tag template literal factory. All input strings must be valid
statements.

@return {Function} tag template literal