compiler icon indicating copy to clipboard operation
compiler copied to clipboard

Feature proposal: enum expansion/inheritance

Open Daniel-Cortez opened this issue 3 years ago • 6 comments

Issue description:

I think it could be useful to have an ability for enumerations to inherit elements from other enumerations. Examples:

enum Entity
{
    type,       // Entity:0
    Float:posX, // Entity:1
    Float:posY  // Entity:2
};

enum Player(Entity)
{
    // enum Player extends enum Entity, so it has fields
    // "posX", "posY" and "type" inherited from the base enum
    Float:health, // Player:3
    numLives      // Player:4
};
enum EnumA
{
    e1 // EnumA:0
};

enum EnumB
{
    e2 // EnumB:0
};

// EnumAB has inherited elements "e1" and "e2".
enum EnumAB(EnumA, EnumB)
{
    // e1 = EnumAB:0
    // e2 = EnumAB:1
};

// Error: element "e1" is present in both EnumA and EnumAB,
// can't have two enum elements with the same name.
enum EnumABB(EnumA, EnumAB) {};

// Error: enumeration must have a name in order for expansion to work.
enum (EnumA) {};

Minimal complete verifiable example (MCVE):

Workspace Information:

  • Compiler version:
  • Command line arguments provided (or sampctl version):
  • Operating System:

Daniel-Cortez avatar Nov 08 '20 14:11 Daniel-Cortez

I think we should introduce a set of completely new extensions instead of overloading enum. enum is already being overloaded/abused to make struct. This has unwanted side effects such as spilling the entries into the global namespace.

Maybe we should introduce a new keyword to allow user-defined aggregate types. Maybe struct?

struct Player {
    userid,
    name[24],
    score,
    Float:somefloat,
    bool:loggedin
};

new Player:players[MAX_PLAYERS]; // I think it is a bad idea to mix tags and structs

func(&Player:player) { }

Internally, this can be stored as enum structs that exist currently. The difference would be that the identifiers of members don't spill out and objects can be passed by-value (internally copy and pass the array) and by-reference (internally just passing an array).

The tag of the user-defined types could be the name of the struct. This would probably allow operator overloading to be supported for these user-defined types easily. But I don't think it's a good idea because tag overrides might become messy (override Float: to Player:?).


struct File {
    id,
    static const INVALID = 0;

    open(const str[]) = fopen;
    
    bool:isopen() { return id != INVALID; }
};

new File:f;
f.open("a.txt");
if (f.isopen()) { }
f.close();

new INVLAID_FILE_HADLE = File.INVALID;

Related: #234

YashasSamaga avatar Nov 08 '20 15:11 YashasSamaga

I came to mention #234 after I saw the e-mail before I saw your edit. I think some combined feature of those would be amazing, without going too far in to feature overload. If we can do it right.

Y-Less avatar Nov 08 '20 15:11 Y-Less

This would be a great feature and hopefully something that would help discourage 'enum abuse' (something that I've been guilty of myself previously)

spacemud avatar Nov 08 '20 16:11 spacemud

Yeah custom types (structures) in pawn would be awesome. Not to mention functions overloading (but thats probably way to far)

NegativeIQ avatar Nov 11 '20 12:11 NegativeIQ

How would this affect something like { Float, ...}?

eoussama avatar Nov 11 '20 14:11 eoussama

How would this affect something like { Float, ...}?

I think this is already covered in #234:

Obviously that would require the tag of a variable to be known at compile time, and this could not work for run-time polymorphism

Daniel-Cortez avatar Nov 11 '20 15:11 Daniel-Cortez