       rvar:     o.scope.free_variable()
       set:      "$@tab$rvar = [];\n"
       @body:    PushNode.wrap(rvar, @body) if @body
-    post:       if returns then "\n${@tab}return $rvar;" else ''
     pre:        "$set${@tab}while ($cond)"
-    return      "$pre null;$post" if not @body
+    return "$pre null;$post" if not @body
     @body:      Expressions.wrap([new IfNode(@filter, @body)]) if @filter
-    "$pre {\n${ @body.compile(o) }\n$@tab}$post"
+    if @do_return
+      post: new ReturnNode(literal(rvar)).compile(merge(o, {indent: @idt()}))
+    else
+      post: ''
+    "$pre {\n${ @body.compile(o) }\n$@tab}\n$post"
 
 statement WhileNode
 

      return @compile_splat(o) if arg instanceof SplatNode
    args: (arg.compile(o) for arg in @args).join(', ')
    return @compile_super(args, o) if @variable is 'super'
    "$@prefix${@variable.compile(o)}($args)"

  # `super()` is converted into a call against the superclass's implementation
  # of the current function.

    o.scope.find name unless @is_value() and @variable.has_properties()
    val: "$name = $val"
    return "$@tab$val;" if stmt
    val: "($val)" if not top
    return val

  # Brief implementation of recursive pattern matching, when assigning array or
  # object literals to a value. Peeks at their properties to assign inner names.
