From 13e659cfec83eb3c2c3c2bbbf10d01ba59bc0d5b Mon Sep 17 00:00:00 2001 From: Clyybber Date: Fri, 28 Aug 2020 22:18:09 +0200 Subject: [PATCH] Big compiler Cleanup (#14777) --- compiler/ast.nim | 34 ++- compiler/btrees.nim | 3 +- compiler/ccgexprs.nim | 2 +- compiler/ccgmerge.nim | 6 +- compiler/ccgstmts.nim | 2 +- compiler/cgen.nim | 2 +- compiler/closureiters.nim | 3 - compiler/commands.nim | 21 +- compiler/condsyms.nim | 2 +- compiler/docgen.nim | 45 ++-- compiler/extccomp.nim | 4 +- compiler/filter_tmpl.nim | 8 +- compiler/forloops.nim | 89 -------- compiler/injectdestructors.nim | 6 +- compiler/int128.nim | 6 +- compiler/layouter.nim | 6 +- compiler/lexer.nim | 157 ++++++-------- compiler/liftdestructors.nim | 5 - compiler/linter.nim | 16 +- compiler/main.nim | 4 +- compiler/modulepaths.nim | 6 +- compiler/modules.nim | 2 +- compiler/msgs.nim | 9 +- compiler/nimconf.nim | 34 +-- compiler/nimlexbase.nim | 10 +- compiler/options.nim | 6 +- compiler/packagehandling.nim | 2 - compiler/parampatterns.nim | 4 +- compiler/parser.nim | 369 ++++++++++++++++----------------- compiler/passes.nim | 6 +- compiler/pragmas.nim | 6 +- compiler/renderer.nim | 28 +-- compiler/renderverbatim.nim | 2 +- compiler/reorder.nim | 27 +-- compiler/rodutils.nim | 6 +- compiler/semexprs.nim | 2 +- compiler/semfold.nim | 2 +- compiler/seminst.nim | 2 +- compiler/semobjconstr.nim | 3 +- compiler/semtempl.nim | 1 - compiler/semtypes.nim | 6 +- compiler/semtypinst.nim | 3 +- compiler/sighashes.nim | 2 +- compiler/sigmatch.nim | 51 ++--- compiler/sourcemap.nim | 8 +- compiler/suggest.nim | 2 +- compiler/syntaxes.nim | 128 ++++-------- compiler/types.nim | 2 +- compiler/vmgen.nim | 21 +- compiler/wordrecg.nim | 74 ++----- nimpretty/nimpretty.nim | 12 +- tools/grammar_nanny.nim | 4 +- tools/nimfind.nim | 3 +- 53 files changed, 481 insertions(+), 783 deletions(-) delete mode 100644 compiler/forloops.nim diff --git a/compiler/ast.nim b/compiler/ast.nim index 06ff92e9f6e3..23b564af3677 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -17,22 +17,21 @@ 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 + 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"] +const CallingConvToStr*: array[TCallingConvention, string] = ["nimcall", "stdcall", + "cdecl", "safecall", "syscall", "inline", "noinline", "fastcall", "thiscall", + "closure", "noconv"] type TNodeKind* = enum # order is extremely important, because ranges are used @@ -1363,7 +1362,7 @@ proc newType*(kind: TTypeKind, owner: PSym): PType = proc mergeLoc(a: var TLoc, b: TLoc) = if a.k == low(a.k): a.k = b.k if a.storage == low(a.storage): a.storage = b.storage - a.flags = a.flags + b.flags + a.flags.incl b.flags if a.lode == nil: a.lode = b.lode if a.r == nil: a.r = b.r @@ -1388,7 +1387,7 @@ proc assignType*(dest, src: PType) = # this fixes 'type TLock = TSysLock': if src.sym != nil: if dest.sym != nil: - dest.sym.flags = dest.sym.flags + (src.sym.flags-{sfExported}) + dest.sym.flags.incl src.sym.flags-{sfExported} if dest.sym.annex == nil: dest.sym.annex = src.sym.annex mergeLoc(dest.sym.loc, src.sym.loc) else: @@ -1495,8 +1494,7 @@ proc isGCedMem*(t: PType): bool {.inline.} = t.kind == tyProc and t.callConv == ccClosure proc propagateToOwner*(owner, elem: PType; propagateHasAsgn = true) = - const HaveTheirOwnEmpty = {tySequence, tySet, tyPtr, tyRef, tyProc} - owner.flags = owner.flags + (elem.flags * {tfHasMeta, tfTriggersCompileTime}) + owner.flags.incl elem.flags * {tfHasMeta, tfTriggersCompileTime} if tfNotNil in elem.flags: if owner.kind in {tyGenericInst, tyGenericBody, tyGenericInvocation}: owner.flags.incl tfNotNil diff --git a/compiler/btrees.nim b/compiler/btrees.nim index 18854d4746c0..473cbd1b0b68 100644 --- a/compiler/btrees.nim +++ b/compiler/btrees.nim @@ -135,8 +135,7 @@ proc `$`[Key, Val](b: BTree[Key, Val]): string = result = "" toString(b.root, "", result) -proc hasNext*[Key, Val](b: BTree[Key, Val]; index: int): bool = - result = index < b.entries +proc hasNext*[Key, Val](b: BTree[Key, Val]; index: int): bool = index < b.entries proc countSubTree[Key, Val](it: Node[Key, Val]): int = if it.isInternal: diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index a97d15d70d39..995b75d697b8 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1653,7 +1653,7 @@ template genDollar(p: BProc, n: PNode, d: var TLoc, frmt: string) = var a: TLoc initLocExpr(p, n[1], a) a.r = ropecg(p.module, frmt, [rdLoc(a)]) - a.flags = a.flags - {lfIndirect} # this flag should not be propagated here (not just for HCR) + a.flags.excl lfIndirect # this flag should not be propagated here (not just for HCR) if d.k == locNone: getTemp(p, n.typ, d) genAssignment(p, d, a, {}) gcUsage(p.config, n) diff --git a/compiler/ccgmerge.nim b/compiler/ccgmerge.nim index c12d6c0b2a2d..a87d5b609c85 100644 --- a/compiler/ccgmerge.nim +++ b/compiler/ccgmerge.nim @@ -282,7 +282,7 @@ proc mergeRequired*(m: BModule): bool = if m.s[i] != nil: #echo "not empty: ", i, " ", m.s[i] return true - for i in low(TCProcSection)..high(TCProcSection): + for i in TCProcSection: if m.initProc.s(i) != nil: #echo "not empty: ", i, " ", m.initProc.s[i] return true @@ -292,7 +292,7 @@ proc mergeFiles*(cfilename: AbsoluteFile, m: BModule) = var old: TMergeSections readMergeSections(cfilename, old) # do the merge; old section before new section: - for i in low(TCFileSection)..high(TCFileSection): + for i in TCFileSection: m.s[i] = old.f[i] & m.s[i] - for i in low(TCProcSection)..high(TCProcSection): + for i in TCProcSection: m.initProc.s(i) = old.p[i] & m.initProc.s(i) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 0f58df3a4696..e40e94d01456 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -1498,7 +1498,7 @@ proc genPragma(p: BProc, n: PNode) = of wEmit: genEmit(p, it) of wInjectStmt: var p = newProc(nil, p.module) - p.options = p.options - {optLineTrace, optStackTrace} + p.options.excl {optLineTrace, optStackTrace} genStmts(p, it[1]) p.module.injectStmt = p.s(cpsStmts) else: discard diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 86860fbf4631..d40aa32d73d7 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -681,7 +681,7 @@ proc loadDynamicLib(m: BModule, lib: PLib) = [loadlib, genStringLiteral(m, lib.path)]) else: var p = newProc(nil, m) - p.options = p.options - {optStackTrace} + p.options.excl optStackTrace p.flags.incl nimErrorFlagDisabled var dest: TLoc initLoc(dest, locTemp, lib.path, OnStack) diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim index 2248f956e221..912172e6266b 100644 --- a/compiler/closureiters.nim +++ b/compiler/closureiters.nim @@ -485,7 +485,6 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode = if ns: needsSplit = true var tmp: PSym - var s: PNode let isExpr = not isEmptyType(n.typ) if isExpr: tmp = ctx.newTempVar(n.typ) @@ -742,8 +741,6 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode = result.add(n) of nkWhileStmt: - var ns = false - var condNeedsSplit = false n[0] = ctx.lowerStmtListExprs(n[0], condNeedsSplit) var bodyNeedsSplit = false diff --git a/compiler/commands.nim b/compiler/commands.nim index b67cd461f132..0af31b2c7f41 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -53,11 +53,10 @@ const "Copyright (c) 2006-" & copyrightYear & " by Andreas Rumpf\n" proc genFeatureDesc[T: enum](t: typedesc[T]): string {.compileTime.} = - var x = "" - for f in low(T)..high(T): - if x.len > 0: x.add "|" - x.add $f - x + result = "" + for f in T: + if result.len > 0: result.add "|" + result.add $f const Usage = slurp"../doc/basicopt.txt".replace(" //", " ") @@ -146,24 +145,24 @@ proc splitSwitch(conf: ConfigRef; switch: string, cmd, arg: var string, pass: TC proc processOnOffSwitch(conf: ConfigRef; op: TOptions, arg: string, pass: TCmdLinePass, info: TLineInfo) = case arg.normalize - of "","on": conf.options = conf.options + op - of "off": conf.options = conf.options - op + of "","on": conf.options.incl op + of "off": conf.options.excl op else: localError(conf, info, errOnOrOffExpectedButXFound % arg) proc processOnOffSwitchOrList(conf: ConfigRef; op: TOptions, arg: string, pass: TCmdLinePass, info: TLineInfo): bool = result = false case arg.normalize - of "on": conf.options = conf.options + op - of "off": conf.options = conf.options - op + of "on": conf.options.incl op + of "off": conf.options.excl op of "list": result = true else: localError(conf, info, errOnOffOrListExpectedButXFound % arg) proc processOnOffSwitchG(conf: ConfigRef; op: TGlobalOptions, arg: string, pass: TCmdLinePass, info: TLineInfo) = case arg.normalize - of "", "on": conf.globalOptions = conf.globalOptions + op - of "off": conf.globalOptions = conf.globalOptions - op + of "", "on": conf.globalOptions.incl op + of "off": conf.globalOptions.excl op else: localError(conf, info, errOnOrOffExpectedButXFound % arg) proc expectArg(conf: ConfigRef; switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index ad13f3e1e897..d99b8b7e654b 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -86,7 +86,7 @@ proc initDefines*(symbols: StringTableRef) = defineSymbol("nimMacrosSizealignof") defineSymbol("nimNoZeroExtendMagic") defineSymbol("nimMacrosGetNodeId") - for f in low(Feature)..high(Feature): + for f in Feature: defineSymbol("nimHas" & $f) for s in WarningsToStr: diff --git a/compiler/docgen.nim b/compiler/docgen.nim index cb8c77e874d7..1e0756d64ec6 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -302,15 +302,13 @@ proc ropeFormatNamedVars(conf: ConfigRef; frmt: FormatStr, proc genComment(d: PDoc, n: PNode): string = result = "" - var dummyHasToc: bool if n.comment.len > 0: - var comment2 = n.comment + let comment = n.comment when false: # RFC: to preseve newlines in comments, this would work: - comment2 = comment2.replace("\n", "\n\n") - renderRstToOut(d[], parseRst(comment2, toFullPath(d.conf, n.info), - toLinenumber(n.info), toColumn(n.info), - dummyHasToc, d.options, d.conf), result) + comment = comment.replace("\n", "\n\n") + renderRstToOut(d[], parseRst(comment, toFullPath(d.conf, n.info), toLinenumber(n.info), + toColumn(n.info), (var dummy: bool; dummy), d.options, d.conf), result) proc genRecCommentAux(d: PDoc, n: PNode): Rope = if n == nil: return nil @@ -342,11 +340,10 @@ proc getPlainDocstring(n: PNode): string = ## You need to call this before genRecComment, whose side effects are removal ## of comments from the tree. The proc will recursively scan and return all ## the concatenated ``##`` comments of the node. - result = "" - if n == nil: return - if startsWith(n.comment, "##"): + if n == nil: result = "" + elif startsWith(n.comment, "##"): result = n.comment - if result.len < 1: + else: for i in 0.. 0: return @@ -458,7 +455,6 @@ proc writeExample(d: PDoc; ex: PNode, rdoccmd: string) = d.exampleGroups[rdoccmd].code.add "import r\"$1\"\n" % outp.string proc runAllExamples(d: PDoc) = - let backend = d.conf.backend # This used to be: `let backend = if isDefined(d.conf, "js"): "js"` (etc), however # using `-d:js` (etc) cannot work properly, eg would fail with `importjs` # since semantics are affected by `config.backend`, not by isDefined(d.conf, "js") @@ -522,20 +518,6 @@ proc prepareExample(d: PDoc; n: PNode): tuple[rdoccmd: string, code: string] = for imp in imports: runnableExamples.add imp runnableExamples.add newTree(nkBlockStmt, newNode(nkEmpty), copyTree savedLastSon) -proc renderNimCodeOld(d: PDoc, n: PNode, dest: var Rope) = - ## this is a rather hacky way to get rid of the initial indentation - ## that the renderer currently produces: - # deadcode - var i = 0 - var body = n.lastSon - if body.len == 1 and body.kind == nkStmtList and - body.lastSon.kind == nkStmtList: - body = body.lastSon - for b in body: - if i > 0: dest.add "\n" - inc i - nodeToHighlightedHtml(d, b, dest, {renderRunnableExamples}, nil) - type RunnableState = enum rsStart rsComment @@ -575,12 +557,9 @@ proc getAllRunnableExamplesImpl(d: PDoc; n: PNode, dest: var Rope, state: Runnab inc d.listingCounter let id = $d.listingCounter dest.add(d.config.getOrDefault"doc.listing_start" % [id, "langNim"]) - when true: - var dest2 = "" - renderNimCode(dest2, code, isLatex = d.conf.cmd == cmdRst2tex) - dest.add dest2 - else: - renderNimCodeOld(d, n, dest) + var dest2 = "" + renderNimCode(dest2, code, isLatex = d.conf.cmd == cmdRst2tex) + dest.add dest2 dest.add(d.config.getOrDefault"doc.listing_end" % id) return rsRunnable else: discard @@ -1213,12 +1192,12 @@ proc genOutFile(d: PDoc): Rope = var tmp = "" renderTocEntries(d[], j, 1, tmp) var toc = tmp.rope - for i in low(TSymKind)..high(TSymKind): + for i in TSymKind: genSection(d, i) toc.add(d.toc[i]) if toc != nil: toc = ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.toc"), ["content"], [toc]) - for i in low(TSymKind)..high(TSymKind): code.add(d.section[i]) + for i in TSymKind: code.add(d.section[i]) # Extract the title. Non API modules generate an entry in the index table. if d.meta[metaTitle].len != 0: diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 1c6b1a8d0401..79b4ba637894 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -331,7 +331,7 @@ proc setCC*(conf: ConfigRef; ccname: string; info: TLineInfo) = conf.compileOptions = getConfigVar(conf, conf.cCompiler, ".options.always") conf.linkOptions = "" conf.cCompilerPath = getConfigVar(conf, conf.cCompiler, ".path") - for i in low(CC)..high(CC): undefSymbol(conf.symbols, CC[i].name) + for c in CC: undefSymbol(conf.symbols, c.name) defineSymbol(conf.symbols, CC[conf.cCompiler].name) proc addOpt(dest: var string, src: string) = @@ -353,7 +353,7 @@ proc addCompileOptionCmd*(conf: ConfigRef; option: string) = proc initVars*(conf: ConfigRef) = # we need to define the symbol here, because ``CC`` may have never been set! - for i in low(CC)..high(CC): undefSymbol(conf.symbols, CC[i].name) + for c in CC: undefSymbol(conf.symbols, c.name) defineSymbol(conf.symbols, CC[conf.cCompiler].name) addCompileOption(conf, getConfigVar(conf, conf.cCompiler, ".options.always")) #addLinkOption(getConfigVar(cCompiler, ".options.linker")) diff --git a/compiler/filter_tmpl.nim b/compiler/filter_tmpl.nim index 1d95369a8a27..6165ff2f3208 100644 --- a/compiler/filter_tmpl.nim +++ b/compiler/filter_tmpl.nim @@ -199,8 +199,8 @@ proc parseLine(p: var TTmplParser) = inc(j) llStreamWrite(p.outp, "\\n\"") -proc filterTmpl*(stdin: PLLStream, filename: AbsoluteFile, - call: PNode; conf: ConfigRef): PLLStream = +proc filterTmpl*(conf: ConfigRef, stdin: PLLStream, filename: AbsoluteFile, + call: PNode): PLLStream = var p: TTmplParser p.config = conf p.info = newLineInfo(conf, filename, 0, 0) @@ -214,9 +214,9 @@ proc filterTmpl*(stdin: PLLStream, filename: AbsoluteFile, p.x = newStringOfCap(120) # do not process the first line which contains the directive: if llStreamReadLine(p.inp, p.x): - p.info.line = p.info.line + 1'u16 + inc p.info.line while llStreamReadLine(p.inp, p.x): - p.info.line = p.info.line + 1'u16 + inc p.info.line parseLine(p) newLine(p) result = p.outp diff --git a/compiler/forloops.nim b/compiler/forloops.nim deleted file mode 100644 index ee91000d4b85..000000000000 --- a/compiler/forloops.nim +++ /dev/null @@ -1,89 +0,0 @@ -# -# -# The Nim Compiler -# (c) Copyright 2015 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module implements for loop detection for better C code generation. - -import ast, astalgo - -const - someCmp = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc, - mLeI, mLeF64, mLeU, mLeEnum, - mLeCh, mLeB, mLePtr, mLtI, mLtF64, mLtU, mLtEnum, - mLtCh, mLtB, mLtPtr} - -proc isCounter(s: PSym): bool {.inline.} = - s.kind in {skResult, skVar, skLet, skTemp} and - {sfGlobal, sfAddrTaken} * s.flags == {} - -proc isCall(n: PNode): bool {.inline.} = - n.kind in nkCallKinds and n[0].kind == nkSym - -proc fromSystem(op: PSym): bool = sfSystemModule in getModule(op).flags - -proc getCounter(lastStmt: PNode): PSym = - if lastStmt.isCall: - let op = lastStmt.sym - if op.magic in {mDec, mInc} or - ((op.name.s == "+=" or op.name.s == "-=") and op.fromSystem): - if op[1].kind == nkSym and isCounter(op[1].sym): - result = op[1].sym - -proc counterInTree(n, loop: PNode; counter: PSym): bool = - # prune the search tree: within the loop the counter may be used: - if n == loop: return - case n.kind - of nkSym: - if n.sym == counter: return true - of nkVarSection, nkLetSection: - # definitions are fine! - for it in n: - if counterInTree(it.lastSon): return true - else: - for i in 0..= denominator: - dividend = dividend - denominator + dividend -= denominator quotient = bitor(quotient, One) denominator = denominator shr 1 diff --git a/compiler/layouter.nim b/compiler/layouter.nim index f5d3084dc706..ee45d357f4bf 100644 --- a/compiler/layouter.nim +++ b/compiler/layouter.nim @@ -35,7 +35,7 @@ type Emitter* = object config: ConfigRef fid: FileIndex - lastTok: TTokType + lastTok: TokType inquote, lastTokWasTerse: bool semicolons: SemicolonKind col, lastLineNumber, lineSpan, indentLevel, indWidth*, inSection: int @@ -402,7 +402,7 @@ proc endsInAlpha(em: Emitter): bool = while i >= 0 and em.kinds[i] in {ltBeginSection, ltEndSection}: dec(i) result = if i >= 0: em.tokens[i].lastChar in SymChars+{'_'} else: false -proc emitComment(em: var Emitter; tok: TToken; dontIndent: bool) = +proc emitComment(em: var Emitter; tok: Token; dontIndent: bool) = var col = em.col let lit = strip fileSection(em.config, em.fid, tok.commentOffsetA, tok.commentOffsetB) em.lineSpan = countNewlines(lit) @@ -417,7 +417,7 @@ proc emitComment(em: var Emitter; tok: TToken; dontIndent: bool) = inc col emitMultilineComment(em, lit, col, dontIndent) -proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) = +proc emitTok*(em: var Emitter; L: Lexer; tok: Token) = template wasExportMarker(em): bool = em.kinds.len > 0 and em.kinds[^1] == ltExportMarker diff --git a/compiler/lexer.nim b/compiler/lexer.nim index f9679adeef8b..ff433928c9fa 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -30,7 +30,7 @@ const # don't forget to update the 'highlite' module if these charsets should change type - TTokType* = enum + TokType* = enum tkInvalid, tkEof, # order is important here! tkSymbol, # keywords: tkAddr, tkAnd, tkAs, tkAsm, @@ -64,7 +64,7 @@ type tkOpr, tkComment, tkAccent, tkSpaces, tkInfixOpr, tkPrefixOpr, tkPostfixOpr - TTokTypes* = set[TTokType] + TokTypes* = set[TokType] const weakTokens = {tkComma, tkSemiColon, tkColon, @@ -73,7 +73,7 @@ const # tokens that should not be considered for previousToken tokKeywordLow* = succ(tkSymbol) tokKeywordHigh* = pred(tkIntLit) - TokTypeToStr*: array[TTokType, string] = ["tkInvalid", "[EOF]", + TokTypeToStr*: array[TokType, string] = ["tkInvalid", "[EOF]", "tkSymbol", "addr", "and", "as", "asm", "bind", "block", "break", "case", "cast", @@ -104,22 +104,19 @@ const "tkPrefixOpr", "tkPostfixOpr"] type - TNumericalBase* = enum + NumericalBase* = enum base10, # base10 is listed as the first element, # so that it is the correct default value base2, base8, base16 - CursorPosition* {.pure.} = enum ## XXX remove this again - None, InToken, BeforeToken, AfterToken - - TToken* = object # a Nim token - tokType*: TTokType # the type of the token + Token* = object # a Nim token + tokType*: TokType # the type of the token indent*: int # the indentation; != -1 if the token has been # preceded with indentation ident*: PIdent # the parsed identifier iNumber*: BiggestInt # the parsed integer literal fNumber*: BiggestFloat # the parsed floating point literal - base*: TNumericalBase # the numerical base; only valid for int + base*: NumericalBase # the numerical base; only valid for int # or float literals strongSpaceA*: int8 # leading spaces of an operator strongSpaceB*: int8 # trailing spaces of an operator @@ -127,26 +124,25 @@ type # documentation comments are here too line*, col*: int when defined(nimpretty): - offsetA*, offsetB*: int # used for pretty printing so that literals - # like 0b01 or r"\L" are unaffected + offsetA*, offsetB*: int # used for pretty printing so that literals + # like 0b01 or r"\L" are unaffected commentOffsetA*, commentOffsetB*: int - TErrorHandler* = proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) - TLexer* = object of TBaseLexer + ErrorHandler* = proc (conf: ConfigRef; info: TLineInfo; msg: TMsgKind; arg: string) + Lexer* = object of TBaseLexer fileIdx*: FileIndex indentAhead*: int # if > 0 an indentation has already been read # this is needed because scanning comments # needs so much look-ahead currLineIndent*: int strongSpaces*, allowTabs*: bool - cursor*: CursorPosition - errorHandler*: TErrorHandler + errorHandler*: ErrorHandler cache*: IdentCache when defined(nimsuggest): previousToken: TLineInfo config*: ConfigRef -proc getLineInfo*(L: TLexer, tok: TToken): TLineInfo {.inline.} = +proc getLineInfo*(L: Lexer, tok: Token): TLineInfo {.inline.} = result = newLineInfo(L.fileIdx, tok.line, tok.col) when defined(nimpretty): result.offsetA = tok.offsetA @@ -154,8 +150,8 @@ proc getLineInfo*(L: TLexer, tok: TToken): TLineInfo {.inline.} = result.commentOffsetA = tok.commentOffsetA result.commentOffsetB = tok.commentOffsetB -proc isKeyword*(kind: TTokType): bool = - result = (kind >= tokKeywordLow) and (kind <= tokKeywordHigh) +proc isKeyword*(kind: TokType): bool = + (kind >= tokKeywordLow) and (kind <= tokKeywordHigh) template ones(n): untyped = ((1 shl n)-1) # for utf-8 conversion @@ -169,28 +165,27 @@ proc isNimIdentifier*(s: string): bool = inc(i) result = true -proc `$`*(tok: TToken): string = +proc `$`*(tok: Token): string = case tok.tokType - of tkIntLit..tkInt64Lit: result = $tok.iNumber - of tkFloatLit..tkFloat64Lit: result = $tok.fNumber - of tkInvalid, tkStrLit..tkCharLit, tkComment: result = tok.literal - of tkParLe..tkColon, tkEof, tkAccent: - result = TokTypeToStr[tok.tokType] + 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] else: if tok.ident != nil: - result = tok.ident.s + tok.ident.s else: - result = "" + "" -proc prettyTok*(tok: TToken): string = - if isKeyword(tok.tokType): result = "keyword " & tok.ident.s - else: result = $tok +proc prettyTok*(tok: Token): string = + if isKeyword(tok.tokType): "keyword " & tok.ident.s + else: $tok -proc printTok*(conf: ConfigRef; tok: TToken) = +proc printTok*(conf: ConfigRef; tok: Token) = msgWriteln(conf, $tok.line & ":" & $tok.col & "\t" & TokTypeToStr[tok.tokType] & " " & $tok) -proc initToken*(L: var TToken) = +proc initToken*(L: var Token) = L.tokType = tkInvalid L.iNumber = 0 L.indent = 0 @@ -203,7 +198,7 @@ proc initToken*(L: var TToken) = L.commentOffsetA = 0 L.commentOffsetB = 0 -proc fillToken(L: var TToken) = +proc fillToken(L: var Token) = L.tokType = tkInvalid L.iNumber = 0 L.indent = 0 @@ -216,7 +211,7 @@ proc fillToken(L: var TToken) = L.commentOffsetA = 0 L.commentOffsetB = 0 -proc openLexer*(lex: var TLexer, fileIdx: FileIndex, inputstream: PLLStream; +proc openLexer*(lex: var Lexer, fileIdx: FileIndex, inputstream: PLLStream; cache: IdentCache; config: ConfigRef) = openBaseLexer(lex, inputstream) lex.fileIdx = fileIdx @@ -228,36 +223,36 @@ proc openLexer*(lex: var TLexer, fileIdx: FileIndex, inputstream: PLLStream; lex.previousToken.fileIndex = fileIdx lex.config = config -proc openLexer*(lex: var TLexer, filename: AbsoluteFile, inputstream: PLLStream; +proc openLexer*(lex: var Lexer, filename: AbsoluteFile, inputstream: PLLStream; cache: IdentCache; config: ConfigRef) = openLexer(lex, fileInfoIdx(config, filename), inputstream, cache, config) -proc closeLexer*(lex: var TLexer) = +proc closeLexer*(lex: var Lexer) = if lex.config != nil: inc(lex.config.linesCompiled, lex.lineNumber) closeBaseLexer(lex) -proc getLineInfo(L: TLexer): TLineInfo = +proc getLineInfo(L: Lexer): TLineInfo = result = newLineInfo(L.fileIdx, L.lineNumber, getColNumber(L, L.bufpos)) -proc dispMessage(L: TLexer; info: TLineInfo; msg: TMsgKind; arg: string) = +proc dispMessage(L: Lexer; info: TLineInfo; msg: TMsgKind; arg: string) = if L.errorHandler.isNil: msgs.message(L.config, info, msg, arg) else: L.errorHandler(L.config, info, msg, arg) -proc lexMessage*(L: TLexer, msg: TMsgKind, arg = "") = +proc lexMessage*(L: Lexer, msg: TMsgKind, arg = "") = L.dispMessage(getLineInfo(L), msg, arg) -proc lexMessageTok*(L: TLexer, msg: TMsgKind, tok: TToken, arg = "") = +proc lexMessageTok*(L: Lexer, msg: TMsgKind, tok: Token, arg = "") = var info = newLineInfo(L.fileIdx, tok.line, tok.col) L.dispMessage(info, msg, arg) -proc lexMessagePos(L: var TLexer, msg: TMsgKind, pos: int, arg = "") = +proc lexMessagePos(L: var Lexer, msg: TMsgKind, pos: int, arg = "") = var info = newLineInfo(L.fileIdx, L.lineNumber, pos - L.lineStart) L.dispMessage(info, msg, arg) -proc matchTwoChars(L: TLexer, first: char, second: set[char]): bool = +proc matchTwoChars(L: Lexer, first: char, second: set[char]): bool = result = (L.buf[L.bufpos] == first) and (L.buf[L.bufpos + 1] in second) template tokenBegin(tok, pos) {.dirty.} = @@ -271,7 +266,6 @@ template tokenEnd(tok, pos) {.dirty.} = let colB = getColNumber(L, pos)+1 if L.fileIdx == L.config.m.trackPos.fileIndex and L.config.m.trackPos.col in colA..colB and L.lineNumber == L.config.m.trackPos.line.int and L.config.ideCmd in {ideSug, ideCon}: - L.cursor = CursorPosition.InToken L.config.m.trackPos.col = colA.int16 colA = 0 when defined(nimpretty): @@ -296,23 +290,22 @@ template tokenEndPrevious(tok, pos) = let colB = getColNumber(L, pos) if L.fileIdx == L.config.m.trackPos.fileIndex and L.config.m.trackPos.col in colA..colB and L.lineNumber == L.config.m.trackPos.line.int and L.config.ideCmd in {ideSug, ideCon}: - L.cursor = CursorPosition.BeforeToken L.config.m.trackPos = L.previousToken L.config.m.trackPosAttached = true colA = 0 when defined(nimpretty): tok.offsetB = L.offsetBase + pos -template eatChar(L: var TLexer, t: var TToken, replacementChar: char) = +template eatChar(L: var Lexer, t: var Token, replacementChar: char) = t.literal.add(replacementChar) inc(L.bufpos) -template eatChar(L: var TLexer, t: var TToken) = +template eatChar(L: var Lexer, t: var Token) = t.literal.add(L.buf[L.bufpos]) inc(L.bufpos) -proc getNumber(L: var TLexer, result: var TToken) = - proc matchUnderscoreChars(L: var TLexer, tok: var TToken, chars: set[char]): Natural = +proc getNumber(L: var Lexer, result: var Token) = + proc matchUnderscoreChars(L: var Lexer, tok: var Token, chars: set[char]): Natural = var pos = L.bufpos # use registers for pos, buf result = 0 while true: @@ -332,19 +325,19 @@ proc getNumber(L: var TLexer, result: var TToken) = inc(pos) L.bufpos = pos - proc matchChars(L: var TLexer, tok: var TToken, chars: set[char]) = + proc matchChars(L: var Lexer, tok: var Token, chars: set[char]) = var pos = L.bufpos # use registers for pos, buf while L.buf[pos] in chars: tok.literal.add(L.buf[pos]) inc(pos) L.bufpos = pos - proc lexMessageLitNum(L: var TLexer, msg: string, startpos: int, msgKind = errGenerated) = + proc lexMessageLitNum(L: var Lexer, msg: string, startpos: int, msgKind = errGenerated) = # Used to get slightly human friendlier err messages. const literalishChars = {'A'..'F', 'a'..'f', '0'..'9', 'X', 'x', 'o', 'O', 'c', 'C', 'b', 'B', '_', '.', '\'', 'd', 'i', 'u'} var msgPos = L.bufpos - var t: TToken + var t: Token t.literal = "" L.bufpos = startpos # Use L.bufpos as pos because of matchChars matchChars(L, t, literalishChars) @@ -612,7 +605,7 @@ proc getNumber(L: var TLexer, result: var TToken) = tokenEnd(result, postPos-1) L.bufpos = postPos -proc handleHexChar(L: var TLexer, xi: var int; position: range[0..4]) = +proc handleHexChar(L: var Lexer, xi: var int; position: range[0..4]) = template invalid() = lexMessage(L, errGenerated, "expected a hex digit, but found: " & L.buf[L.bufpos] & @@ -637,7 +630,7 @@ proc handleHexChar(L: var TLexer, xi: var int; position: range[0..4]) = # Need to progress for `nim check` inc(L.bufpos) -proc handleDecChars(L: var TLexer, xi: var int) = +proc handleDecChars(L: var Lexer, xi: var int) = while L.buf[L.bufpos] in {'0'..'9'}: xi = (xi * 10) + (ord(L.buf[L.bufpos]) - ord('0')) inc(L.bufpos) @@ -680,7 +673,7 @@ proc addUnicodeCodePoint(s: var string, i: int) = s[pos+4] = chr(i shr 6 and ones(6) or 0b10_0000_00) s[pos+5] = chr(i and ones(6) or 0b10_0000_00) -proc getEscapedChar(L: var TLexer, tok: var TToken) = +proc getEscapedChar(L: var Lexer, tok: var Token) = inc(L.bufpos) # skip '\' case L.buf[L.bufpos] of 'n', 'N': @@ -760,13 +753,7 @@ proc getEscapedChar(L: var TLexer, tok: var TToken) = else: lexMessage(L, errGenerated, "invalid character constant") else: lexMessage(L, errGenerated, "invalid character constant") -proc newString(s: cstring, len: int): string = - ## XXX, how come there is no support for this? - result = newString(len) - for i in 0.. ord(tokKeywordHigh) - ord(tkSymbol)): tok.tokType = tkSymbol else: - tok.tokType = TTokType(tok.ident.id + ord(tkSymbol)) + tok.tokType = TokType(tok.ident.id + ord(tkSymbol)) if suspicious and {optStyleHint, optStyleError} * L.config.globalOptions != {}: lintReport(L.config, getLineInfo(L), tok.ident.s.normalize, tok.ident.s) L.bufpos = pos -proc endOperator(L: var TLexer, tok: var TToken, pos: int, +proc endOperator(L: var Lexer, tok: var Token, pos: int, hash: Hash) {.inline.} = var h = !$hash tok.ident = L.cache.getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h) if (tok.ident.id < oprLow) or (tok.ident.id > oprHigh): tok.tokType = tkOpr - else: tok.tokType = TTokType(tok.ident.id - oprLow + ord(tkColon)) + else: tok.tokType = TokType(tok.ident.id - oprLow + ord(tkColon)) L.bufpos = pos -proc getOperator(L: var TLexer, tok: var TToken) = +proc getOperator(L: var Lexer, tok: var Token) = var pos = L.bufpos tokenBegin(tok, pos) var h: Hash = 0 @@ -935,18 +922,15 @@ proc getOperator(L: var TLexer, tok: var TToken) = if L.buf[pos] in {CR, LF, nimlexbase.EndOfFile}: tok.strongSpaceB = -1 -proc getPrecedence*(tok: TToken, strongSpaces: bool): int = +proc getPrecedence*(tok: Token): int = ## Calculates the precedence of the given token. - template considerStrongSpaces(x): untyped = - x + (if strongSpaces: 100 - tok.strongSpaceA.int*10 else: 0) - case tok.tokType of tkOpr: let relevantChar = tok.ident.s[0] # arrow like? if tok.ident.s.len > 1 and tok.ident.s[^1] == '>' and - tok.ident.s[^2] in {'-', '~', '='}: return considerStrongSpaces(1) + tok.ident.s[^2] in {'-', '~', '='}: return 1 template considerAsgn(value: untyped) = result = if tok.ident.s[^1] == '=': 1 else: value @@ -962,15 +946,13 @@ proc getPrecedence*(tok: TToken, strongSpaces: bool): int = of '?': result = 2 else: considerAsgn(2) of tkDiv, tkMod, tkShl, tkShr: result = 9 - of tkIn, tkNotin, tkIs, tkIsnot, tkOf, tkAs, tkFrom: result = 5 of tkDotDot: result = 6 + of tkIn, tkNotin, tkIs, tkIsnot, tkOf, tkAs, tkFrom: result = 5 of tkAnd: result = 4 of tkOr, tkXor, tkPtr, tkRef: result = 3 else: return -10 - result = considerStrongSpaces(result) - -proc newlineFollows*(L: TLexer): bool = +proc newlineFollows*(L: Lexer): bool = var pos = L.bufpos while true: case L.buf[pos] @@ -986,7 +968,7 @@ proc newlineFollows*(L: TLexer): bool = else: break -proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int; +proc skipMultiLineComment(L: var Lexer; tok: var Token; start: int; isDoc: bool) = var pos = start var toStrip = 0 @@ -1051,7 +1033,7 @@ proc skipMultiLineComment(L: var TLexer; tok: var TToken; start: int; when defined(nimpretty): tok.commentOffsetB = L.offsetBase + pos - 1 -proc scanComment(L: var TLexer, tok: var TToken) = +proc scanComment(L: var Lexer, tok: var Token) = var pos = L.bufpos tok.tokType = tkComment # iNumber contains the number of '\n' in the token @@ -1101,7 +1083,7 @@ proc scanComment(L: var TLexer, tok: var TToken) = when defined(nimpretty): tok.commentOffsetB = L.offsetBase + pos - 1 -proc skip(L: var TLexer, tok: var TToken) = +proc skip(L: var Lexer, tok: var Token) = var pos = L.bufpos tokenBegin(tok, pos) tok.strongSpaceA = 0 @@ -1173,7 +1155,7 @@ proc skip(L: var TLexer, tok: var TToken) = tok.tokType = tkComment tok.indent = commentIndent -proc rawGetTok*(L: var TLexer, tok: var TToken) = +proc rawGetTok*(L: var Lexer, tok: var Token) = template atTokenEnd() {.dirty.} = when defined(nimsuggest): # we attach the cursor to the last *strong* token @@ -1181,8 +1163,6 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) = L.previousToken.line = tok.line.uint16 L.previousToken.col = tok.col.int16 - when defined(nimsuggest): - L.cursor = CursorPosition.None fillToken(tok) if L.indentAhead >= 0: tok.indent = L.indentAhead @@ -1253,7 +1233,6 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) = if L.fileIdx == L.config.m.trackPos.fileIndex and tok.col+1 == L.config.m.trackPos.col and tok.line == L.config.m.trackPos.line.int and L.config.ideCmd == ideSug: tok.tokType = tkDot - L.cursor = CursorPosition.InToken L.config.m.trackPos.col = tok.col.int16 inc(L.bufpos) atTokenEnd() @@ -1326,8 +1305,8 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) = proc getIndentWidth*(fileIdx: FileIndex, inputstream: PLLStream; cache: IdentCache; config: ConfigRef): int = - var lex: TLexer - var tok: TToken + var lex: Lexer + var tok: Token initToken(tok) openLexer(lex, fileIdx, inputstream, cache, config) var prevToken = tkEof @@ -1341,11 +1320,11 @@ proc getIndentWidth*(fileIdx: FileIndex, inputstream: PLLStream; proc getPrecedence*(ident: PIdent): int = ## assumes ident is binary operator already - var tok: TToken + var tok: Token initToken(tok) tok.ident = ident tok.tokType = if tok.ident.id in ord(tokKeywordLow) - ord(tkSymbol)..ord(tokKeywordHigh) - ord(tkSymbol): - TTokType(tok.ident.id + ord(tkSymbol)) + TokType(tok.ident.id + ord(tkSymbol)) else: tkOpr - getPrecedence(tok, false) + getPrecedence(tok) diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 1e6b552e2b09..c1fd7981efbb 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -919,11 +919,6 @@ template inst(field, t) = proc isTrival(s: PSym): bool {.inline.} = s == nil or (s.ast != nil and s.ast[bodyPos].len == 0) - -proc isEmptyContainer(g: ModuleGraph, t: PType): bool = - (t.kind == tyArray and lengthOrd(g.config, t[0]) == 0) or - (t.kind == tySequence and t[0].kind == tyError) - proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo) = ## In the semantic pass this is called in strategic places ## to ensure we lift assignment, destructors and moves properly. diff --git a/compiler/linter.nim b/compiler/linter.nim index 07563ddbbb11..a229958e6014 100644 --- a/compiler/linter.nim +++ b/compiler/linter.nim @@ -71,12 +71,9 @@ proc beautifyName(s: string, k: TSymKind): string = proc differ*(line: string, a, b: int, x: string): string = proc substrEq(s: string, pos, last: int, substr: string): bool = - var i = 0 - while i < substr.len and pos+i <= last and s[pos+i] == substr[i]: - inc i - return i == substr.len - - let last = min(b, line.len) + result = true + for i in 0.. last or s[pos+i] != substr[i]: return false result = "" if not substrEq(line, a, b, x): @@ -84,11 +81,6 @@ proc differ*(line: string, a, b: int, x: string): string = if cmpIgnoreStyle(y, x) == 0: result = y -proc checkStyle(conf: ConfigRef; cache: IdentCache; info: TLineInfo, s: string, k: TSymKind; sym: PSym) = - let beau = beautifyName(s, k) - if s != beau: - lintReport(conf, info, beau, s) - proc nep1CheckDefImpl(conf: ConfigRef; info: TLineInfo; s: PSym; k: TSymKind) = # operators stay as they are: if k in {skResult, skTemp} or s.name.s[0] notin Letters: return @@ -136,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 = canonPragmaSpelling(w) + let wanted = specialWords[w] if pragmaName != wanted: lintReport(conf, info, wanted, pragmaName) diff --git a/compiler/main.nim b/compiler/main.nim index 256ec14cd324..774dd7625ead 100644 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -163,8 +163,8 @@ proc commandScan(cache: IdentCache, config: ConfigRef) = var stream = llStreamOpen(f, fmRead) if stream != nil: var - L: TLexer - tok: TToken + L: Lexer + tok: Token initToken(tok) openLexer(L, f, stream, cache, config) while true: diff --git a/compiler/modulepaths.nim b/compiler/modulepaths.nim index 0c8a4628ea63..8511b15921b5 100644 --- a/compiler/modulepaths.nim +++ b/compiler/modulepaths.nim @@ -91,8 +91,7 @@ when false: if result.len > 0: return result proc scriptableImport(pkg, sub: string; info: TLineInfo): string = - result = resolveDollar(gProjectFull, info.toFullPath(), pkg, sub, info) - if result.isNil: result = "" + resolveDollar(gProjectFull, info.toFullPath(), pkg, sub, info) proc lookupPackage(pkg, subdir: PNode): string = let sub = if subdir != nil: renderTree(subdir, {renderNoComments}).replace(" ") else: "" @@ -112,8 +111,7 @@ proc getModuleName*(conf: ConfigRef; n: PNode): string = case n.kind of nkStrLit, nkRStrLit, nkTripleStrLit: try: - result = - pathSubs(conf, n.strVal, toFullPath(conf, n.info).splitFile().dir) + result = pathSubs(conf, n.strVal, toFullPath(conf, n.info).splitFile().dir) except ValueError: localError(conf, n.info, "invalid path: " & n.strVal) result = n.strVal diff --git a/compiler/modules.nim b/compiler/modules.nim index 383858026edb..8c5b86ea4449 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -86,7 +86,7 @@ proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymFlags): P result = r if result == nil: result = newModule(graph, fileIdx) - result.flags = result.flags + flags + result.flags.incl flags result.id = id registerModule(graph, result) else: diff --git a/compiler/msgs.nim b/compiler/msgs.nim index a5953237ec72..7e2b8e8a6986 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -377,15 +377,12 @@ template styledMsgWriteln*(args: varargs[typed]) = when defined(windows): flushFile(stderr) -proc msgKindToString*(kind: TMsgKind): string = +proc msgKindToString*(kind: TMsgKind): string = MsgKindToStr[kind] # later versions may provide translated error messages - result = MsgKindToStr[kind] -proc getMessageStr(msg: TMsgKind, arg: string): string = - result = msgKindToString(msg) % [arg] +proc getMessageStr(msg: TMsgKind, arg: string): string = msgKindToString(msg) % [arg] -type - TErrorHandling* = enum doNothing, doAbort, doRaise +type TErrorHandling* = enum doNothing, doAbort, doRaise proc log*(s: string) = var f: File diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim index bd00832be715..c3591a9452bf 100644 --- a/compiler/nimconf.nim +++ b/compiler/nimconf.nim @@ -16,13 +16,13 @@ import # ---------------- configuration file parser ----------------------------- # we use Nim's scanner here to save space and work -proc ppGetTok(L: var TLexer, tok: var TToken) = +proc ppGetTok(L: var Lexer, tok: var Token) = # simple filter rawGetTok(L, tok) while tok.tokType in {tkComment}: rawGetTok(L, tok) -proc parseExpr(L: var TLexer, tok: var TToken; config: ConfigRef): bool -proc parseAtom(L: var TLexer, tok: var TToken; config: ConfigRef): bool = +proc parseExpr(L: var Lexer, tok: var Token; config: ConfigRef): bool +proc parseAtom(L: var Lexer, tok: var Token; config: ConfigRef): bool = if tok.tokType == tkParLe: ppGetTok(L, tok) result = parseExpr(L, tok, config) @@ -35,21 +35,21 @@ proc parseAtom(L: var TLexer, tok: var TToken; config: ConfigRef): bool = result = isDefined(config, tok.ident.s) ppGetTok(L, tok) -proc parseAndExpr(L: var TLexer, tok: var TToken; config: ConfigRef): bool = +proc parseAndExpr(L: var Lexer, tok: var Token; config: ConfigRef): bool = result = parseAtom(L, tok, config) while tok.tokType == tkAnd: ppGetTok(L, tok) # skip "and" var b = parseAtom(L, tok, config) result = result and b -proc parseExpr(L: var TLexer, tok: var TToken; config: ConfigRef): bool = +proc parseExpr(L: var Lexer, tok: var Token; config: ConfigRef): bool = result = parseAndExpr(L, tok, config) while tok.tokType == tkOr: ppGetTok(L, tok) # skip "or" var b = parseAndExpr(L, tok, config) result = result or b -proc evalppIf(L: var TLexer, tok: var TToken; config: ConfigRef): bool = +proc evalppIf(L: var Lexer, tok: var Token; config: ConfigRef): bool = ppGetTok(L, tok) # skip 'if' or 'elif' result = parseExpr(L, tok, config) if tok.tokType == tkColon: ppGetTok(L, tok) @@ -57,7 +57,7 @@ proc evalppIf(L: var TLexer, tok: var TToken; config: ConfigRef): bool = #var condStack: seq[bool] = @[] -proc doEnd(L: var TLexer, tok: var TToken; condStack: var seq[bool]) = +proc doEnd(L: var Lexer, tok: var Token; condStack: var seq[bool]) = if high(condStack) < 0: lexMessage(L, errGenerated, "expected @if") ppGetTok(L, tok) # skip 'end' setLen(condStack, high(condStack)) @@ -66,21 +66,21 @@ type TJumpDest = enum jdEndif, jdElseEndif -proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest; config: ConfigRef; +proc jumpToDirective(L: var Lexer, tok: var Token, dest: TJumpDest; config: ConfigRef; condStack: var seq[bool]) -proc doElse(L: var TLexer, tok: var TToken; config: ConfigRef; condStack: var seq[bool]) = +proc doElse(L: var Lexer, tok: var Token; config: ConfigRef; condStack: var seq[bool]) = if high(condStack) < 0: lexMessage(L, errGenerated, "expected @if") ppGetTok(L, tok) if tok.tokType == tkColon: ppGetTok(L, tok) if condStack[high(condStack)]: jumpToDirective(L, tok, jdEndif, config, condStack) -proc doElif(L: var TLexer, tok: var TToken; config: ConfigRef; condStack: var seq[bool]) = +proc doElif(L: var Lexer, tok: var Token; config: ConfigRef; condStack: var seq[bool]) = if high(condStack) < 0: lexMessage(L, errGenerated, "expected @if") var res = evalppIf(L, tok, config) if condStack[high(condStack)] or not res: jumpToDirective(L, tok, jdElseEndif, config, condStack) else: condStack[high(condStack)] = true -proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest; config: ConfigRef; +proc jumpToDirective(L: var Lexer, tok: var Token, dest: TJumpDest; config: ConfigRef; condStack: var seq[bool]) = var nestedIfs = 0 while true: @@ -110,7 +110,7 @@ proc jumpToDirective(L: var TLexer, tok: var TToken, dest: TJumpDest; config: Co else: ppGetTok(L, tok) -proc parseDirective(L: var TLexer, tok: var TToken; config: ConfigRef; condStack: var seq[bool]) = +proc parseDirective(L: var Lexer, tok: var Token; config: ConfigRef; condStack: var seq[bool]) = ppGetTok(L, tok) # skip @ case whichKeyword(tok.ident) of wIf: @@ -149,16 +149,16 @@ proc parseDirective(L: var TLexer, tok: var TToken; config: ConfigRef; condStack else: lexMessage(L, errGenerated, "invalid directive: '$1'" % $tok) -proc confTok(L: var TLexer, tok: var TToken; config: ConfigRef; condStack: var seq[bool]) = +proc confTok(L: var Lexer, tok: var Token; config: ConfigRef; condStack: var seq[bool]) = ppGetTok(L, tok) while tok.ident != nil and tok.ident.s == "@": parseDirective(L, tok, config, condStack) # else: give the token to the parser -proc checkSymbol(L: TLexer, tok: TToken) = +proc checkSymbol(L: Lexer, tok: Token) = if tok.tokType notin {tkSymbol..tkInt64Lit, tkStrLit..tkTripleStrLit}: lexMessage(L, errGenerated, "expected identifier, but got: " & $tok) -proc parseAssignment(L: var TLexer, tok: var TToken; +proc parseAssignment(L: var Lexer, tok: var Token; config: ConfigRef; condStack: var seq[bool]) = if tok.ident != nil: if tok.ident.s == "-" or tok.ident.s == "--": @@ -211,8 +211,8 @@ proc parseAssignment(L: var TLexer, tok: var TToken; proc readConfigFile*(filename: AbsoluteFile; cache: IdentCache; config: ConfigRef): bool = var - L: TLexer - tok: TToken + L: Lexer + tok: Token stream: PLLStream stream = llStreamOpen(filename, fmRead) if stream != nil: diff --git a/compiler/nimlexbase.nim b/compiler/nimlexbase.nim index af2ae64a37bd..6132e6f661f9 100644 --- a/compiler/nimlexbase.nim +++ b/compiler/nimlexbase.nim @@ -162,9 +162,9 @@ proc getColNumber(L: TBaseLexer, pos: int): int = proc getCurrentLine(L: TBaseLexer, marker: bool = true): string = result = "" var i = L.lineStart - while not (L.buf[i] in {CR, LF, EndOfFile}): - result.add(L.buf[i]) - inc(i) - result.add("\n") + while L.buf[i] notin {CR, LF, EndOfFile}: + result.add L.buf[i] + inc i + result.add "\n" if marker: - result.add(spaces(getColNumber(L, L.bufpos)) & '^' & "\n") + result.add spaces(getColNumber(L, L.bufpos)) & '^' & "\n" diff --git a/compiler/options.nim b/compiler/options.nim index b5fb546eff81..8ff8cb753a1f 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -691,12 +691,10 @@ iterator nimbleSubs*(conf: ConfigRef; p: string): string = proc toGeneratedFile*(conf: ConfigRef; path: AbsoluteFile, ext: string): AbsoluteFile = ## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod" - let (head, tail) = splitPath(path.string) - result = getNimcacheDir(conf) / RelativeFile changeFileExt(tail, ext) + result = getNimcacheDir(conf) / RelativeFile path.string.splitPath.tail.changeFileExt(ext) proc completeGeneratedFilePath*(conf: ConfigRef; f: AbsoluteFile, createSubDir: bool = true): AbsoluteFile = - let (head, tail) = splitPath(f.string) let subdir = getNimcacheDir(conf) if createSubDir: try: @@ -704,7 +702,7 @@ proc completeGeneratedFilePath*(conf: ConfigRef; f: AbsoluteFile, except OSError: writeLine(stdout, "cannot create directory: " & subdir.string) quit(1) - result = subdir / RelativeFile tail + result = subdir / RelativeFile f.string.splitPath.tail #echo "completeGeneratedFilePath(", f, ") = ", result proc rawFindFile(conf: ConfigRef; f: RelativeFile; suppressStdlib: bool): AbsoluteFile = diff --git a/compiler/packagehandling.nim b/compiler/packagehandling.nim index 2243e7063479..9a3224de202e 100644 --- a/compiler/packagehandling.nim +++ b/compiler/packagehandling.nim @@ -28,8 +28,6 @@ proc getNimbleFile*(conf: ConfigRef; path: string): string = result = file break packageSearch # we also store if we didn't find anything: - when not defined(nimNoNilSeqs): - if result.isNil: result = "" for d in myParentDirs(path): #echo "set cache ", d, " |", result, "|", parents conf.packageCache[d] = result diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index ce9a855d8af9..ed8f2c16a374 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -99,14 +99,14 @@ proc compileConstraints(p: PNode, result: var TPatternCode; conf: ConfigRef) = else: # check all symkinds: internalAssert conf, int(high(TSymKind)) < 255 - for i in low(TSymKind)..high(TSymKind): + for i in TSymKind: if cmpIgnoreStyle(($i).substr(2), spec) == 0: result.add(ppSymKind) result.add(chr(i.ord)) return # check all nodekinds: internalAssert conf, int(high(TNodeKind)) < 255 - for i in low(TNodeKind)..high(TNodeKind): + for i in TNodeKind: if cmpIgnoreStyle($i, spec) == 0: result.add(ppNodeKind) result.add(chr(i.ord)) diff --git a/compiler/parser.nim b/compiler/parser.nim index 8cfeff6b06bf..e7db8d8b195e 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -37,14 +37,14 @@ when defined(nimpretty): import layouter type - TParser* = object # A TParser object represents a file that - # is being parsed - currInd: int # current indentation level - firstTok: bool # Has the first token been read? - hasProgress: bool # some while loop requires progress ensurance - lex*: TLexer # The lexer that is used for parsing - tok*: TToken # The current token - inPragma*: int # Pragma level + Parser* = object # A Parser object represents a file that + # is being parsed + currInd: int # current indentation level + firstTok: bool # Has the first token been read? + hasProgress: bool # some while loop requires progress ensurance + lex*: Lexer # The lexer that is used for parsing + tok*: Token # The current token + inPragma*: int # Pragma level inSemiStmtList*: int emptyNode: PNode when defined(nimpretty): @@ -53,42 +53,42 @@ type SymbolMode = enum smNormal, smAllowNil, smAfterDot - TPrimaryMode = enum + PrimaryMode = enum pmNormal, pmTypeDesc, pmTypeDef, pmSkipSuffix -proc parseAll*(p: var TParser): PNode -proc closeParser*(p: var TParser) -proc parseTopLevelStmt*(p: var TParser): PNode +proc parseAll*(p: var Parser): PNode +proc closeParser*(p: var Parser) +proc parseTopLevelStmt*(p: var Parser): PNode # helpers for the other parsers -proc isOperator*(tok: TToken): bool -proc getTok*(p: var TParser) -proc parMessage*(p: TParser, msg: TMsgKind, arg: string = "") -proc skipComment*(p: var TParser, node: PNode) -proc newNodeP*(kind: TNodeKind, p: TParser): PNode -proc newIntNodeP*(kind: TNodeKind, intVal: BiggestInt, p: TParser): PNode -proc newFloatNodeP*(kind: TNodeKind, floatVal: BiggestFloat, p: TParser): PNode -proc newStrNodeP*(kind: TNodeKind, strVal: string, p: TParser): PNode -proc newIdentNodeP*(ident: PIdent, p: TParser): PNode -proc expectIdentOrKeyw*(p: TParser) -proc expectIdent*(p: TParser) -proc parLineInfo*(p: TParser): TLineInfo -proc eat*(p: var TParser, tokType: TTokType) -proc skipInd*(p: var TParser) -proc optPar*(p: var TParser) -proc optInd*(p: var TParser, n: PNode) -proc indAndComment*(p: var TParser, n: PNode) -proc setBaseFlags*(n: PNode, base: TNumericalBase) -proc parseSymbol*(p: var TParser, mode = smNormal): PNode -proc parseTry(p: var TParser; isExpr: bool): PNode -proc parseCase(p: var TParser): PNode -proc parseStmtPragma(p: var TParser): PNode -proc parsePragma(p: var TParser): PNode -proc postExprBlocks(p: var TParser, x: PNode): PNode -proc parseExprStmt(p: var TParser): PNode -proc parseBlock(p: var TParser): PNode -proc primary(p: var TParser, mode: TPrimaryMode): PNode -proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode +proc isOperator*(tok: Token): bool +proc getTok*(p: var Parser) +proc parMessage*(p: Parser, msg: TMsgKind, arg: string = "") +proc skipComment*(p: var Parser, node: PNode) +proc newNodeP*(kind: TNodeKind, p: Parser): PNode +proc newIntNodeP*(kind: TNodeKind, intVal: BiggestInt, p: Parser): PNode +proc newFloatNodeP*(kind: TNodeKind, floatVal: BiggestFloat, p: Parser): PNode +proc newStrNodeP*(kind: TNodeKind, strVal: string, p: Parser): PNode +proc newIdentNodeP*(ident: PIdent, p: Parser): PNode +proc expectIdentOrKeyw*(p: Parser) +proc expectIdent*(p: Parser) +proc parLineInfo*(p: Parser): TLineInfo +proc eat*(p: var Parser, tokType: TokType) +proc skipInd*(p: var Parser) +proc optPar*(p: var Parser) +proc optInd*(p: var Parser, n: PNode) +proc indAndComment*(p: var Parser, n: PNode) +proc setBaseFlags*(n: PNode, base: NumericalBase) +proc parseSymbol*(p: var Parser, mode = smNormal): PNode +proc parseTry(p: var Parser; isExpr: bool): PNode +proc parseCase(p: var Parser): PNode +proc parseStmtPragma(p: var Parser): PNode +proc parsePragma(p: var Parser): PNode +proc postExprBlocks(p: var Parser, x: PNode): PNode +proc parseExprStmt(p: var Parser): PNode +proc parseBlock(p: var Parser): PNode +proc primary(p: var Parser, mode: PrimaryMode): PNode +proc simpleExprAux(p: var Parser, limit: int, mode: PrimaryMode): PNode # implementation @@ -97,7 +97,7 @@ template prettySection(body) = body when defined(nimpretty): endSection(p.em) -proc getTok(p: var TParser) = +proc getTok(p: var Parser) = ## Get the next token from the parser's lexer, and store it in the parser's ## `tok` member. rawGetTok(p.lex, p.tok) @@ -110,7 +110,7 @@ proc getTok(p: var TParser) = rawGetTok(p.lex, p.tok) emitTok(p.em, p.lex, p.tok) -proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream, +proc openParser*(p: var Parser, fileIdx: FileIndex, inputStream: PLLStream, cache: IdentCache; config: ConfigRef) = ## Open a parser, using the given arguments to set up its internal state. ## @@ -122,25 +122,25 @@ proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream, p.firstTok = true p.emptyNode = newNode(nkEmpty) -proc openParser*(p: var TParser, filename: AbsoluteFile, inputStream: PLLStream, +proc openParser*(p: var Parser, filename: AbsoluteFile, inputStream: PLLStream, cache: IdentCache; config: ConfigRef) = openParser(p, fileInfoIdx(config, filename), inputStream, cache, config) -proc closeParser(p: var TParser) = +proc closeParser(p: var Parser) = ## Close a parser, freeing up its resources. closeLexer(p.lex) when defined(nimpretty): closeEmitter(p.em) -proc parMessage(p: TParser, msg: TMsgKind, arg = "") = +proc parMessage(p: Parser, msg: TMsgKind, arg = "") = ## Produce and emit the parser message `arg` to output. lexMessageTok(p.lex, msg, p.tok, arg) -proc parMessage(p: TParser, msg: string, tok: TToken) = +proc parMessage(p: Parser, msg: string, tok: Token) = ## Produce and emit a parser message to output about the token `tok` parMessage(p, errGenerated, msg % prettyTok(tok)) -proc parMessage(p: TParser, arg: string) = +proc parMessage(p: Parser, arg: string) = ## Produce and emit the parser message `arg` to output. lexMessageTok(p.lex, errGenerated, p.tok, arg) @@ -150,7 +150,7 @@ template withInd(p, body: untyped) = body p.currInd = oldInd -template newlineWasSplitting(p: var TParser) = +template newlineWasSplitting(p: var Parser) = when defined(nimpretty): layouter.newlineWasSplitting(p.em) @@ -158,10 +158,10 @@ template realInd(p): bool = p.tok.indent > p.currInd template sameInd(p): bool = p.tok.indent == p.currInd template sameOrNoInd(p): bool = p.tok.indent == p.currInd or p.tok.indent < 0 -proc validInd(p: var TParser): bool {.inline.} = +proc validInd(p: var Parser): bool {.inline.} = result = p.tok.indent < 0 or p.tok.indent > p.currInd -proc rawSkipComment(p: var TParser, node: PNode) = +proc rawSkipComment(p: var Parser, node: PNode) = if p.tok.tokType == tkComment: if node != nil: when not defined(nimNoNilSeqs): @@ -177,43 +177,42 @@ proc rawSkipComment(p: var TParser, node: PNode) = parMessage(p, errInternal, "skipComment") getTok(p) -proc skipComment(p: var TParser, node: PNode) = +proc skipComment(p: var Parser, node: PNode) = if p.tok.indent < 0: rawSkipComment(p, node) -proc flexComment(p: var TParser, node: PNode) = +proc flexComment(p: var Parser, node: PNode) = if p.tok.indent < 0 or realInd(p): rawSkipComment(p, node) const errInvalidIndentation = "invalid indentation" errIdentifierExpected = "identifier expected, but got '$1'" errExprExpected = "expression expected, but found '$1'" - errTokenExpected = "'$1' expected" -proc skipInd(p: var TParser) = +proc skipInd(p: var Parser) = if p.tok.indent >= 0: if not realInd(p): parMessage(p, errInvalidIndentation) -proc optPar(p: var TParser) = +proc optPar(p: var Parser) = if p.tok.indent >= 0: if p.tok.indent < p.currInd: parMessage(p, errInvalidIndentation) -proc optInd(p: var TParser, n: PNode) = +proc optInd(p: var Parser, n: PNode) = skipComment(p, n) skipInd(p) -proc getTokNoInd(p: var TParser) = +proc getTokNoInd(p: var Parser) = getTok(p) if p.tok.indent >= 0: parMessage(p, errInvalidIndentation) -proc expectIdentOrKeyw(p: TParser) = +proc expectIdentOrKeyw(p: Parser) = if p.tok.tokType != tkSymbol and not isKeyword(p.tok.tokType): lexMessage(p.lex, errGenerated, errIdentifierExpected % prettyTok(p.tok)) -proc expectIdent(p: TParser) = +proc expectIdent(p: Parser) = if p.tok.tokType != tkSymbol: lexMessage(p.lex, errGenerated, errIdentifierExpected % prettyTok(p.tok)) -proc eat(p: var TParser, tokType: TTokType) = +proc eat(p: var Parser, tokType: TokType) = ## Move the parser to the next token if the current token is of type ## `tokType`, otherwise error. if p.tok.tokType == tokType: @@ -222,64 +221,63 @@ proc eat(p: var TParser, tokType: TTokType) = lexMessage(p.lex, errGenerated, "expected: '" & TokTypeToStr[tokType] & "', but got: '" & prettyTok(p.tok) & "'") -proc parLineInfo(p: TParser): TLineInfo = +proc parLineInfo(p: Parser): TLineInfo = ## Retrieve the line information associated with the parser's current state. result = getLineInfo(p.lex, p.tok) -proc indAndComment(p: var TParser, n: PNode) = +proc indAndComment(p: var Parser, n: PNode) = if p.tok.indent > p.currInd: if p.tok.tokType == tkComment: rawSkipComment(p, n) else: parMessage(p, errInvalidIndentation) else: skipComment(p, n) -proc newNodeP(kind: TNodeKind, p: TParser): PNode = +proc newNodeP(kind: TNodeKind, p: Parser): PNode = result = newNodeI(kind, parLineInfo(p)) -proc newIntNodeP(kind: TNodeKind, intVal: BiggestInt, p: TParser): PNode = +proc newIntNodeP(kind: TNodeKind, intVal: BiggestInt, p: Parser): PNode = result = newNodeP(kind, p) result.intVal = intVal proc newFloatNodeP(kind: TNodeKind, floatVal: BiggestFloat, - p: TParser): PNode = + p: Parser): PNode = result = newNodeP(kind, p) result.floatVal = floatVal -proc newStrNodeP(kind: TNodeKind, strVal: string, p: TParser): PNode = +proc newStrNodeP(kind: TNodeKind, strVal: string, p: Parser): PNode = result = newNodeP(kind, p) result.strVal = strVal -proc newIdentNodeP(ident: PIdent, p: TParser): PNode = +proc newIdentNodeP(ident: PIdent, p: Parser): PNode = result = newNodeP(nkIdent, p) result.ident = ident -proc parseExpr(p: var TParser): PNode -proc parseStmt(p: var TParser): PNode -proc parseTypeDesc(p: var TParser): PNode -proc parseParamList(p: var TParser, retColon = true): PNode +proc parseExpr(p: var Parser): PNode +proc parseStmt(p: var Parser): PNode +proc parseTypeDesc(p: var Parser): PNode +proc parseParamList(p: var Parser, retColon = true): PNode -proc isSigilLike(tok: TToken): bool {.inline.} = +proc isSigilLike(tok: Token): bool {.inline.} = result = tok.tokType == tkOpr and tok.ident.s[0] == '@' -proc isRightAssociative(tok: TToken): bool {.inline.} = +proc isRightAssociative(tok: Token): bool {.inline.} = ## Determines whether the token is right assocative. result = tok.tokType == tkOpr and tok.ident.s[0] == '^' # or (tok.ident.s.len > 1 and tok.ident.s[^1] == '>') -proc isOperator(tok: TToken): bool = +proc isOperator(tok: Token): bool = ## Determines if the given token is an operator type token. tok.tokType in {tkOpr, tkDiv, tkMod, tkShl, tkShr, tkIn, tkNotin, tkIs, tkIsnot, tkNot, tkOf, tkAs, tkFrom, tkDotDot, tkAnd, tkOr, tkXor} -proc isUnary(p: TParser): bool = - ## Check if the current parser token is a unary operator - if p.tok.tokType in {tkOpr, tkDotDot} and - p.tok.strongSpaceB == 0 and - p.tok.strongSpaceA > 0: - result = true +proc isUnary(tok: Token): bool = + ## Check if the given token is a unary operator + tok.tokType in {tkOpr, tkDotDot} and + tok.strongSpaceB == 0 and + tok.strongSpaceA > 0 -proc checkBinary(p: TParser) {.inline.} = +proc checkBinary(p: Parser) {.inline.} = ## Check if the current parser token is a binary operator. # we don't check '..' here as that's too annoying if p.tok.tokType == tkOpr: @@ -315,13 +313,13 @@ proc checkBinary(p: TParser) {.inline.} = #| mulExpr = dollarExpr (OP9 optInd dollarExpr)* #| dollarExpr = primary (OP10 optInd primary)* -proc colcom(p: var TParser, n: PNode) = +proc colcom(p: var Parser, n: PNode) = eat(p, tkColon) skipComment(p, n) const tkBuiltInMagics = {tkType, tkStatic, tkAddr} -proc parseSymbol(p: var TParser, mode = smNormal): PNode = +proc parseSymbol(p: var Parser, mode = smNormal): PNode = #| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`' #| | IDENT | KEYW case p.tok.tokType @@ -374,7 +372,7 @@ proc parseSymbol(p: var TParser, mode = smNormal): PNode = #if not isKeyword(p.tok.tokType): getTok(p) result = p.emptyNode -proc colonOrEquals(p: var TParser, a: PNode): PNode = +proc colonOrEquals(p: var Parser, a: PNode): PNode = if p.tok.tokType == tkColon: result = newNodeP(nkExprColonExpr, p) getTok(p) @@ -391,7 +389,7 @@ proc colonOrEquals(p: var TParser, a: PNode): PNode = else: result = a -proc exprColonEqExpr(p: var TParser): PNode = +proc exprColonEqExpr(p: var Parser): PNode = #| exprColonEqExpr = expr (':'|'=' expr)? var a = parseExpr(p) if p.tok.tokType == tkDo: @@ -399,7 +397,7 @@ proc exprColonEqExpr(p: var TParser): PNode = else: result = colonOrEquals(p, a) -proc exprList(p: var TParser, endTok: TTokType, result: PNode) = +proc exprList(p: var Parser, endTok: TokType, result: PNode) = #| exprList = expr ^+ comma when defined(nimpretty): inc p.em.doIndentMore @@ -415,7 +413,7 @@ proc exprList(p: var TParser, endTok: TTokType, result: PNode) = when defined(nimpretty): dec p.em.doIndentMore -proc exprColonEqExprListAux(p: var TParser, endTok: TTokType, result: PNode) = +proc exprColonEqExprListAux(p: var Parser, endTok: TokType, result: PNode) = assert(endTok in {tkCurlyRi, tkCurlyDotRi, tkBracketRi, tkParRi}) getTok(p) flexComment(p, result) @@ -433,13 +431,13 @@ proc exprColonEqExprListAux(p: var TParser, endTok: TTokType, result: PNode) = optPar(p) eat(p, endTok) -proc exprColonEqExprList(p: var TParser, kind: TNodeKind, - endTok: TTokType): PNode = +proc exprColonEqExprList(p: var Parser, kind: TNodeKind, + endTok: TokType): PNode = #| exprColonEqExprList = exprColonEqExpr (comma exprColonEqExpr)* (comma)? result = newNodeP(kind, p) exprColonEqExprListAux(p, endTok, result) -proc dotExpr(p: var TParser, a: PNode): PNode = +proc dotExpr(p: var Parser, a: PNode): PNode = #| dotExpr = expr '.' optInd (symbol | '[:' exprList ']') #| explicitGenericInstantiation = '[:' exprList ']' ( '(' exprColonEqExpr ')' )? var info = p.parLineInfo @@ -461,12 +459,12 @@ proc dotExpr(p: var TParser, a: PNode): PNode = exprColonEqExprListAux(p, tkParRi, y) result = y -proc qualifiedIdent(p: var TParser): PNode = +proc qualifiedIdent(p: var Parser): PNode = #| qualifiedIdent = symbol ('.' optInd symbol)? result = parseSymbol(p) if p.tok.tokType == tkDot: result = dotExpr(p, result) -proc setOrTableConstr(p: var TParser): PNode = +proc setOrTableConstr(p: var Parser): PNode = #| setOrTableConstr = '{' ((exprColonEqExpr comma)* | ':' ) '}' result = newNodeP(nkCurly, p) getTok(p) # skip '{' @@ -486,7 +484,7 @@ proc setOrTableConstr(p: var TParser): PNode = optPar(p) eat(p, tkCurlyRi) # skip '}' -proc parseCast(p: var TParser): PNode = +proc parseCast(p: var Parser): PNode = #| castExpr = 'cast' '[' optInd typeDesc optPar ']' '(' optInd expr optPar ')' result = newNodeP(nkCast, p) getTok(p) @@ -501,14 +499,14 @@ proc parseCast(p: var TParser): PNode = optPar(p) eat(p, tkParRi) -proc setBaseFlags(n: PNode, base: TNumericalBase) = +proc setBaseFlags(n: PNode, base: NumericalBase) = case base of base10: discard of base2: incl(n.flags, nfBase2) of base8: incl(n.flags, nfBase8) of base16: incl(n.flags, nfBase16) -proc parseGStrLit(p: var TParser, a: PNode): PNode = +proc parseGStrLit(p: var Parser, a: PNode): PNode = case p.tok.tokType of tkGStrLit: result = newNodeP(nkCallStrLit, p) @@ -523,10 +521,10 @@ proc parseGStrLit(p: var TParser, a: PNode): PNode = else: result = a -proc complexOrSimpleStmt(p: var TParser): PNode -proc simpleExpr(p: var TParser, mode = pmNormal): PNode +proc complexOrSimpleStmt(p: var Parser): PNode +proc simpleExpr(p: var Parser, mode = pmNormal): PNode -proc semiStmtList(p: var TParser, result: PNode) = +proc semiStmtList(p: var Parser, result: PNode) = inc p.inSemiStmtList result.add(complexOrSimpleStmt(p)) # progress guaranteed @@ -537,7 +535,7 @@ proc semiStmtList(p: var TParser, result: PNode) = dec p.inSemiStmtList result.transitionSonsKind(nkStmtListExpr) -proc parsePar(p: var TParser): PNode = +proc parsePar(p: var Parser): PNode = #| parKeyw = 'discard' | 'include' | 'if' | 'while' | 'case' | 'try' #| | 'finally' | 'except' | 'for' | 'block' | 'const' | 'let' #| | 'when' | 'var' | 'mixin' @@ -607,7 +605,7 @@ proc parsePar(p: var TParser): PNode = optPar(p) eat(p, tkParRi) -proc identOrLiteral(p: var TParser, mode: TPrimaryMode): PNode = +proc identOrLiteral(p: var Parser, mode: PrimaryMode): PNode = #| literal = | INT_LIT | INT8_LIT | INT16_LIT | INT32_LIT | INT64_LIT #| | UINT_LIT | UINT8_LIT | UINT16_LIT | UINT32_LIT | UINT64_LIT #| | FLOAT_LIT | FLOAT32_LIT | FLOAT64_LIT @@ -717,15 +715,15 @@ proc identOrLiteral(p: var TParser, mode: TPrimaryMode): PNode = getTok(p) # we must consume a token here to prevent endless loops! result = p.emptyNode -proc namedParams(p: var TParser, callee: PNode, - kind: TNodeKind, endTok: TTokType): PNode = +proc namedParams(p: var Parser, callee: PNode, + kind: TNodeKind, endTok: TokType): PNode = let a = callee result = newNodeP(kind, p) result.add(a) # progress guaranteed exprColonEqExprListAux(p, endTok, result) -proc commandParam(p: var TParser, isFirstParam: var bool; mode: TPrimaryMode): PNode = +proc commandParam(p: var Parser, isFirstParam: var bool; mode: PrimaryMode): PNode = if mode == pmTypeDesc: result = simpleExpr(p, mode) else: @@ -740,7 +738,7 @@ proc commandParam(p: var TParser, isFirstParam: var bool; mode: TPrimaryMode): P result.add(parseExpr(p)) isFirstParam = false -proc commandExpr(p: var TParser; r: PNode; mode: TPrimaryMode): PNode = +proc commandExpr(p: var Parser; r: PNode; mode: PrimaryMode): PNode = result = newNodeP(nkCommand, p) result.add(r) var isFirstParam = true @@ -748,8 +746,8 @@ proc commandExpr(p: var TParser; r: PNode; mode: TPrimaryMode): PNode = p.hasProgress = false result.add commandParam(p, isFirstParam, mode) -proc primarySuffix(p: var TParser, r: PNode, - baseIndent: int, mode: TPrimaryMode): PNode = +proc primarySuffix(p: var Parser, r: PNode, + baseIndent: int, mode: PrimaryMode): PNode = #| primarySuffix = '(' (exprColonEqExpr comma?)* ')' #| | '.' optInd symbol generalizedLit? #| | '[' optInd exprColonEqExprList optPar ']' @@ -800,7 +798,7 @@ proc primarySuffix(p: var TParser, r: PNode, # `foo ref` or `foo ptr`. Unfortunately, these two are also # used as infix operators for the memory regions feature and # the current parsing rules don't play well here. - if p.inPragma == 0 and (isUnary(p) or p.tok.tokType notin {tkOpr, tkDotDot}): + if p.inPragma == 0 and (isUnary(p.tok) or p.tok.tokType notin {tkOpr, tkDotDot}): # actually parsing {.push hints:off.} as {.push(hints:off).} is a sweet # solution, but pragmas.nim can't handle that result = commandExpr(p, result, mode) @@ -808,17 +806,17 @@ proc primarySuffix(p: var TParser, r: PNode, else: break -proc parseOperators(p: var TParser, headNode: PNode, - limit: int, mode: TPrimaryMode): PNode = +proc parseOperators(p: var Parser, headNode: PNode, + limit: int, mode: PrimaryMode): PNode = result = headNode # expand while operators have priorities higher than 'limit' - var opPrec = getPrecedence(p.tok, false) + var opPrec = getPrecedence(p.tok) let modeB = if mode == pmTypeDef: pmTypeDesc else: mode # the operator itself must not start on a new line: # progress guaranteed - while opPrec >= limit and p.tok.indent < 0 and not isUnary(p): + while opPrec >= limit and p.tok.indent < 0 and not isUnary(p.tok): checkBinary(p) - var leftAssoc = 1-ord(isRightAssociative(p.tok)) + let leftAssoc = ord(not isRightAssociative(p.tok)) var a = newNodeP(nkInfix, p) var opNode = newIdentNodeP(p.tok.ident, p) # skip operator: getTok(p) @@ -830,9 +828,9 @@ proc parseOperators(p: var TParser, headNode: PNode, a.add(result) a.add(b) result = a - opPrec = getPrecedence(p.tok, false) + opPrec = getPrecedence(p.tok) -proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode = +proc simpleExprAux(p: var Parser, limit: int, mode: PrimaryMode): PNode = result = primary(p, mode) if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)) and mode == pmNormal: @@ -842,14 +840,14 @@ proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode = result = pragmaExp result = parseOperators(p, result, limit, mode) -proc simpleExpr(p: var TParser, mode = pmNormal): PNode = +proc simpleExpr(p: var Parser, mode = pmNormal): PNode = when defined(nimpretty): inc p.em.doIndentMore result = simpleExprAux(p, -1, mode) when defined(nimpretty): dec p.em.doIndentMore -proc parseIfExpr(p: var TParser, kind: TNodeKind): PNode = +proc parseIfExpr(p: var Parser, kind: TNodeKind): PNode = #| condExpr = expr colcom expr optInd #| ('elif' expr colcom expr optInd)* #| 'else' colcom expr @@ -907,7 +905,7 @@ proc parseIfExpr(p: var TParser, kind: TNodeKind): PNode = if wasIndented: p.currInd = oldInd -proc parsePragma(p: var TParser): PNode = +proc parsePragma(p: var Parser): PNode = #| pragma = '{.' optInd (exprColonEqExpr comma?)* optPar ('.}' | '}') result = newNodeP(nkPragma, p) inc p.inPragma @@ -936,7 +934,7 @@ proc parsePragma(p: var TParser): PNode = dec p.em.doIndentMore dec p.em.keepIndents -proc identVis(p: var TParser; allowDot=false): PNode = +proc identVis(p: var Parser; allowDot=false): PNode = #| identVis = symbol OPR? # postfix position #| identVisDot = symbol '.' optInd symbol OPR? var a = parseSymbol(p) @@ -952,7 +950,7 @@ proc identVis(p: var TParser; allowDot=false): PNode = else: result = a -proc identWithPragma(p: var TParser; allowDot=false): PNode = +proc identWithPragma(p: var Parser; allowDot=false): PNode = #| identWithPragma = identVis pragma? #| identWithPragmaDot = identVisDot pragma? var a = identVis(p, allowDot) @@ -964,13 +962,13 @@ proc identWithPragma(p: var TParser; allowDot=false): PNode = result = a type - TDeclaredIdentFlag = enum + DeclaredIdentFlag = enum withPragma, # identifier may have pragma withBothOptional # both ':' and '=' parts are optional withDot # allow 'var ident.ident = value' - TDeclaredIdentFlags = set[TDeclaredIdentFlag] + DeclaredIdentFlags = set[DeclaredIdentFlag] -proc parseIdentColonEquals(p: var TParser, flags: TDeclaredIdentFlags): PNode = +proc parseIdentColonEquals(p: var Parser, flags: DeclaredIdentFlags): PNode = #| declColonEquals = identWithPragma (comma identWithPragma)* comma? #| (':' optInd typeDesc)? ('=' optInd expr)? #| identColonEquals = IDENT (comma IDENT)* comma? @@ -1004,7 +1002,7 @@ proc parseIdentColonEquals(p: var TParser, flags: TDeclaredIdentFlags): PNode = else: result.add(newNodeP(nkEmpty, p)) -proc parseTuple(p: var TParser, indentAllowed = false): PNode = +proc parseTuple(p: var Parser, indentAllowed = false): PNode = #| inlTupleDecl = 'tuple' #| '[' optInd (identColonEquals (comma/semicolon)?)* optPar ']' #| extTupleDecl = 'tuple' @@ -1049,7 +1047,7 @@ proc parseTuple(p: var TParser, indentAllowed = false): PNode = else: result = newNodeP(nkTupleClassTy, p) -proc parseParamList(p: var TParser, retColon = true): PNode = +proc parseParamList(p: var Parser, retColon = true): PNode = #| paramList = '(' declColonEquals ^* (comma/semicolon) ')' #| paramListArrow = paramList? ('->' optInd typeDesc)? #| paramListColon = paramList? (':' optInd typeDesc)? @@ -1097,13 +1095,13 @@ proc parseParamList(p: var TParser, retColon = true): PNode = dec p.em.doIndentMore dec p.em.keepIndents -proc optPragmas(p: var TParser): PNode = +proc optPragmas(p: var Parser): PNode = if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)): result = parsePragma(p) else: result = p.emptyNode -proc parseDoBlock(p: var TParser; info: TLineInfo): PNode = +proc parseDoBlock(p: var Parser; info: TLineInfo): PNode = #| doBlock = 'do' paramListArrow pragma? colcom stmt let params = parseParamList(p, retColon=false) let pragmas = optPragmas(p) @@ -1114,7 +1112,7 @@ proc parseDoBlock(p: var TParser; info: TLineInfo): PNode = body = result, params = params, name = p.emptyNode, pattern = p.emptyNode, genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode) -proc parseProcExpr(p: var TParser; isExpr: bool; kind: TNodeKind): PNode = +proc parseProcExpr(p: var Parser; isExpr: bool; kind: TNodeKind): PNode = #| procExpr = 'proc' paramListColon pragma? ('=' COMMENT? stmt)? # either a proc type or a anonymous proc let info = parLineInfo(p) @@ -1136,7 +1134,7 @@ proc parseProcExpr(p: var TParser; isExpr: bool; kind: TNodeKind): PNode = parMessage(p, "func keyword is not allowed in type descriptions, use proc with {.noSideEffect.} pragma instead") result.add(pragmas) -proc isExprStart(p: TParser): bool = +proc isExprStart(p: Parser): bool = case p.tok.tokType of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf, tkFor, tkProc, tkFunc, tkIterator, tkBind, tkBuiltInMagics, @@ -1145,7 +1143,7 @@ proc isExprStart(p: TParser): bool = result = true else: result = false -proc parseSymbolList(p: var TParser, result: PNode) = +proc parseSymbolList(p: var Parser, result: PNode) = # progress guaranteed while true: var s = parseSymbol(p, smAllowNil) @@ -1155,8 +1153,8 @@ proc parseSymbolList(p: var TParser, result: PNode) = getTok(p) optInd(p, s) -proc parseTypeDescKAux(p: var TParser, kind: TNodeKind, - mode: TPrimaryMode): PNode = +proc parseTypeDescKAux(p: var Parser, kind: TNodeKind, + mode: PrimaryMode): PNode = #| distinct = 'distinct' optInd typeDesc result = newNodeP(kind, p) getTok(p) @@ -1178,9 +1176,9 @@ proc parseTypeDescKAux(p: var TParser, kind: TNodeKind, result.add list parseSymbolList(p, list) -proc parseVarTuple(p: var TParser): PNode +proc parseVarTuple(p: var Parser): PNode -proc parseFor(p: var TParser): PNode = +proc parseFor(p: var Parser): PNode = #| forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt #| forExpr = forStmt getTokNoInd(p) @@ -1210,7 +1208,7 @@ template nimprettyDontTouch(body) = when defined(nimpretty): dec p.em.keepIndents -proc parseExpr(p: var TParser): PNode = +proc parseExpr(p: var Parser): PNode = #| expr = (blockExpr #| | ifExpr #| | whenExpr @@ -1241,11 +1239,11 @@ proc parseExpr(p: var TParser): PNode = result = parseTry(p, isExpr=true) else: result = simpleExpr(p) -proc parseEnum(p: var TParser): PNode -proc parseObject(p: var TParser): PNode -proc parseTypeClass(p: var TParser): PNode +proc parseEnum(p: var Parser): PNode +proc parseObject(p: var Parser): PNode +proc parseTypeClass(p: var Parser): PNode -proc primary(p: var TParser, mode: TPrimaryMode): PNode = +proc primary(p: var Parser, mode: PrimaryMode): PNode = #| typeKeyw = 'var' | 'out' | 'ref' | 'ptr' | 'shared' | 'tuple' #| | 'proc' | 'iterator' | 'distinct' | 'object' | 'enum' #| primary = typeKeyw optInd typeDesc @@ -1313,7 +1311,7 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode = if mode != pmSkipSuffix: result = primarySuffix(p, result, baseInd, mode) -proc binaryNot(p: var TParser; a: PNode): PNode = +proc binaryNot(p: var Parser; a: PNode): PNode = if p.tok.tokType == tkNot: let notOpr = newIdentNodeP(p.tok.ident, p) getTok(p) @@ -1326,13 +1324,13 @@ proc binaryNot(p: var TParser; a: PNode): PNode = else: result = a -proc parseTypeDesc(p: var TParser): PNode = +proc parseTypeDesc(p: var Parser): PNode = #| typeDesc = simpleExpr ('not' expr)? newlineWasSplitting(p) result = simpleExpr(p, pmTypeDesc) result = binaryNot(p, result) -proc parseTypeDefAux(p: var TParser): PNode = +proc parseTypeDefAux(p: var Parser): PNode = #| typeDefAux = simpleExpr ('not' expr)? #| | 'concept' typeClass result = simpleExpr(p, pmTypeDef) @@ -1346,7 +1344,7 @@ proc makeCall(n: PNode): PNode = result = newNodeI(nkCall, n.info) result.add n -proc postExprBlocks(p: var TParser, x: PNode): PNode = +proc postExprBlocks(p: var Parser, x: PNode): PNode = #| postExprBlocks = ':' stmt? ( IND{=} doBlock #| | IND{=} 'of' exprList ':' stmt #| | IND{=} 'elif' expr ':' stmt @@ -1420,7 +1418,7 @@ proc postExprBlocks(p: var TParser, x: PNode): PNode = if openingParams.kind != nkEmpty: parMessage(p, "expected ':'") -proc parseExprStmt(p: var TParser): PNode = +proc parseExprStmt(p: var Parser): PNode = #| exprStmt = simpleExpr #| (( '=' optInd expr colonBody? ) #| / ( expr ^+ comma @@ -1456,7 +1454,7 @@ proc parseExprStmt(p: var TParser): PNode = result = a result = postExprBlocks(p, result) -proc parseModuleName(p: var TParser, kind: TNodeKind): PNode = +proc parseModuleName(p: var Parser, kind: TNodeKind): PNode = result = parseExpr(p) when false: # parseExpr already handles 'as' syntax ... @@ -1467,7 +1465,7 @@ proc parseModuleName(p: var TParser, kind: TNodeKind): PNode = result.add(a) result.add(parseExpr(p)) -proc parseImport(p: var TParser, kind: TNodeKind): PNode = +proc parseImport(p: var Parser, kind: TNodeKind): PNode = #| importStmt = 'import' optInd expr #| ((comma expr)* #| / 'except' optInd (expr ^+ comma)) @@ -1495,7 +1493,7 @@ proc parseImport(p: var TParser, kind: TNodeKind): PNode = optInd(p, a) #expectNl(p) -proc parseIncludeStmt(p: var TParser): PNode = +proc parseIncludeStmt(p: var Parser): PNode = #| includeStmt = 'include' optInd expr ^+ comma result = newNodeP(nkIncludeStmt, p) getTok(p) # skip `import` or `include` @@ -1511,7 +1509,7 @@ proc parseIncludeStmt(p: var TParser): PNode = optInd(p, a) #expectNl(p) -proc parseFromStmt(p: var TParser): PNode = +proc parseFromStmt(p: var Parser): PNode = #| fromStmt = 'from' expr 'import' optInd expr (comma expr)* result = newNodeP(nkFromStmt, p) getTok(p) # skip `from` @@ -1531,7 +1529,7 @@ proc parseFromStmt(p: var TParser): PNode = optInd(p, a) #expectNl(p) -proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode = +proc parseReturnOrRaise(p: var Parser, kind: TNodeKind): PNode = #| returnStmt = 'return' optInd expr? #| raiseStmt = 'raise' optInd expr? #| yieldStmt = 'yield' optInd expr? @@ -1552,7 +1550,7 @@ proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode = e = postExprBlocks(p, e) result.add(e) -proc parseIfOrWhen(p: var TParser, kind: TNodeKind): PNode = +proc parseIfOrWhen(p: var Parser, kind: TNodeKind): PNode = #| condStmt = expr colcom stmt COMMENT? #| (IND{=} 'elif' expr colcom stmt)* #| (IND{=} 'else' colcom stmt)? @@ -1576,7 +1574,7 @@ proc parseIfOrWhen(p: var TParser, kind: TNodeKind): PNode = branch.add(parseStmt(p)) result.add(branch) -proc parseWhile(p: var TParser): PNode = +proc parseWhile(p: var Parser): PNode = #| whileStmt = 'while' expr colcom stmt result = newNodeP(nkWhileStmt, p) getTok(p) @@ -1585,7 +1583,7 @@ proc parseWhile(p: var TParser): PNode = colcom(p, result) result.add(parseStmt(p)) -proc parseCase(p: var TParser): PNode = +proc parseCase(p: var Parser): PNode = #| ofBranch = 'of' exprList colcom stmt #| ofBranches = ofBranch (IND{=} ofBranch)* #| (IND{=} 'elif' expr colcom stmt)* @@ -1632,7 +1630,7 @@ proc parseCase(p: var TParser): PNode = if wasIndented: p.currInd = oldInd -proc parseTry(p: var TParser; isExpr: bool): PNode = +proc parseTry(p: var Parser; isExpr: bool): PNode = #| tryStmt = 'try' colcom stmt &(IND{=}? 'except'|'finally') #| (IND{=}? 'except' exprList colcom stmt)* #| (IND{=}? 'finally' colcom stmt)? @@ -1658,14 +1656,14 @@ proc parseTry(p: var TParser; isExpr: bool): PNode = result.add(b) if b == nil: parMessage(p, "expected 'except'") -proc parseExceptBlock(p: var TParser, kind: TNodeKind): PNode = +proc parseExceptBlock(p: var Parser, kind: TNodeKind): PNode = #| exceptBlock = 'except' colcom stmt result = newNodeP(kind, p) getTok(p) colcom(p, result) result.add(parseStmt(p)) -proc parseBlock(p: var TParser): PNode = +proc parseBlock(p: var Parser): PNode = #| blockStmt = 'block' symbol? colcom stmt #| blockExpr = 'block' symbol? colcom stmt result = newNodeP(nkBlockStmt, p) @@ -1675,7 +1673,7 @@ proc parseBlock(p: var TParser): PNode = colcom(p, result) result.add(parseStmt(p)) -proc parseStaticOrDefer(p: var TParser; k: TNodeKind): PNode = +proc parseStaticOrDefer(p: var Parser; k: TNodeKind): PNode = #| staticStmt = 'static' colcom stmt #| deferStmt = 'defer' colcom stmt result = newNodeP(k, p) @@ -1683,7 +1681,7 @@ proc parseStaticOrDefer(p: var TParser; k: TNodeKind): PNode = colcom(p, result) result.add(parseStmt(p)) -proc parseAsm(p: var TParser): PNode = +proc parseAsm(p: var Parser): PNode = #| asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLESTR_LIT) result = newNodeP(nkAsmStmt, p) getTokNoInd(p) @@ -1699,7 +1697,7 @@ proc parseAsm(p: var TParser): PNode = return getTok(p) -proc parseGenericParam(p: var TParser): PNode = +proc parseGenericParam(p: var Parser): PNode = #| genericParam = symbol (comma symbol)* (colon expr)? ('=' optInd expr)? var a: PNode result = newNodeP(nkIdentDefs, p) @@ -1734,7 +1732,7 @@ proc parseGenericParam(p: var TParser): PNode = else: result.add(p.emptyNode) -proc parseGenericParamList(p: var TParser): PNode = +proc parseGenericParamList(p: var Parser): PNode = #| genericParamList = '[' optInd #| genericParam ^* (comma/semicolon) optPar ']' result = newNodeP(nkGenericParams, p) @@ -1752,13 +1750,13 @@ proc parseGenericParamList(p: var TParser): PNode = optPar(p) eat(p, tkBracketRi) -proc parsePattern(p: var TParser): PNode = +proc parsePattern(p: var Parser): PNode = #| pattern = '{' stmt '}' eat(p, tkCurlyLe) result = parseStmt(p) eat(p, tkCurlyRi) -proc parseRoutine(p: var TParser, kind: TNodeKind): PNode = +proc parseRoutine(p: var Parser, kind: TNodeKind): PNode = #| indAndComment = (IND{>} COMMENT)? | COMMENT? #| routine = optInd identVis pattern? genericParamList? #| paramListColon pragma? ('=' COMMENT? stmt)? indAndComment @@ -1785,17 +1783,14 @@ proc parseRoutine(p: var TParser, kind: TNodeKind): PNode = result.add(p.emptyNode) indAndComment(p, result) -proc newCommentStmt(p: var TParser): PNode = +proc newCommentStmt(p: var Parser): PNode = #| commentStmt = COMMENT result = newNodeP(nkCommentStmt, p) result.comment = p.tok.literal getTok(p) -type - TDefParser = proc (p: var TParser): PNode {.nimcall.} - -proc parseSection(p: var TParser, kind: TNodeKind, - defparser: TDefParser): PNode = +proc parseSection(p: var Parser, kind: TNodeKind, + defparser: proc (p: var Parser): PNode {.nimcall.}): PNode = #| section(RULE) = COMMENT? RULE / (IND{>} (RULE / COMMENT)^+IND{=} DED) result = newNodeP(kind, p) if kind != nkTypeSection: getTok(p) @@ -1823,7 +1818,7 @@ proc parseSection(p: var TParser, kind: TNodeKind, else: parMessage(p, errIdentifierExpected, p.tok) -proc parseEnum(p: var TParser): PNode = +proc parseEnum(p: var Parser): PNode = #| enum = 'enum' optInd (symbol pragma? optInd ('=' optInd expr COMMENT?)? comma?)+ result = newNodeP(nkEnumTy, p) getTok(p) @@ -1869,8 +1864,8 @@ proc parseEnum(p: var TParser): PNode = if result.len <= 1: parMessage(p, errIdentifierExpected, p.tok) -proc parseObjectPart(p: var TParser): PNode -proc parseObjectWhen(p: var TParser): PNode = +proc parseObjectPart(p: var Parser): PNode +proc parseObjectWhen(p: var Parser): PNode = #| objectWhen = 'when' expr colcom objectPart COMMENT? #| ('elif' expr colcom objectPart COMMENT?)* #| ('else' colcom objectPart COMMENT?)? @@ -1894,7 +1889,7 @@ proc parseObjectWhen(p: var TParser): PNode = flexComment(p, branch) result.add(branch) -proc parseObjectCase(p: var TParser): PNode = +proc parseObjectCase(p: var Parser): PNode = #| objectBranch = 'of' exprList colcom objectPart #| objectBranches = objectBranch (IND{=} objectBranch)* #| (IND{=} 'elif' expr colcom objectPart)* @@ -1939,7 +1934,7 @@ proc parseObjectCase(p: var TParser): PNode = if wasIndented: p.currInd = oldInd -proc parseObjectPart(p: var TParser): PNode = +proc parseObjectPart(p: var Parser): PNode = #| objectPart = IND{>} objectPart^+IND{=} DED #| / objectWhen / objectCase / 'nil' / 'discard' / declColonEquals if realInd(p): @@ -1971,7 +1966,7 @@ proc parseObjectPart(p: var TParser): PNode = else: result = p.emptyNode -proc parseObject(p: var TParser): PNode = +proc parseObject(p: var Parser): PNode = #| object = 'object' pragma? ('of' typeDesc)? COMMENT? objectPart result = newNodeP(nkObjectTy, p) getTok(p) @@ -1996,7 +1991,7 @@ proc parseObject(p: var TParser): PNode = else: result.add(parseObjectPart(p)) -proc parseTypeClassParam(p: var TParser): PNode = +proc parseTypeClassParam(p: var Parser): PNode = let modifier = case p.tok.tokType of tkOut, tkVar: nkVarTy of tkPtr: nkPtrTy @@ -2012,7 +2007,7 @@ proc parseTypeClassParam(p: var TParser): PNode = else: result = p.parseSymbol -proc parseTypeClass(p: var TParser): PNode = +proc parseTypeClass(p: var Parser): PNode = #| typeClassParam = ('var' | 'out')? symbol #| typeClass = typeClassParam ^* ',' (pragma)? ('of' typeDesc ^* ',')? #| &IND{>} stmt @@ -2047,7 +2042,7 @@ proc parseTypeClass(p: var TParser): PNode = else: result.add(parseStmt(p)) -proc parseTypeDef(p: var TParser): PNode = +proc parseTypeDef(p: var Parser): PNode = #| #| typeDef = identWithPragmaDot genericParamList? '=' optInd typeDefAux #| indAndComment? / identVisDot genericParamList? pragma '=' optInd typeDefAux @@ -2095,7 +2090,7 @@ proc parseTypeDef(p: var TParser): PNode = result.add(p.emptyNode) indAndComment(p, result) # special extension! -proc parseVarTuple(p: var TParser): PNode = +proc parseVarTuple(p: var Parser): PNode = #| varTuple = '(' optInd identWithPragma ^+ comma optPar ')' '=' optInd expr result = newNodeP(nkVarTuple, p) getTok(p) # skip '(' @@ -2111,7 +2106,7 @@ proc parseVarTuple(p: var TParser): PNode = optPar(p) eat(p, tkParRi) -proc parseVariable(p: var TParser): PNode = +proc parseVariable(p: var Parser): PNode = #| colonBody = colcom stmt postExprBlocks? #| variable = (varTuple / identColonEquals) colonBody? indAndComment if p.tok.tokType == tkParLe: @@ -2123,7 +2118,7 @@ proc parseVariable(p: var TParser): PNode = result[^1] = postExprBlocks(p, result[^1]) indAndComment(p, result) -proc parseConstant(p: var TParser): PNode = +proc parseConstant(p: var Parser): PNode = #| constant = (varTuple / identWithPragma) (colon typeDesc)? '=' optInd expr indAndComment if p.tok.tokType == tkParLe: result = parseVarTuple(p) else: @@ -2142,7 +2137,7 @@ proc parseConstant(p: var TParser): PNode = result[^1] = postExprBlocks(p, result[^1]) indAndComment(p, result) -proc parseBind(p: var TParser, k: TNodeKind): PNode = +proc parseBind(p: var Parser, k: TNodeKind): PNode = #| bindStmt = 'bind' optInd qualifiedIdent ^+ comma #| mixinStmt = 'mixin' optInd qualifiedIdent ^+ comma result = newNodeP(k, p) @@ -2157,7 +2152,7 @@ proc parseBind(p: var TParser, k: TNodeKind): PNode = optInd(p, a) #expectNl(p) -proc parseStmtPragma(p: var TParser): PNode = +proc parseStmtPragma(p: var Parser): PNode = #| pragmaStmt = pragma (':' COMMENT? stmt)? result = parsePragma(p) if p.tok.tokType == tkColon and p.tok.indent < 0: @@ -2168,7 +2163,7 @@ proc parseStmtPragma(p: var TParser): PNode = result.add a result.add parseStmt(p) -proc simpleStmt(p: var TParser): PNode = +proc simpleStmt(p: var Parser): PNode = #| simpleStmt = ((returnStmt | raiseStmt | yieldStmt | discardStmt | breakStmt #| | continueStmt | pragmaStmt | importStmt | exportStmt | fromStmt #| | includeStmt | commentStmt) / exprStmt) COMMENT? @@ -2191,7 +2186,7 @@ proc simpleStmt(p: var TParser): PNode = else: result = p.emptyNode if result.kind notin {nkEmpty, nkCommentStmt}: skipComment(p, result) -proc complexOrSimpleStmt(p: var TParser): PNode = +proc complexOrSimpleStmt(p: var Parser): PNode = #| complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt #| | tryStmt | forStmt #| | blockStmt | staticStmt | deferStmt | asmStmt @@ -2251,7 +2246,7 @@ proc complexOrSimpleStmt(p: var TParser): PNode = of tkUsing: result = parseSection(p, nkUsingStmt, parseVariable) else: result = simpleStmt(p) -proc parseStmt(p: var TParser): PNode = +proc parseStmt(p: var Parser): PNode = #| stmt = (IND{>} complexOrSimpleStmt^+(IND{=} / ';') DED) #| / simpleStmt ^+ ';' if p.tok.indent > p.currInd: @@ -2311,7 +2306,7 @@ proc parseStmt(p: var TParser): PNode = getTok(p) if err and p.tok.tokType == tkEof: break -proc parseAll(p: var TParser): PNode = +proc parseAll(p: var Parser): PNode = ## Parses the rest of the input stream held by the parser into a PNode. result = newNodeP(nkStmtList, p) while p.tok.tokType != tkEof: @@ -2326,7 +2321,7 @@ proc parseAll(p: var TParser): PNode = if p.tok.indent != 0: parMessage(p, errInvalidIndentation) -proc parseTopLevelStmt(p: var TParser): PNode = +proc parseTopLevelStmt(p: var Parser): PNode = ## Implements an iterator which, when called repeatedly, returns the next ## top-level statement or emptyNode if end of stream. result = p.emptyNode @@ -2357,7 +2352,7 @@ proc parseTopLevelStmt(p: var TParser): PNode = proc parseString*(s: string; cache: IdentCache; config: ConfigRef; filename: string = ""; line: int = 0; - errorHandler: TErrorHandler = nil): PNode = + errorHandler: ErrorHandler = nil): PNode = ## Parses a string into an AST, returning the top node. ## `filename` and `line`, although optional, provide info so that the ## compiler can generate correct error messages referring to the original @@ -2365,7 +2360,7 @@ proc parseString*(s: string; cache: IdentCache; config: ConfigRef; var stream = llStreamOpen(s) stream.lineOffset = line - var parser: TParser + var parser: Parser parser.lex.errorHandler = errorHandler openParser(parser, AbsoluteFile filename, stream, cache, config) diff --git a/compiler/passes.nim b/compiler/passes.nim index 615b9ac88188..2d30ebbb53ee 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -126,7 +126,7 @@ proc moduleHasChanged*(graph: ModuleGraph; module: PSym): bool {.inline.} = proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {.discardable.} = if graph.stopCompile(): return true var - p: TParsers + p: Parser a: TPassContextArray s: PLLStream fileIdx = module.fileIdx @@ -164,7 +164,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool { else: s = stream while true: - openParsers(p, fileIdx, s, graph.cache, graph.config) + openParser(p, fileIdx, s, graph.cache, graph.config) if module.owner == nil or module.owner.name.s != "stdlib" or module.name.s == "distros": # XXX what about caching? no processing then? what if I change the @@ -212,7 +212,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool { else: #echo "----- single\n", n if not processTopLevelStmt(graph, n, a): break - closeParsers(p) + closeParser(p) if s.kind != llsStdIn: break closePasses(graph, a) # id synchronization point for more consistent code generation: diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 44ff9001012d..b2529a5b86d0 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -238,7 +238,7 @@ proc processMagic(c: PContext, n: PNode, s: PSym) = var v: string if n[1].kind == nkIdent: v = n[1].ident.s else: v = expectStrLit(c, n) - for m in low(TMagic)..high(TMagic): + for m in TMagic: if substr($m, 1) == v: s.magic = m break @@ -257,8 +257,8 @@ proc isTurnedOn(c: PContext, n: PNode): bool = localError(c.config, n.info, "'on' or 'off' expected") proc onOff(c: PContext, n: PNode, op: TOptions, resOptions: var TOptions) = - if isTurnedOn(c, n): resOptions = resOptions + op - else: resOptions = resOptions - op + if isTurnedOn(c, n): resOptions.incl op + else: resOptions.excl op proc pragmaNoForward(c: PContext, n: PNode; flag=sfNoForward) = if isTurnedOn(c, n): diff --git a/compiler/renderer.nim b/compiler/renderer.nim index f600d58bf501..9601bf08259b 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -24,7 +24,7 @@ type renderIr TRenderFlags* = set[TRenderFlag] TRenderTok* = object - kind*: TTokType + kind*: TokType length*: int16 sym*: PSym @@ -118,7 +118,7 @@ proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags; config: ConfigRef) = g.inGenericParams = false g.config = config -proc addTok(g: var TSrcGen, kind: TTokType, s: string; sym: PSym = nil) = +proc addTok(g: var TSrcGen, kind: TokType, s: string; sym: PSym = nil) = setLen(g.tokens, g.tokens.len + 1) g.tokens[^1].kind = kind g.tokens[^1].length = int16(s.len) @@ -178,7 +178,7 @@ proc dedent(g: var TSrcGen) = dec(g.pendingNL, IndentWidth) dec(g.lineLen, IndentWidth) -proc put(g: var TSrcGen, kind: TTokType, s: string; sym: PSym = nil) = +proc put(g: var TSrcGen, kind: TokType, s: string; sym: PSym = nil) = if kind != tkSpaces: addPendingNL(g) if s.len > 0: @@ -250,7 +250,7 @@ proc maxLineLength(s: string): int = inc(lineLen) inc(i) -proc putRawStr(g: var TSrcGen, kind: TTokType, s: string) = +proc putRawStr(g: var TSrcGen, kind: TokType, s: string) = var i = 0 let hi = s.len - 1 var str = "" @@ -459,8 +459,8 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkDo: result = lsons(g, n) + len("do__:_") of nkConstDef, nkIdentDefs: result = lcomma(g, n, 0, - 3) - if n[^2].kind != nkEmpty: result = result + lsub(g, n[^2]) + 2 - if n[^1].kind != nkEmpty: result = result + lsub(g, n[^1]) + 3 + if n[^2].kind != nkEmpty: result += lsub(g, n[^2]) + 2 + if n[^1].kind != nkEmpty: result += lsub(g, n[^1]) + 3 of nkVarTuple: if n[^1].kind == nkEmpty: result = lcomma(g, n, 0, - 2) + len("()") @@ -471,8 +471,8 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkChckRange: result = len("chckRange") + 2 + lcomma(g, n) of nkObjDownConv, nkObjUpConv: result = 2 - if n.len >= 1: result = result + lsub(g, n[0]) - result = result + lcomma(g, n, 1) + if n.len >= 1: result += lsub(g, n[0]) + result += lcomma(g, n, 1) of nkExprColonExpr: result = lsons(g, n) + 2 of nkInfix: result = lsons(g, n) + 2 of nkPrefix: @@ -536,7 +536,7 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkGenericParams: result = lcomma(g, n) + 2 of nkFormalParams: result = lcomma(g, n, 1) + 2 - if n[0].kind != nkEmpty: result = result + lsub(g, n[0]) + 2 + if n[0].kind != nkEmpty: result += lsub(g, n[0]) + 2 of nkExceptBranch: result = lcomma(g, n, 0, -2) + lsub(g, lastSon(n)) + len("except_:_") of nkObjectTy: @@ -575,7 +575,7 @@ proc hasCom(n: PNode): bool = for i in 0.. 0 and s[0] in lexer.SymChars: if n.kind == nkIdent: @@ -855,7 +855,7 @@ proc gident(g: var TSrcGen, n: PNode) = (n.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)): t = tkSymbol else: - t = TTokType(n.ident.id + ord(tkSymbol)) + t = TokType(n.ident.id + ord(tkSymbol)) else: t = tkSymbol else: @@ -1644,7 +1644,7 @@ proc initTokRender*(r: var TSrcGen, n: PNode, renderFlags: TRenderFlags = {}) = initSrcGen(r, renderFlags, newPartialConfigRef()) gsub(r, n) -proc getNextTok*(r: var TSrcGen, kind: var TTokType, literal: var string) = +proc getNextTok*(r: var TSrcGen, kind: var TokType, literal: var string) = if r.idx < r.tokens.len: kind = r.tokens[r.idx].kind let length = r.tokens[r.idx].length.int diff --git a/compiler/renderverbatim.nim b/compiler/renderverbatim.nim index 2dce6824c545..02d4058442fe 100644 --- a/compiler/renderverbatim.nim +++ b/compiler/renderverbatim.nim @@ -107,7 +107,6 @@ proc extractRunnableExamplesSource*(conf: ConfigRef; n: PNode): string = var indent = info.col let numLines = numLines(conf, info.fileIndex).uint16 var lastNonemptyPos = 0 - result = "" var ldata = LineData(lineFirst: first.line.int, conf: conf) visitMultilineStrings(ldata, n[^1]) @@ -116,6 +115,7 @@ proc extractRunnableExamplesSource*(conf: ConfigRef; n: PNode): string = for i in 0.. 0 - if nb == 1: - return parts[0] - result = parts[0] / parts[1] - for i in 2..= 0 and idx < x.len: result = x[int(idx)] else: localError(g.config, n.info, formatErrorIndexBound(idx, x.len-1) & $n) of nkStrLit..nkTripleStrLit: diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 1a7bd9b6bb33..ffeed00d69cd 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -66,7 +66,7 @@ iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym continue let symKind = if q.typ.kind == tyStatic: skConst else: skType var s = newSym(symKind, q.name, getCurrOwner(c), q.info) - s.flags = s.flags + {sfUsed, sfFromGeneric} + s.flags.incl {sfUsed, sfFromGeneric} var t = PType(idTableGet(pt, q.typ)) if t == nil: if tfRetType in q.typ.flags: diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index cd5a52fe9c1a..64a27d1db25b 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -139,8 +139,7 @@ template quoteStr(s: string): string = "'" & s & "'" proc fieldsPresentInInitExpr(c: PContext, fieldsRecList, initExpr: PNode): string = result = "" for field in directFieldsInRecList(fieldsRecList): - let assignment = locateFieldInInitExpr(c, field.sym, initExpr) - if assignment != nil: + if locateFieldInInitExpr(c, field.sym, initExpr) != nil: if result.len != 0: result.add ", " result.add field.sym.name.s.quoteStr diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index e771e17c4bda..a1afd2c6d5f7 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -336,7 +336,6 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = let s = qualifiedLookUp(c.c, n, {}) if s != nil: if s.owner == c.owner and s.kind == skParam and sfTemplateParam in s.flags: - # oldCheck(c, sfGenSym notin s.flags or c.noGenSym == 0): incl(s.flags, sfUsed) result = newSymNode(s, n.info) onUse(n.info, s) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 6a1c1afc9fd7..95380143142f 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -786,7 +786,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, {sfImportc, sfExportc} * fieldOwner.flags != {} and not hasCaseFields and f.loc.r == nil: f.loc.r = rope(f.name.s) - f.flags = f.flags + ({sfImportc, sfExportc} * fieldOwner.flags) + f.flags.incl {sfImportc, sfExportc} * fieldOwner.flags inc(pos) if containsOrIncl(check, f.name.id): localError(c.config, info, "attempt to redefine: '" & f.name.s & "'") @@ -1211,11 +1211,9 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, if hasType: typ = semParamType(c, a[^2], constraint) - let sym = getCurrOwner(c) - var owner = sym.owner # TODO: Disallow typed/untyped in procs in the compiler/stdlib if kind == skProc and (typ.kind == tyTyped or typ.kind == tyUntyped): - if not isMagic(sym): + if not isMagic(getCurrOwner(c)): localError(c.config, a[^2].info, "'" & typ.sym.name.s & "' is only allowed in templates and macros or magic procs") if hasDefault: diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index e7b289d77aa5..5fa3880af743 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -12,8 +12,7 @@ import ast, astalgo, msgs, types, magicsys, semdata, renderer, options, lineinfos -const - tfInstClearedFlags = {tfHasMeta, tfUnresolved} +const tfInstClearedFlags = {tfHasMeta, tfUnresolved} proc checkPartialConstructedType(conf: ConfigRef; info: TLineInfo, t: PType) = if t.kind in {tyVar, tyLent} and t[0].kind in {tyVar, tyLent}: diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 0902a839b8d2..9a16cc3e0780 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -157,7 +157,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = if t.n.len > 0: let oldFlags = t.sym.flags # Mild hack to prevent endless recursion. - t.sym.flags = t.sym.flags - {sfAnon, sfGenSym} + t.sym.flags.excl {sfAnon, sfGenSym} hashTree(c, t.n, flags + {CoHashTypeInsideNode}) t.sym.flags = oldFlags else: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 4be84d659e04..95231744c5d1 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -265,17 +265,12 @@ proc sumGeneric(t: PType): int = else: return 0 -#var ggDebug: bool - proc complexDisambiguation(a, b: PType): int = # 'a' matches better if *every* argument matches better or equal than 'b'. var winner = 0 for i in 1.. y: winner = 1 @@ -337,14 +332,13 @@ proc argTypeToString(arg: PNode; prefer: TPreferedDesc): string = else: result = arg.typ.typeToString(prefer) -proc describeArgs*(c: PContext, n: PNode, startIdx = 1; - prefer: TPreferedDesc = preferName): string = +proc describeArgs*(c: PContext, n: PNode, startIdx = 1; prefer = preferName): string = result = "" for i in startIdx.. 1: m.callee.n[1].sym else: nil - while a < n.len: + var + a = 1 # iterates over the actual given arguments + f = if m.callee.kind != tyGenericBody: 1 + else: 0 # iterates over formal parameters + arg: PNode # current prepared argument + formalLen = m.callee.n.len + formal = if formalLen > 1: m.callee.n[1].sym else: nil # current routine parameter + container: PNode = nil # constructed container + while a < n.len: c.openShadowScope if a >= formalLen-1 and f < formalLen and m.callee.n[f].typ.isVarargsUntyped: @@ -2493,7 +2478,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, f = max(f, formalLen - n.len + a + 1) elif formal.typ.kind != tyVarargs or container == nil: setSon(m.call, formal.position + 1, arg) - inc(f) + inc f container = nil else: # we end up here if the argument can be converted into the varargs @@ -2511,7 +2496,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, else: c.closeShadowScope - inc(a) + inc a # for some edge cases (see tdont_return_unowned_from_owned test case) m.firstMismatch.arg = a m.firstMismatch.formal = formal diff --git a/compiler/sourcemap.nim b/compiler/sourcemap.nim index 90e34eb73855..2ec40227b73a 100644 --- a/compiler/sourcemap.nim +++ b/compiler/sourcemap.nim @@ -78,8 +78,7 @@ proc text*(sourceNode: SourceNode, depth: int): string = result.add(child.node.text(depth + 1)) -proc `$`*(sourceNode: SourceNode): string = - text(sourceNode, 0) +proc `$`*(sourceNode: SourceNode): string = text(sourceNode, 0) # base64_VLQ @@ -107,8 +106,7 @@ proc encode*(i: int): string = z += 1 -type - TokenState = enum Normal, String, Ident, Mangled +type TokenState = enum Normal, String, Ident, Mangled iterator tokenize*(line: string): (bool, string) = # result = @[] @@ -244,10 +242,10 @@ proc serializeMappings(map: SourceMapGenerator, mappings: seq[Mapping]): string var previous = Mapping(generated: (line: 1, column: 0), original: (line: 0, column: 0), name: "", source: "") var previousSourceId = 0 var previousNameId = 0 - result = "" var next = "" var nameId = 0 var sourceId = 0 + result = "" for z, mapping in mappings: next = "" diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 03c65cd423b9..4943603cee0b 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -33,7 +33,7 @@ # included from sigmatch.nim import algorithm, sets, prefixmatches, lineinfos, parseutils, linter -from wordrecg import wDeprecated, wError, wAddr, wYield, specialWords +from wordrecg import wDeprecated, wError, wAddr, wYield when defined(nimsuggest): import passes, tables, pathutils # importer diff --git a/compiler/syntaxes.nim b/compiler/syntaxes.nim index c3f3bc0dc40b..e745e28ba485 100644 --- a/compiler/syntaxes.nim +++ b/compiler/syntaxes.nim @@ -13,44 +13,20 @@ import strutils, llstream, ast, idents, lexer, options, msgs, parser, filters, filter_tmpl, renderer, lineinfos, pathutils -type - TFilterKind* = enum - filtNone, filtTemplate, filtReplace, filtStrip - TParserKind* = enum - skinStandard, skinEndX - -const - parserNames*: array[TParserKind, string] = ["standard", - "endx"] - filterNames*: array[TFilterKind, string] = ["none", "stdtmpl", "replace", - "strip"] +export Parser, parseAll, parseTopLevelStmt, closeParser type - TParsers* = object - skin*: TParserKind - parser*: TParser - -template config(p: TParsers): ConfigRef = p.parser.lex.config - -proc parseAll*(p: var TParsers): PNode = - case p.skin - of skinStandard: - result = parser.parseAll(p.parser) - of skinEndX: - internalError(p.config, "parser to implement") - -proc parseTopLevelStmt*(p: var TParsers): PNode = - case p.skin - of skinStandard: - result = parser.parseTopLevelStmt(p.parser) - of skinEndX: - internalError(p.config, "parser to implement") + FilterKind = enum + filtNone = "none" + filtTemplate = "stdtmpl" + filtReplace = "replace" + filtStrip = "strip" proc utf8Bom(s: string): int = if s.len >= 3 and s[0] == '\xEF' and s[1] == '\xBB' and s[2] == '\xBF': - result = 3 + 3 else: - result = 0 + 0 proc containsShebang(s: string, i: int): bool = if i+1 < s.len and s[i] == '#' and s[i+1] == '!': @@ -78,23 +54,16 @@ proc parsePipe(filename: AbsoluteFile, inputStream: PLLStream; cache: IdentCache else: inc(i, 2) while i < line.len and line[i] in Whitespace: inc(i) - var q: TParser - parser.openParser(q, filename, llStreamOpen(substr(line, i)), cache, config) - result = parser.parseAll(q) - parser.closeParser(q) + var p: Parser + openParser(p, filename, llStreamOpen(substr(line, i)), cache, config) + result = parseAll(p) + closeParser(p) llStreamClose(s) -proc getFilter(ident: PIdent): TFilterKind = - for i in low(TFilterKind)..high(TFilterKind): - if cmpIgnoreStyle(ident.s, filterNames[i]) == 0: +proc getFilter(ident: PIdent): FilterKind = + for i in FilterKind: + if cmpIgnoreStyle(ident.s, $i) == 0: return i - result = filtNone - -proc getParser(conf: ConfigRef; n: PNode; ident: PIdent): TParserKind = - for i in low(TParserKind)..high(TParserKind): - if cmpIgnoreStyle(ident.s, parserNames[i]) == 0: - return i - localError(conf, n.info, "unknown parser: " & ident.s) proc getCallee(conf: ConfigRef; n: PNode): PIdent = if n.kind in nkCallKinds and n[0].kind == nkIdent: @@ -104,30 +73,28 @@ proc getCallee(conf: ConfigRef; n: PNode): PIdent = else: localError(conf, n.info, "invalid filter: " & renderTree(n)) -proc applyFilter(p: var TParsers, n: PNode, filename: AbsoluteFile, +proc applyFilter(p: var Parser, n: PNode, filename: AbsoluteFile, stdin: PLLStream): PLLStream = - var ident = getCallee(p.config, n) - var f = getFilter(ident) - case f - of filtNone: - p.skin = getParser(p.config, n, ident) - result = stdin - of filtTemplate: - result = filterTmpl(stdin, filename, n, p.config) - of filtStrip: - result = filterStrip(p.config, stdin, filename, n) - of filtReplace: - result = filterReplace(p.config, stdin, filename, n) + var f = getFilter(getCallee(p.lex.config, n)) + result = case f + of filtNone: + stdin + of filtTemplate: + filterTmpl(p.lex.config, stdin, filename, n) + of filtStrip: + filterStrip(p.lex.config, stdin, filename, n) + of filtReplace: + filterReplace(p.lex.config, stdin, filename, n) if f != filtNone: - assert p.config != nil - if p.config.hasHint(hintCodeBegin): - rawMessage(p.config, hintCodeBegin, "") - msgWriteln(p.config, result.s) - rawMessage(p.config, hintCodeEnd, "") + assert p.lex.config != nil + if p.lex.config.hasHint(hintCodeBegin): + rawMessage(p.lex.config, hintCodeBegin, "") + msgWriteln(p.lex.config, result.s) + rawMessage(p.lex.config, hintCodeEnd, "") -proc evalPipe(p: var TParsers, n: PNode, filename: AbsoluteFile, +proc evalPipe(p: var Parser, n: PNode, filename: AbsoluteFile, start: PLLStream): PLLStream = - assert p.config != nil + assert p.lex.config != nil result = start if n.kind == nkEmpty: return if n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s == "|": @@ -141,35 +108,28 @@ proc evalPipe(p: var TParsers, n: PNode, filename: AbsoluteFile, else: result = applyFilter(p, n, filename, result) -proc openParsers*(p: var TParsers, fileIdx: FileIndex, inputstream: PLLStream; +proc openParser*(p: var Parser, fileIdx: FileIndex, inputstream: PLLStream; cache: IdentCache; config: ConfigRef) = assert config != nil - var s: PLLStream - p.skin = skinStandard let filename = toFullPathConsiderDirty(config, fileIdx) var pipe = parsePipe(filename, inputstream, cache, config) - p.config() = config - if pipe != nil: s = evalPipe(p, pipe, filename, inputstream) - else: s = inputstream - case p.skin - of skinStandard, skinEndX: - parser.openParser(p.parser, fileIdx, s, cache, config) - -proc closeParsers*(p: var TParsers) = - parser.closeParser(p.parser) + p.lex.config = config + let s = if pipe != nil: evalPipe(p, pipe, filename, inputstream) + else: inputstream + parser.openParser(p, fileIdx, s, cache, config) -proc setupParsers*(p: var TParsers; fileIdx: FileIndex; cache: IdentCache; +proc setupParser*(p: var Parser; fileIdx: FileIndex; cache: IdentCache; config: ConfigRef): bool = - var f: File let filename = toFullPathConsiderDirty(config, fileIdx) + var f: File if not open(f, filename.string): rawMessage(config, errGenerated, "cannot open file: " & filename.string) return false - openParsers(p, fileIdx, llStreamOpen(f), cache, config) + openParser(p, fileIdx, llStreamOpen(f), cache, config) result = true proc parseFile*(fileIdx: FileIndex; cache: IdentCache; config: ConfigRef): PNode = - var p: TParsers - if setupParsers(p, fileIdx, cache, config): + var p: Parser + if setupParser(p, fileIdx, cache, config): result = parseAll(p) - closeParsers(p) + closeParser(p) diff --git a/compiler/types.nim b/compiler/types.nim index b8452c3ea226..44827aa33cf4 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -469,9 +469,9 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = prefer proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = + result = "" let prefer = getPrefer(prefer) let t = typ - result = "" if t == nil: return if prefer in preferToResolveSymbols and t.sym != nil and sfAnon notin t.sym.flags and t.kind != tySequence: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 4ef510d20b0d..c2a2f6d424b5 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1360,19 +1360,6 @@ proc genMarshalStore(c: PCtx, n: PNode, dest: var TDest) = c.gABx(n, opcMarshalStore, 0, c.genType(n[1].typ)) c.freeTemp(tmp) -const - atomicTypes = {tyBool, tyChar, - tyUntyped, tyTyped, tyTypeDesc, tyStatic, - tyEnum, - tyOrdinal, - tyRange, - tyProc, - tyPointer, tyOpenArray, - tyString, tyCString, - tyInt, tyInt8, tyInt16, tyInt32, tyInt64, - tyFloat, tyFloat32, tyFloat64, tyFloat128, - tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64} - proc unneededIndirection(n: PNode): bool = n.typ.skipTypes(abstractInstOwned-{tyTypeDesc}).kind == tyRef @@ -2200,7 +2187,7 @@ proc optimizeJumps(c: PCtx; start: int) = for iters in countdown(maxIterations, 0): case c.code[d].opcode of opcJmp: - d = d + c.code[d].jmpDiff + d += c.code[d].jmpDiff of opcTJmp, opcFJmp: if c.code[d].regA != reg: break # tjmp x, 23 @@ -2208,12 +2195,12 @@ proc optimizeJumps(c: PCtx; start: int) = # tjmp x, 12 # -- we know 'x' is true, and so can jump to 12+13: if c.code[d].opcode == opc: - d = d + c.code[d].jmpDiff + d += c.code[d].jmpDiff else: # tjmp x, 23 # fjmp x, 22 # We know 'x' is true so skip to the next instruction: - d = d + 1 + d += 1 else: break if d != i + c.code[i].jmpDiff: c.finalJumpTarget(i, d - i) @@ -2221,7 +2208,7 @@ proc optimizeJumps(c: PCtx; start: int) = var d = i + c.code[i].jmpDiff var iters = maxIterations while c.code[d].opcode == opcJmp and iters > 0: - d = d + c.code[d].jmpDiff + d += c.code[d].jmpDiff dec iters if c.code[d].opcode == opcRet: # optimize 'jmp to ret' to 'ret' here diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 454224ae493a..e8d03fe4bd46 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -104,8 +104,7 @@ const wAsm, wBreak, wCase, wConst, wContinue, wDo, wElse, wEnum, wExport, wFor, wIf, wReturn, wStatic, wTemplate, wTry, wWhile, wUsing} - specialWords*: array[low(TSpecialWord)..high(TSpecialWord), string] = ["", - + specialWords*: array[TSpecialWord, string] = ["", "addr", "and", "as", "asm", "bind", "block", "break", "case", "cast", "concept", "const", "continue", "converter", @@ -129,35 +128,35 @@ const "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", + "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", + "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", + "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 + "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", + "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", + "asmNoStackFrame", "implicitStatic", "global", "codegenDecl", "unchecked", + "guard", "locks", "partial", "explain", "liftLocals", "auto", "bool", "catch", "char", "class", "compl", "const_cast", "default", "delete", "double", @@ -184,38 +183,3 @@ proc findStr*(a: openArray[string], s: string): int = if cmpIgnoreStyle(a[i], s) == 0: return i result = - 1 - -proc canonPragmaSpelling*(w: TSpecialWord): string = - case w - of wNoSideEffect: "noSideEffect" - of wImportCompilerProc: "importCompilerProc" - of wIncompleteStruct: "incompleteStruct" - of wCompleteStruct: "completeStruct" - of wRequiresInit: "requiresInit" - of wSideEffect: "sideEffect" - of wLineDir: "lineDir" - of wStackTrace: "stackTrace" - of wLineTrace: "lineTrace" - of wRangeChecks: "rangeChecks" - of wBoundChecks: "boundChecks" - of wOverflowChecks: "overflowChecks" - of wNilChecks: "nilChecks" - of wFloatChecks: "floatChecks" - of wNanChecks: "nanChecks" - of wInfChecks: "infChecks" - of wStyleChecks: "styleChecks" - of wNonReloadable: "nonReloadable" - of wExecuteOnReload: "executeOnReload" - of wDeadCodeElimUnused: "deadCodeElim" - of wCompileTime: "compileTime" - of wFieldChecks: "fieldChecks" - of wLinearScanEnd: "linearScanEnd" - of wComputedGoto: "computedGoto" - of wInjectStmt: "injectStmt" - of wAsmNoStackFrame: "asmNoStackFrame" - of wImplicitStatic: "implicitStatic" - of wCodegenDecl: "codegenDecl" - of wLiftLocals: "liftLocals" - of wLocalPassc: "localPassc" - of wWarningAsError: "warningAsError" - else: specialWords[w] diff --git a/nimpretty/nimpretty.nim b/nimpretty/nimpretty.nim index bedf9f2482ae..0fb2c6a9e7df 100644 --- a/nimpretty/nimpretty.nim +++ b/nimpretty/nimpretty.nim @@ -54,12 +54,12 @@ proc prettyPrint(infile, outfile: string, opt: PrettyOptions) = let f = splitFile(outfile.expandTilde) conf.outFile = RelativeFile f.name & f.ext conf.outDir = toAbsoluteDir f.dir - var p: TParsers - p.parser.em.indWidth = opt.indWidth - if setupParsers(p, fileIdx, newIdentCache(), conf): - p.parser.em.maxLineLen = opt.maxLineLen - discard parseAll(p) - closeParsers(p) + var parser: Parser + parser.em.indWidth = opt.indWidth + if setupParser(parser, fileIdx, newIdentCache(), conf): + parser.em.maxLineLen = opt.maxLineLen + discard parseAll(parser) + closeParser(parser) proc main = var outfile, outdir: string diff --git a/tools/grammar_nanny.nim b/tools/grammar_nanny.nim index d07c2bf8cfc5..397041559a39 100644 --- a/tools/grammar_nanny.nim +++ b/tools/grammar_nanny.nim @@ -16,8 +16,8 @@ proc checkGrammarFileImpl(cache: IdentCache, config: ConfigRef) = if stream != nil: declaredSyms.incl "section" # special case for 'section(RULE)' in the grammar var - L: TLexer - tok: TToken + L: Lexer + tok: Token initToken(tok) openLexer(L, f, stream, cache, config) # load the first token: diff --git a/tools/nimfind.nim b/tools/nimfind.nim index 05980d74088e..4ad5fbb4fb36 100644 --- a/tools/nimfind.nim +++ b/tools/nimfind.nim @@ -195,8 +195,7 @@ proc processCmdLine*(pass: TCmdLinePass, cmd: string; conf: ConfigRef) = of cmdArgument: let info = p.key.split(':') if info.len == 3: - let (dir, file, ext) = info[0].splitFile() - conf.projectName = findProjectNimFile(conf, dir) + conf.projectName = findProjectNimFile(conf, info[0].splitFile.dir) if conf.projectName.len == 0: conf.projectName = info[0] try: conf.m.trackPos = newLineInfo(conf, AbsoluteFile info[0],