bmx-ng / bcc

A next-generation bcc parser for BlitzMax
zlib License
33 stars 12 forks source link

Define Enums in Types #668

Open GWRon opened 2 months ago

GWRon commented 2 months ago

Coming from https://skirmish-dev.net/forum/topic/218/libsgd-with-lua/32 where "DruggedBunny" is writing a wrapper/translator of Mark Siblys LibSGD for BlitzMax ... there came up a discussion about enums in classes - and the visibility of enum "elements" inside of their file-scope. (so accessing an element of an enum without the enum-name and thus requiring "full names" of the enum elements while we in Blitzmax need to use the enum name itself in addition - as usual for us :D)

So is there a reason to not allow enums in a Type for "namescoping" them?

SuperStrict
Framework Brl.StandardIO

Enum ETest
    A
    B
End Enum

Type TTest
    Function T()
        SubT()
        Function SubT()
            print "hello world"
        End Function
    End Function

    Enum ETestTest
        A
        B
    End Enum
End Type

The idea there seems ot be that you can have your "all in one class" as name scope container (for SGD it would be Type SGD) and to be able to access enums with that scope (SGD.EMyEnum).

While I brought up the module scopes:

import SGD.core
Local e:SGD.core.EMyEnum = SGD.core.EMyEnum.A

it is of course not the same (eg the ".core" is required as the second level module is mandatory).

Maybe we could achieve something like the desired one without enums in types - but maybe not. What do others think about that and potential limits, issues, ... benefits? @woollybah @HurryStarfish

HurryStarfish commented 1 month ago

Can you clarify what you are requesting/wish to do with this? I'm not sure I fully understand. Being able to freely nest Enums (and Interfaces and Structs) in types would certainly be nice, but I'd expect the visibility and scoping rules for them to be the same as for everything else.

GWRon commented 1 month ago

I myself am not requesting or wishing something - so I might be wrong in my assumptions on what "they" want.

The discussion at Marks forum was about the visibility of enums and how to define some kind of "scope".

Mark at that topic:

OK, BlitzMax enums are closer to C++ enums than C, I didn't know/remember that! In C, the constants in an enum are actually visible in the same outer scope as the enum, eg:

enum BlendMode {
BLEND_MODE_ALPHA=1,
...etc...
};
BlendMode blendMode = BLEND_MODE_ALPHA;

Note how you don't have to qualifiy the BLEND_MODE_ALPHA as you would in BMX with a 'BlendMode' prefix (I don't think you even can in C). This is why 'C' enum member names usually include the enum name too, ie: the BLENDMODE prefix bit to differentiate them from other names that may be the same in the outer scope.

In both BMX and C++ (when using 'enum class' anyway) there's no point adding the enum name to the member name, since you have to specify the enum name when using the member anyway, eg:

// C++/BMX style
enum class BlendMode {
ALPHA=1,   // note: No need for 'BlendMode' prefix here....
};
BlendMode blendMode = BlendMode::ALPHA; // ...since its not optional here

What BMX can't do is let you to add an enum to a class, so while in C++ you could potentially do this:

class SGD {
enum BlendMode {
BLEND_MODE_ALPHA=1,
};
}
SGD::BlendMode blendMode == SGD::BLEND_MODE_ALPHA

In BMX, the BlendMode name would have to appear outside SGD, which defeats the point of placing eveything in an SGD namespace so it doesn't clash with anything.

If BMX did allow you to have enum in classes, you could perhaps tranlsate SGD_BlendMode like this: (Ronny: adjusted code to use Type, not Class, and to be blitzlike)


Type SGD
Enum BlendMode
Alpha = 1
End Enum
End Type

Local blendMode:SGD.BlendMode = SGD.BlendMode.Alpha


---

So I guess the main idea is to have an option to do something "similar" to what you can do now with module scopes already - just that you are not required to have 2 levels of modules (currently you would have to have "mods/sgd.mod/blendmode.mod/blendmode.bmx" which contains some `Alpha` thing ... but of course this wont be an enum then (with the benefits the enums bring - like passed parameter safety).
HurryStarfish commented 1 month ago

Ah, yeah the way enums work in C - where their "members" are leaked into the surrounding scope - has not been copied in any other programming language I know of. As mentioned in the posts you quoted, usually ends up with people putting prefixes on all the member names anyway to keep things organized. This, however:

Type SGD
   Enum BlendMode
      Alpha = 1
   End Enum
End Type

Local blendMode:SGD.BlendMode = SGD.BlendMode.Alpha

is something I agree would be quite useful. Personally I often want to do this with Structs rather than Enums, but I see no real reason why it shouldn't be allowed to nest any other kind of type inside a "Type".