First sorry if this is inconvenient but I am opening an issue/feature request
here as I do not want to use github.
\---
Currently items that are ordinal values in an enum are required to be in
ascending order.
I would like to remove or relax that requirement so that the code below
compiles:
type
unordered_enum = enum
a = 1
b = 0
Run
Some usecases are:
1. Grouping and ordering enum items by semantics and not by value.
2. Easier C code conversion, also asked by [1].
3. Reduce constraints on generated code (specs or standards to code).
These are the options I see, in order of preference and feasability:
1. the requirement be removed entirely.
2. if not possible, the requirement be removed when all the values are
specified.
3. if not possible, have a pragma that lets the user request an unordered
enum.
I am not a language designer and I am not familiar with nim compiler internals.
It is difficult for me to assess the implications of option1 on the
language/compiler/existing code.
So I attempted a patch for option 2.
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index c88795517..0efc3f47c 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -69,6 +69,9 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
e: PSym = nil
base: PType = nil
identToReplace: ptr PNode = nil
+ containsUnspecifiedValues = false
+ containsUnorderedValues = false
+ firstUnorderedValueIndex = 0
counter = 0
base = nil
result = newOrPrevType(tyEnum, prev, c)
@@ -121,16 +124,21 @@ proc semEnum(c: PContext, n: PNode, prev: PType):
PType =
if i != 1:
if x != counter: incl(result.flags, tfEnumHasHoles)
if x < counter:
- localError(c.config, n[i].info, errInvalidOrderInEnumX %
e.name.s)
+ if not containsUnorderedValues:
+ firstUnorderedValueIndex = i
+ containsUnorderedValues = true
x = counter
e.ast = strVal # might be nil
counter = x
of nkSym:
+ containsUnspecifiedValues = true
e = n[i].sym
of nkIdent, nkAccQuoted:
+ containsUnspecifiedValues = true
e = newSymS(skEnumField, n[i], c)
identToReplace = addr n[i]
of nkPragmaExpr:
+ containsUnspecifiedValues = true
e = newSymS(skEnumField, n[i][0], c)
pragma(c, e, n[i][1], enumFieldPragmas)
identToReplace = addr n[i][0]
@@ -162,6 +170,8 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType
=
localError(c.config, n[i].info, errOverflowInEnumX % [e.name.s,
$high(typeof(counter))])
else:
inc(counter)
+ if containsUnorderedValues and containsUnspecifiedValues:
+ localError(c.config, n[firstUnorderedValueIndex].info,
errInvalidOrderInEnumX % e.name.s)
if isPure and sfExported in result.sym.flags:
addPureEnum(c, LazySym(sym: result.sym))
if tfNotNil in e.typ.flags and not hasNull:
Run
Any comments?
[1] <https://github.com/nim-lang/Nim/issues/1043>