 # Trim out all falsy values from an array.
 compact: (array) -> item for item in array when item
 
-# Return a completely flattened version of an array.
+# Return a completely flattened version of an array. Handy for getting a
+# list of `children`.
 flatten: (array) ->
   memo: []
   for item in array
     if item instanceof Array then memo: memo.concat(item) else memo.push(item)
   memo
 
-# Delete a key from an object, returning the value.
+# Delete a key from an object, returning the value. Useful when a node is
+# looking for a particular method in an options hash.
 del: (obj, key) ->
   val: obj[key]
   delete obj[key]
   val
 
-# Quickie helper for a generated LiteralNode.
+# Handy helper for a generating LiteralNode.
 literal: (name) ->
   new LiteralNode(name)

  top_sensitive: ->
    true

  compile_node: (o) ->
    top_level:      del(o, 'top') and not o.returns
    range:          @source instanceof ValueNode and @source.base instanceof RangeNode and not @source.properties.length


# Tabs are two spaces for pretty printing.
TAB: '  '

# Trim out all trailing whitespace, so that the generated code plays nice
# with Git.
TRAILING_WHITESPACE: /\s+$/gm

# Keep this identifier regex in sync with the Lexer.
IDENTIFIER: /^[a-zA-Z$_](\w|\$)*$/

# Utility Functions
# -----------------

# Merge objects, returning a fresh copy with attributes from both sides.
# Used every time `compile` is called, to allow properties in the options hash
# to propagate down the tree without polluting other branches.
merge: (options, overrides) ->
  fresh: {}
  (fresh[key]: val) for key, val of options
