anachronauts / jeff65

a compiler targeting the Commodore 64 with gold-syntax
GNU General Public License v3.0
6 stars 0 forks source link

Annotation/attribute syntax #32

Open jdpage opened 6 years ago

jdpage commented 6 years ago

We... should probably figure out our annotation/attribute syntax at some point. Specifically, #31 has me concerned, because once you have a vmfun, you need vmrefun, and also for vmtfun you need vmtrefun and now you have exponential blowup of keywords and you look at your code with your vmtxz7qfun and you're all like, this is no fun at all.

Additionally, if we target other 6502 machines, we'll want to be able to mark functions as C64-only or Apple-II-only or Atari-only or whatever.

And then if we targeted any 16-bit machines (@kpmgeek is making m68k noises, which I think I pooh-poohed at the time, but hey), all of our existing *fun keywords would suddenly mean exactly the same thing, with the possible exception of refun.

I remember we earmarked {} as a possibility for annotations/attributes, though a small part of me wants to use them for comments. Here are some existing syntaxes. Common to all of them is that they go on the line above the thing they're annotating, e.g. a function.

#[foo(a, b=c), bar, spam=eggs]     /* Rust-style */

[<foo(a, b=c); bar>]    /* F#-style */

[foo(a, b=c), bar]      /* C#-style */

@foo(a, b=c)            /* Java/Python-style */
@bar

Rust also has a syntax to indicate that the attribute applies to the current module #![...], which is handy--we definitely want to mark the vic-ii module as C64-only.

None of these really call to me, though the order I've put them in is roughly the order I'd rank them for gold-syntax suitability. I think putting the attribute before the function is probably the best option. Putting it inside the definition makes it harder to bump them to another line, which is awkward for long attributes, and putting it inside the body makes it hard to apply them to other kinds of toplevel definition which don't have bodies.

The function-call-esque syntax is pretty common. This makes sense though, since all of them are function/constructor/macro calls (though in Rust this wasn't the case until recently, so). I'm not sure it makes sense for us, but I'm also not sure it doesn't make sense for us.

Yes, the F# syntax is super ugly, but you can be sure that it's not going to get confused for anything else.