Enums
Basic version is a list.
Basic List
type Terrain enum [ Wall Floor Rock ]
Will give Wall a value of 0, Floor=1 and Rock=2. It does string conversion
Terrain.Wall.String() // "Wall"
Terrain.Parse("Wall") // Null<Terrain> of Terrain.Wall
Terrain.Parse("Foo") // Null<Terrain> of Null
Flag
type Permission flag [ Read Write Execute ]
This will give the values Read=1, Write=2, Execute=4.
p := Permission.Write | .Read | .Execute // also could be var p Permission = .Write | .Read | .Execute p.String() // "Execute, Write, Read"
After the Permission.Write, we have enough type information for the rest. The string output will be in order from most to least significant.
Compound
type Door enum {
IsOpen bool
IsLocked bool
}[
Closed
Open : IsOpen
Locked: IsLocked
]
This prevents the invalid state of open and locked. It will also assign the values Closed=0 open=1 locked=2 matching the bit pattern. It allows for matching
d := Door.Closed Door.IsOpen(d) // false d = .Locked Door.IsOpen(d) // true
The fields need to be name IsOpen and IsLocked (not Open and Locked) otherwise they would collide with Open and Locked in the values. It may be possible to allow this if Door.Open as a value is equal to Door.Open as a field. So maybe:
type Door enum {
Open bool
Locked bool
}[
Closed
Open
Locked
]
Advanced
type Terrain enum {
Passable bool
Builder enum [
Natural
Human
Orc
Elf
]
}[
Rock: Builder.Natural,
WoodWall : Builder.(Human, Elf)
StonePath: Passable * Builder.(Human, Orc)
BoneWall: Builder.(Elf, Orc)
]
t := Terrain.Rock
Terrain.Passible(t) // False
Terrain.Builder.Natural(t) // true
t = Terrain.WoodWall
Terrain.WoodWall(t) // true
Terrain.Human(t) // true - defaults to lowest value valid combination
t |= Terrain.Elf
Terrain.Elf(t) // true
t.String() // "WoodWall Elf"
t |= Terrain.Orc // Invalid combination
t = Terrain.StonePath
t.String() // "StonePath Passible Human"
This is accomplished through bit masks. So the lowest bit is for Passible. The next two bits are for Builder and the next 4 bits are for the Terrain type.
Not Built In
It may be better to not have this be part of the core language but instead include it in the standard library.
One argument for this is defining "|". Given two valid values, OR could return an invalid value. And on a list, it doesn't make any sense at all. As part of the standard library, OR could return Null<Enum>.
Another is that it allows for greater variation. If I'm defining things on the language, I want to keep things very tight and only allow the minimal cross section. In the standard library, the pressure to keep a minimal set is still there, but much more relaxed.