   Scope:        this.Scope
 
 # Import the helpers we plan to use.
-{compact, flatten, merge, del, include, index_of}: helpers
+{compact, flatten, merge, del, include, index_of, starts}: helpers
 
 #### BaseNode
 

  # If the code generation wishes to use the result of a complex expression
  # in multiple places, ensure that the expression is only ever evaluated once,
  # by assigning it to a temporary variable.
  compile_reference: (o) ->
    reference: literal o.scope.free_variable()
    compiled:  new AssignNode reference, this
    [compiled, reference]

    return    @compile_array(o) unless o.index
    idx:      del o, 'index'
    step:     del o, 'step'
    vars:     "$idx = ${@from_var.compile(o)}"
    step:     if step then step.compile(o) else '1'
    equals:   if @exclusive then '' else '='
    op:       if starts(step, '-') then ">$equals" else "<$equals"
    "$vars; ${idx} $op ${@to_var.compile(o)}; $idx += $step"

  # When used as a value, expand the range into the equivalent array.
  compile_array: (o) ->
    idt:    @idt 1
    vars:   @compile_variables(merge(o, {indent: idt}))
    equals: if @exclusive then '' else '='
    from:   @from_var.compile o
    to:     @to_var.compile o
    clause: "$from <= $to ?"
    pre:    "\n${idt}a = [];${vars}"
    body:   "var i = $from; ($clause i <$equals $to : i >$equals $to); ($clause i += 1 : i -= 1)"
    post:   "a.push(i);\n${idt}return a;\n$o.indent"
    "(function(){${pre}for ($body) $post}).call(this)"

#### SliceNode

