-
-
Notifications
You must be signed in to change notification settings - Fork 180
Description
The Zen of Python says "Namespaces are one honking great idea", and it has a point.
The main use case for namespaces would be for shared libraries like rgbds-structs. Currently authors have to either:
- Give all their macros and constants a unique prefix. This is verbose and noisy when the macros get used often.
- Pick names for all their macros and constants that risk colliding with names from other libraries or from the users' code.
(C lacks namespaces and also has this problem. It's why they've started using a "stdc_" prefix for functions like stdc_popcount, because "popcount" was already known to be a popular user-defined name.)
We could add NAMESPACE name and ENDNAMESPACE to RGBASM, which would put all the contained symbols in a new namespace name. Users would then either use namespace-prefixed symbols, or opt-in to the namespace with USENAMESPACE name (if they're certain that none of their own symbols clash with ones defined inside name).
Prior art: ca65 has .scope/.endscope with a :: separator, and fasm has namespace/end namespace with a . separator. Beyond assemblers, and even beyond programming languages, there are many kinds of namespaces, with separators like ::, :, ., /, \, -, etc.
Three main questions to answer about this feature:
- What syntax for declaring and using namespaces? I think
NAMESPACE,ENDNAMESPACE, andUSENAMESPACEkeywords are fine. They're self-descriptive, and they'd be infrequently used so they don't need to be very short. - What syntax for namespace separators? Some common choices:
::would conflict with our syntax for exported labels (e.g.Foo::Baris defining and exporting labelFooand invoking macroBar).:would conflict with our syntax for labels (e.g.Foo:Baris defining labelFooand invoking macroBar)./or-would conflict with binary operators (e.g.Foo/BarandFoo-Barare numeric expressions).\would conflict with our syntax for line continuations.@would conflict with our identifier characters (e.g.Foo@Baris a valid identifier already).->would work, and we don't yet have any other ideas for arrow-style operators. I'd supportFoo->BarforFoo-namespacedBar.=>would also work, but we already have operators<=,>=, and>>, which are visually similar.
- Should namespaces apply to labels?
- If YES, that would lead to problems:
- Emitting duplicate names in .sym files without their distinguishing namespaces would be confusing, potentially breaking for applications which need to know which symbol is which.
- Emitting namespace-qualified names in .sym files with a new kind of separator would need an update to the .sym file spec, which is not really supposed to depend so closely on RGBASM-specific features.
- Picking a namespace separator that's valid in .sym files would conflict with potential existing names (e.g.
Outer@Inner::, thenNAMESPACE Outer, thenInner::).
- If NO, that would be less problematic:
- Users might be surprised that some symbols are not affected by namespaces.
- Users might want to have labels in a namespace hierarchy. They'll already be able to do this with nested scopes ([Feature request] Nested label scopes #916).
- If YES, that would lead to problems:
- Should namespaces be nestable? I think not, at least not initially; it's a complication we can consider adding later if there's a visible use case or user demand.
- Should namespaces be reopenable? I think so, it's harmless and potentially useful, and would match how C++ namespaces work.
- What should
USENAMESPACEdo inside of an openedNAMESPACE? It could copy symbols from one namespace to another, but I don't think that's a very important feature, so if it's at all difficult or problematic to implement, we could just make it an error.
Summary:
NAMESPACE namestarts a new namespace (or resumes an existing namespace)namefor all non-label symbols inside it.NAMESPACEinsideNAMESPACEis an error.- Labels inside a namespace simply ignore the namespace; they all go in the top-level nameless space, and have "scopes" for their own kind of name hierarchy.
ENDNAMESPACEends the current namespace.ENDNAMESPACEwithout an openedNAMESPACEis of course an error.
USENAMESPACE nameputs all ofname's symbols in the top-level nameless namespace.- If any symbol in
nameis already defined at the top level (whether on its own or from a previousUSENAMESPACE), that's an error.
- If any symbol in
Space->Namerefers to the symbolNamein the namespaceSpace.->is a new token, which should not conflict with existing ones.