summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorcooldome <ariabushenko@gmail.com>2020-11-02 09:35:24 +0000
committerGitHub <noreply@github.com>2020-11-02 10:35:24 +0100
commit00b495de9520a91fe24d81e55da109960189a966 (patch)
treea8534f3cbb7145a912b37b0e6dcb05a1dffb4ea5 /compiler
parent5298366f862861a900c1a3b66d417cd54122a5ec (diff)
downloadNim-00b495de9520a91fe24d81e55da109960189a966.tar.gz
Use modern enums in compiler (#15775)
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim26
-rw-r--r--compiler/astalgo.nim2
-rw-r--r--compiler/commands.nim8
-rw-r--r--compiler/condsyms.nim10
-rw-r--r--compiler/docgen.nim2
-rw-r--r--compiler/idents.nim4
-rw-r--r--compiler/lambdalifting.nim2
-rw-r--r--compiler/layouter.nim18
-rw-r--r--compiler/lexer.nim103
-rw-r--r--compiler/lineinfos.nim106
-rw-r--r--compiler/linter.nim2
-rw-r--r--compiler/main.nim4
-rw-r--r--compiler/msgs.nim6
-rw-r--r--compiler/parser.nim2
-rw-r--r--compiler/pragmas.nim14
-rw-r--r--compiler/renderer.nim2
-rw-r--r--compiler/types.nim2
-rw-r--r--compiler/wordrecg.nim243
18 files changed, 219 insertions, 337 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index a9793fb21..ca931ab09 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -17,21 +17,17 @@ export int128
 
 type
   TCallingConvention* = enum
-    ccNimCall                 # nimcall, also the default
-    ccStdCall                 # procedure is stdcall
-    ccCDecl                   # cdecl
-    ccSafeCall                # safecall
-    ccSysCall                 # system call
-    ccInline                  # proc should be inlined
-    ccNoInline                # proc should not be inlined
-    ccFastCall                # fastcall (pass parameters in registers)
-    ccThisCall                # thiscall (parameters are pushed right-to-left)
-    ccClosure                 # proc has a closure
-    ccNoConvention            # needed for generating proper C procs sometimes
-
-const CallingConvToStr*: array[TCallingConvention, string] = ["nimcall", "stdcall",
-  "cdecl", "safecall", "syscall", "inline", "noinline", "fastcall", "thiscall",
-  "closure", "noconv"]
+    ccNimCall = "nimcall"           # nimcall, also the default
+    ccStdCall = "stdcall"           # procedure is stdcall
+    ccCDecl = "cdecl"               # cdecl
+    ccSafeCall = "safecall"         # safecall
+    ccSysCall = "syscall"           # system call
+    ccInline = "inline"             # proc should be inlined
+    ccNoInline = "noinline"         # proc should not be inlined
+    ccFastCall = "fastcall"         # fastcall (pass parameters in registers)
+    ccThisCall = "thiscall"         # thiscall (parameters are pushed right-to-left)
+    ccClosure  = "closure"          # proc has a closure
+    ccNoConvention = "noconv"       # needed for generating proper C procs sometimes
 
 type
   TNodeKind* = enum # order is extremely important, because ranges are used
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index 6aecb1dcb..d9cd5ade1 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -345,7 +345,7 @@ proc typeToYamlAux(conf: ConfigRef; n: PType, marker: var IntSet, indent: int,
     result.addf("$N$1\"n\": $2",     [istr, treeToYamlAux(conf, n.n, marker, indent + 2, maxRecDepth - 1)])
     if card(n.flags) > 0:
       result.addf("$N$1\"flags\": $2", [istr, flagsToStr(n.flags)])
-    result.addf("$N$1\"callconv\": $2", [istr, makeYamlString(CallingConvToStr[n.callConv])])
+    result.addf("$N$1\"callconv\": $2", [istr, makeYamlString($n.callConv)])
     result.addf("$N$1\"size\": $2", [istr, rope(n.size)])
     result.addf("$N$1\"align\": $2", [istr, rope(n.align)])
     result.addf("$N$1\"sons\": $2", [istr, sonsRope])
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 325b362a9..a35d1dae7 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -193,12 +193,12 @@ proc processSpecificNote*(arg: string, state: TSpecialWord, pass: TCmdLinePass,
   elif i < arg.len and (arg[i] in {':', '='}): inc(i)
   else: invalidCmdLineOption(conf, pass, orig, info)
   if state == wHint:
-    let x = findStr(lineinfos.HintsToStr, id)
-    if x >= 0: n = TNoteKind(x + ord(hintMin))
+    let x = findStr(hintMin..hintMax, id, errUnknown)
+    if x != errUnknown: n = TNoteKind(x)
     else: localError(conf, info, "unknown hint: " & id)
   else:
-    let x = findStr(lineinfos.WarningsToStr, id)
-    if x >= 0: n = TNoteKind(x + ord(warnMin))
+    let x = findStr(warnMin..warnMax, id, errUnknown)
+    if x != errUnknown: n = TNoteKind(x)
     else: localError(conf, info, "unknown warning: " & id)
 
   var val = substr(arg, i).normalize
diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim
index 1fbc30bbe..ee849435f 100644
--- a/compiler/condsyms.nim
+++ b/compiler/condsyms.nim
@@ -13,7 +13,7 @@ import
   strtabs
 
 from options import Feature
-from lineinfos import HintsToStr, WarningsToStr
+from lineinfos import hintMin, hintMax, warnMin, warnMax
 
 proc defineSymbol*(symbols: StringTableRef; symbol: string, value: string = "true") =
   symbols[symbol] = value
@@ -89,10 +89,10 @@ proc initDefines*(symbols: StringTableRef) =
   for f in Feature:
     defineSymbol("nimHas" & $f)
 
-  for s in WarningsToStr:
-    defineSymbol("nimHasWarning" & s)
-  for s in HintsToStr:
-    defineSymbol("nimHasHint" & s)
+  for s in warnMin..warnMax:
+    defineSymbol("nimHasWarning" & $s)
+  for s in hintMin..hintMax:
+    defineSymbol("nimHasHint" & $s)
 
   defineSymbol("nimFixedOwned")
   defineSymbol("nimHasStyleChecks")
diff --git a/compiler/docgen.nim b/compiler/docgen.nim
index 1d950f835..7609c96ee 100644
--- a/compiler/docgen.nim
+++ b/compiler/docgen.nim
@@ -997,7 +997,7 @@ proc documentEffect(cache: IdentCache; n, x: PNode, effectType: TSpecialWord, id
       effects[i].typ = real[i].typ
 
     result = newTreeI(nkExprColonExpr, n.info,
-      newIdentNode(getIdent(cache, specialWords[effectType]), n.info), effects)
+      newIdentNode(getIdent(cache, $effectType), n.info), effects)
 
 proc documentWriteEffect(cache: IdentCache; n: PNode; flag: TSymFlag; pragmaName: string): PNode =
   let s = n[namePos].sym
diff --git a/compiler/idents.nim b/compiler/idents.nim
index b621503ec..1e8c912d9 100644
--- a/compiler/idents.nim
+++ b/compiler/idents.nim
@@ -107,8 +107,8 @@ proc newIdentCache*(): IdentCache =
   result.idDelegator = result.getIdent":delegator"
   result.emptyIdent = result.getIdent("")
   # initialize the keywords:
-  for s in succ(low(specialWords))..high(specialWords):
-    result.getIdent(specialWords[s], hashIgnoreStyle(specialWords[s])).id = ord(s)
+  for s in succ(low(TSpecialWord))..high(TSpecialWord):
+    result.getIdent($s, hashIgnoreStyle($s)).id = ord(s)
 
 proc whichKeyword*(id: PIdent): TSpecialWord =
   if id.id < 0: result = wInvalid
diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim
index b552d9455..95e50d00f 100644
--- a/compiler/lambdalifting.nim
+++ b/compiler/lambdalifting.nim
@@ -295,7 +295,7 @@ proc markAsClosure(g: ModuleGraph; owner: PSym; n: PNode) =
       [s.name.s, typeToString(s.typ), g.config$s.info])
   elif not (owner.typ.callConv == ccClosure or owner.typ.callConv == ccNimCall and tfExplicitCallConv notin owner.typ.flags):
     localError(g.config, n.info, "illegal capture '$1' because '$2' has the calling convention: <$3>" %
-      [s.name.s, owner.name.s, CallingConvToStr[owner.typ.callConv]])
+      [s.name.s, owner.name.s, $owner.typ.callConv])
   incl(owner.typ.flags, tfCapturesEnv)
   owner.typ.callConv = ccClosure
 
diff --git a/compiler/layouter.nim b/compiler/layouter.nim
index ee45d357f..c603c16ff 100644
--- a/compiler/layouter.nim
+++ b/compiler/layouter.nim
@@ -494,7 +494,7 @@ proc emitTok*(em: var Emitter; L: Lexer; tok: Token) =
       wrSpace em
 
     if not em.inquote:
-      wr(em, TokTypeToStr[tok.tokType], ltKeyword)
+      wr(em, $tok.tokType, ltKeyword)
       if tok.tokType in {tkAnd, tkOr, tkIn, tkNotin}:
         rememberSplit(splitIn)
         wrSpace em
@@ -503,28 +503,28 @@ proc emitTok*(em: var Emitter; L: Lexer; tok: Token) =
       wr(em, tok.ident.s, ltIdent)
 
   of tkColon:
-    wr(em, TokTypeToStr[tok.tokType], ltOther)
+    wr(em, $tok.tokType, ltOther)
     wrSpace em
   of tkSemiColon, tkComma:
-    wr(em, TokTypeToStr[tok.tokType], ltOther)
+    wr(em, $tok.tokType, ltOther)
     rememberSplit(splitComma)
     wrSpace em
   of openPars:
     if tok.strongSpaceA > 0 and not em.endsInWhite and
         (not em.wasExportMarker or tok.tokType == tkCurlyDotLe):
       wrSpace em
-    wr(em, TokTypeToStr[tok.tokType], ltSomeParLe)
+    wr(em, $tok.tokType, ltSomeParLe)
     rememberSplit(splitParLe)
   of closedPars:
-    wr(em, TokTypeToStr[tok.tokType], ltSomeParRi)
+    wr(em, $tok.tokType, ltSomeParRi)
   of tkColonColon:
-    wr(em, TokTypeToStr[tok.tokType], ltOther)
+    wr(em, $tok.tokType, ltOther)
   of tkDot:
     lastTokWasTerse = true
-    wr(em, TokTypeToStr[tok.tokType], ltOther)
+    wr(em, $tok.tokType, ltOther)
   of tkEquals:
     if not em.inquote and not em.endsInWhite: wrSpace(em)
-    wr(em, TokTypeToStr[tok.tokType], ltOther)
+    wr(em, $tok.tokType, ltOther)
     if not em.inquote: wrSpace(em)
   of tkOpr, tkDotDot:
     if em.inquote or ((tok.strongSpaceA == 0 and tok.strongSpaceB == 0) and
@@ -544,7 +544,7 @@ proc emitTok*(em: var Emitter; L: Lexer; tok: Token) =
         wrSpace(em)
   of tkAccent:
     if not em.inquote and endsInAlpha(em): wrSpace(em)
-    wr(em, TokTypeToStr[tok.tokType], ltOther)
+    wr(em, $tok.tokType, ltOther)
     em.inquote = not em.inquote
   of tkComment:
     if not preventComment:
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index c15ecddfc..e020236b1 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -31,37 +31,44 @@ const
 
 type
   TokType* = enum
-    tkInvalid, tkEof,         # order is important here!
-    tkSymbol, # keywords:
-    tkAddr, tkAnd, tkAs, tkAsm,
-    tkBind, tkBlock, tkBreak, tkCase, tkCast,
-    tkConcept, tkConst, tkContinue, tkConverter,
-    tkDefer, tkDiscard, tkDistinct, tkDiv, tkDo,
-    tkElif, tkElse, tkEnd, tkEnum, tkExcept, tkExport,
-    tkFinally, tkFor, tkFrom, tkFunc,
-    tkIf, tkImport, tkIn, tkInclude, tkInterface,
-    tkIs, tkIsnot, tkIterator,
-    tkLet,
-    tkMacro, tkMethod, tkMixin, tkMod, tkNil, tkNot, tkNotin,
-    tkObject, tkOf, tkOr, tkOut,
-    tkProc, tkPtr, tkRaise, tkRef, tkReturn,
-    tkShl, tkShr, tkStatic,
-    tkTemplate,
-    tkTry, tkTuple, tkType, tkUsing,
-    tkVar, tkWhen, tkWhile, tkXor,
-    tkYield, # end of keywords
-    tkIntLit, tkInt8Lit, tkInt16Lit, tkInt32Lit, tkInt64Lit,
-    tkUIntLit, tkUInt8Lit, tkUInt16Lit, tkUInt32Lit, tkUInt64Lit,
-    tkFloatLit, tkFloat32Lit, tkFloat64Lit, tkFloat128Lit,
-    tkStrLit, tkRStrLit, tkTripleStrLit,
-    tkGStrLit, tkGTripleStrLit, tkCharLit, tkParLe, tkParRi, tkBracketLe,
-    tkBracketRi, tkCurlyLe, tkCurlyRi,
-    tkBracketDotLe, tkBracketDotRi, # [. and  .]
-    tkCurlyDotLe, tkCurlyDotRi, # {.  and  .}
-    tkParDotLe, tkParDotRi,   # (. and .)
-    tkComma, tkSemiColon,
-    tkColon, tkColonColon, tkEquals, tkDot, tkDotDot, tkBracketLeColon,
-    tkOpr, tkComment, tkAccent,
+    tkInvalid = "tkInvalid", tkEof = "[EOF]", # order is important here!
+    tkSymbol = "tkSymbol", # keywords:
+    tkAddr = "addr", tkAnd = "and", tkAs = "as", tkAsm = "asm",
+    tkBind = "bind", tkBlock = "block", tkBreak = "break", tkCase = "case", tkCast = "cast",
+    tkConcept = "concept", tkConst = "const", tkContinue = "continue", tkConverter = "converter",
+    tkDefer = "defer", tkDiscard = "discard", tkDistinct = "distinct", tkDiv = "div", tkDo = "do",
+    tkElif = "elif", tkElse = "else", tkEnd = "end", tkEnum = "enum", tkExcept = "except", tkExport = "export",
+    tkFinally = "finally", tkFor = "for", tkFrom = "from", tkFunc = "func",
+    tkIf = "if", tkImport = "import", tkIn = "in", tkInclude = "include", tkInterface = "interface",
+    tkIs = "is", tkIsnot = "isnot", tkIterator = "iterator",
+    tkLet = "let",
+    tkMacro = "macro", tkMethod = "method", tkMixin = "mixin", tkMod = "mod", tkNil = "nil", tkNot = "not", tkNotin = "notin",
+    tkObject = "object", tkOf = "of", tkOr = "or", tkOut = "out",
+    tkProc = "proc", tkPtr = "ptr", tkRaise = "raise", tkRef = "ref", tkReturn = "return",
+    tkShl = "shl", tkShr = "shr", tkStatic = "static",
+    tkTemplate = "template",
+    tkTry = "try", tkTuple = "tuple", tkType = "type", tkUsing = "using",
+    tkVar = "var", tkWhen = "when", tkWhile = "while", tkXor = "xor",
+    tkYield = "yield", # end of keywords
+
+    tkIntLit = "tkIntLit", tkInt8Lit = "tkInt8Lit", tkInt16Lit = "tkInt16Lit", 
+    tkInt32Lit = "tkInt32Lit", tkInt64Lit = "tkInt64Lit",
+    tkUIntLit = "tkUIntLit", tkUInt8Lit = "tkUInt8Lit", tkUInt16Lit = "tkUInt16Lit", 
+    tkUInt32Lit = "tkUInt32Lit", tkUInt64Lit = "tkUInt64Lit",
+    tkFloatLit = "tkFloatLit", tkFloat32Lit = "tkFloat32Lit",
+    tkFloat64Lit = "tkFloat64Lit", tkFloat128Lit = "tkFloat128Lit",
+    tkStrLit = "tkStrLit", tkRStrLit = "tkRStrLit", tkTripleStrLit = "tkTripleStrLit",
+    tkGStrLit = "tkGStrLit", tkGTripleStrLit = "tkGTripleStrLit", tkCharLit = "tkCharLit", 
+    
+    tkParLe = "(", tkParRi = ")", tkBracketLe = "[",
+    tkBracketRi = "]", tkCurlyLe = "{", tkCurlyRi = "}",
+    tkBracketDotLe = "[.", tkBracketDotRi = ".]",
+    tkCurlyDotLe = "{.", tkCurlyDotRi = ".}",
+    tkParDotLe = "(.", tkParDotRi = ".)",
+    tkComma = ",", tkSemiColon = ";",
+    tkColon = ":", tkColonColon = "::", tkEquals = "=", 
+    tkDot = ".", tkDotDot = "..", tkBracketLeColon = "[:",
+    tkOpr, tkComment, tkAccent = "`",
     # these are fake tokens used by renderer.nim
     tkSpaces, tkInfixOpr, tkPrefixOpr, tkPostfixOpr
 
@@ -74,35 +81,6 @@ const
     # tokens that should not be considered for previousToken
   tokKeywordLow* = succ(tkSymbol)
   tokKeywordHigh* = pred(tkIntLit)
-  TokTypeToStr*: array[TokType, string] = ["tkInvalid", "[EOF]",
-    "tkSymbol",
-    "addr", "and", "as", "asm",
-    "bind", "block", "break", "case", "cast",
-    "concept", "const", "continue", "converter",
-    "defer", "discard", "distinct", "div", "do",
-    "elif", "else", "end", "enum", "except", "export",
-    "finally", "for", "from", "func", "if",
-    "import", "in", "include", "interface", "is", "isnot", "iterator",
-    "let",
-    "macro", "method", "mixin", "mod",
-    "nil", "not", "notin", "object", "of", "or",
-    "out", "proc", "ptr", "raise", "ref", "return",
-    "shl", "shr", "static",
-    "template",
-    "try", "tuple", "type", "using",
-    "var", "when", "while", "xor",
-    "yield",
-    "tkIntLit", "tkInt8Lit", "tkInt16Lit", "tkInt32Lit", "tkInt64Lit",
-    "tkUIntLit", "tkUInt8Lit", "tkUInt16Lit", "tkUInt32Lit", "tkUInt64Lit",
-    "tkFloatLit", "tkFloat32Lit", "tkFloat64Lit", "tkFloat128Lit",
-    "tkStrLit", "tkRStrLit",
-    "tkTripleStrLit", "tkGStrLit", "tkGTripleStrLit", "tkCharLit", "(",
-    ")", "[", "]", "{", "}", "[.", ".]", "{.", ".}", "(.", ".)",
-    ",", ";",
-    ":", "::", "=", ".", "..", "[:",
-    "tkOpr", "tkComment", "`",
-    "tkSpaces", "tkInfixOpr",
-    "tkPrefixOpr", "tkPostfixOpr"]
 
 type
   NumericalBase* = enum
@@ -171,7 +149,7 @@ proc `$`*(tok: Token): string =
   of tkIntLit..tkInt64Lit: $tok.iNumber
   of tkFloatLit..tkFloat64Lit: $tok.fNumber
   of tkInvalid, tkStrLit..tkCharLit, tkComment: tok.literal
-  of tkParLe..tkColon, tkEof, tkAccent: TokTypeToStr[tok.tokType]
+  of tkParLe..tkColon, tkEof, tkAccent: $tok.tokType
   else:
     if tok.ident != nil:
       tok.ident.s
@@ -183,8 +161,7 @@ proc prettyTok*(tok: Token): string =
   else: $tok
 
 proc printTok*(conf: ConfigRef; tok: Token) =
-  msgWriteln(conf, $tok.line & ":" & $tok.col & "\t" &
-      TokTypeToStr[tok.tokType] & " " & $tok)
+  msgWriteln(conf, $tok.line & ":" & $tok.col & "\t" & $tok.tokType & " " & $tok)
 
 proc initToken*(L: var Token) =
   L.tokType = tkInvalid
diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim
index 4a7c09276..759002312 100644
--- a/compiler/lineinfos.nim
+++ b/compiler/lineinfos.nim
@@ -36,40 +36,40 @@ type
     errProveInit, # deadcode
     errGenerated,
     errUser,
-    warnCannotOpenFile,
-    warnOctalEscape, warnXIsNeverRead, warnXmightNotBeenInit,
-    warnDeprecated, warnConfigDeprecated,
-    warnSmallLshouldNotBeUsed, warnUnknownMagic, warnRedefinitionOfLabel,
-    warnUnknownSubstitutionX, warnLanguageXNotSupported,
-    warnFieldXNotSupported, warnCommentXIgnored,
-    warnTypelessParam,
-    warnUseBase, warnWriteToForeignHeap, warnUnsafeCode,
-    warnUnusedImportX,
-    warnInheritFromException,
-    warnEachIdentIsTuple,
-    warnUnsafeSetLen,
-    warnUnsafeDefault,
-    warnProveInit, warnProveField, warnProveIndex,
-    warnUnreachableElse, warnUnreachableCode,
-    warnStaticIndexCheck, warnGcUnsafe, warnGcUnsafe2,
-    warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed,
-    warnInconsistentSpacing, warnCaseTransition, warnCycleCreated,
-    warnObservableStores,
-    warnUser,
-    hintSuccess, hintSuccessX, hintCC,
-    hintLineTooLong, hintXDeclaredButNotUsed,
-    hintXCannotRaiseY,
-    hintConvToBaseNotNeeded,
-    hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
-    hintProcessing, hintCodeBegin, hintCodeEnd, hintConf, hintPath,
-    hintConditionAlwaysTrue, hintConditionAlwaysFalse, hintName, hintPattern,
-    hintExecuting, hintLinking, hintDependency,
-    hintSource, hintPerformance, hintStackTrace, hintGCStats,
-    hintGlobalVar, hintExpandMacro,
-    hintUser, hintUserRaw,
-    hintExtendedContext,
-    hintMsgOrigin, # since 1.3.5
-    hintDeclaredLoc, # since 1.5.1
+    
+    warnCannotOpenFile = "CannotOpenFile", warnOctalEscape = "OctalEscape", 
+    warnXIsNeverRead = "XIsNeverRead", warnXmightNotBeenInit = "XmightNotBeenInit",
+    warnDeprecated = "Deprecated", warnConfigDeprecated = "ConfigDeprecated",
+    warnSmallLshouldNotBeUsed = "SmallLshouldNotBeUsed", warnUnknownMagic = "UnknownMagic", 
+    warnRedefinitionOfLabel = "RedefinitionOfLabel", warnUnknownSubstitutionX = "UnknownSubstitutionX", 
+    warnLanguageXNotSupported = "LanguageXNotSupported", warnFieldXNotSupported = "FieldXNotSupported", 
+    warnCommentXIgnored = "CommentXIgnored", warnTypelessParam = "TypelessParam",
+    warnUseBase = "UseBase", warnWriteToForeignHeap = "WriteToForeignHeap", 
+    warnUnsafeCode = "UnsafeCode", warnUnusedImportX = "UnusedImport",
+    warnInheritFromException = "InheritFromException", warnEachIdentIsTuple = "EachIdentIsTuple",
+    warnUnsafeSetLen = "UnsafeSetLen", warnUnsafeDefault = "UnsafeDefault",
+    warnProveInit = "ProveInit", warnProveField = "ProveField", warnProveIndex = "ProveIndex",
+    warnUnreachableElse = "UnreachableElse", warnUnreachableCode = "UnreachableCode",
+    warnStaticIndexCheck = "IndexCheck", warnGcUnsafe = "GcUnsafe", warnGcUnsafe2 = "GcUnsafe2",
+    warnUninit = "Uninit", warnGcMem = "GcMem", warnDestructor = "Destructor", 
+    warnLockLevel = "LockLevel", warnResultShadowed = "ResultShadowed", 
+    warnInconsistentSpacing = "Spacing",  warnCaseTransition = "CaseTransition", 
+    warnCycleCreated = "CycleCreated", warnObservableStores = "ObservableStores", 
+    warnUser = "User",
+
+    hintSuccess = "Success", hintSuccessX = "SuccessX", hintCC = "CC",
+    hintLineTooLong = "LineTooLong", hintXDeclaredButNotUsed = "XDeclaredButNotUsed",
+    hintXCannotRaiseY = "XCannotRaiseY", hintConvToBaseNotNeeded = "ConvToBaseNotNeeded",
+    hintConvFromXtoItselfNotNeeded = "ConvFromXtoItselfNotNeeded", hintExprAlwaysX = "ExprAlwaysX", 
+    hintQuitCalled = "QuitCalled", hintProcessing = "Processing", hintCodeBegin = "CodeBegin", 
+    hintCodeEnd = "CodeEnd", hintConf = "Conf", hintPath = "Path",
+    hintConditionAlwaysTrue = "CondTrue", hintConditionAlwaysFalse = "CondFalse", hintName = "Name", 
+    hintPattern = "Pattern", hintExecuting = "Exec", hintLinking = "Link", hintDependency = "Dependency",
+    hintSource = "Source", hintPerformance = "Performance", hintStackTrace = "StackTrace", 
+    hintGCStats = "GCStats", hintGlobalVar = "GlobalVar", hintExpandMacro = "ExpandMacro",
+    hintUser = "User", hintUserRaw = "UserRaw", hintExtendedContext = "ExtendedContext",
+    hintMsgOrigin = "MsgOrigin", # since 1.3.5
+    hintDeclaredLoc = "DeclaredLoc", # since 1.5.1
 
 const
   MsgKindToStr*: array[TMsgKind, string] = [
@@ -164,34 +164,6 @@ const
   ]
 
 const
-  WarningsToStr* = ["CannotOpenFile", "OctalEscape",
-    "XIsNeverRead", "XmightNotBeenInit",
-    "Deprecated", "ConfigDeprecated",
-    "SmallLshouldNotBeUsed", "UnknownMagic",
-    "RedefinitionOfLabel", "UnknownSubstitutionX",
-    "LanguageXNotSupported", "FieldXNotSupported",
-    "CommentXIgnored",
-    "TypelessParam", "UseBase", "WriteToForeignHeap",
-    "UnsafeCode", "UnusedImport", "InheritFromException",
-    "EachIdentIsTuple",
-    "UnsafeSetLen", "UnsafeDefault",
-    "ProveInit", "ProveField", "ProveIndex", "UnreachableElse", "UnreachableCode",
-    "IndexCheck", "GcUnsafe", "GcUnsafe2", "Uninit",
-    "GcMem", "Destructor", "LockLevel", "ResultShadowed",
-    "Spacing", "CaseTransition", "CycleCreated",
-    "ObservableStores", "User"]
-
-  HintsToStr* = [
-    "Success", "SuccessX", "CC", "LineTooLong",
-    "XDeclaredButNotUsed", "XCannotRaiseY",
-    "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
-    "ExprAlwaysX", "QuitCalled", "Processing", "CodeBegin", "CodeEnd", "Conf",
-    "Path", "CondTrue", "CondFalse", "Name", "Pattern", "Exec", "Link", "Dependency",
-    "Source", "Performance", "StackTrace", "GCStats", "GlobalVar", "ExpandMacro",
-    "User", "UserRaw", "ExtendedContext", "MsgOrigin", "DeclaredLoc"
-  ]
-
-const
   fatalMin* = errUnknown
   fatalMax* = errInternal
   errMin* = errUnknown
@@ -201,16 +173,6 @@ const
   hintMin* = hintSuccess
   hintMax* = high(TMsgKind)
 
-proc msgToStr*(msg: TMsgKind): string =
-  case msg
-  of warnMin..warnMax: WarningsToStr[ord(msg) - ord(warnMin)]
-  of hintMin..hintMax: HintsToStr[ord(msg) - ord(hintMin)]
-  else: "" # we could at least do $msg - prefix `err`
-
-static:
-  doAssert HintsToStr.len == ord(hintMax) - ord(hintMin) + 1
-  doAssert WarningsToStr.len == ord(warnMax) - ord(warnMin) + 1
-
 type
   TNoteKind* = range[warnMin..hintMax] # "notes" are warnings or hints
   TNoteKinds* = set[TNoteKind]
diff --git a/compiler/linter.nim b/compiler/linter.nim
index a229958e6..77e0a84e4 100644
--- a/compiler/linter.nim
+++ b/compiler/linter.nim
@@ -128,6 +128,6 @@ proc styleCheckUse*(conf: ConfigRef; info: TLineInfo; s: PSym) =
     lintReport(conf, info, newName, oldName)
 
 proc checkPragmaUse*(conf: ConfigRef; info: TLineInfo; w: TSpecialWord; pragmaName: string) =
-  let wanted = specialWords[w]
+  let wanted = $w
   if pragmaName != wanted:
     lintReport(conf, info, wanted, pragmaName)
diff --git a/compiler/main.nim b/compiler/main.nim
index 210933231..af9102414 100644
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -303,10 +303,10 @@ proc mainCommand*(graph: ModuleGraph) =
 
       var hints = newJObject() # consider factoring with `listHints`
       for a in hintMin..hintMax:
-        hints[a.msgToStr] = %(a in conf.notes)
+        hints[$a] = %(a in conf.notes)
       var warnings = newJObject()
       for a in warnMin..warnMax:
-        warnings[a.msgToStr] = %(a in conf.notes)
+        warnings[$a] = %(a in conf.notes)
 
       var dumpdata = %[
         (key: "version", val: %VersionAsString),
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index 7e2b8e8a6..0f5879ff6 100644
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -489,7 +489,7 @@ proc liMessage*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
     color: ForegroundColor
     ignoreMsg = false
     sev: Severity
-  let kind = if msg != hintUserRaw: msg.msgToStr else: "" # xxx not sure why hintUserRaw is special
+  let kind = if msg in warnMin..hintMax and msg != hintUserRaw: $msg else: "" # xxx not sure why hintUserRaw is special
   case msg
   of errMin..errMax:
     sev = Severity.Error
@@ -536,7 +536,7 @@ proc liMessage*(conf: ConfigRef; info: TLineInfo, msg: TMsgKind, arg: string,
         if hintMsgOrigin in conf.mainPackageNotes:
           styledMsgWriteln(styleBright, toFileLineCol(info2), resetStyle,
             " compiler msg initiated here", KindColor,
-            KindFormat % hintMsgOrigin.msgToStr,
+            KindFormat % $hintMsgOrigin,
             resetStyle)
   handleError(conf, msg, eh, s)
 
@@ -612,7 +612,7 @@ proc quotedFilename*(conf: ConfigRef; i: TLineInfo): Rope =
 
 template listMsg(title, r) =
   msgWriteln(conf, title)
-  for a in r: msgWriteln(conf, "  [$1] $2" % [if a in conf.notes: "x" else: " ", a.msgToStr])
+  for a in r: msgWriteln(conf, "  [$1] $2" % [if a in conf.notes: "x" else: " ", $a])
 
 proc listWarnings*(conf: ConfigRef) = listMsg("Warnings:", warnMin..warnMax)
 proc listHints*(conf: ConfigRef) = listMsg("Hints:", hintMin..hintMax)
diff --git a/compiler/parser.nim b/compiler/parser.nim
index e3cf54b38..01ec6fe95 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -219,7 +219,7 @@ proc eat(p: var Parser, tokType: TokType) =
     getTok(p)
   else:
     lexMessage(p.lex, errGenerated,
-      "expected: '" & TokTypeToStr[tokType] & "', but got: '" & prettyTok(p.tok) & "'")
+      "expected: '" & $tokType & "', but got: '" & prettyTok(p.tok) & "'")
 
 proc parLineInfo(p: Parser): TLineInfo =
   ## Retrieve the line information associated with the parser's current state.
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 273b2b004..c1d54c4a2 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -330,10 +330,10 @@ proc processDynLib(c: PContext, n: PNode, sym: PSym) =
       sym.typ.callConv = ccCDecl
 
 proc processNote(c: PContext, n: PNode) =
-  template handleNote(toStrArray, msgMin, notes) =
-    let x = findStr(toStrArray, n[0][1].ident.s)
-    if x >= 0:
-      nk = TNoteKind(x + ord(msgMin))
+  template handleNote(enumVals, notes) =
+    let x = findStr(enumVals, n[0][1].ident.s, errUnknown)
+    if x !=  errUnknown:
+      nk = TNoteKind(x)
       let x = c.semConstBoolExpr(c, n[1])
       n[1] = x
       if x.kind == nkIntLit and x.intVal != 0: incl(notes, nk)
@@ -347,9 +347,9 @@ proc processNote(c: PContext, n: PNode) =
       n[0][1].kind == nkIdent and n[0][0].kind == nkIdent:
     var nk: TNoteKind
     case whichKeyword(n[0][0].ident)
-    of wHint: handleNote(HintsToStr, hintMin, c.config.notes)
-    of wWarning: handleNote(WarningsToStr, warnMin, c.config.notes)
-    of wWarningAsError: handleNote(WarningsToStr, warnMin, c.config.warningAsErrors)
+    of wHint: handleNote(hintMin .. hintMax, c.config.notes)
+    of wWarning: handleNote(warnMin .. warnMax, c.config.notes)
+    of wWarningAsError: handleNote(warnMin .. warnMax, c.config.warningAsErrors)
     else: invalidPragma(c, n)
   else: invalidPragma(c, n)
 
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index b897aff5d..a4152cf29 100644
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -597,7 +597,7 @@ proc gcommaAux(g: var TSrcGen, n: PNode, ind: int, start: int = 0,
     gsub(g, n[i])
     if c:
       if g.tokens.len > oldLen:
-        putWithSpace(g, separator, TokTypeToStr[separator])
+        putWithSpace(g, separator, $separator)
       if hasCom(n[i]):
         gcoms(g)
         optNL(g, ind)
diff --git a/compiler/types.nim b/compiler/types.nim
index 9875f5e1b..42b7de416 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -700,7 +700,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
         if i < t.len - 1: result.add(", ")
       result.add(')')
       if t.len > 0 and t[0] != nil: result.add(": " & typeToString(t[0]))
-      var prag = if t.callConv == ccNimCall and tfExplicitCallConv notin t.flags: "" else: CallingConvToStr[t.callConv]
+      var prag = if t.callConv == ccNimCall and tfExplicitCallConv notin t.flags: "" else: $t.callConv
       if tfNoSideEffect in t.flags:
         addSep(prag)
         prag.add("noSideEffect")
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index f6fc92dc8..e2e3a1d2f 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -15,78 +15,99 @@
 
 from strutils import cmpIgnoreStyle
 
-# Keywords must be kept sorted and within a range
-
 type
   TSpecialWord* = enum
-    wInvalid,
-
-    wAddr, wAnd, wAs, wAsm,
-    wBind, wBlock, wBreak, wCase, wCast, wConcept, wConst,
-    wContinue, wConverter, wDefer, wDiscard, wDistinct, wDiv, wDo,
-    wElif, wElse, wEnd, wEnum, wExcept, wExport,
-    wFinally, wFor, wFrom, wFunc, wIf, wImport, wIn,
-    wInclude, wInterface, wIs, wIsnot, wIterator, wLet,
-    wMacro, wMethod, wMixin, wMod, wNil,
-    wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn,
-    wShl, wShr, wStatic, wTemplate, wTry, wTuple, wType, wUsing, wVar,
-    wWhen, wWhile, wXor, wYield,
-
-    wColon, wColonColon, wEquals, wDot, wDotDot,
-    wStar, wMinus,
-    wMagic, wThread, wFinal, wProfiler, wMemTracker, wObjChecks,
-    wIntDefine, wStrDefine, wBoolDefine, wCursor, wNoalias,
-
-    wImmediate, wConstructor, wDestructor, wDelegator, wOverride,
-    wImportCpp, wImportObjC,
-    wImportCompilerProc,
-    wImportc, wImportJs, wExportc, wExportCpp, wExportNims,
-    wIncompleteStruct, # deprecated
-    wCompleteStruct,
-    wRequiresInit,
-    wAlign, wNodecl, wPure, wSideEffect, wHeader,
-    wNoSideEffect, wGcSafe, wNoreturn, wNosinks, wMerge, wLib, wDynlib,
-    wCompilerProc, wCore, wProcVar, wBase, wUsed,
-    wFatal, wError, wWarning, wHint, wWarningAsError, wLine, wPush, wPop, wDefine, wUndef,
-    wLineDir, wStackTrace, wLineTrace, wLink, wCompile,
-    wLinksys, wDeprecated, wVarargs, wCallconv, wDebugger,
-    wNimcall, wStdcall, wCdecl, wSafecall, wSyscall, wInline, wNoInline,
-    wFastcall, wThiscall, wClosure, wNoconv, wOn, wOff, wChecks, wRangeChecks,
-    wBoundChecks, wOverflowChecks, wNilChecks,
-    wFloatChecks, wNanChecks, wInfChecks, wStyleChecks, wStaticBoundchecks,
-    wNonReloadable, wExecuteOnReload,
-    wAssertions, wPatterns, wTrMacros, wSinkInference, wWarnings,
-    wHints, wOptimization, wRaises, wWrites, wReads, wSize, wEffects, wTags,
-    wRequires, wEnsures, wInvariant, wAssume, wAssert,
-    wDeadCodeElimUnused,  # deprecated, dead code elim always happens
-    wSafecode, wPackage, wNoForward, wReorder, wNoRewrite, wNoDestroy,
-    wPragma,
-    wCompileTime, wNoInit,
-    wPassc, wPassl, wLocalPassc, wBorrow, wDiscardable,
-    wFieldChecks,
-    wSubsChar, wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto,
-    wInjectStmt, wExperimental,
-    wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit,
-    wAsmNoStackFrame,
-    wImplicitStatic, wGlobal, wCodegenDecl, wUnchecked, wGuard, wLocks,
-    wPartial, wExplain, wLiftLocals,
-
-    wAuto, wBool, wCatch, wChar, wClass, wCompl
-    wConst_cast, wDefault, wDelete, wDouble, wDynamic_cast,
-    wExplicit, wExtern, wFalse, wFloat, wFriend,
-    wGoto, wInt, wLong, wMutable, wNamespace, wNew, wOperator,
-    wPrivate, wProtected, wPublic, wRegister, wReinterpret_cast, wRestrict,
-    wShort, wSigned, wSizeof, wStatic_cast, wStruct, wSwitch,
-    wThis, wThrow, wTrue, wTypedef, wTypeid, wTypeof, wTypename,
-    wUnion, wPacked, wUnsigned, wVirtual, wVoid, wVolatile, wWchar_t,
-
-    wAlignas, wAlignof, wConstexpr, wDecltype, wNullptr, wNoexcept,
-    wThread_local, wStatic_assert, wChar16_t, wChar32_t,
-
-    wStdIn, wStdOut, wStdErr,
-
-    wInOut, wByCopy, wByRef, wOneWay,
-    wBitsize
+    wInvalid = "",
+    wAddr = "addr", wAnd = "and", wAs = "as", wAsm = "asm",
+    wBind = "bind", wBlock = "block", wBreak = "break", wCase = "case", wCast = "cast", 
+    wConcept = "concept", wConst = "const", wContinue = "continue", wConverter = "converter", 
+    wDefer = "defer", wDiscard = "discard", wDistinct = "distinct", wDiv = "div", wDo = "do",
+    wElif = "elif", wElse = "else", wEnd = "end", wEnum = "enum", wExcept = "except", 
+    wExport = "export", wFinally = "finally", wFor = "for", wFrom = "from", wFunc = "func", 
+    wIf = "if", wImport = "import", wIn = "in", wInclude = "include", wInterface = "interface", 
+    wIs = "is", wIsnot = "isnot",  wIterator = "iterator", wLet = "let", wMacro = "macro",
+    wMethod = "method", wMixin = "mixin", wMod = "mod", wNil = "nil", wNot = "not", wNotin = "notin", 
+    wObject = "object", wOf = "of", wOr = "or", wOut = "out", wProc = "proc", wPtr = "ptr", 
+    wRaise = "raise", wRef = "ref", wReturn = "return", wShl = "shl", wShr = "shr", wStatic = "static", 
+    wTemplate = "template", wTry = "try", wTuple = "tuple", wType = "type", wUsing = "using", 
+    wVar = "var", wWhen = "when", wWhile = "while", wXor = "xor", wYield = "yield",
+
+    wColon = ":", wColonColon = "::", wEquals = "=", wDot = ".", wDotDot = "..",
+    wStar = "*", wMinus = "-",
+    wMagic = "magic", wThread = "thread", wFinal = "final", wProfiler = "profiler", 
+    wMemTracker = "memtracker", wObjChecks = "objchecks",
+    wIntDefine = "intdefine", wStrDefine = "strdefine", wBoolDefine = "booldefine", 
+    wCursor = "cursor", wNoalias = "noalias",
+
+    wImmediate = "immediate", wConstructor = "constructor", wDestructor = "destructor", 
+    wDelegator = "delegator", wOverride = "override", wImportCpp = "importcpp", 
+    wImportObjC = "importobjc", wImportCompilerProc = "importcompilerproc",
+    wImportc = "importc", wImportJs = "importjs", wExportc = "exportc", wExportCpp = "exportcpp", 
+    wExportNims = "exportnims",
+    wIncompleteStruct = "incompleteStruct", # deprecated
+    wCompleteStruct = "completeStruct", wRequiresInit = "requiresInit", wAlign = "align",
+    wNodecl = "nodecl", wPure = "pure", wSideEffect = "sideEffect", wHeader = "header",
+    wNoSideEffect = "noSideEffect", wGcSafe = "gcsafe", wNoreturn = "noreturn",
+    wNosinks = "nosinks", wMerge = "merge", wLib = "lib", wDynlib = "dynlib",
+    wCompilerProc = "compilerproc", wCore = "core", wProcVar = "procvar", 
+    wBase = "base", wUsed = "used", wFatal = "fatal", wError = "error", wWarning = "warning", 
+    wHint = "hint", wWarningAsError = "warningAsError", wLine = "line", wPush = "push",
+    wPop = "pop", wDefine = "define", wUndef = "undef", wLineDir = "lineDir", 
+    wStackTrace = "stackTrace", wLineTrace = "lineTrace", wLink = "link", wCompile = "compile",
+    wLinksys = "linksys", wDeprecated = "deprecated", wVarargs = "varargs", wCallconv = "callconv", 
+    wDebugger = "debugger", wNimcall = "nimcall", wStdcall = "stdcall", wCdecl = "cdecl", 
+    wSafecall = "safecall", wSyscall = "syscall", wInline = "inline", wNoInline = "noinline",
+    wFastcall = "fastcall", wThiscall = "thiscall", wClosure = "closure", wNoconv = "noconv",
+    wOn = "on", wOff = "off", wChecks = "checks", wRangeChecks = "rangeChecks", 
+    wBoundChecks = "boundChecks", wOverflowChecks = "overflowChecks", wNilChecks = "nilChecks",
+    wFloatChecks = "floatChecks", wNanChecks = "nanChecks", wInfChecks = "infChecks", 
+    wStyleChecks = "styleChecks", wStaticBoundchecks = "staticBoundChecks",
+    wNonReloadable = "nonReloadable", wExecuteOnReload = "executeOnReload",
+
+    wAssertions = "assertions", wPatterns = "patterns", wTrMacros = "trmacros", 
+    wSinkInference = "sinkInference", wWarnings = "warnings",
+    wHints = "hints", wOptimization = "optimization", wRaises = "raises", 
+    wWrites = "writes", wReads = "reads", wSize = "size", wEffects = "effects", wTags = "tags",
+    wRequires = "requires", wEnsures = "ensures", wInvariant = "invariant",
+    wAssume = "assume", wAssert = "assert",
+    wDeadCodeElimUnused = "deadCodeElim",  # deprecated, dead code elim always happens
+    wSafecode = "safecode", wPackage = "package", wNoForward = "noforward", wReorder = "reorder",
+    wNoRewrite = "norewrite", wNoDestroy = "nodestroy", wPragma = "pragma",
+    wCompileTime = "compileTime", wNoInit = "noinit", wPassc = "passc", wPassl = "passl",
+    wLocalPassc = "localPassC", wBorrow = "borrow", wDiscardable = "discardable", 
+    wFieldChecks = "fieldChecks", wSubsChar = "subschar", wAcyclic = "acyclic",
+    wShallow = "shallow", wUnroll = "unroll", wLinearScanEnd = "linearScanEnd",
+    wComputedGoto = "computedGoto", wInjectStmt = "injectStmt", wExperimental = "experimental",
+    wWrite = "write", wGensym = "gensym", wInject = "inject", wDirty = "dirty", 
+    wInheritable = "inheritable", wThreadVar = "threadvar", wEmit = "emit",
+    wAsmNoStackFrame = "asmNoStackFrame", wImplicitStatic = "implicitStatic",
+    wGlobal = "global", wCodegenDecl = "codegenDecl", wUnchecked = "unchecked",
+    wGuard = "guard", wLocks = "locks", wPartial = "partial", wExplain = "explain",
+    wLiftLocals = "liftlocals",
+
+    wAuto = "auto", wBool = "bool", wCatch = "catch", wChar = "char", 
+    wClass = "class", wCompl = "compl", wConst_cast = "const_cast", wDefault = "default", 
+    wDelete = "delete", wDouble = "double", wDynamic_cast = "dynamic_cast", 
+    wExplicit = "explicit", wExtern = "extern", wFalse = "false", wFloat = "float",
+    wFriend = "friend", wGoto = "goto", wInt = "int", wLong = "long", wMutable = "mutable", 
+    wNamespace = "namespace", wNew = "new", wOperator = "operator", wPrivate = "private", 
+    wProtected = "protected", wPublic = "public", wRegister = "register", 
+    wReinterpret_cast = "reinterpret_cast", wRestrict = "restrict", wShort = "short", 
+    wSigned = "signed", wSizeof = "sizeof", wStatic_cast = "static_cast", wStruct = "struct", 
+    wSwitch = "switch", wThis = "this", wThrow = "throw", wTrue = "true", wTypedef = "typedef", 
+    wTypeid = "typeid", wTypeof = "typeof",  wTypename = "typename",
+    wUnion = "union", wPacked = "packed", wUnsigned = "unsigned", wVirtual = "virtual", 
+    wVoid = "void", wVolatile = "volatile", wWchar_t = "wchar_t",
+
+    wAlignas = "alignas", wAlignof = "alignof", wConstexpr = "constexpr", wDecltype = "decltype", 
+    wNullptr = "nullptr", wNoexcept = "noexcept",
+    wThread_local = "thread_local", wStatic_assert = "static_assert", 
+    wChar16_t = "char16_t", wChar32_t = "char32_t",
+
+    wStdIn = "stdin", wStdOut = "stdout", wStdErr = "stderr",
+
+    wInOut = "inout", wByCopy = "bycopy", wByRef = "byref", wOneWay = "oneway",
+    wBitsize = "bitsize"
 
   TSpecialWords* = set[TSpecialWord]
 
@@ -104,82 +125,8 @@ const
     wAsm, wBreak, wCase, wConst, wContinue, wDo, wElse, wEnum, wExport,
     wFor, wIf, wReturn, wStatic, wTemplate, wTry, wWhile, wUsing}
 
-  specialWords*: array[TSpecialWord, string] = ["",
-    "addr", "and", "as", "asm",
-    "bind", "block", "break", "case", "cast",
-    "concept", "const", "continue", "converter",
-    "defer", "discard", "distinct", "div", "do",
-    "elif", "else", "end", "enum", "except", "export",
-    "finally", "for", "from", "func", "if",
-    "import", "in", "include", "interface", "is", "isnot", "iterator",
-    "let",
-    "macro", "method", "mixin", "mod", "nil", "not", "notin",
-    "object", "of", "or",
-    "out", "proc", "ptr", "raise", "ref", "return",
-    "shl", "shr", "static",
-    "template", "try", "tuple", "type", "using", "var",
-    "when", "while", "xor",
-    "yield",
-
-    ":", "::", "=", ".", "..",
-    "*", "-",
-    "magic", "thread", "final", "profiler", "memtracker", "objchecks",
-    "intdefine", "strdefine", "booldefine", "cursor", "noalias",
-
-    "immediate", "constructor", "destructor", "delegator", "override",
-    "importcpp", "importobjc",
-    "importCompilerProc", "importc", "importjs", "exportc", "exportcpp", "exportnims",
-    "incompleteStruct",
-    "completeStruct",
-    "requiresInit", "align", "nodecl", "pure", "sideEffect",
-    "header", "noSideEffect", "gcsafe", "noreturn", "nosinks", "merge", "lib", "dynlib",
-    "compilerproc", "core", "procvar", "base", "used",
-    "fatal", "error", "warning", "hint", "warningAsError", "line",
-    "push", "pop", "define", "undef", "lineDir", "stackTrace", "lineTrace",
-    "link", "compile", "linksys", "deprecated", "varargs",
-    "callconv", "debugger", "nimcall", "stdcall",
-    "cdecl", "safecall", "syscall", "inline", "noinline", "fastcall", "thiscall", "closure",
-    "noconv", "on", "off", "checks", "rangeChecks", "boundChecks",
-    "overflowChecks", "nilChecks",
-    "floatChecks", "nanChecks", "infChecks", "styleChecks", "staticBoundChecks",
-    "nonReloadable", "executeOnReload",
-
-    "assertions", "patterns", "trmacros", "sinkinference", "warnings", "hints",
-    "optimization", "raises", "writes", "reads", "size", "effects", "tags",
-    "requires", "ensures", "invariant", "assume", "assert",
-    "deadCodeElim",  # deprecated, dead code elim always happens
-    "safecode", "package", "noforward", "reorder", "norewrite", "nodestroy",
-    "pragma",
-    "compileTime", "noinit",
-    "passc", "passl", "localPassC", "borrow", "discardable", "fieldChecks",
-    "subschar", "acyclic", "shallow", "unroll", "linearScanEnd",
-    "computedGoto", "injectStmt", "experimental",
-    "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
-    "asmNoStackFrame", "implicitStatic", "global", "codegenDecl", "unchecked",
-    "guard", "locks", "partial", "explain", "liftLocals",
-
-    "auto", "bool", "catch", "char", "class", "compl",
-    "const_cast", "default", "delete", "double",
-    "dynamic_cast", "explicit", "extern", "false",
-    "float", "friend", "goto", "int", "long", "mutable",
-    "namespace", "new", "operator",
-    "private", "protected", "public", "register", "reinterpret_cast", "restrict",
-    "short", "signed", "sizeof", "static_cast", "struct", "switch",
-    "this", "throw", "true", "typedef", "typeid", "typeof",
-    "typename", "union", "packed", "unsigned", "virtual", "void", "volatile",
-    "wchar_t",
-
-    "alignas", "alignof", "constexpr", "decltype", "nullptr", "noexcept",
-    "thread_local", "static_assert", "char16_t", "char32_t",
-
-    "stdin", "stdout", "stderr",
-
-    "inout", "bycopy", "byref", "oneway",
-    "bitsize"
-    ]
-
-proc findStr*(a: openArray[string], s: string): int =
-  for i in low(a)..high(a):
-    if cmpIgnoreStyle(a[i], s) == 0:
+proc findStr*[T:enum](a: Slice[T], s: string, default: T): T =  
+  for i in a:
+    if cmpIgnoreStyle($i, s) == 0:
       return i
-  result = - 1
+  result = default
\ No newline at end of file