Enums

From Adam Colton
Jump to navigation Jump to search

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.