7 ms·
A MOS6502 assembler implemented as a Rust macro
- vvanders 11y agoLink appears to be broken, working one is: https://play.rust-lang.org/?gist=a18d697454f9261b28ff https://play.rust-lang.org/?gist=a18d697454f9261b28ff
- hathawsh 11y agoVery cool. As a Rust newbie I'd like to understand what's going on here. Is this a "procedural" macro? Does Rust specifically target writing DSLs using its macro system? Can we expect macros like this to continue working for a long time? There's a blog post that suggests possible changes: https://internals.rust-lang.org/t/the-future-of-syntax-extensions-and-macros/2889 https://internals.rust-lang.org/t/the-future-of-syntax-exten...
- mcpherrinm 11y agoThis isn't a procedural macro: Procedural macros run Rust code to transform your program, and interact with the guts of the compiler (AST, etc). That's hopefully going to change to not be compiler-version specific, etc. This is using a system known as "macro_rules" which are a system of "expanding" -- in some ways it's a fancier version of the C preprocessor, but also resembling the Lisp/Racket macro system to some degree too. Let's take a random little piece of that code from the post and talk about it: macro_rules! codelen { () => { 0 }; ( $($c:expr),+ ) => { [$($c),+].len() }; } This declares a new macro substitution rule called `codelen`. Without going into too much depth, that's defining rules (on the left hand of the `=>`) and saying what code to expand them into, on the other side. The first replaces `()` with `{0};`, just a simple substitution. In the second rule, the `$($variable),+ is the essential construct here, letting you operate on sequences of input stuff. It's a little hard to read -- writing your own macros in Rust is a little bit complicated and I don't think it's actually something that should be done often. You can write little DSLs with it for sure. This variety is going to stick around and will keep working. It is called macro_rules! and not just macro! to leave that name free for a future, enhanced way to write macros, though.
- deleted 11y ago[deleted]
- steveklabnik 11y ago> Is this a "procedural" macro? This is not a procedural macro, it's a regular-old macro. > Does Rust specifically target writing DSLs using its macro system? I would say that "specifically" is a bit strong, but they are one application of them, yes. > Can we expect macros like this to continue working for a long time? This functionality runs on Rust stable, and therefore should continue working forever. The post you're referring to is talking about procedural macros/syntax extensions/compiler plugins, which are not stable and will see lots of change. We also may end up with a new macro system as well, but it will not conflict with the existing macro system if we do.
- JustSomeNobody 11y agoThat ... is ... f*ing ... ugly to look at.
- vardump 11y agoWell, a creative abuse of the language. Programmer humor.
- JustSomeNobody 11y agoBeing a developer myself, I'm well aware of this. Still, it's ugly.
- Animats 11y agoWhen I see this, I understand why the Go crowd didn't put generics or macros in Go. It's so easy to write useful but awful things with them, and they're really hard to fix and debug. This is getting to be a big problem with Rust. The language, or maybe its community, encourages cutesy stuff like this. Remember "Diesel", the Rust compiler for SQL, from a few days ago? Just because you can doesn't mean you should. Too much fancy template stuff is being baked into the low level libraries. This may not end well. C++ went down this road. The template system turned out to be more powerful than intended. Then people started writing cool stuff as fancy templates. Then the C++ committee added features to support the fancy templates better. Overly elaborate templates damaged C++; nobody could figure out what was going on. Use of C++ for new work declined. All of this comes from smart people with good intentions. But when there's too much of this stuff, the mental load required to keep up with all of it becomes excessive. Especially if it changes a lot.
- pcwalton 11y agoThis is silly. Rust could not achieve its performance and safety goals without macros and generics. Generics may have been optional for Go (I don't agree, but let's go with it), but there is no way to achieve zero-cost memory safety without generics (while supporting first-class references and dynamic allocation). Rust generics are deliberately less expressive than C++ templates, in that they're strongly typed. That's why we get so many complaints from C++ and D developers that you can't do certain things. But Rust sticks with its strongly-typed generics, because Rust has always tried hard to strike a balance between code expressivity and maintainability. This is a terrible example if you want to prove that point, anyway. This 6502 assembler is obviously a total abuse of the system, and nobody will deploy it to production. It's a neat hack, and that's all. Nobody would use an obfuscated quine written in Go to argue that Go is unreadable. This is exactly analogous. Finally, Diesel is just an ORM. It uses exactly enough features to be an ORM; the only "problem" with it is that it's an ORM.
- deleted 11y ago[deleted]
- GlitchMr 11y agoIt doesn't support explicit accumulator addressing mode (ASL A, LSR A, ROL A, ROR A), but otherwise quite neat. (from a quick look at it) (also, 0x syntax is quite unusual, but I assume $ couldn't have been implemented for some reason)
- pvg 11y agoYou mean as syntax? Because the opcodes seem to be there.
- vardump 11y agoIsn't A the only register those ops can use anyways? Although it's been a while, 25 years...
- duskwuff 11y agoYou can't ASL X or Y, but you can ASL $0 or ASL $0, X. (Using either a zero-page address or an absolute address.)
- to3m 11y agoThis seems to be somewhat common - I've used a few assemblers that make you write ASL A as just ASL (and so on). Benefit (?): you can now have a label called "A".
- ddingus 11y agoThe accumulator is the only register those work with. It was very common to not specify it.at all. I actually never have in all the 6502 assembly code I've ever written. Wasn't required.
- pvg 11y agoI don't think that's true. http://www.downloads.reactivemicro.com/Public/Users/David_Craig/Apple2OriginalROMInfo.TXT http://www.downloads.reactivemicro.com/Public/Users/David_Cr... Code is straight from the Red Book listings. Search for ROR - accumulator (shown explicitly), indexed, you name it. 4 modes each.
- CodeWriter23 11y agoThat's a new twist on the Macro Assembler.
- mmastrac 11y agoThe author appears to have a crate for it as well: https://github.com/jonas-schievink/rustasm6502 https://github.com/jonas-schievink/rustasm6502
- monocasa 11y agoReminds me of this sweet paper http://research.microsoft.com/en-us/um/people/nick/coqasm.pdf http://research.microsoft.com/en-us/um/people/nick/coqasm.pd...
- nickpsecurity 11y agoThat's the exact one I thought of. On top of it, there's typed assembler: https://www.cs.cornell.edu/talc/ https://www.cs.cornell.edu/talc/ And Vx86 used in Microsoft hypervisor: http://swt.informatik.uni-freiburg.de/staff/maus/dissemain.pdf http://swt.informatik.uni-freiburg.de/staff/maus/dissemain.p... Note: Microsoft also used a TAL, though can't recall if same as Cornell, in their VerveOS that was verified down to assembler. Combined with SLAM, it's safe to say their researchers are kicking serious behind on practical, cutting-edge verification. I wouldn't have believed it 10+ years ago if someone told me haha.
- gamache 11y agoNo ORG, no deal. I can't use this in production unless it supports ORG.
- PythonForGirls 11y agoFinally!
- ilurkedhere 11y agoLisp user here. This reminded me of https://github.com/kingcons/cl-6502 https://github.com/kingcons/cl-6502 where the opcodes are defined using a defasm macro https://github.com/kingcons/cl-6502/blob/master/src/cpu.lisp#L183 https://github.com/kingcons/cl-6502/blob/master/src/cpu.lisp... and implemented here https://github.com/kingcons/cl-6502/blob/master/src/opcodes.lisp https://github.com/kingcons/cl-6502/blob/master/src/opcodes.... Are Lisp macros pretty much on par with Rust macros?
- FreeFull 11y agoI was under the impression Lisp macros are more powerful/flexible than Rust's macro_rules! macros, although I don't know enough about Lisp macros to be sure.