Hacker News new | ask | show | jobs
by quasigloam 636 days ago
Yes, at the moment I just assume that all atoms are rust idents because that makes it easier to implement (I can just match against $x:ident), so it doesn't support dashes in atoms. I guess you could match against `$x:ident $(- $y:ident)*` instead? That should work I think, I'd have to change some details in some of the arms but it seems like that would be possible.
2 comments

Wouldn’t that match “(foo - bar)” as well as “(foo-bar)”? I don’t think you can get around token whitespace in macro_rules
Yes it would match both, this would require us to assume that "foo - bar" can only be an atom. It's not a great solution.
It would, but lisp has prefix operators, so you wouldn’t have to worry about it getting confused.
Although in a Lisp such as Scheme, you could pass around the negation operator in something like (map - '(1 2 3)), so it would be a valid concern that it might clash.
The problem with that is that there are spaces between map, -, and '(1 2 3). The only way to get spaces into a name is by using vertical bars:

  (defvar |do i 10| 1.100)
Does Rust have something like a reader macro where you can have arbitrary syntax for a bit?
It's almost but not quite arbitrary. It still has to be a valid Rust token stream with matching braces/parens. Since it's whitespace insensitive with respect to tokens and "-" is its own token, "(foo-bar)" and "(foo - bar)" result in the same token stream minus the span information.

You can use proc_macro::Span.line()/column() [1] to track how much whitespace there is between tokens and merge them, but the macro will have to rename them to valid Rust identities ("foo-bar" to "foo_bar") and make sure there's no collisions.

[1] https://doc.rust-lang.org/proc_macro/struct.Span.html#method...