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>

Reply via email to