jashkenas--coffeescript/lib/coffee-script
Simon Lydell 021d2e4376 Refactor `Literal` into several subtypes
Previously, the parser created `Literal` nodes for many things. This resulted in
information loss. Instead of being able to check the node type, we had to use
regexes to tell the different types of `Literal`s apart. That was a bit like
parsing literals twice: Once in the lexer, and once (or more) in the compiler.
It also caused problems, such as `` `this` `` and `this` being indistinguishable
(fixes #2009).

Instead returning `new Literal` in the grammar, subtypes of it are now returned
instead, such as `NumberLiteral`, `StringLiteral` and `IdentifierLiteral`. `new
Literal` by itself is only used to represent code chunks that fit no category.
(While mentioning `NumberLiteral`, there's also `InfinityLiteral` now, which is
a subtype of `NumberLiteral`.)

`StringWithInterpolations` has been added as a subtype of `Parens`, and
`RegexWithInterpolations` as a subtype of `Call`. This makes it easier for other
programs to make use of CoffeeScript's "AST" (nodes). For example, it is now
possible to distinguish between `"a #{b} c"` and `"a " + b + " c"`. Fixes #4192.

`SuperCall` has been added as a subtype of `Call`.

Note, though, that some information is still lost, especially in the lexer. For
example, there is no way to distinguish a heredoc from a regular string, or a
heregex without interpolations from a regular regex. Binary and octal number
literals are indistinguishable from hexadecimal literals.

After the new subtypes were added, they were taken advantage of, removing most
regexes in nodes.coffee. `SIMPLENUM` (which matches non-hex integers) had to be
kept, though, because such numbers need special handling in JavaScript (for
example in `1..toString()`).

An especially nice hack to get rid of was using `new String()` for the token
value for reserved identifiers (to be able to set a property on them which could
survive through the parser). Now it's a good old regular string.

In range literals, slices, splices and for loop steps when number literals
are involved, CoffeeScript can do some optimizations, such as precomputing the
value of, say, `5 - 3` (outputting `2` instead of `5 - 3` literally). As a side
bonus, this now also works with hexadecimal number literals, such as `0x02`.

Finally, this also improves the output of `coffee --nodes`:

    # Before:
    $ bin/coffee -ne 'while true
      "#{a}"
      break'
    Block
      While
        Value
          Bool
        Block
          Value
            Parens
              Block
                Op +
                  Value """"
                  Value
                    Parens
                      Block
                        Value "a" "break"

    # After:
    $ bin/coffee -ne 'while true
      "#{a}"
      break'
    Block
      While
        Value BooleanLiteral: true
        Block
          Value
            StringWithInterpolations
              Block
                Op +
                  Value StringLiteral: ""
                  Value
                    Parens
                      Block
                        Value IdentifierLiteral: a
          StatementLiteral: break
2016-03-05 17:08:11 +01:00
..
browser.js Fix broken `CoffeeScript.register()` and commit build 2016-01-31 19:48:40 +01:00
cake.js Remove uncaught error vars 2015-09-13 12:27:07 +02:00
coffee-script.js Refactor `Literal` into several subtypes 2016-03-05 17:08:11 +01:00
command.js Fix broken `CoffeeScript.register()` and commit build 2016-01-31 19:48:40 +01:00
grammar.js Refactor `Literal` into several subtypes 2016-03-05 17:08:11 +01:00
helpers.js Refactor `Literal` into several subtypes 2016-03-05 17:08:11 +01:00
index.js CoffeeScript 1.10.0 2015-09-03 20:10:18 +02:00
lexer.js Refactor `Literal` into several subtypes 2016-03-05 17:08:11 +01:00
nodes.js Refactor `Literal` into several subtypes 2016-03-05 17:08:11 +01:00
optparse.js CoffeeScript 1.10.0 2015-09-03 20:10:18 +02:00
parser.js Refactor `Literal` into several subtypes 2016-03-05 17:08:11 +01:00
register.js Fix broken `CoffeeScript.register()` and commit build 2016-01-31 19:48:40 +01:00
repl.js Fix #4137: Caught errors named `undefined` 2015-11-02 08:05:35 +01:00
rewriter.js Refactor `Literal` into several subtypes 2016-03-05 17:08:11 +01:00
scope.js CoffeeScript 1.10.0 2015-09-03 20:10:18 +02:00
sourcemap.js CoffeeScript 1.10.0 2015-09-03 20:10:18 +02:00