Popup YouTube Video
Sheerpower Logo

Enum Statement and Associated Built-in Functions


ENUM Statement in Sheerpower

The ENUM statement defines a related set of named numeric constants. Values can be assigned explicitly or generated automatically in sequence.

Enums are useful for representing states, choices, categories, command words, and other sets of related values. They improve readability by replacing unexplained numeric values with meaningful names.

Syntax

enum enum_name: name1, name2, name3, ...

In this syntax:

enum_name
The name of the enum type.
name1, name2, name3, ...
The names of the enum members. When no explicit values are supplied, Sheerpower assigns values automatically, starting with 1 and increasing by 1 for each following member.

You can also assign explicit numeric values if required:

enum enum_name: name1=value1, name2=value2, name3=value3, ...

When a member does not include an explicit value, Sheerpower assigns it the value of the preceding member plus 1. It is recommended that you do not use values of zero or duplicate values. This makes checking for unknown enum values easier.

Example: Traffic Light States

enum traffic_light: red, yellow, green current_state = traffic_light->yellow select case current_state case traffic_light->red print "Stop" case traffic_light->yellow print "Get Ready" case traffic_light->green print "Go" case else print "Unknown State" end select ! Print the number of members in the enum print "Number of members: "; size(traffic_light, 2)

Explanation

In this example, the ENUM statement defines three traffic-light states. Because no explicit values are supplied, Sheerpower assigns the following values:

  • traffic_light->red is 1.
  • traffic_light->yellow is 2.
  • traffic_light->green is 3.

The current state is set to yellow. The select case statement then selects the action associated with that state.

The size(enum_name, 2) function returns the number of members in an enum. In this example, it returns 3.

Using an enum improves readability by replacing hardcoded numeric values with meaningful names. It also reduces errors and makes the program easier to maintain.

Explicit Values

Enum members can be assigned specific numeric values:

enum status: pending=10, approved=20, rejected=30, expired=40

Members following an explicitly assigned value continue sequentially unless another explicit value is supplied:

enum response: unknown=0, accepted=10, delayed, rejected=20 ! unknown = 0 ! accepted = 10 ! delayed = 11 ! rejected = 20

Best Practices

Use meaningful and consistent member names. Keep each enum focused on one concept, such as states, categories, commands, or options.

Avoid unnecessarily long names that make expressions difficult to read. The enum type name should provide enough context to keep its member names concise.

Unless you have special case needs, there is no need to specify any values in your enum statement.

enum order_status: pending, paid, shipped, delivered, cancelled

Using enumname$() with Enums

The enumname$() function converts an assigned enum value into its corresponding member name. It is useful for error reporting, logging, debugging, and displaying enum values.

Syntax

name$ = enumname$(enum_type, value)
enum_type
An enum type declared with the ENUM statement.
value
The assigned numeric value whose member name is required.
name$
The matching enum member name.

Example

enum status: pending, approved, rejected, expired current = status->approved print "Status: "; enumname$(status, current) ! Outputs: APPROVED print "Status: "; enumname$(status, 999) ! Outputs: ?999? print "_integer after failure: "; _integer ! Outputs: 0

When a matching member is found, enumname$() returns its name. If no member has the supplied value, it returns the value inside question marks and sets _integer to zero.

Avoiding Hardcoded Member Names

Using enumname$() avoids duplicating enum member names as string literals.

enum status: pending, approved, rejected current = status->rejected print "Status: "; enumname$(status, current)

If a member is renamed, code that obtains the name through enumname$() remains synchronized with the enum declaration.

Problem → Hardcoded strings for enum member names can drift out of sync with the actual identifiers and produce incorrect logs or messages.

Solution → Use enumname$() to obtain the member name directly from the enum.

Efficiency → When enumname$() is called with a compile-time enum member, such as enumname$(status, status->approved), the resulting string is calculated at compile time and embedded as a constant. This requires no runtime lookup or allocation.

Takeaway → Prefer enumname$() in logs and messages to keep names correct, consistent, and easy to maintain.

enumvalue() - Convert an Enum Member Name to Its Value

The enumvalue() function looks up an enum member by name and returns the numeric value assigned to that member.

It is the inverse of enumname$():

enum traffic_light: red, yellow, green enumname$(traffic_light, 2) ! Returns "YELLOW" enumvalue(traffic_light, "yellow") ! Returns 2

The name comparison is case-insensitive. Therefore, "yellow", "Yellow", and "YELLOW" all match the same enum member.

Syntax

result = enumvalue(enum_type, name$)
enum_type
An enum type declared with the ENUM statement.
name$
The enum member name to find. The comparison is case-insensitive.
result
The numeric value assigned to the matching enum member. If no member matches, the function returns zero.

Assigned Values and Ordinal Positions

Every enum member has both an assigned numeric value and an ordinal position.

The assigned value is the number associated with the member. The ordinal is the member's position in the enum declaration, independent of its assigned value.

enum mode: off=0, slow=10, fast=20 ! Member Assigned value Ordinal ! off 0 1 ! slow 10 2 ! fast 20 3

