anko / eslisp

un-opinionated S-expression syntax and macro system for JavaScript
ISC License
528 stars 31 forks source link

Export ast-to-estree? #52

Open newhouseb opened 7 years ago

newhouseb commented 7 years ago

Hi,

I'd like to use eslisp to evaluate eslisp, so that I can do things like:

(eval (quote (+ 1 2 3)))

eval, of course, takes Javascript so I'd like a way to transform the estree (as returned by quote) to javascript. Looking at https://github.com/anko/eslisp/blob/master/src/index.ls, it appears that we might be able to export ast-to-estree such that something like

(eval (ast-to-estree (quote (+ 1 2 3))))

could work (edit: not quite, the AST used internally seems to be different from what quote returns). Another option would be to make compileOnce, etc default to this behavior if the input was an estree instead of a string.

What do you think?

Thanks, Ben

anko commented 7 years ago

Trying to isolate the root issue—correct me if I'm wrong:

You want to evaluate (+ 1 2 3) at compile-time, such that its output (6) is inserted into the output JavaScript as a numeric constant.

At the moment, you could do that with this.evaluate inside a macro:

; Define a new macro that compiles & evaluates its input, and outputs the result
(macro precompute
       (lambda (input)
        (var output ((. this evaluate) input))
        (return ((. this atom) output))))

; Call it
(precompute (+ 1 2 3))

The output is:

6;

The only sparse documentation I've written for this sort of thing so far is here. It's buried behind a few links from the main readme, because my thoughts on it haven't fully come together yet—sorry about that. It has various unit tests though.

To return array and object literals from macros, you currently have to manually construct the appropriate estree objects and return those. Macros should probably expose a generic this.valueToEstree. This isn't documented anywhere, because again I'm not convinced I've fully figured it out yet.

Eventually, I want to get rid of as much of this AST-format juggling as possible, and document properly what's going on. It's actually not very complex, it's just liable to change a lot.

Does some of that answer some of your questions? :sweat_smile: