Skip to content

Commit cb16d60

Browse files
authored
fixed issue with variadic ampersand symbol in macros (#773)
HI, could you please review patch to treat the ampersand operator in macros as a standalone symbol. Fixes #772. Test included. thanks Co-authored-by: ikappaki <[email protected]>
1 parent d0d7cb6 commit cb16d60

File tree

4 files changed

+21
-1
lines changed

4 files changed

+21
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020
* Fix an issue for executing Basilisp scripts via a shebang where certain platforms may not support more than one argument in the shebang line (#764)
2121
* Fix issue with keywords throwing `TypeError` when used as a function on vectors (#770)
2222
* Fix an issue where the constructors of types created by `deftype` and `defrecord` could not be called if they contained `-` characters (#777)
23+
* Fix issue with the variadic ampersand operator treated as a binding in macros (#772)
2324

2425
## [v0.1.0b0]
2526
### Added

src/basilisp/lang/reader.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,9 @@ def _read_sym(ctx: ReaderContext) -> MaybeSymbol:
948948
If a symbol appears in a syntax quoted form, the reader will attempt
949949
to resolve the symbol using the resolver in the ReaderContext `ctx`.
950950
The resolver will look into the current namespace for an alias or
951-
namespace matching the symbol's namespace."""
951+
namespace matching the symbol's namespace. If no namespace is specififed
952+
for the symbol, it will be assigned to the current namespace, unless the
953+
symbol is `&`."""
952954
ns, name = _read_namespaced(ctx, allowed_suffix="#")
953955
if not ctx.is_syntax_quoted and name.endswith("#"):
954956
raise ctx.syntax_error("Gensym may not appear outside syntax quote")
@@ -967,6 +969,8 @@ def _read_sym(ctx: ReaderContext) -> MaybeSymbol:
967969
return True
968970
elif name == "false":
969971
return False
972+
elif name == "&":
973+
return _AMPERSAND
970974
if ctx.is_syntax_quoted and not name.endswith("#"):
971975
return ctx.resolve(sym.symbol(name, ns))
972976
return sym.symbol(name, ns=ns)

tests/basilisp/reader_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,14 @@ def complex_resolver(s: sym.Symbol) -> sym.Symbol:
773773
),
774774
) == read_str_first("`(~'my-symbol)"), "Do not resolve unquoted quoted syms"
775775

776+
assert llist.l(sym.symbol("quote"), sym.symbol("&")) == read_str_first(
777+
"`&"
778+
), "do not resolve the not namespaced ampersand"
779+
780+
assert llist.l(
781+
sym.symbol("quote"), sym.symbol("&", ns="test-ns")
782+
) == read_str_first("`test-ns/&"), "resolve fq namespaced ampersand"
783+
776784

777785
def test_syntax_quote_gensym():
778786
resolver = lambda s: sym.symbol(s.name, ns="test-ns")

tests/basilisp/test_core_macros.lpy

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,3 +1456,10 @@
14561456
(conj coll m)
14571457
(conj accum a b))
14581458
[coll (apply str accum)]))))))
1459+
1460+
(defmacro ^:private variadic-fn []
1461+
`(fn [& r#] r#))
1462+
1463+
(deftest macro-variadic-fn
1464+
(testing "defining variadic fn with ampersand"
1465+
(is (= '(2 3 4) ((variadic-fn) 2 3 4)))))

0 commit comments

Comments
 (0)