The first member has ordinal 1, the second has ordinal 2, and so on.

Detecting a Successful Lookup

After enumvalue() performs a lookup, _integer contains the ordinal position of the matching member.

If no member matches, _integer is zero. Therefore, the reliable not-found test is:

value = enumvalue(my_enum, name$) if _integer = 0 then ! name$ is not a member of my_enum end if
Important: Test _integer, not the value returned by enumvalue(). An enum member may legitimately have an assigned value of zero.

Why _integer Contains the Ordinal

The value returned by enumvalue() cannot reliably indicate whether the lookup succeeded because zero may be a valid enum value.

enum mode: off=0, slow=1, fast=2 value = enumvalue(mode, "off") ! value = 0 ! _integer = 1 value = enumvalue(mode, "bogus") ! value = 0 ! _integer = 0

Both calls return zero. However, _integer distinguishes the successful lookup from the failed lookup:

  • "off" matches the first member, so _integer is 1.
  • "bogus" does not match a member, so _integer is 0.

Using the ordinal guarantees that every successful lookup sets _integer to a value greater than zero. Zero is reserved exclusively for a failed lookup.

Note: This differs from enumname$(), which places the matched enum value in _integer. With enumvalue(), the assigned value is already returned by the function, so _integer provides the complementary ordinal position.

Names That Do Not Match

An unknown name does not raise an exception. Instead, enumvalue() returns zero and sets _integer to zero.

value = enumvalue(mode, "nope") ! value = 0 ! _integer = 0 value = enumvalue(mode, "") ! value = 0 ! _integer = 0

Validating User or Configuration Input

A common use of enumvalue() is converting a text setting into an enum value while detecting spelling errors or unsupported values.

enum log_level: debug=10, info=20, warn=30, error=40 level$ = getsymbol$("level") level = enumvalue(log_level, trim$(level$)) if _integer = 0 then print "Error: unknown log level '"; level$; "'" else print "Logging at "; level$; " ("; level; ")" end if

Converting a Stored Name Back to a Value

Use enumname$() and enumvalue() together when enum member names are stored in a file, database, or configuration setting.

enum status: active=10, inactive=20, archived=30 saved$ = enumname$(status, status->active) ! saved$ = "ACTIVE" ! Later, after saved$ has been read from storage: code = enumvalue(status, saved$) ! code = 10 ! _integer = 1

Converting a Web Form Value

A web form can submit an enum member name. The program can convert the name and substitute a default when the submitted name is not recognized.

enum sort_dir: ascending, descending dir$ = getsymbol$("sort") dir = enumvalue(sort_dir, trim$(dir$)) if _integer = 0 then dir = sort_dir->ascending end if

Parsing Keywords

The function can recognize enum member names while processing tokens or command words.

enum command: start=1, stop=2, pause=3 for i = 1 to elements(line$, " ") word$ = element$(line$, i, " ") cmd = enumvalue(command, word$) if _integer <> 0 then do_command_word end if next i

Unknown words are ignored because they set _integer to zero.

Using the Ordinal Position

The ordinal stored in _integer can be used as an index into an array containing information associated with each enum member.

enum planet: mercury=100, venus=200, earth=300, mars=400 dim distance_au$(4) distance_au$(1) = "0.39" distance_au$(2) = "0.72" distance_au$(3) = "1.00" distance_au$(4) = "1.52" name$ = "earth" value = enumvalue(planet, name$) ordinal = _integer if ordinal > 0 then print distance_au$(ordinal) end if

In this example, value is 300 and ordinal is 3.

Quick Reference

Operation enumvalue(enum_type, name$)
Conversion Member name to assigned numeric value
Name comparison Case-insensitive
Successful lookup Returns the member's assigned value and sets _integer to its ordinal position
Failed lookup Returns zero and sets _integer to zero
Not-found test if _integer = 0 then ...
Inverse function enumname$(enum_type, value)

Comparing enumname$() and enumvalue()

The two enum lookup functions are inverses of each other, and they treat _integer differently. enumname$() places the matched value in _integer; enumvalue() places the matched ordinal position there. The table contrasts both functions side by side.

Aspect enumname$(enum_type, value) enumvalue(enum_type, name$)
Conversion Assigned value to member name Member name to assigned value
Lookup key Numeric value Member name (string)
Returns on success The member name, in uppercase The member's assigned numeric value
Returns on failure The supplied value wrapped in question marks, such as ?999? Zero
_integer on success The matched enum value The member's ordinal position (begins at 1)
_integer on failure Zero Zero
Reliable not-found test Returned string has the ?value? form. You can also use if _integer = 0 then ... if none of your enum values are zero. if _integer = 0 then ... — always reliable, since ordinals begin at 1.
Name comparison Not applicable Case-insensitive
Compile-time constants folding Yes Yes
Inverse function enumvalue() enumname$()
Hide Description

    

       


      

Enter or modify the code below, and then click on RUN

Looking for the full power of Sheerpower?
Check out the Sheerpower website. Free to download. Free to use.