Skip to content

Commit

Permalink
Use modern enums in compiler (nim-lang#15775)
Browse files Browse the repository at this point in the history
  • Loading branch information
cooldome authored and PMunch committed Jan 6, 2021
1 parent 4dc46ba commit 42b032c
Show file tree
Hide file tree
Showing 18 changed files with 219 additions and 337 deletions.
26 changes: 11 additions & 15 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/astalgo.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down
8 changes: 4 additions & 4 deletions compiler/commands.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions compiler/condsyms.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion compiler/docgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions compiler/idents.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/lambdalifting.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
18 changes: 9 additions & 9 deletions compiler/layouter.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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:
Expand Down
103 changes: 40 additions & 63 deletions compiler/lexer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
Loading

0 comments on commit 42b032c

Please sign in to comment.