code: function mapLogicalOp(ast, state) {
          if (Array.isArray(ast)) 
              return ast.map(function (n) {
              return mapLogicalOp(n, state);
          });
          treeWalk(ast, function (node, descend, path) {
              descend();
              if (node.type === 'LogicalExpression' && containsAwait(node.right)) {
                  var codeFrag;
                  var z = ident(generateSymbol("logical" + (node.operator === '&&' ? "And" : "Or")));
                  if (node.operator === '||') {
                      codeFrag = "var $0; if (!($0 = $1)) {$0 = $2} return $0";
                  } else if (node.operator === '&&') {
                      codeFrag = "var $0; if ($0 = $1) {$0 = $2} return $0";
                  } else 
                      throw new Error(where(node) + "Illegal logical operator: " + node.operator);
                  coerce(node, internalIIAFE(parsePart(codeFrag, [z,node.left,node.right]).body));
              }
          }, state);
          return ast;
      }
docs: /*
  To implement conditional execution, logical operators with an awaited RHS are mapped thus:
  
  Translate a || b into await (async function Or(){ var z ; if (!(z=a)) z=b ; return z })
  Translate a && b into await (async function And(){ var z ; if (z=a) z=b ; return z })
  
  Note that 'await (async function(){})()' can be optimized to a Thenable since no args are passed