Skip to content

Commit bd7ecff

Browse files
committed
Allow macros to return estree objects
This change allows macros to return arbitrary [estree][1] objects as an alternative to returning arrays and objects as usual. This means you can now write macros that support estree features that eslisp doesn't yet (e.g. ES6 arrow functions), as long as [escodegen][2] supports them. You can even use crazy experimental estree extensions (e.g. Facebook's [JSX][3], or #11; ES7 async/await), as long as your macro can do the appropriate transformation to the core eslisp standard that escodegen understands before returning. [1]: https://github.com/estree/estree [2]: https://github.com/estools/escodegen [3]: https://github.com/facebook/jsx
1 parent ed5bed7 commit bd7ecff

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

src/import-macro.ls

+3-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ to-compiler-form = (ast) ->
5252
# Objects are expected to represent atoms
5353
| \Object =>
5454
if ast.atom then atom ("" + ast.atom), macro-location-string
55-
else throw Error "Macro returned object without `atom` property, or atom property set to empty string (got #{JSON.stringify ast})"
55+
else
56+
ast # assume the returned object is in estree form
5657

5758
# Strings become strings as you'd expect
5859
| \String => string ast, macro-location-string
@@ -82,6 +83,7 @@ macro-env = (env) ->
8283
# Create the functions to be exposed for use in a macro's body based on the
8384
# given compilation environment
8485

86+
compile : -> it |> to-compiler-form |> env.compile
8587
evaluate : ->
8688
it |> to-compiler-form |> env.compile |> env.compile-to-js |> eval
8789
multi : (...args) -> multiple-statements args

test.ls

+42
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,48 @@ test "macro return intermediates may be invalid if fixed by later macro" ->
10751075
'''
10761076
..`@equals` "x;"
10771077

1078+
test "macro can return estree object" ->
1079+
esl '''
1080+
(macro identifier (lambda ()
1081+
(return (object "type" "Identifier"
1082+
"name" "x"))))
1083+
(identifier)
1084+
'''
1085+
..`@equals` "x;"
1086+
1087+
test "macro can multi-return estree objects" ->
1088+
esl '''
1089+
(macro identifiers (lambda ()
1090+
(return ((. this multi)
1091+
(object "type" "Identifier"
1092+
"name" "x")
1093+
(object "type" "Identifier"
1094+
"name" "y")))))
1095+
(identifiers)
1096+
'''
1097+
..`@equals` "x;\ny;"
1098+
1099+
test "macro can multi-return estree objects as well as arrays" ->
1100+
esl '''
1101+
(macro identifiers (lambda ()
1102+
(return ((. this multi)
1103+
(object "type" "Identifier"
1104+
"name" "x")
1105+
'x))))
1106+
(identifiers)
1107+
'''
1108+
..`@equals` "x;\nx;"
1109+
1110+
test "macro can compile and return parameter as estree" ->
1111+
esl '''
1112+
(macro that (lambda (x)
1113+
(return ((. this compile) x))))
1114+
(that 3)
1115+
(that "hi")
1116+
(that (c))
1117+
'''
1118+
..`@equals` "3;\n'hi';\nc();"
1119+
10781120
test "multiple invocations of the compiler are separate" ->
10791121
esl "(macro what (lambda () (return 'hi)))"
10801122
esl "(what)"

0 commit comments

Comments
 (0)