Skip to content

Commit

Permalink
Unify macro input and output formats
Browse files Browse the repository at this point in the history
This is a major rework of the macro API to clean up abstractions.  I
tried to avoid making a single large commit, but because the macro API
touches almost everything, this was hard to chunk.

Summary of changes
------------------

These changes eliminate the technical distinction between user-defined
and built-in macros.  Now all macros take JS objects as arguments and
output either those same JS objects or estree objects.

S-expressions are now always represented in the form

    {
      type : "list",
      values : [
        { type : "atom", value : "f" },
        { type : "string", value : "hi" }
      ]
    }

This unification of macro formats also means dropping the "capturing
macros" vs "non-capturing macros" distinction.  Macro return values can
now contain calls to any macro in their outer environment (also macros
defined after them), which fixes #27.

User macros being able to return estree objects also enables
experimental estree extensions like JSX or ES6/7 features (#11).  As
long as you can come up with a way of converting them to valid estree
that [escodegen][1] understands, anything goes.

Now that user macros can access the full compilation environment that
built-in macros use, they can do low-level stuff like create new macro
environments with `env.derive`, and query the macro table with
`env.findMacro`.  These can be very helpful when debugging.

Also threw away some tests that were just showing off rather than
actually testing something, and made some others more specific.

Still-awkward points
--------------------

These will be addressed in soon forthcoming commits.

The macro environment (containing stuff like the `compile` and
`evaluate` functions) is currently passed to macros as the first
argument, which is super clumsy to use, but was great for
integration-testing that these changes are OK otherwise, since that's
how all the built-in macros received their env.  The environment should
be passed as `this`.

The "type-value"-object format is quite annoying to write out in full,
and is fragile to future changes.  It might be cleaner to expose S-expr
AST-node constructors on the environment object, so they could be
constructed with a simple `env.atom("hi")` call and typechecked with
`instanceof`.

 [1]: https://github.com/estools/escodegen
  • Loading branch information
anko committed Nov 6, 2015
1 parent bd7ecff commit 2b47f4b
Show file tree
Hide file tree
Showing 8 changed files with 444 additions and 541 deletions.
137 changes: 0 additions & 137 deletions src/ast.ls

This file was deleted.

Loading

0 comments on commit 2b47f4b

Please sign in to comment.