• Daniel Gackle's avatar
    An initial implementation of source mappings. · 053e9d45
    Daniel Gackle authored
    When consuming source code from a stream, the compiler now optionally
    collects the start and end position of each list the reader reads
    (atoms aren't tracked - see below), threads this information all the
    way through to the printer, and associates it with the start and end
    positions of the corresponding JS being generated.
    Note that this is an expression-based way of doing source maps as
    opposed to the line-based approach of the Google/Mozilla source map
    spec. This is a much richer and Lispier way to do it. But converting
    to the line-based format will require tracking lines in the printer.
    That work is not part of this commit.
    Text extents of forms are tracked in a big EQ-hash-table of which the
    forms themselves are the keys. This has the disadvantage that atomic
    tokens such as variable names don't get their source mappings tracked
    (though see note [1] below). It has the much greater advantage of
    making the source mapping implementation not be too invasive. I tried
    the alternative implementation of consing the text extents as metadata
    onto the heads of each cons to be compiled. This worked, but had the
    consequence that any compiler code that needs to pick apart the forms
    it is given must be aware of this optional (because source mappings
    may be turned off) metadata at the head - and, Lisp being what it is,
    "compiler code" here includes any PS macros that anybody writes. That
    is far too heavy a burden to place on macros even if the PS compiler
    itself could stand it. Storing the metadata on the side avoids this;
    now only those portions of the compiler that care about preserving the
    source mappings of the forms they are given need worry about them, and
    for any forms they are passing on untransformed they can just ignore
    this extra information. Similarly, macros that wish to propagate
    source mappings have the option of doing so, but also have the option
    of remaining blissfully ignorant.
    [1] Tricks could be applied to work around this. For example, atoms
    that appear inside conses could be uniquely identified using the cons
    plus an integer index. But this would be a lot more work, both to
    develop and more importantly at runtime, and it's not clear whether
    the more precise mappings would be worth it.
output-tests.lisp 79.1 KB