commit
1051e8d69d
130 changed files with 1427 additions and 3117 deletions
20
changelog.md
20
changelog.md
|
|
@ -17,6 +17,9 @@
|
||||||
- The ``not nil`` type annotation now has to be enabled explicitly
|
- The ``not nil`` type annotation now has to be enabled explicitly
|
||||||
via ``{.experimental: "notnil"}`` as we are still not pleased with how this
|
via ``{.experimental: "notnil"}`` as we are still not pleased with how this
|
||||||
feature works with Nim's containers.
|
feature works with Nim's containers.
|
||||||
|
- The parser now warns about inconsistent spacing around binary operators as
|
||||||
|
these can easily be confused with unary operators. This warning will likely
|
||||||
|
become an error in the future.
|
||||||
|
|
||||||
|
|
||||||
#### Breaking changes in the standard library
|
#### Breaking changes in the standard library
|
||||||
|
|
@ -38,6 +41,9 @@
|
||||||
|
|
||||||
#### Breaking changes in the compiler
|
#### Breaking changes in the compiler
|
||||||
|
|
||||||
|
- The undocumented ``#? braces`` parsing mode was removed.
|
||||||
|
- The undocumented PHP backend was removed.
|
||||||
|
|
||||||
### Library additions
|
### Library additions
|
||||||
|
|
||||||
- ``re.split`` now also supports the ``maxsplit`` parameter for consistency
|
- ``re.split`` now also supports the ``maxsplit`` parameter for consistency
|
||||||
|
|
@ -63,6 +69,11 @@
|
||||||
fields.
|
fields.
|
||||||
- ``system.SomeReal`` is now called ``SomeFloat`` for consistency and
|
- ``system.SomeReal`` is now called ``SomeFloat`` for consistency and
|
||||||
correctness.
|
correctness.
|
||||||
|
- ``algorithm.smartBinarySearch`` and ``algorithm.binarySearch`` is
|
||||||
|
now joined in ``binarySearch``. ``smartbinarySearch`` is now
|
||||||
|
deprecated.
|
||||||
|
- The `terminal` module now exports additional procs for generating ANSI color
|
||||||
|
codes as strings.
|
||||||
|
|
||||||
### Language additions
|
### Language additions
|
||||||
|
|
||||||
|
|
@ -86,11 +97,18 @@
|
||||||
|
|
||||||
- ``nil`` for strings/seqs is finally gone. Instead the default value for
|
- ``nil`` for strings/seqs is finally gone. Instead the default value for
|
||||||
these is ``"" / @[]``.
|
these is ``"" / @[]``.
|
||||||
|
|
||||||
- Accessing the binary zero terminator in Nim's native strings
|
- Accessing the binary zero terminator in Nim's native strings
|
||||||
is now invalid. Internally a Nim string still has the trailing zero for
|
is now invalid. Internally a Nim string still has the trailing zero for
|
||||||
zero-copy interoperability with ``cstring``. Compile your code with the
|
zero-copy interoperability with ``cstring``. Compile your code with the
|
||||||
next switch ``--laxStrings:on`` if you need a transition period.
|
new switch ``--laxStrings:on`` if you need a transition period.
|
||||||
|
|
||||||
|
- The command syntax now supports keyword arguments after the first comma.
|
||||||
|
|
||||||
|
- Thread-local variables can now be declared inside procs. This implies all
|
||||||
|
the effects of the `global` pragma.
|
||||||
|
|
||||||
|
- Nim now supports `except` clause in the export statement.
|
||||||
|
|
||||||
### Tool changes
|
### Tool changes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1615,6 +1615,19 @@ proc originatingModule*(s: PSym): PSym =
|
||||||
proc isRoutine*(s: PSym): bool {.inline.} =
|
proc isRoutine*(s: PSym): bool {.inline.} =
|
||||||
result = s.kind in skProcKinds
|
result = s.kind in skProcKinds
|
||||||
|
|
||||||
|
proc isCompileTimeProc*(s: PSym): bool {.inline.} =
|
||||||
|
result = s.kind == skMacro or
|
||||||
|
s.kind == skProc and sfCompileTime in s.flags
|
||||||
|
|
||||||
|
proc requiredParams*(s: PSym): int =
|
||||||
|
# Returns the number of required params (without default values)
|
||||||
|
# XXX: Perhaps we can store this in the `offset` field of the
|
||||||
|
# symbol instead?
|
||||||
|
for i in 1 ..< s.typ.len:
|
||||||
|
if s.typ.n[i].sym.ast != nil:
|
||||||
|
return i - 1
|
||||||
|
return s.typ.len - 1
|
||||||
|
|
||||||
proc hasPattern*(s: PSym): bool {.inline.} =
|
proc hasPattern*(s: PSym): bool {.inline.} =
|
||||||
result = isRoutine(s) and s.ast.sons[patternPos].kind != nkEmpty
|
result = isRoutine(s) and s.ast.sons[patternPos].kind != nkEmpty
|
||||||
|
|
||||||
|
|
@ -1671,7 +1684,7 @@ proc isException*(t: PType): bool =
|
||||||
|
|
||||||
var base = t
|
var base = t
|
||||||
while base != nil:
|
while base != nil:
|
||||||
if base.sym.magic == mException:
|
if base.sym != nil and base.sym.magic == mException:
|
||||||
return true
|
return true
|
||||||
base = base.lastSon
|
base = base.lastSon
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
|
|
@ -69,22 +69,22 @@ proc debug*(n: PNode) {.deprecated.}
|
||||||
|
|
||||||
template mdbg*: bool {.dirty.} =
|
template mdbg*: bool {.dirty.} =
|
||||||
when compiles(c.module):
|
when compiles(c.module):
|
||||||
c.module.fileIdx == gProjectMainIdx
|
c.module.fileIdx.int32 == gProjectMainIdx
|
||||||
elif compiles(c.c.module):
|
elif compiles(c.c.module):
|
||||||
c.c.module.fileIdx == gProjectMainIdx
|
c.c.module.fileIdx.int32 == gProjectMainIdx
|
||||||
elif compiles(m.c.module):
|
elif compiles(m.c.module):
|
||||||
m.c.module.fileIdx == gProjectMainIdx
|
m.c.module.fileIdx.int32 == gProjectMainIdx
|
||||||
elif compiles(cl.c.module):
|
elif compiles(cl.c.module):
|
||||||
cl.c.module.fileIdx == gProjectMainIdx
|
cl.c.module.fileIdx.int32 == gProjectMainIdx
|
||||||
elif compiles(p):
|
elif compiles(p):
|
||||||
when compiles(p.lex):
|
when compiles(p.lex):
|
||||||
p.lex.fileIdx == gProjectMainIdx
|
p.lex.fileIdx.int32 == gProjectMainIdx
|
||||||
else:
|
else:
|
||||||
p.module.module.fileIdx == gProjectMainIdx
|
p.module.module.fileIdx.int32 == gProjectMainIdx
|
||||||
elif compiles(m.module.fileIdx):
|
elif compiles(m.module.fileIdx):
|
||||||
m.module.fileIdx == gProjectMainIdx
|
m.module.fileIdx.int32 == gProjectMainIdx
|
||||||
elif compiles(L.fileIdx):
|
elif compiles(L.fileIdx):
|
||||||
L.fileIdx == gProjectMainIdx
|
L.fileIdx.int32 == gProjectMainIdx
|
||||||
else:
|
else:
|
||||||
error()
|
error()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,7 @@ proc rdCharLoc(a: TLoc): Rope =
|
||||||
|
|
||||||
proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
|
proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
|
||||||
takeAddr: bool) =
|
takeAddr: bool) =
|
||||||
if p.module.compileToCpp and t.isException:
|
if p.module.compileToCpp and t.isException and not isDefined("noCppExceptions"):
|
||||||
# init vtable in Exception object for polymorphic exceptions
|
# init vtable in Exception object for polymorphic exceptions
|
||||||
includeHeader(p.module, "<new>")
|
includeHeader(p.module, "<new>")
|
||||||
linefmt(p, section, "new ($1) $2;$n", rdLoc(a), getTypeDesc(p.module, t))
|
linefmt(p, section, "new ($1) $2;$n", rdLoc(a), getTypeDesc(p.module, t))
|
||||||
|
|
@ -746,7 +746,7 @@ proc genProcAux(m: BModule, prc: PSym) =
|
||||||
else:
|
else:
|
||||||
fillResult(resNode)
|
fillResult(resNode)
|
||||||
assignParam(p, res)
|
assignParam(p, res)
|
||||||
resetLoc(p, res.loc)
|
if sfNoInit notin prc.flags: resetLoc(p, res.loc)
|
||||||
if skipTypes(res.typ, abstractInst).kind == tyArray:
|
if skipTypes(res.typ, abstractInst).kind == tyArray:
|
||||||
#incl(res.loc.flags, lfIndirect)
|
#incl(res.loc.flags, lfIndirect)
|
||||||
res.loc.storage = OnUnknown
|
res.loc.storage = OnUnknown
|
||||||
|
|
|
||||||
|
|
@ -430,6 +430,7 @@ proc injectDestructorCalls*(owner: PSym; n: PNode): PNode =
|
||||||
c.tmp.typ = c.tmpObj
|
c.tmp.typ = c.tmpObj
|
||||||
c.destroys = newNodeI(nkStmtList, n.info)
|
c.destroys = newNodeI(nkStmtList, n.info)
|
||||||
c.topLevelVars = newNodeI(nkVarSection, n.info)
|
c.topLevelVars = newNodeI(nkVarSection, n.info)
|
||||||
|
c.toDropBit = initTable[int, PSym]()
|
||||||
let cfg = constructCfg(owner, n)
|
let cfg = constructCfg(owner, n)
|
||||||
shallowCopy(c.g, cfg)
|
shallowCopy(c.g, cfg)
|
||||||
c.jumpTargets = initIntSet()
|
c.jumpTargets = initIntSet()
|
||||||
|
|
|
||||||
|
|
@ -790,7 +790,7 @@ proc writeOutputJson*(d: PDoc, filename, outExt: string,
|
||||||
discard "fixme: error report"
|
discard "fixme: error report"
|
||||||
|
|
||||||
proc commandDoc*() =
|
proc commandDoc*() =
|
||||||
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
|
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache(), newConfigRef())
|
||||||
if ast == nil: return
|
if ast == nil: return
|
||||||
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
||||||
d.hasToc = true
|
d.hasToc = true
|
||||||
|
|
@ -840,7 +840,7 @@ proc commandRst2TeX*() =
|
||||||
commandRstAux(gProjectFull, TexExt)
|
commandRstAux(gProjectFull, TexExt)
|
||||||
|
|
||||||
proc commandJson*() =
|
proc commandJson*() =
|
||||||
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
|
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache(), newConfigRef())
|
||||||
if ast == nil: return
|
if ast == nil: return
|
||||||
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
||||||
d.hasToc = true
|
d.hasToc = true
|
||||||
|
|
@ -855,7 +855,7 @@ proc commandJson*() =
|
||||||
writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false)
|
writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false)
|
||||||
|
|
||||||
proc commandTags*() =
|
proc commandTags*() =
|
||||||
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache())
|
var ast = parseFile(gProjectMainIdx.FileIndex, newIdentCache(), newConfigRef())
|
||||||
if ast == nil: return
|
if ast == nil: return
|
||||||
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
var d = newDocumentor(gProjectFull, options.gConfigVars)
|
||||||
d.hasToc = true
|
d.hasToc = true
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ proc evalTemplateArgs(n: PNode, s: PSym; fromHlo: bool): PNode =
|
||||||
# if the template has zero arguments, it can be called without ``()``
|
# if the template has zero arguments, it can be called without ``()``
|
||||||
# `n` is then a nkSym or something similar
|
# `n` is then a nkSym or something similar
|
||||||
var totalParams = case n.kind
|
var totalParams = case n.kind
|
||||||
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit: n.len-1
|
of nkCallKinds: n.len-1
|
||||||
else: 0
|
else: 0
|
||||||
|
|
||||||
var
|
var
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ proc scanPar(p: var TTmplParser, d: int) =
|
||||||
let hi = p.x.len - 1
|
let hi = p.x.len - 1
|
||||||
while i <= hi:
|
while i <= hi:
|
||||||
case p.x[i]
|
case p.x[i]
|
||||||
of '\0': break
|
|
||||||
of '(': inc(p.par)
|
of '(': inc(p.par)
|
||||||
of ')': dec(p.par)
|
of ')': dec(p.par)
|
||||||
of '[': inc(p.bracket)
|
of '[': inc(p.bracket)
|
||||||
|
|
@ -64,16 +63,22 @@ const
|
||||||
|
|
||||||
proc parseLine(p: var TTmplParser) =
|
proc parseLine(p: var TTmplParser) =
|
||||||
var j = 0
|
var j = 0
|
||||||
while p.x[j] == ' ': inc(j)
|
let hi = p.x.len - 1
|
||||||
|
|
||||||
|
if hi == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
while j <= hi and p.x[j] == ' ': inc(j)
|
||||||
|
|
||||||
if p.x[0] == p.nimDirective and p.x[1] == '?':
|
if p.x[0] == p.nimDirective and p.x[1] == '?':
|
||||||
newLine(p)
|
newLine(p)
|
||||||
elif p.x[j] == p.nimDirective:
|
elif p.x[j] == p.nimDirective:
|
||||||
newLine(p)
|
newLine(p)
|
||||||
inc(j)
|
inc(j)
|
||||||
while p.x[j] == ' ': inc(j)
|
while j <= hi and p.x[j] == ' ': inc(j)
|
||||||
let d = j
|
let d = j
|
||||||
var keyw = ""
|
var keyw = ""
|
||||||
while p.x[j] in PatternChars:
|
while j <= hi and p.x[j] in PatternChars:
|
||||||
add(keyw, p.x[j])
|
add(keyw, p.x[j])
|
||||||
inc(j)
|
inc(j)
|
||||||
|
|
||||||
|
|
@ -127,10 +132,8 @@ proc parseLine(p: var TTmplParser) =
|
||||||
llStreamWrite(p.outp, "(\"")
|
llStreamWrite(p.outp, "(\"")
|
||||||
inc(p.emitPar)
|
inc(p.emitPar)
|
||||||
p.state = psTempl
|
p.state = psTempl
|
||||||
while true:
|
while j <= hi:
|
||||||
case p.x[j]
|
case p.x[j]
|
||||||
of '\0':
|
|
||||||
break
|
|
||||||
of '\x01'..'\x1F', '\x80'..'\xFF':
|
of '\x01'..'\x1F', '\x80'..'\xFF':
|
||||||
llStreamWrite(p.outp, "\\x")
|
llStreamWrite(p.outp, "\\x")
|
||||||
llStreamWrite(p.outp, toHex(ord(p.x[j]), 2))
|
llStreamWrite(p.outp, toHex(ord(p.x[j]), 2))
|
||||||
|
|
@ -157,11 +160,8 @@ proc parseLine(p: var TTmplParser) =
|
||||||
llStreamWrite(p.outp, '(')
|
llStreamWrite(p.outp, '(')
|
||||||
inc(j)
|
inc(j)
|
||||||
var curly = 0
|
var curly = 0
|
||||||
while true:
|
while j <= hi:
|
||||||
case p.x[j]
|
case p.x[j]
|
||||||
of '\0':
|
|
||||||
localError(p.info, errXExpected, "}")
|
|
||||||
break
|
|
||||||
of '{':
|
of '{':
|
||||||
inc(j)
|
inc(j)
|
||||||
inc(curly)
|
inc(curly)
|
||||||
|
|
@ -174,6 +174,9 @@ proc parseLine(p: var TTmplParser) =
|
||||||
else:
|
else:
|
||||||
llStreamWrite(p.outp, p.x[j])
|
llStreamWrite(p.outp, p.x[j])
|
||||||
inc(j)
|
inc(j)
|
||||||
|
if curly > 0:
|
||||||
|
localError(p.info, errXExpected, "}")
|
||||||
|
break
|
||||||
llStreamWrite(p.outp, ')')
|
llStreamWrite(p.outp, ')')
|
||||||
llStreamWrite(p.outp, p.conc)
|
llStreamWrite(p.outp, p.conc)
|
||||||
llStreamWrite(p.outp, '\"')
|
llStreamWrite(p.outp, '\"')
|
||||||
|
|
@ -182,7 +185,7 @@ proc parseLine(p: var TTmplParser) =
|
||||||
llStreamWrite(p.outp, p.conc)
|
llStreamWrite(p.outp, p.conc)
|
||||||
llStreamWrite(p.outp, p.toStr)
|
llStreamWrite(p.outp, p.toStr)
|
||||||
llStreamWrite(p.outp, '(')
|
llStreamWrite(p.outp, '(')
|
||||||
while p.x[j] in PatternChars:
|
while j <= hi and p.x[j] in PatternChars:
|
||||||
llStreamWrite(p.outp, p.x[j])
|
llStreamWrite(p.outp, p.x[j])
|
||||||
inc(j)
|
inc(j)
|
||||||
llStreamWrite(p.outp, ')')
|
llStreamWrite(p.outp, ')')
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,13 @@ import
|
||||||
proc evalImport*(c: PContext, n: PNode): PNode
|
proc evalImport*(c: PContext, n: PNode): PNode
|
||||||
proc evalFrom*(c: PContext, n: PNode): PNode
|
proc evalFrom*(c: PContext, n: PNode): PNode
|
||||||
|
|
||||||
|
proc readExceptSet*(n: PNode): IntSet =
|
||||||
|
assert n.kind in {nkImportExceptStmt, nkExportExceptStmt}
|
||||||
|
result = initIntSet()
|
||||||
|
for i in 1 ..< n.len:
|
||||||
|
let ident = lookups.considerQuotedIdent(n[i])
|
||||||
|
result.incl(ident.id)
|
||||||
|
|
||||||
proc importPureEnumField*(c: PContext; s: PSym) =
|
proc importPureEnumField*(c: PContext; s: PSym) =
|
||||||
var check = strTableGet(c.importTable.symbols, s.name)
|
var check = strTableGet(c.importTable.symbols, s.name)
|
||||||
if check == nil:
|
if check == nil:
|
||||||
|
|
@ -198,9 +205,5 @@ proc evalImportExcept*(c: PContext, n: PNode): PNode =
|
||||||
if m != nil:
|
if m != nil:
|
||||||
n.sons[0] = newSymNode(m)
|
n.sons[0] = newSymNode(m)
|
||||||
addDecl(c, m, n.info) # add symbol to symbol table of module
|
addDecl(c, m, n.info) # add symbol to symbol table of module
|
||||||
var exceptSet = initIntSet()
|
importAllSymbolsExcept(c, m, readExceptSet(n))
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
|
||||||
let ident = lookups.considerQuotedIdent(n.sons[i])
|
|
||||||
exceptSet.incl(ident.id)
|
|
||||||
importAllSymbolsExcept(c, m, exceptSet)
|
|
||||||
#importForwarded(c, m.ast, exceptSet)
|
#importForwarded(c, m.ast, exceptSet)
|
||||||
|
|
|
||||||
|
|
@ -144,13 +144,12 @@ type
|
||||||
cache*: IdentCache
|
cache*: IdentCache
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
previousToken: TLineInfo
|
previousToken: TLineInfo
|
||||||
|
config*: ConfigRef
|
||||||
|
|
||||||
when defined(nimpretty):
|
when defined(nimpretty):
|
||||||
var
|
var
|
||||||
gIndentationWidth*: int
|
gIndentationWidth*: int
|
||||||
|
|
||||||
var gLinesCompiled*: int # all lines that have been compiled
|
|
||||||
|
|
||||||
proc getLineInfo*(L: TLexer, tok: TToken): TLineInfo {.inline.} =
|
proc getLineInfo*(L: TLexer, tok: TToken): TLineInfo {.inline.} =
|
||||||
result = newLineInfo(L.fileIdx, tok.line, tok.col)
|
result = newLineInfo(L.fileIdx, tok.line, tok.col)
|
||||||
when defined(nimpretty):
|
when defined(nimpretty):
|
||||||
|
|
@ -222,7 +221,7 @@ proc fillToken(L: var TToken) =
|
||||||
L.commentOffsetB = 0
|
L.commentOffsetB = 0
|
||||||
|
|
||||||
proc openLexer*(lex: var TLexer, fileIdx: FileIndex, inputstream: PLLStream;
|
proc openLexer*(lex: var TLexer, fileIdx: FileIndex, inputstream: PLLStream;
|
||||||
cache: IdentCache) =
|
cache: IdentCache; config: ConfigRef) =
|
||||||
openBaseLexer(lex, inputstream)
|
openBaseLexer(lex, inputstream)
|
||||||
lex.fileIdx = fileidx
|
lex.fileIdx = fileidx
|
||||||
lex.indentAhead = - 1
|
lex.indentAhead = - 1
|
||||||
|
|
@ -231,13 +230,15 @@ proc openLexer*(lex: var TLexer, fileIdx: FileIndex, inputstream: PLLStream;
|
||||||
lex.cache = cache
|
lex.cache = cache
|
||||||
when defined(nimsuggest):
|
when defined(nimsuggest):
|
||||||
lex.previousToken.fileIndex = fileIdx
|
lex.previousToken.fileIndex = fileIdx
|
||||||
|
lex.config = config
|
||||||
|
|
||||||
proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream;
|
proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream;
|
||||||
cache: IdentCache) =
|
cache: IdentCache; config: ConfigRef) =
|
||||||
openLexer(lex, filename.fileInfoIdx, inputstream, cache)
|
openLexer(lex, filename.fileInfoIdx, inputstream, cache, config)
|
||||||
|
|
||||||
proc closeLexer*(lex: var TLexer) =
|
proc closeLexer*(lex: var TLexer) =
|
||||||
inc(gLinesCompiled, lex.lineNumber)
|
if lex.config != nil:
|
||||||
|
inc(lex.config.linesCompiled, lex.lineNumber)
|
||||||
closeBaseLexer(lex)
|
closeBaseLexer(lex)
|
||||||
|
|
||||||
proc getLineInfo(L: TLexer): TLineInfo =
|
proc getLineInfo(L: TLexer): TLineInfo =
|
||||||
|
|
@ -576,17 +577,18 @@ proc getNumber(L: var TLexer, result: var TToken) =
|
||||||
result.iNumber = parseBiggestInt(result.literal)
|
result.iNumber = parseBiggestInt(result.literal)
|
||||||
|
|
||||||
# Explicit bounds checks
|
# Explicit bounds checks
|
||||||
let outOfRange = case result.tokType:
|
let outOfRange =
|
||||||
of tkInt8Lit: (result.iNumber < int8.low or result.iNumber > int8.high)
|
case result.tokType
|
||||||
of tkUInt8Lit: (result.iNumber < BiggestInt(uint8.low) or
|
of tkInt8Lit: (result.iNumber < int8.low or result.iNumber > int8.high)
|
||||||
result.iNumber > BiggestInt(uint8.high))
|
of tkUInt8Lit: (result.iNumber < BiggestInt(uint8.low) or
|
||||||
of tkInt16Lit: (result.iNumber < int16.low or result.iNumber > int16.high)
|
result.iNumber > BiggestInt(uint8.high))
|
||||||
of tkUInt16Lit: (result.iNumber < BiggestInt(uint16.low) or
|
of tkInt16Lit: (result.iNumber < int16.low or result.iNumber > int16.high)
|
||||||
result.iNumber > BiggestInt(uint16.high))
|
of tkUInt16Lit: (result.iNumber < BiggestInt(uint16.low) or
|
||||||
of tkInt32Lit: (result.iNumber < int32.low or result.iNumber > int32.high)
|
result.iNumber > BiggestInt(uint16.high))
|
||||||
of tkUInt32Lit: (result.iNumber < BiggestInt(uint32.low) or
|
of tkInt32Lit: (result.iNumber < int32.low or result.iNumber > int32.high)
|
||||||
result.iNumber > BiggestInt(uint32.high))
|
of tkUInt32Lit: (result.iNumber < BiggestInt(uint32.low) or
|
||||||
else: false
|
result.iNumber > BiggestInt(uint32.high))
|
||||||
|
else: false
|
||||||
|
|
||||||
if outOfRange: lexMessageLitNum(L, errNumberOutOfRange, startpos)
|
if outOfRange: lexMessageLitNum(L, errNumberOutOfRange, startpos)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,9 +129,10 @@ proc commandEval(graph: ModuleGraph; cache: IdentCache; exp: string) =
|
||||||
interactivePasses(graph, cache)
|
interactivePasses(graph, cache)
|
||||||
compileSystemModule(graph, cache)
|
compileSystemModule(graph, cache)
|
||||||
let echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")"
|
let echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")"
|
||||||
evalNim(graph, echoExp.parseString(cache), makeStdinModule(graph), cache)
|
evalNim(graph, echoExp.parseString(cache, graph.config),
|
||||||
|
makeStdinModule(graph), cache)
|
||||||
|
|
||||||
proc commandScan(cache: IdentCache) =
|
proc commandScan(cache: IdentCache, config: ConfigRef) =
|
||||||
var f = addFileExt(mainCommandArg(), NimExt)
|
var f = addFileExt(mainCommandArg(), NimExt)
|
||||||
var stream = llStreamOpen(f, fmRead)
|
var stream = llStreamOpen(f, fmRead)
|
||||||
if stream != nil:
|
if stream != nil:
|
||||||
|
|
@ -139,7 +140,7 @@ proc commandScan(cache: IdentCache) =
|
||||||
L: TLexer
|
L: TLexer
|
||||||
tok: TToken
|
tok: TToken
|
||||||
initToken(tok)
|
initToken(tok)
|
||||||
openLexer(L, f, stream, cache)
|
openLexer(L, f, stream, cache, config)
|
||||||
while true:
|
while true:
|
||||||
rawGetTok(L, tok)
|
rawGetTok(L, tok)
|
||||||
printTok(tok)
|
printTok(tok)
|
||||||
|
|
@ -265,11 +266,11 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) =
|
||||||
of "parse":
|
of "parse":
|
||||||
gCmd = cmdParse
|
gCmd = cmdParse
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
discard parseFile(FileIndex gProjectMainIdx, cache)
|
discard parseFile(FileIndex gProjectMainIdx, cache, graph.config)
|
||||||
of "scan":
|
of "scan":
|
||||||
gCmd = cmdScan
|
gCmd = cmdScan
|
||||||
wantMainModule()
|
wantMainModule()
|
||||||
commandScan(cache)
|
commandScan(cache, graph.config)
|
||||||
msgWriteln("Beware: Indentation tokens depend on the parser's state!")
|
msgWriteln("Beware: Indentation tokens depend on the parser's state!")
|
||||||
of "secret":
|
of "secret":
|
||||||
gCmd = cmdInteractive
|
gCmd = cmdInteractive
|
||||||
|
|
@ -291,7 +292,7 @@ proc mainCommand*(graph: ModuleGraph; cache: IdentCache) =
|
||||||
let usedMem = formatSize(getMaxMem()) & " peakmem"
|
let usedMem = formatSize(getMaxMem()) & " peakmem"
|
||||||
else:
|
else:
|
||||||
let usedMem = formatSize(getTotalMem())
|
let usedMem = formatSize(getTotalMem())
|
||||||
rawMessage(hintSuccessX, [$gLinesCompiled,
|
rawMessage(hintSuccessX, [$graph.config.linesCompiled,
|
||||||
formatFloat(epochTime() - gLastCmdTime, ffDecimal, 3),
|
formatFloat(epochTime() - gLastCmdTime, ffDecimal, 3),
|
||||||
usedMem,
|
usedMem,
|
||||||
if condSyms.isDefined("release"): "Release Build"
|
if condSyms.isDefined("release"): "Release Build"
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
|
||||||
|
|
||||||
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
|
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
|
||||||
cache: IdentCache): PNode {.procvar.} =
|
cache: IdentCache): PNode {.procvar.} =
|
||||||
result = syntaxes.parseFile(fileIdx, cache)
|
result = syntaxes.parseFile(fileIdx, cache, graph.config)
|
||||||
graph.addDep(s, fileIdx)
|
graph.addDep(s, fileIdx)
|
||||||
graph.addIncludeDep(s.position.FileIndex, fileIdx)
|
graph.addIncludeDep(s.position.FileIndex, fileIdx)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ type
|
||||||
warnEachIdentIsTuple, warnShadowIdent,
|
warnEachIdentIsTuple, warnShadowIdent,
|
||||||
warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
|
warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
|
||||||
warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed,
|
warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed,
|
||||||
warnUser,
|
warnInconsistentSpacing, warnUser,
|
||||||
hintSuccess, hintSuccessX,
|
hintSuccess, hintSuccessX,
|
||||||
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
|
||||||
hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
|
hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
|
||||||
|
|
@ -146,7 +146,7 @@ const
|
||||||
errUnknown: "unknown error",
|
errUnknown: "unknown error",
|
||||||
errInternal: "internal error: $1",
|
errInternal: "internal error: $1",
|
||||||
errIllFormedAstX: "illformed AST: $1",
|
errIllFormedAstX: "illformed AST: $1",
|
||||||
errCannotOpenFile: "cannot open \'$1\'",
|
errCannotOpenFile: "cannot open '$1'",
|
||||||
errGenerated: "$1",
|
errGenerated: "$1",
|
||||||
errStringLiteralExpected: "string literal expected",
|
errStringLiteralExpected: "string literal expected",
|
||||||
errIntLiteralExpected: "integer literal expected",
|
errIntLiteralExpected: "integer literal expected",
|
||||||
|
|
@ -160,39 +160,39 @@ const
|
||||||
errNumberOutOfRange: "number $1 out of valid range",
|
errNumberOutOfRange: "number $1 out of valid range",
|
||||||
errNnotAllowedInCharacter: "\\n not allowed in character literal",
|
errNnotAllowedInCharacter: "\\n not allowed in character literal",
|
||||||
errClosingBracketExpected: "closing ']' expected, but end of file reached",
|
errClosingBracketExpected: "closing ']' expected, but end of file reached",
|
||||||
errMissingFinalQuote: "missing final \' for character literal",
|
errMissingFinalQuote: "missing final ' for character literal",
|
||||||
errIdentifierExpected: "identifier expected, but found \'$1\'",
|
errIdentifierExpected: "identifier expected, but found '$1'",
|
||||||
errNewlineExpected: "newline expected, but found \'$1\'",
|
errNewlineExpected: "newline expected, but found '$1'",
|
||||||
errInvalidModuleName: "invalid module name: '$1'",
|
errInvalidModuleName: "invalid module name: '$1'",
|
||||||
errOperatorExpected: "operator expected, but found \'$1\'",
|
errOperatorExpected: "operator expected, but found '$1'",
|
||||||
errTokenExpected: "\'$1\' expected",
|
errTokenExpected: "'$1' expected",
|
||||||
errRecursiveDependencyX: "recursive dependency: \'$1\'",
|
errRecursiveDependencyX: "recursive dependency: '$1'",
|
||||||
errOnOrOffExpected: "\'on\' or \'off\' expected",
|
errOnOrOffExpected: "'on' or 'off' expected",
|
||||||
errNoneSpeedOrSizeExpected: "\'none\', \'speed\' or \'size\' expected",
|
errNoneSpeedOrSizeExpected: "'none', 'speed' or 'size' expected",
|
||||||
errInvalidPragma: "invalid pragma",
|
errInvalidPragma: "invalid pragma",
|
||||||
errUnknownPragma: "unknown pragma: \'$1\'",
|
errUnknownPragma: "unknown pragma: '$1'",
|
||||||
errInvalidDirectiveX: "invalid directive: \'$1\'",
|
errInvalidDirectiveX: "invalid directive: '$1'",
|
||||||
errAtPopWithoutPush: "\'pop\' without a \'push\' pragma",
|
errAtPopWithoutPush: "'pop' without a 'push' pragma",
|
||||||
errEmptyAsm: "empty asm statement",
|
errEmptyAsm: "empty asm statement",
|
||||||
errInvalidIndentation: "invalid indentation",
|
errInvalidIndentation: "invalid indentation",
|
||||||
errExceptionAlreadyHandled: "exception already handled",
|
errExceptionAlreadyHandled: "exception already handled",
|
||||||
errYieldNotAllowedHere: "'yield' only allowed in an iterator",
|
errYieldNotAllowedHere: "'yield' only allowed in an iterator",
|
||||||
errYieldNotAllowedInTryStmt: "'yield' cannot be used within 'try' in a non-inlined iterator",
|
errYieldNotAllowedInTryStmt: "'yield' cannot be used within 'try' in a non-inlined iterator",
|
||||||
errInvalidNumberOfYieldExpr: "invalid number of \'yield\' expressions",
|
errInvalidNumberOfYieldExpr: "invalid number of 'yield' expressions",
|
||||||
errCannotReturnExpr: "current routine cannot return an expression",
|
errCannotReturnExpr: "current routine cannot return an expression",
|
||||||
errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type",
|
errNoReturnWithReturnTypeNotAllowed: "routines with NoReturn pragma are not allowed to have return type",
|
||||||
errAttemptToRedefine: "redefinition of \'$1\'",
|
errAttemptToRedefine: "redefinition of '$1'",
|
||||||
errStmtInvalidAfterReturn: "statement not allowed after \'return\', \'break\', \'raise\', \'continue\' or proc call with noreturn pragma",
|
errStmtInvalidAfterReturn: "statement not allowed after 'return', 'break', 'raise', 'continue' or proc call with noreturn pragma",
|
||||||
errStmtExpected: "statement expected",
|
errStmtExpected: "statement expected",
|
||||||
errInvalidLabel: "\'$1\' is no label",
|
errInvalidLabel: "'$1' is no label",
|
||||||
errInvalidCmdLineOption: "invalid command line option: \'$1\'",
|
errInvalidCmdLineOption: "invalid command line option: '$1'",
|
||||||
errCmdLineArgExpected: "argument for command line option expected: \'$1\'",
|
errCmdLineArgExpected: "argument for command line option expected: '$1'",
|
||||||
errCmdLineNoArgExpected: "invalid argument for command line option: \'$1\'",
|
errCmdLineNoArgExpected: "invalid argument for command line option: '$1'",
|
||||||
errInvalidVarSubstitution: "invalid variable substitution in \'$1\'",
|
errInvalidVarSubstitution: "invalid variable substitution in '$1'",
|
||||||
errUnknownVar: "unknown variable: \'$1\'",
|
errUnknownVar: "unknown variable: '$1'",
|
||||||
errUnknownCcompiler: "unknown C compiler: \'$1\'",
|
errUnknownCcompiler: "unknown C compiler: '$1'",
|
||||||
errOnOrOffExpectedButXFound: "\'on\' or \'off\' expected, but \'$1\' found",
|
errOnOrOffExpectedButXFound: "'on' or 'off' expected, but '$1' found",
|
||||||
errOnOffOrListExpectedButXFound: "\'on\', \'off\' or \'list\' expected, but \'$1\' found",
|
errOnOffOrListExpectedButXFound: "'on', 'off' or 'list' expected, but '$1' found",
|
||||||
errNoneBoehmRefcExpectedButXFound: "'none', 'boehm' or 'refc' expected, but '$1' found",
|
errNoneBoehmRefcExpectedButXFound: "'none', 'boehm' or 'refc' expected, but '$1' found",
|
||||||
errNoneSpeedOrSizeExpectedButXFound: "'none', 'speed' or 'size' expected, but '$1' found",
|
errNoneSpeedOrSizeExpectedButXFound: "'none', 'speed' or 'size' expected, but '$1' found",
|
||||||
errGuiConsoleOrLibExpectedButXFound: "'gui', 'console' or 'lib' expected, but '$1' found",
|
errGuiConsoleOrLibExpectedButXFound: "'gui', 'console' or 'lib' expected, but '$1' found",
|
||||||
|
|
@ -201,19 +201,19 @@ const
|
||||||
errGenOutExpectedButXFound: "'c', 'c++' or 'yaml' expected, but '$1' found",
|
errGenOutExpectedButXFound: "'c', 'c++' or 'yaml' expected, but '$1' found",
|
||||||
errArgsNeedRunOption: "arguments can only be given if the '--run' option is selected",
|
errArgsNeedRunOption: "arguments can only be given if the '--run' option is selected",
|
||||||
errInvalidMultipleAsgn: "multiple assignment is not allowed",
|
errInvalidMultipleAsgn: "multiple assignment is not allowed",
|
||||||
errColonOrEqualsExpected: "\':\' or \'=\' expected, but found \'$1\'",
|
errColonOrEqualsExpected: "':' or '=' expected, but found '$1'",
|
||||||
errExprExpected: "expression expected, but found \'$1\'",
|
errExprExpected: "expression expected, but found '$1'",
|
||||||
errUndeclaredField: "undeclared field: \'$1\'",
|
errUndeclaredField: "undeclared field: '$1'",
|
||||||
errUndeclaredRoutine: "attempting to call undeclared routine: \'$1\'",
|
errUndeclaredRoutine: "attempting to call undeclared routine: '$1'",
|
||||||
errUseQualifier: "ambiguous identifier: \'$1\' -- use a qualifier",
|
errUseQualifier: "ambiguous identifier: '$1' -- use a qualifier",
|
||||||
errTypeExpected: "type expected",
|
errTypeExpected: "type expected",
|
||||||
errSystemNeeds: "system module needs \'$1\'",
|
errSystemNeeds: "system module needs '$1'",
|
||||||
errExecutionOfProgramFailed: "execution of an external program failed: '$1'",
|
errExecutionOfProgramFailed: "execution of an external program failed: '$1'",
|
||||||
errNotOverloadable: "overloaded \'$1\' leads to ambiguous calls",
|
errNotOverloadable: "overloaded '$1' leads to ambiguous calls",
|
||||||
errInvalidArgForX: "invalid argument for \'$1\'",
|
errInvalidArgForX: "invalid argument for '$1'",
|
||||||
errStmtHasNoEffect: "statement has no effect",
|
errStmtHasNoEffect: "statement has no effect",
|
||||||
errXExpectsTypeOrValue: "\'$1\' expects a type or value",
|
errXExpectsTypeOrValue: "'$1' expects a type or value",
|
||||||
errXExpectsArrayType: "\'$1\' expects an array type",
|
errXExpectsArrayType: "'$1' expects an array type",
|
||||||
errIteratorCannotBeInstantiated: "'$1' cannot be instantiated because its body has not been compiled yet",
|
errIteratorCannotBeInstantiated: "'$1' cannot be instantiated because its body has not been compiled yet",
|
||||||
errExprXAmbiguous: "expression '$1' ambiguous in this context",
|
errExprXAmbiguous: "expression '$1' ambiguous in this context",
|
||||||
errConstantDivisionByZero: "division by zero",
|
errConstantDivisionByZero: "division by zero",
|
||||||
|
|
@ -221,26 +221,26 @@ const
|
||||||
errOrdinalOrFloatTypeExpected: "ordinal or float type expected",
|
errOrdinalOrFloatTypeExpected: "ordinal or float type expected",
|
||||||
errOverOrUnderflow: "over- or underflow",
|
errOverOrUnderflow: "over- or underflow",
|
||||||
errCannotEvalXBecauseIncompletelyDefined: "cannot evaluate '$1' because type is not defined completely",
|
errCannotEvalXBecauseIncompletelyDefined: "cannot evaluate '$1' because type is not defined completely",
|
||||||
errChrExpectsRange0_255: "\'chr\' expects an int in the range 0..255",
|
errChrExpectsRange0_255: "'chr' expects an int in the range 0..255",
|
||||||
errDynlibRequiresExportc: "\'dynlib\' requires \'exportc\'",
|
errDynlibRequiresExportc: "'dynlib' requires 'exportc'",
|
||||||
errUndeclaredFieldX: "undeclared field: \'$1\'",
|
errUndeclaredFieldX: "undeclared field: '$1'",
|
||||||
errNilAccess: "attempt to access a nil address",
|
errNilAccess: "attempt to access a nil address",
|
||||||
errIndexOutOfBounds: "index out of bounds",
|
errIndexOutOfBounds: "index out of bounds",
|
||||||
errIndexTypesDoNotMatch: "index types do not match",
|
errIndexTypesDoNotMatch: "index types do not match",
|
||||||
errBracketsInvalidForType: "\'[]\' operator invalid for this type",
|
errBracketsInvalidForType: "'[]' operator invalid for this type",
|
||||||
errValueOutOfSetBounds: "value out of set bounds",
|
errValueOutOfSetBounds: "value out of set bounds",
|
||||||
errFieldInitTwice: "field initialized twice: \'$1\'",
|
errFieldInitTwice: "field initialized twice: '$1'",
|
||||||
errFieldNotInit: "field \'$1\' not initialized",
|
errFieldNotInit: "field '$1' not initialized",
|
||||||
errExprXCannotBeCalled: "expression \'$1\' cannot be called",
|
errExprXCannotBeCalled: "expression '$1' cannot be called",
|
||||||
errExprHasNoType: "expression has no type",
|
errExprHasNoType: "expression has no type",
|
||||||
errExprXHasNoType: "expression \'$1\' has no type (or is ambiguous)",
|
errExprXHasNoType: "expression '$1' has no type (or is ambiguous)",
|
||||||
errCastNotInSafeMode: "\'cast\' not allowed in safe mode",
|
errCastNotInSafeMode: "'cast' not allowed in safe mode",
|
||||||
errExprCannotBeCastToX: "expression cannot be cast to $1",
|
errExprCannotBeCastToX: "expression cannot be cast to $1",
|
||||||
errCommaOrParRiExpected: "',' or ')' expected",
|
errCommaOrParRiExpected: "',' or ')' expected",
|
||||||
errCurlyLeOrParLeExpected: "\'{\' or \'(\' expected",
|
errCurlyLeOrParLeExpected: "'{' or '(' expected",
|
||||||
errSectionExpected: "section (\'type\', \'proc\', etc.) expected",
|
errSectionExpected: "section ('type', 'proc', etc.) expected",
|
||||||
errRangeExpected: "range expected",
|
errRangeExpected: "range expected",
|
||||||
errMagicOnlyInSystem: "\'magic\' only allowed in system module",
|
errMagicOnlyInSystem: "'magic' only allowed in system module",
|
||||||
errPowerOfTwoExpected: "power of two expected",
|
errPowerOfTwoExpected: "power of two expected",
|
||||||
errStringMayNotBeEmpty: "string literal may not be empty",
|
errStringMayNotBeEmpty: "string literal may not be empty",
|
||||||
errCallConvExpected: "calling convention expected",
|
errCallConvExpected: "calling convention expected",
|
||||||
|
|
@ -257,51 +257,51 @@ const
|
||||||
errWrongNumberOfVariables: "wrong number of variables",
|
errWrongNumberOfVariables: "wrong number of variables",
|
||||||
errExprCannotBeRaised: "only a 'ref object' can be raised",
|
errExprCannotBeRaised: "only a 'ref object' can be raised",
|
||||||
errBreakOnlyInLoop: "'break' only allowed in loop construct",
|
errBreakOnlyInLoop: "'break' only allowed in loop construct",
|
||||||
errTypeXhasUnknownSize: "type \'$1\' has unknown size",
|
errTypeXhasUnknownSize: "type '$1' has unknown size",
|
||||||
errConstNeedsConstExpr: "a constant can only be initialized with a constant expression",
|
errConstNeedsConstExpr: "a constant can only be initialized with a constant expression",
|
||||||
errConstNeedsValue: "a constant needs a value",
|
errConstNeedsValue: "a constant needs a value",
|
||||||
errResultCannotBeOpenArray: "the result type cannot be on open array",
|
errResultCannotBeOpenArray: "the result type cannot be on open array",
|
||||||
errSizeTooBig: "computing the type\'s size produced an overflow",
|
errSizeTooBig: "computing the type's size produced an overflow",
|
||||||
errSetTooBig: "set is too large",
|
errSetTooBig: "set is too large",
|
||||||
errBaseTypeMustBeOrdinal: "base type of a set must be an ordinal",
|
errBaseTypeMustBeOrdinal: "base type of a set must be an ordinal",
|
||||||
errInheritanceOnlyWithNonFinalObjects: "inheritance only works with non-final objects",
|
errInheritanceOnlyWithNonFinalObjects: "inheritance only works with non-final objects",
|
||||||
errInheritanceOnlyWithEnums: "inheritance only works with an enum",
|
errInheritanceOnlyWithEnums: "inheritance only works with an enum",
|
||||||
errIllegalRecursionInTypeX: "illegal recursion in type \'$1\'",
|
errIllegalRecursionInTypeX: "illegal recursion in type '$1'",
|
||||||
errCannotInstantiateX: "cannot instantiate: \'$1\'",
|
errCannotInstantiateX: "cannot instantiate: '$1'",
|
||||||
errExprHasNoAddress: "expression has no address",
|
errExprHasNoAddress: "expression has no address",
|
||||||
errXStackEscape: "address of '$1' may not escape its stack frame",
|
errXStackEscape: "address of '$1' may not escape its stack frame",
|
||||||
errVarForOutParamNeededX: "for a \'var\' type a variable needs to be passed; but '$1' is immutable",
|
errVarForOutParamNeededX: "for a 'var' type a variable needs to be passed; but '$1' is immutable",
|
||||||
errPureTypeMismatch: "type mismatch",
|
errPureTypeMismatch: "type mismatch",
|
||||||
errTypeMismatch: "type mismatch: got <",
|
errTypeMismatch: "type mismatch: got <",
|
||||||
errButExpected: "but expected one of: ",
|
errButExpected: "but expected one of: ",
|
||||||
errButExpectedX: "but expected \'$1\'",
|
errButExpectedX: "but expected '$1'",
|
||||||
errAmbiguousCallXYZ: "ambiguous call; both $1 and $2 match for: $3",
|
errAmbiguousCallXYZ: "ambiguous call; both $1 and $2 match for: $3",
|
||||||
errWrongNumberOfArguments: "wrong number of arguments",
|
errWrongNumberOfArguments: "wrong number of arguments",
|
||||||
errWrongNumberOfArgumentsInCall: "wrong number of arguments in call to '$1'",
|
errWrongNumberOfArgumentsInCall: "wrong number of arguments in call to '$1'",
|
||||||
errMissingGenericParamsForTemplate: "'$1' has unspecified generic parameters",
|
errMissingGenericParamsForTemplate: "'$1' has unspecified generic parameters",
|
||||||
errXCannotBePassedToProcVar: "\'$1\' cannot be passed to a procvar",
|
errXCannotBePassedToProcVar: "'$1' cannot be passed to a procvar",
|
||||||
errPragmaOnlyInHeaderOfProcX: "pragmas are only allowed in the header of a proc; redefinition of $1",
|
errPragmaOnlyInHeaderOfProcX: "pragmas are only allowed in the header of a proc; redefinition of $1",
|
||||||
errImplOfXNotAllowed: "implementation of \'$1\' is not allowed",
|
errImplOfXNotAllowed: "implementation of '$1' is not allowed",
|
||||||
errImplOfXexpected: "implementation of \'$1\' expected",
|
errImplOfXexpected: "implementation of '$1' expected",
|
||||||
errNoSymbolToBorrowFromFound: "no symbol to borrow from found",
|
errNoSymbolToBorrowFromFound: "no symbol to borrow from found",
|
||||||
errDiscardValueX: "value of type '$1' has to be discarded",
|
errDiscardValueX: "value of type '$1' has to be discarded",
|
||||||
errInvalidDiscard: "statement returns no value that can be discarded",
|
errInvalidDiscard: "statement returns no value that can be discarded",
|
||||||
errIllegalConvFromXtoY: "conversion from $1 to $2 is invalid",
|
errIllegalConvFromXtoY: "conversion from $1 to $2 is invalid",
|
||||||
errCannotBindXTwice: "cannot bind parameter \'$1\' twice",
|
errCannotBindXTwice: "cannot bind parameter '$1' twice",
|
||||||
errInvalidOrderInArrayConstructor: "invalid order in array constructor",
|
errInvalidOrderInArrayConstructor: "invalid order in array constructor",
|
||||||
errInvalidOrderInEnumX: "invalid order in enum \'$1\'",
|
errInvalidOrderInEnumX: "invalid order in enum '$1'",
|
||||||
errEnumXHasHoles: "enum \'$1\' has holes",
|
errEnumXHasHoles: "enum '$1' has holes",
|
||||||
errExceptExpected: "\'except\' or \'finally\' expected",
|
errExceptExpected: "'except' or 'finally' expected",
|
||||||
errInvalidTry: "after catch all \'except\' or \'finally\' no section may follow",
|
errInvalidTry: "after catch all 'except' or 'finally' no section may follow",
|
||||||
errOptionExpected: "option expected, but found \'$1\'",
|
errOptionExpected: "option expected, but found '$1'",
|
||||||
errXisNoLabel: "\'$1\' is not a label",
|
errXisNoLabel: "'$1' is not a label",
|
||||||
errNotAllCasesCovered: "not all cases are covered",
|
errNotAllCasesCovered: "not all cases are covered",
|
||||||
errUnknownSubstitionVar: "unknown substitution variable: \'$1\'",
|
errUnknownSubstitionVar: "unknown substitution variable: '$1'",
|
||||||
errComplexStmtRequiresInd: "complex statement requires indentation",
|
errComplexStmtRequiresInd: "complex statement requires indentation",
|
||||||
errXisNotCallable: "\'$1\' is not callable",
|
errXisNotCallable: "'$1' is not callable",
|
||||||
errNoPragmasAllowedForX: "no pragmas allowed for $1",
|
errNoPragmasAllowedForX: "no pragmas allowed for $1",
|
||||||
errNoGenericParamsAllowedForX: "no generic parameters allowed for $1",
|
errNoGenericParamsAllowedForX: "no generic parameters allowed for $1",
|
||||||
errInvalidParamKindX: "invalid param kind: \'$1\'",
|
errInvalidParamKindX: "invalid param kind: '$1'",
|
||||||
errDefaultArgumentInvalid: "default argument invalid",
|
errDefaultArgumentInvalid: "default argument invalid",
|
||||||
errNamedParamHasToBeIdent: "named parameter has to be an identifier",
|
errNamedParamHasToBeIdent: "named parameter has to be an identifier",
|
||||||
errNoReturnTypeForX: "no return type allowed for $1",
|
errNoReturnTypeForX: "no return type allowed for $1",
|
||||||
|
|
@ -309,24 +309,24 @@ const
|
||||||
errInvalidPragmaX: "invalid pragma: $1",
|
errInvalidPragmaX: "invalid pragma: $1",
|
||||||
errXNotAllowedHere: "$1 not allowed here",
|
errXNotAllowedHere: "$1 not allowed here",
|
||||||
errInvalidControlFlowX: "invalid control flow: $1",
|
errInvalidControlFlowX: "invalid control flow: $1",
|
||||||
errXisNoType: "invalid type: \'$1\'",
|
errXisNoType: "invalid type: '$1'",
|
||||||
errCircumNeedsPointer: "'[]' needs a pointer or reference type",
|
errCircumNeedsPointer: "'[]' needs a pointer or reference type",
|
||||||
errInvalidExpression: "invalid expression",
|
errInvalidExpression: "invalid expression",
|
||||||
errInvalidExpressionX: "invalid expression: \'$1\'",
|
errInvalidExpressionX: "invalid expression: '$1'",
|
||||||
errEnumHasNoValueX: "enum has no value \'$1\'",
|
errEnumHasNoValueX: "enum has no value '$1'",
|
||||||
errNamedExprExpected: "named expression expected",
|
errNamedExprExpected: "named expression expected",
|
||||||
errNamedExprNotAllowed: "named expression not allowed here",
|
errNamedExprNotAllowed: "named expression not allowed here",
|
||||||
errXExpectsOneTypeParam: "\'$1\' expects one type parameter",
|
errXExpectsOneTypeParam: "'$1' expects one type parameter",
|
||||||
errArrayExpectsTwoTypeParams: "array expects two type parameters",
|
errArrayExpectsTwoTypeParams: "array expects two type parameters",
|
||||||
errInvalidVisibilityX: "invalid visibility: \'$1\'",
|
errInvalidVisibilityX: "invalid visibility: '$1'",
|
||||||
errInitHereNotAllowed: "initialization not allowed here",
|
errInitHereNotAllowed: "initialization not allowed here",
|
||||||
errXCannotBeAssignedTo: "\'$1\' cannot be assigned to",
|
errXCannotBeAssignedTo: "'$1' cannot be assigned to",
|
||||||
errIteratorNotAllowed: "iterators can only be defined at the module\'s top level",
|
errIteratorNotAllowed: "iterators can only be defined at the module's top level",
|
||||||
errXNeedsReturnType: "$1 needs a return type",
|
errXNeedsReturnType: "$1 needs a return type",
|
||||||
errNoReturnTypeDeclared: "no return type declared",
|
errNoReturnTypeDeclared: "no return type declared",
|
||||||
errNoCommand: "no command given",
|
errNoCommand: "no command given",
|
||||||
errInvalidCommandX: "invalid command: \'$1\'",
|
errInvalidCommandX: "invalid command: '$1'",
|
||||||
errXOnlyAtModuleScope: "\'$1\' is only allowed at top level",
|
errXOnlyAtModuleScope: "'$1' is only allowed at top level",
|
||||||
errXNeedsParamObjectType: "'$1' needs a parameter that has an object type",
|
errXNeedsParamObjectType: "'$1' needs a parameter that has an object type",
|
||||||
errTemplateInstantiationTooNested: "template instantiation too nested, try --evalTemplateLimit:N",
|
errTemplateInstantiationTooNested: "template instantiation too nested, try --evalTemplateLimit:N",
|
||||||
errMacroInstantiationTooNested: "macro instantiation too nested, try --evalMacroLimit:N",
|
errMacroInstantiationTooNested: "macro instantiation too nested, try --evalMacroLimit:N",
|
||||||
|
|
@ -334,17 +334,17 @@ const
|
||||||
errInvalidIndexValueForTuple: "invalid index value for tuple subscript",
|
errInvalidIndexValueForTuple: "invalid index value for tuple subscript",
|
||||||
errCommandExpectsFilename: "command expects a filename argument",
|
errCommandExpectsFilename: "command expects a filename argument",
|
||||||
errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file",
|
errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file",
|
||||||
errXExpected: "\'$1\' expected",
|
errXExpected: "'$1' expected",
|
||||||
errTIsNotAConcreteType: "\'$1\' is not a concrete type.",
|
errTIsNotAConcreteType: "'$1' is not a concrete type.",
|
||||||
errCastToANonConcreteType: "cannot cast to a non concrete type: \'$1\'",
|
errCastToANonConcreteType: "cannot cast to a non concrete type: '$1'",
|
||||||
errInvalidSectionStart: "invalid section start",
|
errInvalidSectionStart: "invalid section start",
|
||||||
errGridTableNotImplemented: "grid table is not implemented",
|
errGridTableNotImplemented: "grid table is not implemented",
|
||||||
errGeneralParseError: "general parse error",
|
errGeneralParseError: "general parse error",
|
||||||
errNewSectionExpected: "new section expected",
|
errNewSectionExpected: "new section expected",
|
||||||
errWhitespaceExpected: "whitespace expected, got \'$1\'",
|
errWhitespaceExpected: "whitespace expected, got '$1'",
|
||||||
errXisNoValidIndexFile: "\'$1\' is no valid index file",
|
errXisNoValidIndexFile: "'$1' is no valid index file",
|
||||||
errCannotRenderX: "cannot render reStructuredText element \'$1\'",
|
errCannotRenderX: "cannot render reStructuredText element '$1'",
|
||||||
errVarVarTypeNotAllowed: "type \'var var\' is not allowed",
|
errVarVarTypeNotAllowed: "type 'var var' is not allowed",
|
||||||
errInstantiateXExplicitly: "instantiate '$1' explicitly",
|
errInstantiateXExplicitly: "instantiate '$1' explicitly",
|
||||||
errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator",
|
errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator",
|
||||||
errUsingNoSymbol: "'$1' is not a variable, constant or a proc name",
|
errUsingNoSymbol: "'$1' is not a variable, constant or a proc name",
|
||||||
|
|
@ -354,26 +354,26 @@ const
|
||||||
"A destructor must be associated will all instantiations of a generic type",
|
"A destructor must be associated will all instantiations of a generic type",
|
||||||
errInlineIteratorsAsProcParams: "inline iterators can be used as parameters only for " &
|
errInlineIteratorsAsProcParams: "inline iterators can be used as parameters only for " &
|
||||||
"templates, macros and other inline iterators",
|
"templates, macros and other inline iterators",
|
||||||
errXExpectsTwoArguments: "\'$1\' expects two arguments",
|
errXExpectsTwoArguments: "'$1' expects two arguments",
|
||||||
errXExpectsObjectTypes: "\'$1\' expects object types",
|
errXExpectsObjectTypes: "'$1' expects object types",
|
||||||
errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype",
|
errXcanNeverBeOfThisSubtype: "'$1' can never be of this subtype",
|
||||||
errTooManyIterations: "interpretation requires too many iterations; " &
|
errTooManyIterations: "interpretation requires too many iterations; " &
|
||||||
"if you are sure this is not a bug in your code edit " &
|
"if you are sure this is not a bug in your code edit " &
|
||||||
"compiler/vmdef.MaxLoopIterations and rebuild the compiler",
|
"compiler/vmdef.MaxLoopIterations and rebuild the compiler",
|
||||||
errCannotInterpretNodeX: "cannot evaluate \'$1\'",
|
errCannotInterpretNodeX: "cannot evaluate '$1'",
|
||||||
errFieldXNotFound: "field \'$1\' cannot be found",
|
errFieldXNotFound: "field '$1' cannot be found",
|
||||||
errInvalidConversionFromTypeX: "invalid conversion from type \'$1\'",
|
errInvalidConversionFromTypeX: "invalid conversion from type '$1'",
|
||||||
errAssertionFailed: "assertion failed",
|
errAssertionFailed: "assertion failed",
|
||||||
errCannotGenerateCodeForX: "cannot generate code for \'$1\'",
|
errCannotGenerateCodeForX: "cannot generate code for '$1'",
|
||||||
errXRequiresOneArgument: "$1 requires one parameter",
|
errXRequiresOneArgument: "$1 requires one parameter",
|
||||||
errUnhandledExceptionX: "unhandled exception: $1",
|
errUnhandledExceptionX: "unhandled exception: $1",
|
||||||
errCyclicTree: "macro returned a cyclic abstract syntax tree",
|
errCyclicTree: "macro returned a cyclic abstract syntax tree",
|
||||||
errXisNoMacroOrTemplate: "\'$1\' is no macro or template",
|
errXisNoMacroOrTemplate: "'$1' is no macro or template",
|
||||||
errXhasSideEffects: "\'$1\' can have side effects",
|
errXhasSideEffects: "'$1' can have side effects",
|
||||||
errIteratorExpected: "iterator within for loop context expected",
|
errIteratorExpected: "iterator within for loop context expected",
|
||||||
errLetNeedsInit: "'let' symbol requires an initialization",
|
errLetNeedsInit: "'let' symbol requires an initialization",
|
||||||
errThreadvarCannotInit: "a thread var cannot be initialized explicitly; this would only run for the main thread",
|
errThreadvarCannotInit: "a thread var cannot be initialized explicitly; this would only run for the main thread",
|
||||||
errWrongSymbolX: "usage of \'$1\' is a user-defined error",
|
errWrongSymbolX: "usage of '$1' is a user-defined error",
|
||||||
errIllegalCaptureX: "illegal capture '$1'",
|
errIllegalCaptureX: "illegal capture '$1'",
|
||||||
errXCannotBeClosure: "'$1' cannot have 'closure' calling convention",
|
errXCannotBeClosure: "'$1' cannot have 'closure' calling convention",
|
||||||
errXMustBeCompileTime: "'$1' can only be used in compile-time context",
|
errXMustBeCompileTime: "'$1' can only be used in compile-time context",
|
||||||
|
|
@ -384,22 +384,22 @@ const
|
||||||
"it is used as an operand to another routine and the types " &
|
"it is used as an operand to another routine and the types " &
|
||||||
"of the generic paramers can be inferred from the expected signature.",
|
"of the generic paramers can be inferred from the expected signature.",
|
||||||
errProcHasNoConcreteType: "'$1' doesn't have a concrete type, due to unspecified generic parameters.",
|
errProcHasNoConcreteType: "'$1' doesn't have a concrete type, due to unspecified generic parameters.",
|
||||||
errCompilerDoesntSupportTarget: "The current compiler \'$1\' doesn't support the requested compilation target",
|
errCompilerDoesntSupportTarget: "The current compiler '$1' doesn't support the requested compilation target",
|
||||||
errInOutFlagNotExtern: "The `$1` modifier can be used only with imported types",
|
errInOutFlagNotExtern: "The `$1` modifier can be used only with imported types",
|
||||||
errUser: "$1",
|
errUser: "$1",
|
||||||
warnCannotOpenFile: "cannot open \'$1\'",
|
warnCannotOpenFile: "cannot open '$1'",
|
||||||
warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored",
|
warnOctalEscape: "octal escape sequences do not exist; leading zero is ignored",
|
||||||
warnXIsNeverRead: "\'$1\' is never read",
|
warnXIsNeverRead: "'$1' is never read",
|
||||||
warnXmightNotBeenInit: "\'$1\' might not have been initialized",
|
warnXmightNotBeenInit: "'$1' might not have been initialized",
|
||||||
warnDeprecated: "$1 is deprecated",
|
warnDeprecated: "$1 is deprecated",
|
||||||
warnConfigDeprecated: "config file '$1' is deprecated",
|
warnConfigDeprecated: "config file '$1' is deprecated",
|
||||||
warnSmallLshouldNotBeUsed: "\'l\' should not be used as an identifier; may look like \'1\' (one)",
|
warnSmallLshouldNotBeUsed: "'l' should not be used as an identifier; may look like '1' (one)",
|
||||||
warnUnknownMagic: "unknown magic \'$1\' might crash the compiler",
|
warnUnknownMagic: "unknown magic '$1' might crash the compiler",
|
||||||
warnRedefinitionOfLabel: "redefinition of label \'$1\'",
|
warnRedefinitionOfLabel: "redefinition of label '$1'",
|
||||||
warnUnknownSubstitutionX: "unknown substitution \'$1\'",
|
warnUnknownSubstitutionX: "unknown substitution '$1'",
|
||||||
warnLanguageXNotSupported: "language \'$1\' not supported",
|
warnLanguageXNotSupported: "language '$1' not supported",
|
||||||
warnFieldXNotSupported: "field \'$1\' not supported",
|
warnFieldXNotSupported: "field '$1' not supported",
|
||||||
warnCommentXIgnored: "comment \'$1\' ignored",
|
warnCommentXIgnored: "comment '$1' ignored",
|
||||||
warnTypelessParam: "'$1' has no type. Typeless parameters are deprecated; only allowed for 'template'",
|
warnTypelessParam: "'$1' has no type. Typeless parameters are deprecated; only allowed for 'template'",
|
||||||
warnUseBase: "use {.base.} for base methods; baseless methods are deprecated",
|
warnUseBase: "use {.base.} for base methods; baseless methods are deprecated",
|
||||||
warnWriteToForeignHeap: "write to foreign heap",
|
warnWriteToForeignHeap: "write to foreign heap",
|
||||||
|
|
@ -416,19 +416,20 @@ const
|
||||||
warnDestructor: "usage of a type with a destructor in a non destructible context. This will become a compile time error in the future.",
|
warnDestructor: "usage of a type with a destructor in a non destructible context. This will become a compile time error in the future.",
|
||||||
warnLockLevel: "$1",
|
warnLockLevel: "$1",
|
||||||
warnResultShadowed: "Special variable 'result' is shadowed.",
|
warnResultShadowed: "Special variable 'result' is shadowed.",
|
||||||
|
warnInconsistentSpacing: "Number of spaces around '$#' is not consistent",
|
||||||
warnUser: "$1",
|
warnUser: "$1",
|
||||||
hintSuccess: "operation successful",
|
hintSuccess: "operation successful",
|
||||||
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)",
|
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)",
|
||||||
hintLineTooLong: "line too long",
|
hintLineTooLong: "line too long",
|
||||||
hintXDeclaredButNotUsed: "\'$1\' is declared but not used",
|
hintXDeclaredButNotUsed: "'$1' is declared but not used",
|
||||||
hintConvToBaseNotNeeded: "conversion to base object is not needed",
|
hintConvToBaseNotNeeded: "conversion to base object is not needed",
|
||||||
hintConvFromXtoItselfNotNeeded: "conversion from $1 to itself is pointless",
|
hintConvFromXtoItselfNotNeeded: "conversion from $1 to itself is pointless",
|
||||||
hintExprAlwaysX: "expression evaluates always to \'$1\'",
|
hintExprAlwaysX: "expression evaluates always to '$1'",
|
||||||
hintQuitCalled: "quit() called",
|
hintQuitCalled: "quit() called",
|
||||||
hintProcessing: "$1",
|
hintProcessing: "$1",
|
||||||
hintCodeBegin: "generated code listing:",
|
hintCodeBegin: "generated code listing:",
|
||||||
hintCodeEnd: "end of listing",
|
hintCodeEnd: "end of listing",
|
||||||
hintConf: "used config file \'$1\'",
|
hintConf: "used config file '$1'",
|
||||||
hintPath: "added path: '$1'",
|
hintPath: "added path: '$1'",
|
||||||
hintConditionAlwaysTrue: "condition is always true: '$1'",
|
hintConditionAlwaysTrue: "condition is always true: '$1'",
|
||||||
hintName: "name should be: '$1'",
|
hintName: "name should be: '$1'",
|
||||||
|
|
@ -454,7 +455,8 @@ const
|
||||||
"TypelessParam", "UseBase", "WriteToForeignHeap",
|
"TypelessParam", "UseBase", "WriteToForeignHeap",
|
||||||
"UnsafeCode", "EachIdentIsTuple", "ShadowIdent",
|
"UnsafeCode", "EachIdentIsTuple", "ShadowIdent",
|
||||||
"ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
|
"ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
|
||||||
"GcMem", "Destructor", "LockLevel", "ResultShadowed", "User"]
|
"GcMem", "Destructor", "LockLevel", "ResultShadowed",
|
||||||
|
"Spacing", "User"]
|
||||||
|
|
||||||
HintsToStr* = ["Success", "SuccessX", "LineTooLong",
|
HintsToStr* = ["Success", "SuccessX", "LineTooLong",
|
||||||
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ proc readConfigFile(filename: string; cache: IdentCache; config: ConfigRef) =
|
||||||
stream = llStreamOpen(filename, fmRead)
|
stream = llStreamOpen(filename, fmRead)
|
||||||
if stream != nil:
|
if stream != nil:
|
||||||
initToken(tok)
|
initToken(tok)
|
||||||
openLexer(L, filename, stream, cache)
|
openLexer(L, filename, stream, cache, config)
|
||||||
tok.tokType = tkEof # to avoid a pointless warning
|
tok.tokType = tkEof # to avoid a pointless warning
|
||||||
confTok(L, tok, config) # read in the first token
|
confTok(L, tok, config) # read in the first token
|
||||||
while tok.tokType != tkEof: parseAssignment(L, tok, config)
|
while tok.tokType != tkEof: parseAssignment(L, tok, config)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
import
|
import
|
||||||
strutils, os, intsets, strtabs
|
strutils, os, intsets, strtabs
|
||||||
|
|
||||||
import "../compiler" / [options, ast, astalgo, msgs, semdata, ropes, idents]
|
import ".." / [options, ast, astalgo, msgs, semdata, ropes, idents]
|
||||||
import prettybase
|
import prettybase
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import strutils, lexbase, streams
|
import strutils, lexbase, streams
|
||||||
import "../compiler" / [ast, msgs, idents]
|
import ".." / [ast, msgs, idents]
|
||||||
from os import splitFile
|
from os import splitFile
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ type
|
||||||
notnil
|
notnil
|
||||||
|
|
||||||
ConfigRef* = ref object ## eventually all global configuration should be moved here
|
ConfigRef* = ref object ## eventually all global configuration should be moved here
|
||||||
|
linesCompiled*: int # all lines that have been compiled
|
||||||
cppDefines*: HashSet[string]
|
cppDefines*: HashSet[string]
|
||||||
headerFile*: string
|
headerFile*: string
|
||||||
features*: set[Feature]
|
features*: set[Feature]
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ when isMainModule:
|
||||||
outp.close
|
outp.close
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, lexer, idents, strutils, ast, astalgo, msgs
|
llstream, lexer, idents, strutils, ast, astalgo, msgs, options
|
||||||
|
|
||||||
type
|
type
|
||||||
TParser* = object # A TParser object represents a file that
|
TParser* = object # A TParser object represents a file that
|
||||||
|
|
@ -84,20 +84,20 @@ proc getTok(p: var TParser) =
|
||||||
p.hasProgress = true
|
p.hasProgress = true
|
||||||
|
|
||||||
proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream,
|
proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream,
|
||||||
cache: IdentCache;
|
cache: IdentCache; config: ConfigRef;
|
||||||
strongSpaces=false) =
|
strongSpaces=false) =
|
||||||
## Open a parser, using the given arguments to set up its internal state.
|
## Open a parser, using the given arguments to set up its internal state.
|
||||||
##
|
##
|
||||||
initToken(p.tok)
|
initToken(p.tok)
|
||||||
openLexer(p.lex, fileIdx, inputStream, cache)
|
openLexer(p.lex, fileIdx, inputStream, cache, config)
|
||||||
getTok(p) # read the first token
|
getTok(p) # read the first token
|
||||||
p.firstTok = true
|
p.firstTok = true
|
||||||
p.strongSpaces = strongSpaces
|
p.strongSpaces = strongSpaces
|
||||||
|
|
||||||
proc openParser*(p: var TParser, filename: string, inputStream: PLLStream,
|
proc openParser*(p: var TParser, filename: string, inputStream: PLLStream,
|
||||||
cache: IdentCache;
|
cache: IdentCache; config: ConfigRef;
|
||||||
strongSpaces=false) =
|
strongSpaces=false) =
|
||||||
openParser(p, filename.fileInfoIdx, inputStream, cache, strongSpaces)
|
openParser(p, filename.fileInfoIdx, inputStream, cache, config, strongSpaces)
|
||||||
|
|
||||||
proc closeParser(p: var TParser) =
|
proc closeParser(p: var TParser) =
|
||||||
## Close a parser, freeing up its resources.
|
## Close a parser, freeing up its resources.
|
||||||
|
|
@ -268,13 +268,9 @@ proc isUnary(p: TParser): bool =
|
||||||
proc checkBinary(p: TParser) {.inline.} =
|
proc checkBinary(p: TParser) {.inline.} =
|
||||||
## Check if the current parser token is a binary operator.
|
## Check if the current parser token is a binary operator.
|
||||||
# we don't check '..' here as that's too annoying
|
# we don't check '..' here as that's too annoying
|
||||||
if p.strongSpaces and p.tok.tokType == tkOpr:
|
if p.tok.tokType == tkOpr:
|
||||||
if p.tok.strongSpaceB > 0 and p.tok.strongSpaceA != p.tok.strongSpaceB:
|
if p.tok.strongSpaceB > 0 and p.tok.strongSpaceA != p.tok.strongSpaceB:
|
||||||
parMessage(p, errGenerated,
|
parMessage(p, warnInconsistentSpacing, prettyTok(p.tok))
|
||||||
"Number of spaces around '$#' not consistent" %
|
|
||||||
prettyTok(p.tok))
|
|
||||||
elif p.tok.strongSpaceA notin {0,1,2,4,8}:
|
|
||||||
parMessage(p, errGenerated, "Number of spaces must be 0,1,2,4 or 8")
|
|
||||||
|
|
||||||
#| module = stmt ^* (';' / IND{=})
|
#| module = stmt ^* (';' / IND{=})
|
||||||
#|
|
#|
|
||||||
|
|
@ -706,10 +702,17 @@ proc namedParams(p: var TParser, callee: PNode,
|
||||||
# progress guaranteed
|
# progress guaranteed
|
||||||
exprColonEqExprListAux(p, endTok, result)
|
exprColonEqExprListAux(p, endTok, result)
|
||||||
|
|
||||||
proc commandParam(p: var TParser): PNode =
|
proc commandParam(p: var TParser, isFirstParam: var bool): PNode =
|
||||||
result = parseExpr(p)
|
result = parseExpr(p)
|
||||||
if p.tok.tokType == tkDo:
|
if p.tok.tokType == tkDo:
|
||||||
result = postExprBlocks(p, result)
|
result = postExprBlocks(p, result)
|
||||||
|
elif p.tok.tokType == tkEquals and not isFirstParam:
|
||||||
|
let lhs = result
|
||||||
|
result = newNodeP(nkExprEqExpr, p)
|
||||||
|
getTok(p)
|
||||||
|
addSon(result, lhs)
|
||||||
|
addSon(result, parseExpr(p))
|
||||||
|
isFirstParam = false
|
||||||
|
|
||||||
proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
|
proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
|
||||||
#| primarySuffix = '(' (exprColonEqExpr comma?)* ')' doBlocks?
|
#| primarySuffix = '(' (exprColonEqExpr comma?)* ')' doBlocks?
|
||||||
|
|
@ -744,17 +747,19 @@ proc primarySuffix(p: var TParser, r: PNode, baseIndent: int): PNode =
|
||||||
# progress guaranteed
|
# progress guaranteed
|
||||||
somePar()
|
somePar()
|
||||||
result = namedParams(p, result, nkCurlyExpr, tkCurlyRi)
|
result = namedParams(p, result, nkCurlyExpr, tkCurlyRi)
|
||||||
of tkSymbol, tkAccent, tkIntLit..tkCharLit, tkNil, tkCast, tkAddr, tkType:
|
of tkSymbol, tkAccent, tkIntLit..tkCharLit, tkNil, tkCast, tkAddr, tkType,
|
||||||
if p.inPragma == 0:
|
tkOpr, tkDotDot:
|
||||||
|
if p.inPragma == 0 and (isUnary(p) or p.tok.tokType notin {tkOpr, tkDotDot}):
|
||||||
# actually parsing {.push hints:off.} as {.push(hints:off).} is a sweet
|
# actually parsing {.push hints:off.} as {.push(hints:off).} is a sweet
|
||||||
# solution, but pragmas.nim can't handle that
|
# solution, but pragmas.nim can't handle that
|
||||||
let a = result
|
let a = result
|
||||||
result = newNodeP(nkCommand, p)
|
result = newNodeP(nkCommand, p)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
|
var isFirstParam = true
|
||||||
when true:
|
when true:
|
||||||
# progress NOT guaranteed
|
# progress NOT guaranteed
|
||||||
p.hasProgress = false
|
p.hasProgress = false
|
||||||
addSon result, commandParam(p)
|
addSon result, commandParam(p, isFirstParam)
|
||||||
if not p.hasProgress: break
|
if not p.hasProgress: break
|
||||||
else:
|
else:
|
||||||
while p.tok.tokType != tkEof:
|
while p.tok.tokType != tkEof:
|
||||||
|
|
@ -1306,17 +1311,18 @@ proc parseExprStmt(p: var TParser): PNode =
|
||||||
addSon(result, b)
|
addSon(result, b)
|
||||||
else:
|
else:
|
||||||
# simpleExpr parsed 'p a' from 'p a, b'?
|
# simpleExpr parsed 'p a' from 'p a, b'?
|
||||||
|
var isFirstParam = false
|
||||||
if p.tok.indent < 0 and p.tok.tokType == tkComma and a.kind == nkCommand:
|
if p.tok.indent < 0 and p.tok.tokType == tkComma and a.kind == nkCommand:
|
||||||
result = a
|
result = a
|
||||||
while true:
|
while true:
|
||||||
getTok(p)
|
getTok(p)
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
addSon(result, commandParam(p))
|
addSon(result, commandParam(p, isFirstParam))
|
||||||
if p.tok.tokType != tkComma: break
|
if p.tok.tokType != tkComma: break
|
||||||
elif p.tok.indent < 0 and isExprStart(p):
|
elif p.tok.indent < 0 and isExprStart(p):
|
||||||
result = newNode(nkCommand, a.info, @[a])
|
result = newNode(nkCommand, a.info, @[a])
|
||||||
while true:
|
while true:
|
||||||
addSon(result, commandParam(p))
|
addSon(result, commandParam(p, isFirstParam))
|
||||||
if p.tok.tokType != tkComma: break
|
if p.tok.tokType != tkComma: break
|
||||||
getTok(p)
|
getTok(p)
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
|
|
@ -2181,8 +2187,8 @@ proc parseTopLevelStmt(p: var TParser): PNode =
|
||||||
if result.kind == nkEmpty: parMessage(p, errExprExpected, p.tok)
|
if result.kind == nkEmpty: parMessage(p, errExprExpected, p.tok)
|
||||||
break
|
break
|
||||||
|
|
||||||
proc parseString*(s: string; cache: IdentCache; filename: string = "";
|
proc parseString*(s: string; cache: IdentCache; config: ConfigRef;
|
||||||
line: int = 0;
|
filename: string = ""; line: int = 0;
|
||||||
errorHandler: TErrorHandler = nil): PNode =
|
errorHandler: TErrorHandler = nil): PNode =
|
||||||
## Parses a string into an AST, returning the top node.
|
## Parses a string into an AST, returning the top node.
|
||||||
## `filename` and `line`, although optional, provide info so that the
|
## `filename` and `line`, although optional, provide info so that the
|
||||||
|
|
@ -2195,7 +2201,7 @@ proc parseString*(s: string; cache: IdentCache; filename: string = "";
|
||||||
# XXX for now the builtin 'parseStmt/Expr' functions do not know about strong
|
# XXX for now the builtin 'parseStmt/Expr' functions do not know about strong
|
||||||
# spaces...
|
# spaces...
|
||||||
parser.lex.errorHandler = errorHandler
|
parser.lex.errorHandler = errorHandler
|
||||||
openParser(parser, filename, stream, cache, false)
|
openParser(parser, filename, stream, cache, config, false)
|
||||||
|
|
||||||
result = parser.parseAll
|
result = parser.parseAll
|
||||||
closeParser(parser)
|
closeParser(parser)
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream,
|
||||||
else:
|
else:
|
||||||
s = stream
|
s = stream
|
||||||
while true:
|
while true:
|
||||||
openParsers(p, fileIdx, s, cache)
|
openParsers(p, fileIdx, s, cache, graph.config)
|
||||||
|
|
||||||
if sfSystemModule notin module.flags:
|
if sfSystemModule notin module.flags:
|
||||||
# XXX what about caching? no processing then? what if I change the
|
# XXX what about caching? no processing then? what if I change the
|
||||||
|
|
|
||||||
1790
compiler/pbraces.nim
1790
compiler/pbraces.nim
File diff suppressed because it is too large
Load diff
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
## The builtin 'system.locals' implemented as a plugin.
|
## The builtin 'system.locals' implemented as a plugin.
|
||||||
|
|
||||||
import "../../" / [pluginsupport, ast, astalgo,
|
import "../../" / [pluginsupport, ast, astalgo,
|
||||||
magicsys, lookups, semdata, lowerings]
|
magicsys, lookups, semdata, lowerings]
|
||||||
|
|
||||||
proc semLocals(c: PContext, n: PNode): PNode =
|
proc semLocals(c: PContext, n: PNode): PNode =
|
||||||
|
|
|
||||||
|
|
@ -777,7 +777,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
|
||||||
incl(sym.flags, sfRegister)
|
incl(sym.flags, sfRegister)
|
||||||
of wThreadVar:
|
of wThreadVar:
|
||||||
noVal(it)
|
noVal(it)
|
||||||
incl(sym.flags, sfThread)
|
incl(sym.flags, {sfThread, sfGlobal})
|
||||||
of wDeadCodeElimUnused: discard # deprecated, dead code elim always on
|
of wDeadCodeElimUnused: discard # deprecated, dead code elim always on
|
||||||
of wNoForward: pragmaNoForward(c, it)
|
of wNoForward: pragmaNoForward(c, it)
|
||||||
of wReorder: pragmaNoForward(c, it, sfReorder)
|
of wReorder: pragmaNoForward(c, it, sfReorder)
|
||||||
|
|
|
||||||
|
|
@ -342,7 +342,7 @@ proc atom(g: TSrcGen; n: PNode): string =
|
||||||
of nkIdent: result = n.ident.s
|
of nkIdent: result = n.ident.s
|
||||||
of nkSym: result = n.sym.name.s
|
of nkSym: result = n.sym.name.s
|
||||||
of nkStrLit: result = ""; result.addQuoted(n.strVal)
|
of nkStrLit: result = ""; result.addQuoted(n.strVal)
|
||||||
of nkRStrLit: result = "r\"" & replace(n.strVal, "\"", "\"\"") & '\"'
|
of nkRStrLit: result = "r\"" & replace(n.strVal, "\"", "\"\"") & '\"'
|
||||||
of nkTripleStrLit: result = "\"\"\"" & n.strVal & "\"\"\""
|
of nkTripleStrLit: result = "\"\"\"" & n.strVal & "\"\"\""
|
||||||
of nkCharLit:
|
of nkCharLit:
|
||||||
result = "\'"
|
result = "\'"
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ proc hasIncludes(n:PNode): bool =
|
||||||
|
|
||||||
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
|
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex;
|
||||||
cache: IdentCache): PNode {.procvar.} =
|
cache: IdentCache): PNode {.procvar.} =
|
||||||
result = syntaxes.parseFile(fileIdx, cache)
|
result = syntaxes.parseFile(fileIdx, cache, graph.config)
|
||||||
graph.addDep(s, fileIdx)
|
graph.addDep(s, fileIdx)
|
||||||
graph.addIncludeDep(FileIndex s.position, fileIdx)
|
graph.addIncludeDep(FileIndex s.position, fileIdx)
|
||||||
|
|
||||||
|
|
@ -273,9 +273,9 @@ proc hasCommand(n: PNode): bool =
|
||||||
of nkStmtList, nkStmtListExpr, nkWhenStmt, nkElifBranch, nkElse,
|
of nkStmtList, nkStmtListExpr, nkWhenStmt, nkElifBranch, nkElse,
|
||||||
nkStaticStmt, nkLetSection, nkConstSection, nkVarSection,
|
nkStaticStmt, nkLetSection, nkConstSection, nkVarSection,
|
||||||
nkIdentDefs:
|
nkIdentDefs:
|
||||||
for a in n:
|
for a in n:
|
||||||
if a.hasCommand:
|
if a.hasCommand:
|
||||||
return true
|
return true
|
||||||
else:
|
else:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ proc listDirs(a: VmArgs, filter: set[PathComponent]) =
|
||||||
proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||||
config: ConfigRef): PEvalContext =
|
config: ConfigRef): PEvalContext =
|
||||||
# For Nimble we need to export 'setupVM'.
|
# For Nimble we need to export 'setupVM'.
|
||||||
result = newCtx(module, cache)
|
result = newCtx(module, cache, config)
|
||||||
result.mode = emRepl
|
result.mode = emRepl
|
||||||
registerAdditionalOps(result)
|
registerAdditionalOps(result)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -313,7 +313,7 @@ proc tryConstExpr(c: PContext, n: PNode): PNode =
|
||||||
msgs.gErrorMax = high(int)
|
msgs.gErrorMax = high(int)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = evalConstExpr(c.module, c.cache, e)
|
result = evalConstExpr(c.module, c.cache, c.graph.config, e)
|
||||||
if result == nil or result.kind == nkEmpty:
|
if result == nil or result.kind == nkEmpty:
|
||||||
result = nil
|
result = nil
|
||||||
else:
|
else:
|
||||||
|
|
@ -334,7 +334,7 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
|
||||||
result = getConstExpr(c.module, e)
|
result = getConstExpr(c.module, e)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
#if e.kind == nkEmpty: globalError(n.info, errConstExprExpected)
|
#if e.kind == nkEmpty: globalError(n.info, errConstExprExpected)
|
||||||
result = evalConstExpr(c.module, c.cache, e)
|
result = evalConstExpr(c.module, c.cache, c.graph.config, e)
|
||||||
if result == nil or result.kind == nkEmpty:
|
if result == nil or result.kind == nkEmpty:
|
||||||
if e.info != n.info:
|
if e.info != n.info:
|
||||||
pushInfoContext(n.info)
|
pushInfoContext(n.info)
|
||||||
|
|
@ -439,7 +439,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
||||||
|
|
||||||
#if c.evalContext == nil:
|
#if c.evalContext == nil:
|
||||||
# c.evalContext = c.createEvalContext(emStatic)
|
# c.evalContext = c.createEvalContext(emStatic)
|
||||||
result = evalMacroCall(c.module, c.cache, n, nOrig, sym)
|
result = evalMacroCall(c.module, c.cache, c.graph.config, n, nOrig, sym)
|
||||||
if efNoSemCheck notin flags:
|
if efNoSemCheck notin flags:
|
||||||
result = semAfterMacroCall(c, n, result, sym, flags)
|
result = semAfterMacroCall(c, n, result, sym, flags)
|
||||||
result = wrapInComesFrom(nOrig.info, sym, result)
|
result = wrapInComesFrom(nOrig.info, sym, result)
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ type
|
||||||
ambiguousSymbols*: IntSet # ids of all ambiguous symbols (cannot
|
ambiguousSymbols*: IntSet # ids of all ambiguous symbols (cannot
|
||||||
# store this info in the syms themselves!)
|
# store this info in the syms themselves!)
|
||||||
inGenericContext*: int # > 0 if we are in a generic type
|
inGenericContext*: int # > 0 if we are in a generic type
|
||||||
|
inStaticContext*: int # > 0 if we are inside a static: block
|
||||||
inUnrolledContext*: int # > 0 if we are unrolling a loop
|
inUnrolledContext*: int # > 0 if we are unrolling a loop
|
||||||
compilesContextId*: int # > 0 if we are in a ``compiles`` magic
|
compilesContextId*: int # > 0 if we are in a ``compiles`` magic
|
||||||
compilesContextIdGenerator*: int
|
compilesContextIdGenerator*: int
|
||||||
|
|
|
||||||
|
|
@ -605,12 +605,12 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
|
||||||
call.add(a)
|
call.add(a)
|
||||||
#echo "NOW evaluating at compile time: ", call.renderTree
|
#echo "NOW evaluating at compile time: ", call.renderTree
|
||||||
if sfCompileTime in callee.flags:
|
if sfCompileTime in callee.flags:
|
||||||
result = evalStaticExpr(c.module, c.cache, call, c.p.owner)
|
result = evalStaticExpr(c.module, c.cache, c.graph.config, call, c.p.owner)
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
localError(n.info, errCannotInterpretNodeX, renderTree(call))
|
localError(n.info, errCannotInterpretNodeX, renderTree(call))
|
||||||
else: result = fixupTypeAfterEval(c, result, n)
|
else: result = fixupTypeAfterEval(c, result, n)
|
||||||
else:
|
else:
|
||||||
result = evalConstExpr(c.module, c.cache, call)
|
result = evalConstExpr(c.module, c.cache, c.graph.config, call)
|
||||||
if result.isNil: result = n
|
if result.isNil: result = n
|
||||||
else: result = fixupTypeAfterEval(c, result, n)
|
else: result = fixupTypeAfterEval(c, result, n)
|
||||||
#if result != n:
|
#if result != n:
|
||||||
|
|
@ -619,7 +619,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
|
||||||
proc semStaticExpr(c: PContext, n: PNode): PNode =
|
proc semStaticExpr(c: PContext, n: PNode): PNode =
|
||||||
let a = semExpr(c, n.sons[0])
|
let a = semExpr(c, n.sons[0])
|
||||||
if a.findUnresolvedStatic != nil: return a
|
if a.findUnresolvedStatic != nil: return a
|
||||||
result = evalStaticExpr(c.module, c.cache, a, c.p.owner)
|
result = evalStaticExpr(c.module, c.cache, c.graph.config, a, c.p.owner)
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
localError(n.info, errCannotInterpretNodeX, renderTree(n))
|
localError(n.info, errCannotInterpretNodeX, renderTree(n))
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
@ -960,18 +960,20 @@ proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
|
||||||
else:
|
else:
|
||||||
result = newSymNode(s, n.info)
|
result = newSymNode(s, n.info)
|
||||||
of skMacro:
|
of skMacro:
|
||||||
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0:
|
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or
|
||||||
|
(n.kind notin nkCallKinds and s.requiredParams > 0):
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = symChoice(c, n, s, scClosed)
|
||||||
else:
|
else:
|
||||||
result = semMacroExpr(c, n, n, s, flags)
|
result = semMacroExpr(c, n, n, s, flags)
|
||||||
of skTemplate:
|
of skTemplate:
|
||||||
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or
|
if efNoEvaluateGeneric in flags and s.ast[genericParamsPos].len > 0 or
|
||||||
|
(n.kind notin nkCallKinds and s.requiredParams > 0) or
|
||||||
sfCustomPragma in sym.flags:
|
sfCustomPragma in sym.flags:
|
||||||
markUsed(n.info, s, c.graph.usageSym)
|
markUsed(n.info, s, c.graph.usageSym)
|
||||||
styleCheckUse(n.info, s)
|
styleCheckUse(n.info, s)
|
||||||
result = newSymNode(s, n.info)
|
result = symChoice(c, n, s, scClosed)
|
||||||
else:
|
else:
|
||||||
result = semTemplateExpr(c, n, s, flags)
|
result = semTemplateExpr(c, n, s, flags)
|
||||||
of skParam:
|
of skParam:
|
||||||
|
|
@ -1778,6 +1780,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
let oldInGenericContext = c.inGenericContext
|
let oldInGenericContext = c.inGenericContext
|
||||||
let oldInUnrolledContext = c.inUnrolledContext
|
let oldInUnrolledContext = c.inUnrolledContext
|
||||||
let oldInGenericInst = c.inGenericInst
|
let oldInGenericInst = c.inGenericInst
|
||||||
|
let oldInStaticContext = c.inStaticContext
|
||||||
let oldProcCon = c.p
|
let oldProcCon = c.p
|
||||||
c.generics = @[]
|
c.generics = @[]
|
||||||
var err: string
|
var err: string
|
||||||
|
|
@ -1792,6 +1795,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
c.inGenericContext = oldInGenericContext
|
c.inGenericContext = oldInGenericContext
|
||||||
c.inUnrolledContext = oldInUnrolledContext
|
c.inUnrolledContext = oldInUnrolledContext
|
||||||
c.inGenericInst = oldInGenericInst
|
c.inGenericInst = oldInGenericInst
|
||||||
|
c.inStaticContext = oldInStaticContext
|
||||||
c.p = oldProcCon
|
c.p = oldProcCon
|
||||||
msgs.setInfoContextLen(oldContextLen)
|
msgs.setInfoContextLen(oldContextLen)
|
||||||
setLen(c.graph.owners, oldOwnerLen)
|
setLen(c.graph.owners, oldOwnerLen)
|
||||||
|
|
@ -2156,9 +2160,25 @@ proc semBlock(c: PContext, n: PNode): PNode =
|
||||||
closeScope(c)
|
closeScope(c)
|
||||||
dec(c.p.nestedBlockCounter)
|
dec(c.p.nestedBlockCounter)
|
||||||
|
|
||||||
|
proc semExportExcept(c: PContext, n: PNode): PNode =
|
||||||
|
let moduleName = semExpr(c, n[0])
|
||||||
|
if moduleName.kind != nkSym or moduleName.sym.kind != skModule:
|
||||||
|
localError(n.info, "The export/except syntax expects a module name")
|
||||||
|
return
|
||||||
|
let exceptSet = readExceptSet(n)
|
||||||
|
let exported = moduleName.sym
|
||||||
|
strTableAdd(c.module.tab, exported)
|
||||||
|
var i: TTabIter
|
||||||
|
var s = initTabIter(i, exported.tab)
|
||||||
|
while s != nil:
|
||||||
|
if s.kind in ExportableSymKinds+{skModule} and
|
||||||
|
s.name.id notin exceptSet:
|
||||||
|
strTableAdd(c.module.tab, s)
|
||||||
|
s = nextIter(i, exported.tab)
|
||||||
|
result = n
|
||||||
|
|
||||||
proc semExport(c: PContext, n: PNode): PNode =
|
proc semExport(c: PContext, n: PNode): PNode =
|
||||||
var x = newNodeI(n.kind, n.info)
|
var x = newNodeI(n.kind, n.info)
|
||||||
#let L = if n.kind == nkExportExceptStmt: L = 1 else: n.len
|
|
||||||
for i in 0..<n.len:
|
for i in 0..<n.len:
|
||||||
let a = n.sons[i]
|
let a = n.sons[i]
|
||||||
var o: TOverloadIter
|
var o: TOverloadIter
|
||||||
|
|
@ -2444,9 +2464,12 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
of nkIncludeStmt:
|
of nkIncludeStmt:
|
||||||
#if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "include")
|
#if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "include")
|
||||||
result = evalInclude(c, n)
|
result = evalInclude(c, n)
|
||||||
of nkExportStmt, nkExportExceptStmt:
|
of nkExportStmt:
|
||||||
if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "export")
|
if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "export")
|
||||||
result = semExport(c, n)
|
result = semExport(c, n)
|
||||||
|
of nkExportExceptStmt:
|
||||||
|
if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "export")
|
||||||
|
result = semExportExcept(c, n)
|
||||||
of nkPragmaBlock:
|
of nkPragmaBlock:
|
||||||
result = semPragmaBlock(c, n)
|
result = semPragmaBlock(c, n)
|
||||||
of nkStaticStmt:
|
of nkStaticStmt:
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,10 @@ proc semBindSym(c: PContext, n: PNode): PNode =
|
||||||
if s != nil:
|
if s != nil:
|
||||||
# we need to mark all symbols:
|
# we need to mark all symbols:
|
||||||
var sc = symChoice(c, id, s, TSymChoiceRule(isMixin.intVal))
|
var sc = symChoice(c, id, s, TSymChoiceRule(isMixin.intVal))
|
||||||
|
if not (c.inStaticContext > 0 or getCurrOwner(c).isCompileTimeProc):
|
||||||
|
# inside regular code, bindSym resolves to the sym-choice
|
||||||
|
# nodes (see tinspectsymbol)
|
||||||
|
return sc
|
||||||
result.add(sc)
|
result.add(sc)
|
||||||
else:
|
else:
|
||||||
errorUndeclaredIdentifier(c, n.sons[1].info, sl.strVal)
|
errorUndeclaredIdentifier(c, n.sons[1].info, sl.strVal)
|
||||||
|
|
|
||||||
|
|
@ -545,7 +545,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||||
b.sons[j] = newSymNode(v)
|
b.sons[j] = newSymNode(v)
|
||||||
checkNilable(v)
|
checkNilable(v)
|
||||||
if sfCompileTime in v.flags: hasCompileTime = true
|
if sfCompileTime in v.flags: hasCompileTime = true
|
||||||
if hasCompileTime: vm.setupCompileTimeVar(c.module, c.cache, result)
|
if hasCompileTime:
|
||||||
|
vm.setupCompileTimeVar(c.module, c.cache, c.graph.config, result)
|
||||||
|
|
||||||
proc semConst(c: PContext, n: PNode): PNode =
|
proc semConst(c: PContext, n: PNode): PNode =
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
|
|
@ -846,7 +847,7 @@ proc checkCovariantParamsUsages(genericType: PType) =
|
||||||
if subType != nil:
|
if subType != nil:
|
||||||
subresult traverseSubTypes(subType)
|
subresult traverseSubTypes(subType)
|
||||||
if result:
|
if result:
|
||||||
error("non-invariant type param used in a proc type: " & $t)
|
error("non-invariant type param used in a proc type: " & $t)
|
||||||
|
|
||||||
of tySequence:
|
of tySequence:
|
||||||
return traverseSubTypes(t[0])
|
return traverseSubTypes(t[0])
|
||||||
|
|
@ -1753,9 +1754,11 @@ proc semPragmaBlock(c: PContext, n: PNode): PNode =
|
||||||
proc semStaticStmt(c: PContext, n: PNode): PNode =
|
proc semStaticStmt(c: PContext, n: PNode): PNode =
|
||||||
#echo "semStaticStmt"
|
#echo "semStaticStmt"
|
||||||
#writeStackTrace()
|
#writeStackTrace()
|
||||||
|
inc c.inStaticContext
|
||||||
let a = semStmt(c, n.sons[0])
|
let a = semStmt(c, n.sons[0])
|
||||||
|
dec c.inStaticContext
|
||||||
n.sons[0] = a
|
n.sons[0] = a
|
||||||
evalStaticStmt(c.module, c.cache, a, c.p.owner)
|
evalStaticStmt(c.module, c.cache, c.graph.config, a, c.p.owner)
|
||||||
result = newNodeI(nkDiscardStmt, n.info, 1)
|
result = newNodeI(nkDiscardStmt, n.info, 1)
|
||||||
result.sons[0] = emptyNode
|
result.sons[0] = emptyNode
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1962,7 +1962,8 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
|
||||||
inc(m.genericMatches)
|
inc(m.genericMatches)
|
||||||
if arg.typ == nil:
|
if arg.typ == nil:
|
||||||
result = arg
|
result = arg
|
||||||
elif skipTypes(arg.typ, abstractVar-{tyTypeDesc}).kind == tyTuple:
|
elif skipTypes(arg.typ, abstractVar-{tyTypeDesc}).kind == tyTuple or
|
||||||
|
m.inheritancePenalty > 0:
|
||||||
result = implicitConv(nkHiddenSubConv, f, arg, m, c)
|
result = implicitConv(nkHiddenSubConv, f, arg, m, c)
|
||||||
elif arg.typ.isEmptyContainer:
|
elif arg.typ.isEmptyContainer:
|
||||||
result = arg.copyTree
|
result = arg.copyTree
|
||||||
|
|
@ -2032,8 +2033,9 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
|
||||||
y.calleeSym = m.calleeSym
|
y.calleeSym = m.calleeSym
|
||||||
z.calleeSym = m.calleeSym
|
z.calleeSym = m.calleeSym
|
||||||
var best = -1
|
var best = -1
|
||||||
for i in countup(0, sonsLen(arg) - 1):
|
for i in 0 ..< arg.len:
|
||||||
if arg.sons[i].sym.kind in {skProc, skFunc, skMethod, skConverter, skIterator}:
|
if arg.sons[i].sym.kind in {skProc, skFunc, skMethod, skConverter,
|
||||||
|
skIterator, skMacro, skTemplate}:
|
||||||
copyCandidate(z, m)
|
copyCandidate(z, m)
|
||||||
z.callee = arg.sons[i].typ
|
z.callee = arg.sons[i].typ
|
||||||
if tfUnresolved in z.callee.flags: continue
|
if tfUnresolved in z.callee.flags: continue
|
||||||
|
|
@ -2062,6 +2064,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
|
||||||
x = z
|
x = z
|
||||||
elif cmp == 0:
|
elif cmp == 0:
|
||||||
y = z # z is as good as x
|
y = z # z is as good as x
|
||||||
|
|
||||||
if x.state == csEmpty:
|
if x.state == csEmpty:
|
||||||
result = nil
|
result = nil
|
||||||
elif y.state == csMatch and cmpCandidates(x, y) == 0:
|
elif y.state == csMatch and cmpCandidates(x, y) == 0:
|
||||||
|
|
@ -2070,7 +2073,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
|
||||||
# ambiguous: more than one symbol fits!
|
# ambiguous: more than one symbol fits!
|
||||||
# See tsymchoice_for_expr as an example. 'f.kind == tyExpr' should match
|
# See tsymchoice_for_expr as an example. 'f.kind == tyExpr' should match
|
||||||
# anyway:
|
# anyway:
|
||||||
if f.kind == tyExpr: result = arg
|
if f.kind in {tyExpr, tyStmt}: result = arg
|
||||||
else: result = nil
|
else: result = nil
|
||||||
else:
|
else:
|
||||||
# only one valid interpretation found:
|
# only one valid interpretation found:
|
||||||
|
|
@ -2171,7 +2174,8 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
var formal: PSym = if formalLen > 1: m.callee.n.sons[1].sym else: nil
|
var formal: PSym = if formalLen > 1: m.callee.n.sons[1].sym else: nil
|
||||||
|
|
||||||
while a < n.len:
|
while a < n.len:
|
||||||
if a >= formalLen-1 and formal != nil and formal.typ.isVarargsUntyped:
|
if a >= formalLen-1 and f < formalLen and m.callee.n[f].typ.isVarargsUntyped:
|
||||||
|
formal = m.callee.n.sons[f].sym
|
||||||
incl(marker, formal.position)
|
incl(marker, formal.position)
|
||||||
if container.isNil:
|
if container.isNil:
|
||||||
container = newNodeIT(nkArgList, n.sons[a].info, arrayConstr(c, n.info))
|
container = newNodeIT(nkArgList, n.sons[a].info, arrayConstr(c, n.info))
|
||||||
|
|
|
||||||
|
|
@ -11,17 +11,17 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
|
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
|
||||||
pbraces, filters, filter_tmpl, renderer
|
filters, filter_tmpl, renderer
|
||||||
|
|
||||||
type
|
type
|
||||||
TFilterKind* = enum
|
TFilterKind* = enum
|
||||||
filtNone, filtTemplate, filtReplace, filtStrip
|
filtNone, filtTemplate, filtReplace, filtStrip
|
||||||
TParserKind* = enum
|
TParserKind* = enum
|
||||||
skinStandard, skinStrongSpaces, skinBraces, skinEndX
|
skinStandard, skinStrongSpaces, skinEndX
|
||||||
|
|
||||||
const
|
const
|
||||||
parserNames*: array[TParserKind, string] = ["standard", "strongspaces",
|
parserNames*: array[TParserKind, string] = ["standard", "strongspaces",
|
||||||
"braces", "endx"]
|
"endx"]
|
||||||
filterNames*: array[TFilterKind, string] = ["none", "stdtmpl", "replace",
|
filterNames*: array[TFilterKind, string] = ["none", "stdtmpl", "replace",
|
||||||
"strip"]
|
"strip"]
|
||||||
|
|
||||||
|
|
@ -34,8 +34,6 @@ proc parseAll*(p: var TParsers): PNode =
|
||||||
case p.skin
|
case p.skin
|
||||||
of skinStandard, skinStrongSpaces:
|
of skinStandard, skinStrongSpaces:
|
||||||
result = parser.parseAll(p.parser)
|
result = parser.parseAll(p.parser)
|
||||||
of skinBraces:
|
|
||||||
result = pbraces.parseAll(p.parser)
|
|
||||||
of skinEndX:
|
of skinEndX:
|
||||||
internalError("parser to implement")
|
internalError("parser to implement")
|
||||||
result = ast.emptyNode
|
result = ast.emptyNode
|
||||||
|
|
@ -44,8 +42,6 @@ proc parseTopLevelStmt*(p: var TParsers): PNode =
|
||||||
case p.skin
|
case p.skin
|
||||||
of skinStandard, skinStrongSpaces:
|
of skinStandard, skinStrongSpaces:
|
||||||
result = parser.parseTopLevelStmt(p.parser)
|
result = parser.parseTopLevelStmt(p.parser)
|
||||||
of skinBraces:
|
|
||||||
result = pbraces.parseTopLevelStmt(p.parser)
|
|
||||||
of skinEndX:
|
of skinEndX:
|
||||||
internalError("parser to implement")
|
internalError("parser to implement")
|
||||||
result = ast.emptyNode
|
result = ast.emptyNode
|
||||||
|
|
@ -62,7 +58,8 @@ proc containsShebang(s: string, i: int): bool =
|
||||||
while j < s.len and s[j] in Whitespace: inc(j)
|
while j < s.len and s[j] in Whitespace: inc(j)
|
||||||
result = s[j] == '/'
|
result = s[j] == '/'
|
||||||
|
|
||||||
proc parsePipe(filename: string, inputStream: PLLStream; cache: IdentCache): PNode =
|
proc parsePipe(filename: string, inputStream: PLLStream; cache: IdentCache;
|
||||||
|
config: ConfigRef): PNode =
|
||||||
result = ast.emptyNode
|
result = ast.emptyNode
|
||||||
var s = llStreamOpen(filename, fmRead)
|
var s = llStreamOpen(filename, fmRead)
|
||||||
if s != nil:
|
if s != nil:
|
||||||
|
|
@ -78,7 +75,7 @@ proc parsePipe(filename: string, inputStream: PLLStream; cache: IdentCache): PNo
|
||||||
inc(i, 2)
|
inc(i, 2)
|
||||||
while i < line.len and line[i] in Whitespace: inc(i)
|
while i < line.len and line[i] in Whitespace: inc(i)
|
||||||
var q: TParser
|
var q: TParser
|
||||||
parser.openParser(q, filename, llStreamOpen(substr(line, i)), cache)
|
parser.openParser(q, filename, llStreamOpen(substr(line, i)), cache, config)
|
||||||
result = parser.parseAll(q)
|
result = parser.parseAll(q)
|
||||||
parser.closeParser(q)
|
parser.closeParser(q)
|
||||||
llStreamClose(s)
|
llStreamClose(s)
|
||||||
|
|
@ -139,23 +136,23 @@ proc evalPipe(p: var TParsers, n: PNode, filename: string,
|
||||||
result = applyFilter(p, n, filename, result)
|
result = applyFilter(p, n, filename, result)
|
||||||
|
|
||||||
proc openParsers*(p: var TParsers, fileIdx: FileIndex, inputstream: PLLStream;
|
proc openParsers*(p: var TParsers, fileIdx: FileIndex, inputstream: PLLStream;
|
||||||
cache: IdentCache) =
|
cache: IdentCache; config: ConfigRef) =
|
||||||
var s: PLLStream
|
var s: PLLStream
|
||||||
p.skin = skinStandard
|
p.skin = skinStandard
|
||||||
let filename = fileIdx.toFullPathConsiderDirty
|
let filename = fileIdx.toFullPathConsiderDirty
|
||||||
var pipe = parsePipe(filename, inputstream, cache)
|
var pipe = parsePipe(filename, inputstream, cache, config)
|
||||||
if pipe != nil: s = evalPipe(p, pipe, filename, inputstream)
|
if pipe != nil: s = evalPipe(p, pipe, filename, inputstream)
|
||||||
else: s = inputstream
|
else: s = inputstream
|
||||||
case p.skin
|
case p.skin
|
||||||
of skinStandard, skinBraces, skinEndX:
|
of skinStandard, skinEndX:
|
||||||
parser.openParser(p.parser, fileIdx, s, cache, false)
|
parser.openParser(p.parser, fileIdx, s, cache, config, false)
|
||||||
of skinStrongSpaces:
|
of skinStrongSpaces:
|
||||||
parser.openParser(p.parser, fileIdx, s, cache, true)
|
parser.openParser(p.parser, fileIdx, s, cache, config, true)
|
||||||
|
|
||||||
proc closeParsers*(p: var TParsers) =
|
proc closeParsers*(p: var TParsers) =
|
||||||
parser.closeParser(p.parser)
|
parser.closeParser(p.parser)
|
||||||
|
|
||||||
proc parseFile*(fileIdx: FileIndex; cache: IdentCache): PNode {.procvar.} =
|
proc parseFile*(fileIdx: FileIndex; cache: IdentCache; config: ConfigRef): PNode {.procvar.} =
|
||||||
var
|
var
|
||||||
p: TParsers
|
p: TParsers
|
||||||
f: File
|
f: File
|
||||||
|
|
@ -163,6 +160,6 @@ proc parseFile*(fileIdx: FileIndex; cache: IdentCache): PNode {.procvar.} =
|
||||||
if not open(f, filename):
|
if not open(f, filename):
|
||||||
rawMessage(errCannotOpenFile, filename)
|
rawMessage(errCannotOpenFile, filename)
|
||||||
return
|
return
|
||||||
openParsers(p, fileIdx, llStreamOpen(f), cache)
|
openParsers(p, fileIdx, llStreamOpen(f), cache, config)
|
||||||
result = parseAll(p)
|
result = parseAll(p)
|
||||||
closeParsers(p)
|
closeParsers(p)
|
||||||
|
|
|
||||||
|
|
@ -612,7 +612,7 @@ proc firstOrd*(t: PType): BiggestInt =
|
||||||
else:
|
else:
|
||||||
assert(t.n.sons[0].kind == nkSym)
|
assert(t.n.sons[0].kind == nkSym)
|
||||||
result = t.n.sons[0].sym.position
|
result = t.n.sons[0].sym.position
|
||||||
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic:
|
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred:
|
||||||
result = firstOrd(lastSon(t))
|
result = firstOrd(lastSon(t))
|
||||||
of tyOrdinal:
|
of tyOrdinal:
|
||||||
if t.len > 0: result = firstOrd(lastSon(t))
|
if t.len > 0: result = firstOrd(lastSon(t))
|
||||||
|
|
@ -651,7 +651,7 @@ proc lastOrd*(t: PType; fixedUnsigned = false): BiggestInt =
|
||||||
of tyEnum:
|
of tyEnum:
|
||||||
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
|
assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym)
|
||||||
result = t.n.sons[sonsLen(t.n) - 1].sym.position
|
result = t.n.sons[sonsLen(t.n) - 1].sym.position
|
||||||
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic:
|
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tyStatic, tyInferred:
|
||||||
result = lastOrd(lastSon(t))
|
result = lastOrd(lastSon(t))
|
||||||
of tyProxy: result = 0
|
of tyProxy: result = 0
|
||||||
of tyOrdinal:
|
of tyOrdinal:
|
||||||
|
|
|
||||||
|
|
@ -210,8 +210,14 @@ proc putIntoNode(n: var PNode; x: TFullReg) =
|
||||||
of rkInt: n.intVal = x.intVal
|
of rkInt: n.intVal = x.intVal
|
||||||
of rkFloat: n.floatVal = x.floatVal
|
of rkFloat: n.floatVal = x.floatVal
|
||||||
of rkNode:
|
of rkNode:
|
||||||
if nfIsRef in x.node.flags: n = x.node
|
if nfIsRef in x.node.flags:
|
||||||
else: n[] = x.node[]
|
n = x.node
|
||||||
|
else:
|
||||||
|
let destIsRef = nfIsRef in n.flags
|
||||||
|
n[] = x.node[]
|
||||||
|
# Ref-ness must be kept for the destination
|
||||||
|
if destIsRef:
|
||||||
|
n.flags.incl nfIsRef
|
||||||
of rkRegisterAddr: putIntoNode(n, x.regAddr[])
|
of rkRegisterAddr: putIntoNode(n, x.regAddr[])
|
||||||
of rkNodeAddr: n[] = x.nodeAddr[][]
|
of rkNodeAddr: n[] = x.nodeAddr[][]
|
||||||
|
|
||||||
|
|
@ -1341,8 +1347,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
decodeB(rkNode)
|
decodeB(rkNode)
|
||||||
# c.debug[pc].line.int - countLines(regs[rb].strVal) ?
|
# c.debug[pc].line.int - countLines(regs[rb].strVal) ?
|
||||||
var error: string
|
var error: string
|
||||||
let ast = parseString(regs[rb].node.strVal, c.cache, c.debug[pc].toFullPath,
|
let ast = parseString(regs[rb].node.strVal, c.cache, c.config,
|
||||||
c.debug[pc].line.int,
|
c.debug[pc].toFullPath, c.debug[pc].line.int,
|
||||||
proc (info: TLineInfo; msg: TMsgKind; arg: string) =
|
proc (info: TLineInfo; msg: TMsgKind; arg: string) =
|
||||||
if error.isNil and msg <= msgs.errMax:
|
if error.isNil and msg <= msgs.errMax:
|
||||||
error = formatMsg(info, msg, arg))
|
error = formatMsg(info, msg, arg))
|
||||||
|
|
@ -1355,8 +1361,8 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
of opcParseStmtToAst:
|
of opcParseStmtToAst:
|
||||||
decodeB(rkNode)
|
decodeB(rkNode)
|
||||||
var error: string
|
var error: string
|
||||||
let ast = parseString(regs[rb].node.strVal, c.cache, c.debug[pc].toFullPath,
|
let ast = parseString(regs[rb].node.strVal, c.cache, c.config,
|
||||||
c.debug[pc].line.int,
|
c.debug[pc].toFullPath, c.debug[pc].line.int,
|
||||||
proc (info: TLineInfo; msg: TMsgKind; arg: string) =
|
proc (info: TLineInfo; msg: TMsgKind; arg: string) =
|
||||||
if error.isNil and msg <= msgs.errMax:
|
if error.isNil and msg <= msgs.errMax:
|
||||||
error = formatMsg(info, msg, arg))
|
error = formatMsg(info, msg, arg))
|
||||||
|
|
@ -1643,9 +1649,9 @@ include vmops
|
||||||
var
|
var
|
||||||
globalCtx*: PCtx
|
globalCtx*: PCtx
|
||||||
|
|
||||||
proc setupGlobalCtx(module: PSym; cache: IdentCache) =
|
proc setupGlobalCtx(module: PSym; cache: IdentCache; config: ConfigRef) =
|
||||||
if globalCtx.isNil:
|
if globalCtx.isNil:
|
||||||
globalCtx = newCtx(module, cache)
|
globalCtx = newCtx(module, cache, config)
|
||||||
registerAdditionalOps(globalCtx)
|
registerAdditionalOps(globalCtx)
|
||||||
else:
|
else:
|
||||||
refresh(globalCtx, module)
|
refresh(globalCtx, module)
|
||||||
|
|
@ -1656,7 +1662,7 @@ proc myOpen(graph: ModuleGraph; module: PSym; cache: IdentCache): PPassContext =
|
||||||
#pushStackFrame(c, newStackFrame())
|
#pushStackFrame(c, newStackFrame())
|
||||||
|
|
||||||
# XXX produce a new 'globals' environment here:
|
# XXX produce a new 'globals' environment here:
|
||||||
setupGlobalCtx(module, cache)
|
setupGlobalCtx(module, cache, graph.config)
|
||||||
result = globalCtx
|
result = globalCtx
|
||||||
when hasFFI:
|
when hasFFI:
|
||||||
globalCtx.features = {allowFFI, allowCast}
|
globalCtx.features = {allowFFI, allowCast}
|
||||||
|
|
@ -1677,10 +1683,11 @@ proc myClose(graph: ModuleGraph; c: PPassContext, n: PNode): PNode =
|
||||||
|
|
||||||
const evalPass* = makePass(myOpen, nil, myProcess, myClose)
|
const evalPass* = makePass(myOpen, nil, myProcess, myClose)
|
||||||
|
|
||||||
proc evalConstExprAux(module: PSym; cache: IdentCache; prc: PSym, n: PNode,
|
proc evalConstExprAux(module: PSym; cache: IdentCache;
|
||||||
|
config: ConfigRef; prc: PSym, n: PNode,
|
||||||
mode: TEvalMode): PNode =
|
mode: TEvalMode): PNode =
|
||||||
let n = transformExpr(module, n)
|
let n = transformExpr(module, n)
|
||||||
setupGlobalCtx(module, cache)
|
setupGlobalCtx(module, cache, config)
|
||||||
var c = globalCtx
|
var c = globalCtx
|
||||||
let oldMode = c.mode
|
let oldMode = c.mode
|
||||||
defer: c.mode = oldMode
|
defer: c.mode = oldMode
|
||||||
|
|
@ -1695,17 +1702,17 @@ proc evalConstExprAux(module: PSym; cache: IdentCache; prc: PSym, n: PNode,
|
||||||
result = rawExecute(c, start, tos).regToNode
|
result = rawExecute(c, start, tos).regToNode
|
||||||
if result.info.col < 0: result.info = n.info
|
if result.info.col < 0: result.info = n.info
|
||||||
|
|
||||||
proc evalConstExpr*(module: PSym; cache: IdentCache, e: PNode): PNode =
|
proc evalConstExpr*(module: PSym; cache: IdentCache, config: ConfigRef; e: PNode): PNode =
|
||||||
result = evalConstExprAux(module, cache, nil, e, emConst)
|
result = evalConstExprAux(module, cache, config, nil, e, emConst)
|
||||||
|
|
||||||
proc evalStaticExpr*(module: PSym; cache: IdentCache, e: PNode, prc: PSym): PNode =
|
proc evalStaticExpr*(module: PSym; cache: IdentCache, config: ConfigRef; e: PNode, prc: PSym): PNode =
|
||||||
result = evalConstExprAux(module, cache, prc, e, emStaticExpr)
|
result = evalConstExprAux(module, cache, config, prc, e, emStaticExpr)
|
||||||
|
|
||||||
proc evalStaticStmt*(module: PSym; cache: IdentCache, e: PNode, prc: PSym) =
|
proc evalStaticStmt*(module: PSym; cache: IdentCache, config: ConfigRef; e: PNode, prc: PSym) =
|
||||||
discard evalConstExprAux(module, cache, prc, e, emStaticStmt)
|
discard evalConstExprAux(module, cache, config, prc, e, emStaticStmt)
|
||||||
|
|
||||||
proc setupCompileTimeVar*(module: PSym; cache: IdentCache, n: PNode) =
|
proc setupCompileTimeVar*(module: PSym; cache: IdentCache, config: ConfigRef; n: PNode) =
|
||||||
discard evalConstExprAux(module, cache, nil, n, emStaticStmt)
|
discard evalConstExprAux(module, cache, config, nil, n, emStaticStmt)
|
||||||
|
|
||||||
proc setupMacroParam(x: PNode, typ: PType): TFullReg =
|
proc setupMacroParam(x: PNode, typ: PType): TFullReg =
|
||||||
case typ.kind
|
case typ.kind
|
||||||
|
|
@ -1733,8 +1740,8 @@ iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) =
|
||||||
const evalMacroLimit = 1000
|
const evalMacroLimit = 1000
|
||||||
var evalMacroCounter: int
|
var evalMacroCounter: int
|
||||||
|
|
||||||
proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode,
|
proc evalMacroCall*(module: PSym; cache: IdentCache; config: ConfigRef;
|
||||||
sym: PSym): PNode =
|
n, nOrig: PNode, sym: PSym): PNode =
|
||||||
# XXX globalError() is ugly here, but I don't know a better solution for now
|
# XXX globalError() is ugly here, but I don't know a better solution for now
|
||||||
inc(evalMacroCounter)
|
inc(evalMacroCounter)
|
||||||
if evalMacroCounter > evalMacroLimit:
|
if evalMacroCounter > evalMacroLimit:
|
||||||
|
|
@ -1746,7 +1753,7 @@ proc evalMacroCall*(module: PSym; cache: IdentCache, n, nOrig: PNode,
|
||||||
globalError(n.info, "in call '$#' got $#, but expected $# argument(s)" % [
|
globalError(n.info, "in call '$#' got $#, but expected $# argument(s)" % [
|
||||||
n.renderTree, $(n.safeLen-1), $(sym.typ.len-1)])
|
n.renderTree, $(n.safeLen-1), $(sym.typ.len-1)])
|
||||||
|
|
||||||
setupGlobalCtx(module, cache)
|
setupGlobalCtx(module, cache, config)
|
||||||
var c = globalCtx
|
var c = globalCtx
|
||||||
c.comesFromHeuristic.line = 0'u16
|
c.comesFromHeuristic.line = 0'u16
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module contains the type definitions for the new evaluation engine.
|
## This module contains the type definitions for the new evaluation engine.
|
||||||
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
## An instruction is 1-3 int32s in memory, it is a register based VM.
|
||||||
|
|
||||||
import ast, passes, msgs, idents, intsets
|
import ast, passes, msgs, idents, intsets, options
|
||||||
|
|
||||||
const
|
const
|
||||||
byteExcess* = 128 # we use excess-K for immediates
|
byteExcess* = 128 # we use excess-K for immediates
|
||||||
|
|
@ -206,17 +206,19 @@ type
|
||||||
callbacks*: seq[tuple[key: string, value: VmCallback]]
|
callbacks*: seq[tuple[key: string, value: VmCallback]]
|
||||||
errorFlag*: string
|
errorFlag*: string
|
||||||
cache*: IdentCache
|
cache*: IdentCache
|
||||||
|
config*: ConfigRef
|
||||||
|
|
||||||
TPosition* = distinct int
|
TPosition* = distinct int
|
||||||
|
|
||||||
PEvalContext* = PCtx
|
PEvalContext* = PCtx
|
||||||
|
|
||||||
proc newCtx*(module: PSym; cache: IdentCache): PCtx =
|
proc newCtx*(module: PSym; cache: IdentCache; config: ConfigRef = nil): PCtx =
|
||||||
|
let conf = if config != nil: config else: newConfigRef()
|
||||||
PCtx(code: @[], debug: @[],
|
PCtx(code: @[], debug: @[],
|
||||||
globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
|
globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
|
||||||
prc: PProc(blocks: @[]), module: module, loopIterations: MaxLoopIterations,
|
prc: PProc(blocks: @[]), module: module, loopIterations: MaxLoopIterations,
|
||||||
comesFromHeuristic: unknownLineInfo(), callbacks: @[], errorFlag: "",
|
comesFromHeuristic: unknownLineInfo(), callbacks: @[], errorFlag: "",
|
||||||
cache: cache)
|
cache: cache, config: conf)
|
||||||
|
|
||||||
proc refresh*(c: PCtx, module: PSym) =
|
proc refresh*(c: PCtx, module: PSym) =
|
||||||
c.module = module
|
c.module = module
|
||||||
|
|
|
||||||
|
|
@ -790,7 +790,7 @@ proc genIntCast(c: PCtx; n: PNode; dest: var TDest) =
|
||||||
elif src.kind in signedIntegers and dst.kind in unsignedIntegers:
|
elif src.kind in signedIntegers and dst.kind in unsignedIntegers:
|
||||||
# cast signed to unsigned integer of same size
|
# cast signed to unsigned integer of same size
|
||||||
# unsignedVal = (offset +% signedVal +% 1) and offset
|
# unsignedVal = (offset +% signedVal +% 1) and offset
|
||||||
let offset = (1 shl (src_size * 8)) - 1
|
let offset = (1 shl (src_size * 8)) - 1
|
||||||
c.gABx(n, opcLdConst, tmp2, mkIntLit(offset))
|
c.gABx(n, opcLdConst, tmp2, mkIntLit(offset))
|
||||||
c.gABx(n, opcLdConst, dest, mkIntLit(offset+1))
|
c.gABx(n, opcLdConst, dest, mkIntLit(offset+1))
|
||||||
c.gABC(n, opcAddu, tmp3, tmp, dest)
|
c.gABC(n, opcAddu, tmp3, tmp, dest)
|
||||||
|
|
@ -1554,7 +1554,7 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||||
of tyCString, tyString:
|
of tyCString, tyString:
|
||||||
result = newNodeIT(nkStrLit, info, t)
|
result = newNodeIT(nkStrLit, info, t)
|
||||||
result.strVal = ""
|
result.strVal = ""
|
||||||
of tyVar, tyLent, tyPointer, tyPtr, tySequence, tyExpr,
|
of tyVar, tyLent, tyPointer, tyPtr, tyExpr,
|
||||||
tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil:
|
tyStmt, tyTypeDesc, tyStatic, tyRef, tyNil:
|
||||||
result = newNodeIT(nkNilLit, info, t)
|
result = newNodeIT(nkNilLit, info, t)
|
||||||
of tyProc:
|
of tyProc:
|
||||||
|
|
@ -1585,6 +1585,8 @@ proc getNullValue(typ: PType, info: TLineInfo): PNode =
|
||||||
result = newNodeIT(nkCurly, info, t)
|
result = newNodeIT(nkCurly, info, t)
|
||||||
of tyOpt:
|
of tyOpt:
|
||||||
result = newNodeIT(nkNilLit, info, t)
|
result = newNodeIT(nkNilLit, info, t)
|
||||||
|
of tySequence:
|
||||||
|
result = newNodeIT(nkBracket, info, t)
|
||||||
else:
|
else:
|
||||||
globalError(info, "cannot create null element for: " & $t.kind)
|
globalError(info, "cannot create null element for: " & $t.kind)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6298,6 +6298,9 @@ modules don't need to import a module's dependencies:
|
||||||
var x: MyObject
|
var x: MyObject
|
||||||
echo $x
|
echo $x
|
||||||
|
|
||||||
|
When the exported symbol is another module, all of its definitions will
|
||||||
|
be forwarded. You can use an ``except`` list to exclude some of the symbols.
|
||||||
|
|
||||||
Note on paths
|
Note on paths
|
||||||
-----------
|
-----------
|
||||||
In module related statements, if any part of the module name /
|
In module related statements, if any part of the module name /
|
||||||
|
|
@ -7798,8 +7801,9 @@ Future directions:
|
||||||
Threadvar pragma
|
Threadvar pragma
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
A global variable can be marked with the ``threadvar`` pragma; it is
|
A variable can be marked with the ``threadvar`` pragma, which makes it a
|
||||||
a `thread-local`:idx: variable then:
|
`thread-local`:idx: variable; Additionally, this implies all the effects
|
||||||
|
of the ``global`` pragma.
|
||||||
|
|
||||||
.. code-block:: nim
|
.. code-block:: nim
|
||||||
var checkpoints* {.threadvar.}: seq[string]
|
var checkpoints* {.threadvar.}: seq[string]
|
||||||
|
|
|
||||||
2
koch.nim
2
koch.nim
|
|
@ -252,7 +252,7 @@ proc xz(args: string) =
|
||||||
|
|
||||||
proc buildTool(toolname, args: string) =
|
proc buildTool(toolname, args: string) =
|
||||||
nimexec("cc $# $#" % [args, toolname])
|
nimexec("cc $# $#" % [args, toolname])
|
||||||
copyFile(dest="bin"/ splitFile(toolname).name.exe, source=toolname.exe)
|
copyFile(dest="bin" / splitFile(toolname).name.exe, source=toolname.exe)
|
||||||
|
|
||||||
proc buildTools(latest: bool) =
|
proc buildTools(latest: bool) =
|
||||||
let nimsugExe = "bin/nimsuggest".exe
|
let nimsugExe = "bin/nimsuggest".exe
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ type
|
||||||
|
|
||||||
{.deprecated: [TBindSymRule: BindSymRule].}
|
{.deprecated: [TBindSymRule: BindSymRule].}
|
||||||
|
|
||||||
proc bindSym*(ident: string, rule: BindSymRule = brClosed): NimNode {.
|
proc bindSym*(ident: static[string], rule: BindSymRule = brClosed): NimNode {.
|
||||||
magic: "NBindSym", noSideEffect.}
|
magic: "NBindSym", noSideEffect.}
|
||||||
## creates a node that binds `ident` to a symbol node. The bound symbol
|
## creates a node that binds `ident` to a symbol node. The bound symbol
|
||||||
## may be an overloaded symbol.
|
## may be an overloaded symbol.
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import sockets, strutils, parseutils, times, os, asyncio
|
||||||
|
|
||||||
from asyncnet import nil
|
from asyncnet import nil
|
||||||
from nativesockets import nil
|
from nativesockets import nil
|
||||||
from asyncdispatch import PFuture
|
from asyncdispatch import Future
|
||||||
## **Note**: This module is deprecated since version 0.11.3.
|
## **Note**: This module is deprecated since version 0.11.3.
|
||||||
## You should use the async version of this module
|
## You should use the async version of this module
|
||||||
## `asyncftpclient <asyncftpclient.html>`_.
|
## `asyncftpclient <asyncftpclient.html>`_.
|
||||||
|
|
|
||||||
|
|
@ -853,7 +853,6 @@ type
|
||||||
DirKind = enum # must be ordered alphabetically!
|
DirKind = enum # must be ordered alphabetically!
|
||||||
dkNone, dkAuthor, dkAuthors, dkCode, dkCodeBlock, dkContainer, dkContents,
|
dkNone, dkAuthor, dkAuthors, dkCode, dkCodeBlock, dkContainer, dkContents,
|
||||||
dkFigure, dkImage, dkInclude, dkIndex, dkRaw, dkTitle
|
dkFigure, dkImage, dkInclude, dkIndex, dkRaw, dkTitle
|
||||||
{.deprecated: [TDirKind: DirKind].}
|
|
||||||
|
|
||||||
const
|
const
|
||||||
DirIds: array[0..12, string] = ["", "author", "authors", "code",
|
DirIds: array[0..12, string] = ["", "author", "authors", "code",
|
||||||
|
|
@ -1114,7 +1113,6 @@ proc parseHeadline(p: var RstParser): PRstNode =
|
||||||
|
|
||||||
type
|
type
|
||||||
IntSeq = seq[int]
|
IntSeq = seq[int]
|
||||||
{.deprecated: [TIntSeq: IntSeq].}
|
|
||||||
|
|
||||||
proc tokEnd(p: RstParser): int =
|
proc tokEnd(p: RstParser): int =
|
||||||
result = p.tok[p.idx].col + len(p.tok[p.idx].symbol) - 1
|
result = p.tok[p.idx].col + len(p.tok[p.idx].symbol) - 1
|
||||||
|
|
@ -1408,8 +1406,6 @@ type
|
||||||
hasArg, hasOptions, argIsFile, argIsWord
|
hasArg, hasOptions, argIsFile, argIsWord
|
||||||
DirFlags = set[DirFlag]
|
DirFlags = set[DirFlag]
|
||||||
SectionParser = proc (p: var RstParser): PRstNode {.nimcall.}
|
SectionParser = proc (p: var RstParser): PRstNode {.nimcall.}
|
||||||
{.deprecated: [TDirFlag: DirFlag, TDirFlags: DirFlags,
|
|
||||||
TSectionParser: SectionParser].}
|
|
||||||
|
|
||||||
proc parseDirective(p: var RstParser, flags: DirFlags): PRstNode =
|
proc parseDirective(p: var RstParser, flags: DirFlags): PRstNode =
|
||||||
## Parses arguments and options for a directive block.
|
## Parses arguments and options for a directive block.
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,6 @@ type
|
||||||
## the document or the section
|
## the document or the section
|
||||||
level*: int ## valid for some node kinds
|
level*: int ## valid for some node kinds
|
||||||
sons*: RstNodeSeq ## the node's sons
|
sons*: RstNodeSeq ## the node's sons
|
||||||
{.deprecated: [TRstNodeKind: RstNodeKind, TRstNodeSeq: RstNodeSeq,
|
|
||||||
TRstNode: RstNode].}
|
|
||||||
|
|
||||||
proc len*(n: PRstNode): int =
|
proc len*(n: PRstNode): int =
|
||||||
result = len(n.sons)
|
result = len(n.sons)
|
||||||
|
|
@ -99,7 +97,6 @@ type
|
||||||
RenderContext {.pure.} = object
|
RenderContext {.pure.} = object
|
||||||
indent: int
|
indent: int
|
||||||
verbatim: int
|
verbatim: int
|
||||||
{.deprecated: [TRenderContext: RenderContext].}
|
|
||||||
|
|
||||||
proc renderRstToRst(d: var RenderContext, n: PRstNode,
|
proc renderRstToRst(d: var RenderContext, n: PRstNode,
|
||||||
result: var string) {.gcsafe.}
|
result: var string) {.gcsafe.}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,6 @@ type
|
||||||
SortOrder* = enum ## sort order
|
SortOrder* = enum ## sort order
|
||||||
Descending, Ascending
|
Descending, Ascending
|
||||||
|
|
||||||
{.deprecated: [TSortOrder: SortOrder].}
|
|
||||||
|
|
||||||
|
|
||||||
proc `*`*(x: int, order: SortOrder): int {.inline.} =
|
proc `*`*(x: int, order: SortOrder): int {.inline.} =
|
||||||
## flips `x` if ``order == Descending``;
|
## flips `x` if ``order == Descending``;
|
||||||
## if ``order == Ascending`` then `x` is returned.
|
## if ``order == Ascending`` then `x` is returned.
|
||||||
|
|
@ -69,21 +66,25 @@ proc reversed*[T](a: openArray[T]): seq[T] =
|
||||||
|
|
||||||
proc binarySearch*[T](a: openArray[T], key: T): int =
|
proc binarySearch*[T](a: openArray[T], key: T): int =
|
||||||
## binary search for `key` in `a`. Returns -1 if not found.
|
## binary search for `key` in `a`. Returns -1 if not found.
|
||||||
var b = len(a)
|
if ((a.len - 1) and a.len) == 0 and a.len > 0:
|
||||||
while result < b:
|
# when `a.len` is a power of 2, a faster div can be used.
|
||||||
var mid = (result + b) div 2
|
var step = a.len div 2
|
||||||
if a[mid] < key: result = mid + 1
|
while step > 0:
|
||||||
else: b = mid
|
if a[result or step] <= key:
|
||||||
if result >= len(a) or a[result] != key: result = -1
|
result = result or step
|
||||||
|
step = step shr 1
|
||||||
|
if a[result] != key: result = -1
|
||||||
|
else:
|
||||||
|
var b = len(a)
|
||||||
|
while result < b:
|
||||||
|
var mid = (result + b) div 2
|
||||||
|
if a[mid] < key: result = mid + 1
|
||||||
|
else: b = mid
|
||||||
|
if result >= len(a) or a[result] != key: result = -1
|
||||||
|
|
||||||
proc smartBinarySearch*[T](a: openArray[T], key: T): int =
|
proc smartBinarySearch*[T](a: openArray[T], key: T): int {.deprecated.} =
|
||||||
## ``a.len`` must be a power of 2 for this to work.
|
## **Deprecated since version 0.18.1**; Use ``binarySearch`` instead.
|
||||||
var step = a.len div 2
|
binarySearch(a,key)
|
||||||
while step > 0:
|
|
||||||
if a[result or step] <= key:
|
|
||||||
result = result or step
|
|
||||||
step = step shr 1
|
|
||||||
if a[result] != key: result = -1
|
|
||||||
|
|
||||||
const
|
const
|
||||||
onlySafeCode = true
|
onlySafeCode = true
|
||||||
|
|
@ -363,10 +364,11 @@ when isMainModule:
|
||||||
var srt1 = [1,2,3,4,4,4,4,5]
|
var srt1 = [1,2,3,4,4,4,4,5]
|
||||||
var srt2 = ["iello","hello"]
|
var srt2 = ["iello","hello"]
|
||||||
var srt3 = [1.0,1.0,1.0]
|
var srt3 = [1.0,1.0,1.0]
|
||||||
var srt4: seq[int] = @[]
|
var srt4: seq[int]
|
||||||
assert srt1.isSorted(cmp) == true
|
assert srt1.isSorted(cmp) == true
|
||||||
assert srt2.isSorted(cmp) == false
|
assert srt2.isSorted(cmp) == false
|
||||||
assert srt3.isSorted(cmp) == true
|
assert srt3.isSorted(cmp) == true
|
||||||
|
assert srt4.isSorted(cmp) == true
|
||||||
var srtseq = newSeq[int]()
|
var srtseq = newSeq[int]()
|
||||||
assert srtseq.isSorted(cmp) == true
|
assert srtseq.isSorted(cmp) == true
|
||||||
# Tests for reversed
|
# Tests for reversed
|
||||||
|
|
@ -395,7 +397,7 @@ proc rotateInternal[T](arg: var openarray[T]; first, middle, last: int): int =
|
||||||
|
|
||||||
swap(arg[mFirst], arg[next])
|
swap(arg[mFirst], arg[next])
|
||||||
mFirst += 1
|
mFirst += 1
|
||||||
next += 1
|
next += 1
|
||||||
if mFirst == mMiddle:
|
if mFirst == mMiddle:
|
||||||
mMiddle = next
|
mMiddle = next
|
||||||
|
|
||||||
|
|
@ -514,4 +516,24 @@ when isMainModule:
|
||||||
|
|
||||||
block fillEmptySeq:
|
block fillEmptySeq:
|
||||||
var s = newSeq[int]()
|
var s = newSeq[int]()
|
||||||
s.fill(0)
|
s.fill(0)
|
||||||
|
|
||||||
|
block testBinarySearch:
|
||||||
|
var noData: seq[int]
|
||||||
|
doAssert binarySearch(noData, 7) == -1
|
||||||
|
let oneData = @[1]
|
||||||
|
doAssert binarySearch(oneData, 1) == 0
|
||||||
|
doAssert binarySearch(onedata, 7) == -1
|
||||||
|
let someData = @[1,3,4,7]
|
||||||
|
doAssert binarySearch(someData, 1) == 0
|
||||||
|
doAssert binarySearch(somedata, 7) == 3
|
||||||
|
doAssert binarySearch(someData, -1) == -1
|
||||||
|
doAssert binarySearch(someData, 5) == -1
|
||||||
|
doAssert binarySearch(someData, 13) == -1
|
||||||
|
let moreData = @[1,3,5,7,4711]
|
||||||
|
doAssert binarySearch(moreData, -1) == -1
|
||||||
|
doAssert binarySearch(moreData, 1) == 0
|
||||||
|
doAssert binarySearch(moreData, 5) == 2
|
||||||
|
doAssert binarySearch(moreData, 6) == -1
|
||||||
|
doAssert binarySearch(moreData, 4711) == 4
|
||||||
|
doAssert binarySearch(moreData, 4712) == -1
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ type
|
||||||
FutureError* = object of Exception
|
FutureError* = object of Exception
|
||||||
cause*: FutureBase
|
cause*: FutureBase
|
||||||
|
|
||||||
{.deprecated: [PFutureBase: FutureBase, PFuture: Future].}
|
|
||||||
|
|
||||||
when not defined(release):
|
when not defined(release):
|
||||||
var currentID = 0
|
var currentID = 0
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,6 @@ type
|
||||||
reusePort: bool
|
reusePort: bool
|
||||||
maxBody: int ## The maximum content-length that will be read for the body.
|
maxBody: int ## The maximum content-length that will be read for the body.
|
||||||
|
|
||||||
{.deprecated: [TRequest: Request, PAsyncHttpServer: AsyncHttpServer,
|
|
||||||
THttpCode: HttpCode, THttpVersion: HttpVersion].}
|
|
||||||
|
|
||||||
proc newAsyncHttpServer*(reuseAddr = true, reusePort = false,
|
proc newAsyncHttpServer*(reuseAddr = true, reusePort = false,
|
||||||
maxBody = 8388608): AsyncHttpServer =
|
maxBody = 8388608): AsyncHttpServer =
|
||||||
## Creates a new ``AsyncHttpServer`` instance.
|
## Creates a new ``AsyncHttpServer`` instance.
|
||||||
|
|
|
||||||
|
|
@ -134,8 +134,6 @@ type
|
||||||
protocol: Protocol
|
protocol: Protocol
|
||||||
AsyncSocket* = ref AsyncSocketDesc
|
AsyncSocket* = ref AsyncSocketDesc
|
||||||
|
|
||||||
{.deprecated: [PAsyncSocket: AsyncSocket].}
|
|
||||||
|
|
||||||
proc newAsyncSocket*(fd: AsyncFD, domain: Domain = AF_INET,
|
proc newAsyncSocket*(fd: AsyncFD, domain: Domain = AF_INET,
|
||||||
sockType: SockType = SOCK_STREAM,
|
sockType: SockType = SOCK_STREAM,
|
||||||
protocol: Protocol = IPPROTO_TCP, buffered = true): AsyncSocket =
|
protocol: Protocol = IPPROTO_TCP, buffered = true): AsyncSocket =
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,6 @@ type
|
||||||
methodPost, ## query uses the POST method
|
methodPost, ## query uses the POST method
|
||||||
methodGet ## query uses the GET method
|
methodGet ## query uses the GET method
|
||||||
|
|
||||||
{.deprecated: [TRequestMethod: RequestMethod, ECgi: CgiError].}
|
|
||||||
|
|
||||||
proc cgiError*(msg: string) {.noreturn.} =
|
proc cgiError*(msg: string) {.noreturn.} =
|
||||||
## raises an ECgi exception with message `msg`.
|
## raises an ECgi exception with message `msg`.
|
||||||
var e: ref CgiError
|
var e: ref CgiError
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,13 @@ iterator items*[A](s: HashSet[A]): A =
|
||||||
for h in 0..high(s.data):
|
for h in 0..high(s.data):
|
||||||
if isFilled(s.data[h].hcode): yield s.data[h].key
|
if isFilled(s.data[h].hcode): yield s.data[h].key
|
||||||
|
|
||||||
|
proc hash*[A](s: HashSet[A]): Hash =
|
||||||
|
## hashing of HashSet
|
||||||
|
assert s.isValid, "The set needs to be initialized."
|
||||||
|
for h in 0..high(s.data):
|
||||||
|
result = result xor s.data[h].hcode
|
||||||
|
result = !$result
|
||||||
|
|
||||||
const
|
const
|
||||||
growthFactor = 2
|
growthFactor = 2
|
||||||
|
|
||||||
|
|
@ -690,6 +697,13 @@ iterator items*[A](s: OrderedSet[A]): A =
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
yield s.data[h].key
|
yield s.data[h].key
|
||||||
|
|
||||||
|
proc hash*[A](s: OrderedSet[A]): Hash =
|
||||||
|
## hashing of OrderedSet
|
||||||
|
assert s.isValid, "The set needs to be initialized."
|
||||||
|
forAllOrderedPairs:
|
||||||
|
result = result !& s.data[h].hcode
|
||||||
|
result = !$result
|
||||||
|
|
||||||
iterator pairs*[A](s: OrderedSet[A]): tuple[a: int, b: A] =
|
iterator pairs*[A](s: OrderedSet[A]): tuple[a: int, b: A] =
|
||||||
assert s.isValid, "The set needs to be initialized"
|
assert s.isValid, "The set needs to be initialized"
|
||||||
forAllOrderedPairs:
|
forAllOrderedPairs:
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ import strutils
|
||||||
type
|
type
|
||||||
Color* = distinct int ## a color stored as RGB
|
Color* = distinct int ## a color stored as RGB
|
||||||
|
|
||||||
{.deprecated: [TColor: Color].}
|
|
||||||
|
|
||||||
proc `==` *(a, b: Color): bool {.borrow.}
|
proc `==` *(a, b: Color): bool {.borrow.}
|
||||||
## compares two colors.
|
## compares two colors.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,6 @@ type
|
||||||
Complex* = tuple[re, im: float]
|
Complex* = tuple[re, im: float]
|
||||||
## a complex number, consisting of a real and an imaginary part
|
## a complex number, consisting of a real and an imaginary part
|
||||||
|
|
||||||
{.deprecated: [TComplex: Complex].}
|
|
||||||
|
|
||||||
proc toComplex*(x: SomeInteger): Complex =
|
proc toComplex*(x: SomeInteger): Complex =
|
||||||
## Convert some integer ``x`` to a complex number.
|
## Convert some integer ``x`` to a complex number.
|
||||||
result.re = x
|
result.re = x
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,6 @@ type
|
||||||
foreignKey*: bool ## is this a foreign key?
|
foreignKey*: bool ## is this a foreign key?
|
||||||
DbColumns* = seq[DbColumn]
|
DbColumns* = seq[DbColumn]
|
||||||
|
|
||||||
{.deprecated: [EDb: DbError, TSqlQuery: SqlQuery, FDb: DbEffect,
|
|
||||||
FReadDb: ReadDbEffect, FWriteDb: WriteDbEffect].}
|
|
||||||
|
|
||||||
template sql*(query: string): SqlQuery =
|
template sql*(query: string): SqlQuery =
|
||||||
## constructs a SqlQuery from the string `query`. This is supposed to be
|
## constructs a SqlQuery from the string `query`. This is supposed to be
|
||||||
## used as a raw-string-literal modifier:
|
## used as a raw-string-literal modifier:
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@
|
||||||
## Loading a simple C function
|
## Loading a simple C function
|
||||||
## ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
## ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
##
|
##
|
||||||
## The following example demonstrates loading a function called 'greet'
|
## The following example demonstrates loading a function called 'greet'
|
||||||
## from a library that is determined at runtime based upon a language choice.
|
## from a library that is determined at runtime based upon a language choice.
|
||||||
## If the library fails to load or the function 'greet' is not found,
|
## If the library fails to load or the function 'greet' is not found,
|
||||||
## it quits with a failure error code.
|
## it quits with a failure error code.
|
||||||
##
|
##
|
||||||
## .. code-block::nim
|
## .. code-block::nim
|
||||||
|
|
@ -59,8 +59,6 @@ import strutils
|
||||||
type
|
type
|
||||||
LibHandle* = pointer ## a handle to a dynamically loaded library
|
LibHandle* = pointer ## a handle to a dynamically loaded library
|
||||||
|
|
||||||
{.deprecated: [TLibHandle: LibHandle].}
|
|
||||||
|
|
||||||
proc loadLib*(path: string, global_symbols=false): LibHandle {.gcsafe.}
|
proc loadLib*(path: string, global_symbols=false): LibHandle {.gcsafe.}
|
||||||
## loads a library from `path`. Returns nil if the library could not
|
## loads a library from `path`. Returns nil if the library could not
|
||||||
## be loaded.
|
## be loaded.
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ type
|
||||||
EncodingError* = object of ValueError ## exception that is raised
|
EncodingError* = object of ValueError ## exception that is raised
|
||||||
## for encoding errors
|
## for encoding errors
|
||||||
|
|
||||||
{.deprecated: [EInvalidEncoding: EncodingError, PConverter: EncodingConverter].}
|
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
proc eqEncodingNames(a, b: string): bool =
|
proc eqEncodingNames(a, b: string): bool =
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,6 @@ type
|
||||||
s: seq[EventHandler]
|
s: seq[EventHandler]
|
||||||
EventError* = object of ValueError
|
EventError* = object of ValueError
|
||||||
|
|
||||||
{.deprecated: [TEventArgs: EventArgs, TEventHandler: EventHandler,
|
|
||||||
TEventEmitter: EventEmitter, EInvalidEvent: EventError].}
|
|
||||||
|
|
||||||
proc initEventHandler*(name: string): EventHandler =
|
proc initEventHandler*(name: string): EventHandler =
|
||||||
## Initializes an EventHandler with the specified name and returns it.
|
## Initializes an EventHandler with the specified name and returns it.
|
||||||
result.handlers = @[]
|
result.handlers = @[]
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ type
|
||||||
Hash* = int ## a hash value; hash tables using these values should
|
Hash* = int ## a hash value; hash tables using these values should
|
||||||
## always have a size of a power of two and can use the ``and``
|
## always have a size of a power of two and can use the ``and``
|
||||||
## operator instead of ``mod`` for truncation of the hash value.
|
## operator instead of ``mod`` for truncation of the hash value.
|
||||||
{.deprecated: [THash: Hash].}
|
|
||||||
|
|
||||||
proc `!&`*(h: Hash, val: int): Hash {.inline.} =
|
proc `!&`*(h: Hash, val: int): Hash {.inline.} =
|
||||||
## mixes a hash value `h` with `val` to produce a new hash value. This is
|
## mixes a hash value `h` with `val` to produce a new hash value. This is
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,6 @@ type
|
||||||
tagVar, ## the HTML ``var`` element
|
tagVar, ## the HTML ``var`` element
|
||||||
tagVideo, ## the HTML ``video`` element
|
tagVideo, ## the HTML ``video`` element
|
||||||
tagWbr ## the HTML ``wbr`` element
|
tagWbr ## the HTML ``wbr`` element
|
||||||
{.deprecated: [THtmlTag: HtmlTag].}
|
|
||||||
|
|
||||||
const
|
const
|
||||||
tagToStr* = [
|
tagToStr* = [
|
||||||
|
|
|
||||||
|
|
@ -219,10 +219,6 @@ type
|
||||||
## and ``postContent`` proc,
|
## and ``postContent`` proc,
|
||||||
## when the server returns an error
|
## when the server returns an error
|
||||||
|
|
||||||
{.deprecated: [TResponse: Response, PProxy: Proxy,
|
|
||||||
EInvalidProtocol: ProtocolError, EHttpRequestErr: HttpRequestError
|
|
||||||
].}
|
|
||||||
|
|
||||||
const defUserAgent* = "Nim httpclient/" & NimVersion
|
const defUserAgent* = "Nim httpclient/" & NimVersion
|
||||||
|
|
||||||
proc httpError(msg: string) =
|
proc httpError(msg: string) =
|
||||||
|
|
@ -362,8 +358,6 @@ proc parseResponse(s: Socket, getBody: bool, timeout: int): Response =
|
||||||
else:
|
else:
|
||||||
result.body = ""
|
result.body = ""
|
||||||
|
|
||||||
{.deprecated: [THttpMethod: HttpMethod].}
|
|
||||||
|
|
||||||
when not defined(ssl):
|
when not defined(ssl):
|
||||||
type SSLContext = ref object
|
type SSLContext = ref object
|
||||||
var defaultSSLContext {.threadvar.}: SSLContext
|
var defaultSSLContext {.threadvar.}: SSLContext
|
||||||
|
|
@ -585,7 +579,7 @@ proc request*(url: string, httpMethod: string, extraHeaders = "",
|
||||||
|
|
||||||
result = parseResponse(s, httpMethod != "HEAD", timeout)
|
result = parseResponse(s, httpMethod != "HEAD", timeout)
|
||||||
|
|
||||||
proc request*(url: string, httpMethod = httpGET, extraHeaders = "",
|
proc request*(url: string, httpMethod = HttpGET, extraHeaders = "",
|
||||||
body = "", sslContext = defaultSSLContext, timeout = -1,
|
body = "", sslContext = defaultSSLContext, timeout = -1,
|
||||||
userAgent = defUserAgent, proxy: Proxy = nil): Response
|
userAgent = defUserAgent, proxy: Proxy = nil): Response
|
||||||
{.deprecated.} =
|
{.deprecated.} =
|
||||||
|
|
@ -627,13 +621,13 @@ proc get*(url: string, extraHeaders = "", maxRedirects = 5,
|
||||||
## server takes longer than specified an ETimeout exception will be raised.
|
## server takes longer than specified an ETimeout exception will be raised.
|
||||||
##
|
##
|
||||||
## **Deprecated since version 0.15.0**: use ``HttpClient.get`` instead.
|
## **Deprecated since version 0.15.0**: use ``HttpClient.get`` instead.
|
||||||
result = request(url, httpGET, extraHeaders, "", sslContext, timeout,
|
result = request(url, HttpGET, extraHeaders, "", sslContext, timeout,
|
||||||
userAgent, proxy)
|
userAgent, proxy)
|
||||||
var lastURL = url
|
var lastURL = url
|
||||||
for i in 1..maxRedirects:
|
for i in 1..maxRedirects:
|
||||||
if result.status.redirection():
|
if result.status.redirection():
|
||||||
let redirectTo = getNewLocation(lastURL, result.headers)
|
let redirectTo = getNewLocation(lastURL, result.headers)
|
||||||
result = request(redirectTo, httpGET, extraHeaders, "", sslContext,
|
result = request(redirectTo, HttpGET, extraHeaders, "", sslContext,
|
||||||
timeout, userAgent, proxy)
|
timeout, userAgent, proxy)
|
||||||
lastURL = redirectTo
|
lastURL = redirectTo
|
||||||
|
|
||||||
|
|
@ -687,13 +681,13 @@ proc post*(url: string, extraHeaders = "", body = "",
|
||||||
if not multipart.isNil:
|
if not multipart.isNil:
|
||||||
xh.add(withNewLine("Content-Type: " & mpContentType))
|
xh.add(withNewLine("Content-Type: " & mpContentType))
|
||||||
|
|
||||||
result = request(url, httpPOST, xh, xb, sslContext, timeout, userAgent,
|
result = request(url, HttpPOST, xh, xb, sslContext, timeout, userAgent,
|
||||||
proxy)
|
proxy)
|
||||||
var lastURL = url
|
var lastURL = url
|
||||||
for i in 1..maxRedirects:
|
for i in 1..maxRedirects:
|
||||||
if result.status.redirection():
|
if result.status.redirection():
|
||||||
let redirectTo = getNewLocation(lastURL, result.headers)
|
let redirectTo = getNewLocation(lastURL, result.headers)
|
||||||
var meth = if result.status != "307": httpGet else: httpPost
|
var meth = if result.status != "307": HttpGet else: HttpPost
|
||||||
result = request(redirectTo, meth, xh, xb, sslContext, timeout,
|
result = request(redirectTo, meth, xh, xb, sslContext, timeout,
|
||||||
userAgent, proxy)
|
userAgent, proxy)
|
||||||
lastURL = redirectTo
|
lastURL = redirectTo
|
||||||
|
|
@ -749,7 +743,7 @@ proc generateHeaders(requestUrl: Uri, httpMethod: string,
|
||||||
|
|
||||||
if proxy.isNil or requestUrl.scheme == "https":
|
if proxy.isNil or requestUrl.scheme == "https":
|
||||||
# /path?query
|
# /path?query
|
||||||
if requestUrl.path[0] != '/': result.add '/'
|
if not requestUrl.path.startsWith("/"): result.add '/'
|
||||||
result.add(requestUrl.path)
|
result.add(requestUrl.path)
|
||||||
if requestUrl.query.len > 0:
|
if requestUrl.query.len > 0:
|
||||||
result.add("?" & requestUrl.query)
|
result.add("?" & requestUrl.query)
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,6 @@ type
|
||||||
## TCP/IP tunnel, usually used for proxies.
|
## TCP/IP tunnel, usually used for proxies.
|
||||||
HttpPatch ## Applies partial modifications to a resource.
|
HttpPatch ## Applies partial modifications to a resource.
|
||||||
|
|
||||||
{.deprecated: [httpGet: HttpGet, httpHead: HttpHead, httpPost: HttpPost,
|
|
||||||
httpPut: HttpPut, httpDelete: HttpDelete, httpTrace: HttpTrace,
|
|
||||||
httpOptions: HttpOptions, httpConnect: HttpConnect].}
|
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
Http100* = HttpCode(100)
|
Http100* = HttpCode(100)
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,6 @@ when false:
|
||||||
# TODO: Fix this, or get rid of it.
|
# TODO: Fix this, or get rid of it.
|
||||||
type
|
type
|
||||||
RequestMethod = enum reqGet, reqPost
|
RequestMethod = enum reqGet, reqPost
|
||||||
{.deprecated: [TRequestMethod: RequestMethod].}
|
|
||||||
|
|
||||||
proc executeCgi(client: Socket, path, query: string, meth: RequestMethod) =
|
proc executeCgi(client: Socket, path, query: string, meth: RequestMethod) =
|
||||||
var env = newStringTable(modeCaseInsensitive)
|
var env = newStringTable(modeCaseInsensitive)
|
||||||
|
|
@ -225,7 +224,6 @@ type
|
||||||
PAsyncHTTPServer* = ref AsyncHTTPServer
|
PAsyncHTTPServer* = ref AsyncHTTPServer
|
||||||
AsyncHTTPServer = object of Server
|
AsyncHTTPServer = object of Server
|
||||||
asyncSocket: AsyncSocket
|
asyncSocket: AsyncSocket
|
||||||
{.deprecated: [TAsyncHTTPServer: AsyncHTTPServer, TServer: Server].}
|
|
||||||
|
|
||||||
proc open*(s: var Server, port = Port(80), reuseAddr = false) =
|
proc open*(s: var Server, port = Port(80), reuseAddr = false) =
|
||||||
## creates a new server at port `port`. If ``port == 0`` a free port is
|
## creates a new server at port `port`. If ``port == 0`` a free port is
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,13 @@ proc createAsyncNativeSocket*(domain: Domain = Domain.AF_INET,
|
||||||
createAsyncNativeSocketImpl(domain, sockType, protocol)
|
createAsyncNativeSocketImpl(domain, sockType, protocol)
|
||||||
|
|
||||||
proc newAsyncNativeSocket*(domain: cint, sockType: cint,
|
proc newAsyncNativeSocket*(domain: cint, sockType: cint,
|
||||||
protocol: cint): AsyncFD {.deprecated.} =
|
protocol: cint): AsyncFD {.deprecated: "use createAsyncNativeSocket instead".} =
|
||||||
createAsyncNativeSocketImpl(domain, sockType, protocol)
|
createAsyncNativeSocketImpl(domain, sockType, protocol)
|
||||||
|
|
||||||
proc newAsyncNativeSocket*(domain: Domain = Domain.AF_INET,
|
proc newAsyncNativeSocket*(domain: Domain = Domain.AF_INET,
|
||||||
sockType: SockType = SOCK_STREAM,
|
sockType: SockType = SOCK_STREAM,
|
||||||
protocol: Protocol = IPPROTO_TCP): AsyncFD
|
protocol: Protocol = IPPROTO_TCP): AsyncFD
|
||||||
{.deprecated.} =
|
{.deprecated: "use createAsyncNativeSocket instead".} =
|
||||||
createAsyncNativeSocketImpl(domain, sockType, protocol)
|
createAsyncNativeSocketImpl(domain, sockType, protocol)
|
||||||
|
|
||||||
when defined(windows) or defined(nimdoc):
|
when defined(windows) or defined(nimdoc):
|
||||||
|
|
|
||||||
|
|
@ -12,50 +12,6 @@ when not defined(nimscript):
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
import winlean
|
import winlean
|
||||||
|
|
||||||
proc osErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} =
|
|
||||||
## Retrieves the operating system's error flag, ``errno``.
|
|
||||||
## On Windows ``GetLastError`` is checked before ``errno``.
|
|
||||||
## Returns "" if no error occurred.
|
|
||||||
##
|
|
||||||
## **Deprecated since version 0.9.4**: use the other ``osErrorMsg`` proc.
|
|
||||||
|
|
||||||
result = ""
|
|
||||||
when defined(Windows) and not defined(nimscript):
|
|
||||||
var err = getLastError()
|
|
||||||
if err != 0'i32:
|
|
||||||
when useWinUnicode:
|
|
||||||
var msgbuf: WideCString
|
|
||||||
if formatMessageW(0x00000100 or 0x00001000 or 0x00000200 or 0x000000FF,
|
|
||||||
nil, err, 0, addr(msgbuf), 0, nil) != 0'i32:
|
|
||||||
result = $msgbuf
|
|
||||||
if msgbuf != nil: localFree(cast[pointer](msgbuf))
|
|
||||||
else:
|
|
||||||
var msgbuf: cstring
|
|
||||||
if formatMessageA(0x00000100 or 0x00001000 or 0x00000200 or 0x000000FF,
|
|
||||||
nil, err, 0, addr(msgbuf), 0, nil) != 0'i32:
|
|
||||||
result = $msgbuf
|
|
||||||
if msgbuf != nil: localFree(msgbuf)
|
|
||||||
when not defined(nimscript):
|
|
||||||
if errno != 0'i32:
|
|
||||||
result = $c_strerror(errno)
|
|
||||||
|
|
||||||
{.push warning[deprecated]: off.}
|
|
||||||
proc raiseOSError*(msg: string = "") {.noinline, rtl, extern: "nos$1",
|
|
||||||
deprecated.} =
|
|
||||||
## raises an OSError exception with the given message ``msg``.
|
|
||||||
## If ``msg == ""``, the operating system's error flag
|
|
||||||
## (``errno``) is converted to a readable error message. On Windows
|
|
||||||
## ``GetLastError`` is checked before ``errno``.
|
|
||||||
## If no error flag is set, the message ``unknown OS error`` is used.
|
|
||||||
##
|
|
||||||
## **Deprecated since version 0.9.4**: use the other ``raiseOSError`` proc.
|
|
||||||
if len(msg) == 0:
|
|
||||||
var m = osErrorMsg()
|
|
||||||
raise newException(OSError, if m.len > 0: m else: "unknown OS error")
|
|
||||||
else:
|
|
||||||
raise newException(OSError, msg)
|
|
||||||
{.pop.}
|
|
||||||
|
|
||||||
proc `==`*(err1, err2: OSErrorCode): bool {.borrow.}
|
proc `==`*(err1, err2: OSErrorCode): bool {.borrow.}
|
||||||
proc `$`*(err: OSErrorCode): string {.borrow.}
|
proc `$`*(err: OSErrorCode): string {.borrow.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158,9 +158,6 @@ type
|
||||||
JsonKindError* = object of ValueError ## raised by the ``to`` macro if the
|
JsonKindError* = object of ValueError ## raised by the ``to`` macro if the
|
||||||
## JSON kind is incorrect.
|
## JSON kind is incorrect.
|
||||||
|
|
||||||
{.deprecated: [TJsonEventKind: JsonEventKind, TJsonError: JsonError,
|
|
||||||
TJsonParser: JsonParser, TTokKind: TokKind].}
|
|
||||||
|
|
||||||
const
|
const
|
||||||
errorMessages: array[JsonError, string] = [
|
errorMessages: array[JsonError, string] = [
|
||||||
"no error",
|
"no error",
|
||||||
|
|
@ -622,9 +619,6 @@ type
|
||||||
|
|
||||||
JsonParsingError* = object of ValueError ## is raised for a JSON error
|
JsonParsingError* = object of ValueError ## is raised for a JSON error
|
||||||
|
|
||||||
{.deprecated: [EJsonParsingError: JsonParsingError, TJsonNode: JsonNodeObj,
|
|
||||||
PJsonNode: JsonNode, TJsonNodeKind: JsonNodeKind].}
|
|
||||||
|
|
||||||
proc raiseParseErr*(p: JsonParser, msg: string) {.noinline, noreturn.} =
|
proc raiseParseErr*(p: JsonParser, msg: string) {.noinline, noreturn.} =
|
||||||
## raises an `EJsonParsingError` exception.
|
## raises an `EJsonParsingError` exception.
|
||||||
raise newException(JsonParsingError, errorMsgExpected(p, msg))
|
raise newException(JsonParsingError, errorMsgExpected(p, msg))
|
||||||
|
|
@ -695,7 +689,7 @@ proc getBiggestInt*(n: JsonNode, default: BiggestInt = 0): BiggestInt =
|
||||||
if n.isNil or n.kind != JInt: return default
|
if n.isNil or n.kind != JInt: return default
|
||||||
else: return n.num
|
else: return n.num
|
||||||
|
|
||||||
proc getNum*(n: JsonNode, default: BiggestInt = 0): BiggestInt {.deprecated.} =
|
proc getNum*(n: JsonNode, default: BiggestInt = 0): BiggestInt {.deprecated: "use getInt or getBiggestInt instead".} =
|
||||||
## **Deprecated since v0.18.2:** use ``getInt`` or ``getBiggestInt`` instead.
|
## **Deprecated since v0.18.2:** use ``getInt`` or ``getBiggestInt`` instead.
|
||||||
getBiggestInt(n, default)
|
getBiggestInt(n, default)
|
||||||
|
|
||||||
|
|
@ -709,7 +703,7 @@ proc getFloat*(n: JsonNode, default: float = 0.0): float =
|
||||||
of JInt: return float(n.num)
|
of JInt: return float(n.num)
|
||||||
else: return default
|
else: return default
|
||||||
|
|
||||||
proc getFNum*(n: JsonNode, default: float = 0.0): float {.deprecated.} =
|
proc getFNum*(n: JsonNode, default: float = 0.0): float {.deprecated: "use getFloat instead".} =
|
||||||
## **Deprecated since v0.18.2:** use ``getFloat`` instead.
|
## **Deprecated since v0.18.2:** use ``getFloat`` instead.
|
||||||
getFloat(n, default)
|
getFloat(n, default)
|
||||||
|
|
||||||
|
|
@ -720,7 +714,7 @@ proc getBool*(n: JsonNode, default: bool = false): bool =
|
||||||
if n.isNil or n.kind != JBool: return default
|
if n.isNil or n.kind != JBool: return default
|
||||||
else: return n.bval
|
else: return n.bval
|
||||||
|
|
||||||
proc getBVal*(n: JsonNode, default: bool = false): bool {.deprecated.} =
|
proc getBVal*(n: JsonNode, default: bool = false): bool {.deprecated: "use getBool instead".} =
|
||||||
## **Deprecated since v0.18.2:** use ``getBool`` instead.
|
## **Deprecated since v0.18.2:** use ``getBool`` instead.
|
||||||
getBool(n, default)
|
getBool(n, default)
|
||||||
|
|
||||||
|
|
@ -946,7 +940,7 @@ proc contains*(node: JsonNode, val: JsonNode): bool =
|
||||||
assert(node.kind == JArray)
|
assert(node.kind == JArray)
|
||||||
find(node.elems, val) >= 0
|
find(node.elems, val) >= 0
|
||||||
|
|
||||||
proc existsKey*(node: JsonNode, key: string): bool {.deprecated.} = node.hasKey(key)
|
proc existsKey*(node: JsonNode, key: string): bool {.deprecated: "use hasKey instead".} = node.hasKey(key)
|
||||||
## **Deprecated:** use `hasKey` instead.
|
## **Deprecated:** use `hasKey` instead.
|
||||||
|
|
||||||
proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) {.inline.} =
|
proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) {.inline.} =
|
||||||
|
|
@ -1277,7 +1271,6 @@ else:
|
||||||
from math import `mod`
|
from math import `mod`
|
||||||
type
|
type
|
||||||
JSObject = object
|
JSObject = object
|
||||||
{.deprecated: [TJSObject: JSObject].}
|
|
||||||
|
|
||||||
proc parseNativeJson(x: cstring): JSObject {.importc: "JSON.parse".}
|
proc parseNativeJson(x: cstring): JSObject {.importc: "JSON.parse".}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,6 @@ type
|
||||||
offsetBase*: int # use ``offsetBase + bufpos`` to get the offset
|
offsetBase*: int # use ``offsetBase + bufpos`` to get the offset
|
||||||
refillChars: set[char]
|
refillChars: set[char]
|
||||||
|
|
||||||
{.deprecated: [TBaseLexer: BaseLexer].}
|
|
||||||
|
|
||||||
const
|
const
|
||||||
chrSize = sizeof(char)
|
chrSize = sizeof(char)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,10 +96,6 @@ when not defined(js):
|
||||||
logFiles: int # how many log files already created, e.g. basename.1, basename.2...
|
logFiles: int # how many log files already created, e.g. basename.1, basename.2...
|
||||||
bufSize: int # size of output buffer (-1: use system defaults, 0: unbuffered, >0: fixed buffer size)
|
bufSize: int # size of output buffer (-1: use system defaults, 0: unbuffered, >0: fixed buffer size)
|
||||||
|
|
||||||
{.deprecated: [PFileLogger: FileLogger, PRollingFileLogger: RollingFileLogger].}
|
|
||||||
|
|
||||||
{.deprecated: [TLevel: Level, PLogger: Logger, PConsoleLogger: ConsoleLogger].}
|
|
||||||
|
|
||||||
var
|
var
|
||||||
level {.threadvar.}: Level ## global log filter
|
level {.threadvar.}: Level ## global log filter
|
||||||
handlers {.threadvar.}: seq[Logger] ## handlers with their own log levels
|
handlers {.threadvar.}: seq[Logger] ## handlers with their own log levels
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,6 @@ when not defined(testing) and isMainModule:
|
||||||
Node = object
|
Node = object
|
||||||
next, prev: PNode
|
next, prev: PNode
|
||||||
data: string
|
data: string
|
||||||
{.deprecated: [TNode: Node].}
|
|
||||||
|
|
||||||
proc buildList(): PNode =
|
proc buildList(): PNode =
|
||||||
new(result)
|
new(result)
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,21 @@ proc binom*(n, k: int): int {.noSideEffect.} =
|
||||||
for i in countup(2, k):
|
for i in countup(2, k):
|
||||||
result = (result * (n + 1 - i)) div i
|
result = (result * (n + 1 - i)) div i
|
||||||
|
|
||||||
proc fac*(n: int): int {.noSideEffect.} =
|
proc createFactTable[N: static[int]]: array[N, int] =
|
||||||
|
result[0] = 1
|
||||||
|
for i in 1 ..< N:
|
||||||
|
result[i] = result[i - 1] * i
|
||||||
|
|
||||||
|
proc fac*(n: int): int =
|
||||||
## Computes the faculty/factorial function.
|
## Computes the faculty/factorial function.
|
||||||
result = 1
|
const factTable =
|
||||||
for i in countup(2, n):
|
when sizeof(int) == 4:
|
||||||
result = result * i
|
createFactTable[13]()
|
||||||
|
else:
|
||||||
|
createFactTable[21]()
|
||||||
|
assert(n > 0, $n & " must not be negative.")
|
||||||
|
assert(n < factTable.len, $n & " is too large to look up in the table")
|
||||||
|
factTable[n]
|
||||||
|
|
||||||
{.push checks:off, line_dir:off, stack_trace:off.}
|
{.push checks:off, line_dir:off, stack_trace:off.}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,6 @@ type
|
||||||
else:
|
else:
|
||||||
handle: cint
|
handle: cint
|
||||||
|
|
||||||
{.deprecated: [TMemFile: MemFile].}
|
|
||||||
|
|
||||||
proc mapMem*(m: var MemFile, mode: FileMode = fmRead,
|
proc mapMem*(m: var MemFile, mode: FileMode = fmRead,
|
||||||
mappedSize = -1, offset = 0): pointer =
|
mappedSize = -1, offset = 0): pointer =
|
||||||
## returns a pointer to a mapped portion of MemFile `m`
|
## returns a pointer to a mapped portion of MemFile `m`
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ type
|
||||||
mt: array[0..623, uint32]
|
mt: array[0..623, uint32]
|
||||||
index: int
|
index: int
|
||||||
|
|
||||||
{.deprecated: [TMersenneTwister: MersenneTwister].}
|
|
||||||
|
|
||||||
proc newMersenneTwister*(seed: uint32): MersenneTwister =
|
proc newMersenneTwister*(seed: uint32): MersenneTwister =
|
||||||
result.index = 0
|
result.index = 0
|
||||||
result.mt[0] = seed
|
result.mt[0] = seed
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,6 @@ type
|
||||||
MimeDB* = object
|
MimeDB* = object
|
||||||
mimes: StringTableRef
|
mimes: StringTableRef
|
||||||
|
|
||||||
{.deprecated: [TMimeDB: MimeDB].}
|
|
||||||
|
|
||||||
const mimes* = {
|
const mimes* = {
|
||||||
"ez": "application/andrew-inset",
|
"ez": "application/andrew-inset",
|
||||||
"anx": "application/annodex",
|
"anx": "application/annodex",
|
||||||
|
|
|
||||||
|
|
@ -85,9 +85,6 @@ type
|
||||||
length*: int
|
length*: int
|
||||||
addrList*: seq[string]
|
addrList*: seq[string]
|
||||||
|
|
||||||
{.deprecated: [TPort: Port, TDomain: Domain, TType: SockType,
|
|
||||||
TProtocol: Protocol, TServent: Servent, THostent: Hostent].}
|
|
||||||
|
|
||||||
when useWinVersion:
|
when useWinVersion:
|
||||||
let
|
let
|
||||||
osInvalidSocket* = winlean.INVALID_SOCKET
|
osInvalidSocket* = winlean.INVALID_SOCKET
|
||||||
|
|
@ -640,7 +637,7 @@ proc pruneSocketSet(s: var seq[SocketHandle], fd: var TFdSet) =
|
||||||
inc(i)
|
inc(i)
|
||||||
setLen(s, L)
|
setLen(s, L)
|
||||||
|
|
||||||
proc select*(readfds: var seq[SocketHandle], timeout = 500): int {.deprecated.} =
|
proc select*(readfds: var seq[SocketHandle], timeout = 500): int {.deprecated: "use selectRead instead".} =
|
||||||
## When a socket in ``readfds`` is ready to be read from then a non-zero
|
## When a socket in ``readfds`` is ready to be read from then a non-zero
|
||||||
## value will be returned specifying the count of the sockets which can be
|
## value will be returned specifying the count of the sockets which can be
|
||||||
## read from. The sockets which can be read from will also be removed
|
## read from. The sockets which can be read from will also be removed
|
||||||
|
|
|
||||||
|
|
@ -110,9 +110,6 @@ when defineSsl:
|
||||||
serverGetPskFunc: SslServerGetPskFunc
|
serverGetPskFunc: SslServerGetPskFunc
|
||||||
clientGetPskFunc: SslClientGetPskFunc
|
clientGetPskFunc: SslClientGetPskFunc
|
||||||
|
|
||||||
{.deprecated: [ESSL: SSLError, TSSLCVerifyMode: SSLCVerifyMode,
|
|
||||||
TSSLProtVersion: SSLProtVersion, PSSLContext: SSLContext,
|
|
||||||
TSSLAcceptResult: SSLAcceptResult].}
|
|
||||||
else:
|
else:
|
||||||
type
|
type
|
||||||
SslContext* = void # TODO: Workaround #4797.
|
SslContext* = void # TODO: Workaround #4797.
|
||||||
|
|
@ -159,10 +156,6 @@ type
|
||||||
Peek,
|
Peek,
|
||||||
SafeDisconn ## Ensures disconnection exceptions (ECONNRESET, EPIPE etc) are not thrown.
|
SafeDisconn ## Ensures disconnection exceptions (ECONNRESET, EPIPE etc) are not thrown.
|
||||||
|
|
||||||
{.deprecated: [TSocketFlags: SocketFlag, ETimeout: TimeoutError,
|
|
||||||
TReadLineResult: ReadLineResult, TSOBool: SOBool, PSocket: Socket,
|
|
||||||
TSocketImpl: SocketImpl].}
|
|
||||||
|
|
||||||
type
|
type
|
||||||
IpAddressFamily* {.pure.} = enum ## Describes the type of an IP address
|
IpAddressFamily* {.pure.} = enum ## Describes the type of an IP address
|
||||||
IPv6, ## IPv6 address
|
IPv6, ## IPv6 address
|
||||||
|
|
@ -176,8 +169,6 @@ type
|
||||||
of IpAddressFamily.IPv4:
|
of IpAddressFamily.IPv4:
|
||||||
address_v4*: array[0..3, uint8] ## Contains the IP address in bytes in
|
address_v4*: array[0..3, uint8] ## Contains the IP address in bytes in
|
||||||
## case of IPv4
|
## case of IPv4
|
||||||
{.deprecated: [TIpAddress: IpAddress].}
|
|
||||||
|
|
||||||
|
|
||||||
proc socketError*(socket: Socket, err: int = -1, async = false,
|
proc socketError*(socket: Socket, err: int = -1, async = false,
|
||||||
lastError = (-1).OSErrorCode): void {.gcsafe.}
|
lastError = (-1).OSErrorCode): void {.gcsafe.}
|
||||||
|
|
@ -969,7 +960,7 @@ when defined(posix) and not defined(nimdoc):
|
||||||
raise newException(ValueError, "socket path too long")
|
raise newException(ValueError, "socket path too long")
|
||||||
copyMem(addr result.sun_path, path.cstring, path.len + 1)
|
copyMem(addr result.sun_path, path.cstring, path.len + 1)
|
||||||
|
|
||||||
when defined(posix):
|
when defined(posix) or defined(nimdoc):
|
||||||
proc connectUnix*(socket: Socket, path: string) =
|
proc connectUnix*(socket: Socket, path: string) =
|
||||||
## Connects to Unix socket on `path`.
|
## Connects to Unix socket on `path`.
|
||||||
## This only works on Unix-style systems: Mac OS X, BSD and Linux
|
## This only works on Unix-style systems: Mac OS X, BSD and Linux
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ when not declared(system.StackTrace):
|
||||||
type StackTrace = object
|
type StackTrace = object
|
||||||
lines: array[0..20, cstring]
|
lines: array[0..20, cstring]
|
||||||
files: array[0..20, cstring]
|
files: array[0..20, cstring]
|
||||||
{.deprecated: [TStackTrace: StackTrace].}
|
|
||||||
proc `[]`*(st: StackTrace, i: int): cstring = st.lines[i]
|
proc `[]`*(st: StackTrace, i: int): cstring = st.lines[i]
|
||||||
|
|
||||||
# We use a simple hash table of bounded size to keep track of the stack traces:
|
# We use a simple hash table of bounded size to keep track of the stack traces:
|
||||||
|
|
@ -39,7 +38,6 @@ type
|
||||||
total: int
|
total: int
|
||||||
st: StackTrace
|
st: StackTrace
|
||||||
ProfileData = array[0..64*1024-1, ptr ProfileEntry]
|
ProfileData = array[0..64*1024-1, ptr ProfileEntry]
|
||||||
{.deprecated: [TProfileEntry: ProfileEntry, TProfileData: ProfileData].}
|
|
||||||
|
|
||||||
proc `==`(a, b: StackTrace): bool =
|
proc `==`(a, b: StackTrace): bool =
|
||||||
for i in 0 .. high(a.lines):
|
for i in 0 .. high(a.lines):
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,9 @@ type
|
||||||
fuzz: int32 ##
|
fuzz: int32 ##
|
||||||
count: int32 ##
|
count: int32 ##
|
||||||
|
|
||||||
{.deprecated: [Toid: Oid].}
|
|
||||||
|
|
||||||
proc `==`*(oid1: Oid, oid2: Oid): bool =
|
proc `==`*(oid1: Oid, oid2: Oid): bool =
|
||||||
## Compare two Mongo Object IDs for equality
|
## Compare two Mongo Object IDs for equality
|
||||||
return (oid1.time == oid2.time) and (oid1.fuzz == oid2.fuzz) and (oid1.count == oid2.count)
|
return (oid1.time == oid2.time) and (oid1.fuzz == oid2.fuzz) and (oid1.count == oid2.count)
|
||||||
|
|
||||||
proc hexbyte*(hex: char): int =
|
proc hexbyte*(hex: char): int =
|
||||||
case hex
|
case hex
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ proc get*[T](self: Option[T]): T =
|
||||||
|
|
||||||
proc get*[T](self: Option[T], otherwise: T): T =
|
proc get*[T](self: Option[T], otherwise: T): T =
|
||||||
## Returns the contents of this option or `otherwise` if the option is none.
|
## Returns the contents of this option or `otherwise` if the option is none.
|
||||||
if self.has:
|
if self.isSome:
|
||||||
self.val
|
self.val
|
||||||
else:
|
else:
|
||||||
otherwise
|
otherwise
|
||||||
|
|
@ -154,7 +154,7 @@ proc map*[T, R](self: Option[T], callback: proc (input: T): R): Option[R] =
|
||||||
|
|
||||||
proc flatten*[A](self: Option[Option[A]]): Option[A] =
|
proc flatten*[A](self: Option[Option[A]]): Option[A] =
|
||||||
## Remove one level of structure in a nested Option.
|
## Remove one level of structure in a nested Option.
|
||||||
if self.has:
|
if self.isSome:
|
||||||
self.val
|
self.val
|
||||||
else:
|
else:
|
||||||
none(A)
|
none(A)
|
||||||
|
|
@ -179,14 +179,14 @@ proc filter*[T](self: Option[T], callback: proc (input: T): bool): Option[T] =
|
||||||
proc `==`*(a, b: Option): bool =
|
proc `==`*(a, b: Option): bool =
|
||||||
## Returns ``true`` if both ``Option``s are ``none``,
|
## Returns ``true`` if both ``Option``s are ``none``,
|
||||||
## or if they have equal values
|
## or if they have equal values
|
||||||
(a.has and b.has and a.val == b.val) or (not a.has and not b.has)
|
(a.isSome and b.isSome and a.val == b.val) or (not a.isSome and not b.isSome)
|
||||||
|
|
||||||
proc `$`*[T](self: Option[T]): string =
|
proc `$`*[T](self: Option[T]): string =
|
||||||
## Get the string representation of this option. If the option has a value,
|
## Get the string representation of this option. If the option has a value,
|
||||||
## the result will be `Some(x)` where `x` is the string representation of the contained value.
|
## the result will be `Some(x)` where `x` is the string representation of the contained value.
|
||||||
## If the option does not have a value, the result will be `None[T]` where `T` is the name of
|
## If the option does not have a value, the result will be `None[T]` where `T` is the name of
|
||||||
## the type contained in the option.
|
## the type contained in the option.
|
||||||
if self.has:
|
if self.isSome:
|
||||||
"Some(" & $self.val & ")"
|
"Some(" & $self.val & ")"
|
||||||
else:
|
else:
|
||||||
"None[" & T.name & "]"
|
"None[" & T.name & "]"
|
||||||
|
|
|
||||||
|
|
@ -431,8 +431,6 @@ type
|
||||||
fpOthersWrite, ## write access for others
|
fpOthersWrite, ## write access for others
|
||||||
fpOthersRead ## read access for others
|
fpOthersRead ## read access for others
|
||||||
|
|
||||||
{.deprecated: [TFilePermission: FilePermission].}
|
|
||||||
|
|
||||||
proc getFilePermissions*(filename: string): set[FilePermission] {.
|
proc getFilePermissions*(filename: string): set[FilePermission] {.
|
||||||
rtl, extern: "nos$1", tags: [ReadDirEffect].} =
|
rtl, extern: "nos$1", tags: [ReadDirEffect].} =
|
||||||
## retrieves file permissions for `filename`. `OSError` is raised in case of
|
## retrieves file permissions for `filename`. `OSError` is raised in case of
|
||||||
|
|
@ -730,8 +728,6 @@ type
|
||||||
pcDir, ## path refers to a directory
|
pcDir, ## path refers to a directory
|
||||||
pcLinkToDir ## path refers to a symbolic link to a directory
|
pcLinkToDir ## path refers to a symbolic link to a directory
|
||||||
|
|
||||||
{.deprecated: [TPathComponent: PathComponent].}
|
|
||||||
|
|
||||||
|
|
||||||
when defined(posix):
|
when defined(posix):
|
||||||
proc getSymlinkFileKind(path: string): PathComponent =
|
proc getSymlinkFileKind(path: string): PathComponent =
|
||||||
|
|
@ -1441,18 +1437,6 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} =
|
||||||
if result.len == 0:
|
if result.len == 0:
|
||||||
result = getApplHeuristic()
|
result = getApplHeuristic()
|
||||||
|
|
||||||
proc getApplicationFilename*(): string {.rtl, extern: "nos$1", deprecated.} =
|
|
||||||
## Returns the filename of the application's executable.
|
|
||||||
## **Deprecated since version 0.8.12**: use ``getAppFilename``
|
|
||||||
## instead.
|
|
||||||
result = getAppFilename()
|
|
||||||
|
|
||||||
proc getApplicationDir*(): string {.rtl, extern: "nos$1", deprecated.} =
|
|
||||||
## Returns the directory of the application's executable.
|
|
||||||
## **Deprecated since version 0.8.12**: use ``getAppDir``
|
|
||||||
## instead.
|
|
||||||
result = splitFile(getAppFilename()).dir
|
|
||||||
|
|
||||||
proc getAppDir*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} =
|
proc getAppDir*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} =
|
||||||
## Returns the directory of the application's executable.
|
## Returns the directory of the application's executable.
|
||||||
result = splitFile(getAppFilename()).dir
|
result = splitFile(getAppFilename()).dir
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,6 @@ type
|
||||||
|
|
||||||
OSErrorCode* = distinct int32 ## Specifies an OS Error Code.
|
OSErrorCode* = distinct int32 ## Specifies an OS Error Code.
|
||||||
|
|
||||||
{.deprecated: [FReadEnv: ReadEnvEffect, FWriteEnv: WriteEnvEffect,
|
|
||||||
FReadDir: ReadDirEffect,
|
|
||||||
FWriteDir: WriteDirEffect,
|
|
||||||
TOSErrorCode: OSErrorCode
|
|
||||||
].}
|
|
||||||
const
|
const
|
||||||
doslikeFileSystem* = defined(windows) or defined(OS2) or defined(DOS)
|
doslikeFileSystem* = defined(windows) or defined(OS2) or defined(DOS)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,6 @@ type
|
||||||
Process* = ref ProcessObj ## represents an operating system process
|
Process* = ref ProcessObj ## represents an operating system process
|
||||||
|
|
||||||
|
|
||||||
{.deprecated: [TProcess: ProcessObj, PProcess: Process,
|
|
||||||
TProcessOption: ProcessOption].}
|
|
||||||
|
|
||||||
const poUseShell* {.deprecated.} = poUsePath
|
const poUseShell* {.deprecated.} = poUsePath
|
||||||
## Deprecated alias for poUsePath.
|
## Deprecated alias for poUsePath.
|
||||||
|
|
||||||
|
|
@ -373,17 +370,15 @@ template streamAccess(p) =
|
||||||
when defined(Windows) and not defined(useNimRtl):
|
when defined(Windows) and not defined(useNimRtl):
|
||||||
# We need to implement a handle stream for Windows:
|
# We need to implement a handle stream for Windows:
|
||||||
type
|
type
|
||||||
PFileHandleStream = ref FileHandleStream
|
FileHandleStream = ref object of StreamObj
|
||||||
FileHandleStream = object of StreamObj
|
|
||||||
handle: Handle
|
handle: Handle
|
||||||
atTheEnd: bool
|
atTheEnd: bool
|
||||||
{.deprecated: [TFileHandleStream: FileHandleStream].}
|
|
||||||
|
|
||||||
proc hsClose(s: Stream) = discard # nothing to do here
|
proc hsClose(s: Stream) = discard # nothing to do here
|
||||||
proc hsAtEnd(s: Stream): bool = return PFileHandleStream(s).atTheEnd
|
proc hsAtEnd(s: Stream): bool = return FileHandleStream(s).atTheEnd
|
||||||
|
|
||||||
proc hsReadData(s: Stream, buffer: pointer, bufLen: int): int =
|
proc hsReadData(s: Stream, buffer: pointer, bufLen: int): int =
|
||||||
var s = PFileHandleStream(s)
|
var s = FileHandleStream(s)
|
||||||
if s.atTheEnd: return 0
|
if s.atTheEnd: return 0
|
||||||
var br: int32
|
var br: int32
|
||||||
var a = winlean.readFile(s.handle, buffer, bufLen.cint, addr br, nil)
|
var a = winlean.readFile(s.handle, buffer, bufLen.cint, addr br, nil)
|
||||||
|
|
@ -395,13 +390,13 @@ when defined(Windows) and not defined(useNimRtl):
|
||||||
result = br
|
result = br
|
||||||
|
|
||||||
proc hsWriteData(s: Stream, buffer: pointer, bufLen: int) =
|
proc hsWriteData(s: Stream, buffer: pointer, bufLen: int) =
|
||||||
var s = PFileHandleStream(s)
|
var s = FileHandleStream(s)
|
||||||
var bytesWritten: int32
|
var bytesWritten: int32
|
||||||
var a = winlean.writeFile(s.handle, buffer, bufLen.cint,
|
var a = winlean.writeFile(s.handle, buffer, bufLen.cint,
|
||||||
addr bytesWritten, nil)
|
addr bytesWritten, nil)
|
||||||
if a == 0: raiseOSError(osLastError())
|
if a == 0: raiseOSError(osLastError())
|
||||||
|
|
||||||
proc newFileHandleStream(handle: Handle): PFileHandleStream =
|
proc newFileHandleStream(handle: Handle): FileHandleStream =
|
||||||
new(result)
|
new(result)
|
||||||
result.handle = handle
|
result.handle = handle
|
||||||
result.closeImpl = hsClose
|
result.closeImpl = hsClose
|
||||||
|
|
@ -527,7 +522,7 @@ when defined(Windows) and not defined(useNimRtl):
|
||||||
if setHandleInformation(he, DWORD(1), DWORD(0)) == 0'i32:
|
if setHandleInformation(he, DWORD(1), DWORD(0)) == 0'i32:
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
if setHandleInformation(hi, DWORD(1), DWORD(0)) == 0'i32:
|
if setHandleInformation(hi, DWORD(1), DWORD(0)) == 0'i32:
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
if setHandleInformation(ho, DWORD(1), DWORD(0)) == 0'i32:
|
if setHandleInformation(ho, DWORD(1), DWORD(0)) == 0'i32:
|
||||||
raiseOsError(osLastError())
|
raiseOsError(osLastError())
|
||||||
else:
|
else:
|
||||||
|
|
@ -752,14 +747,14 @@ elif not defined(useNimRtl):
|
||||||
copyMem(result[i], addr(x[0]), x.len+1)
|
copyMem(result[i], addr(x[0]), x.len+1)
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
||||||
type StartProcessData = object
|
type
|
||||||
sysCommand: string
|
StartProcessData = object
|
||||||
sysArgs: cstringArray
|
sysCommand: string
|
||||||
sysEnv: cstringArray
|
sysArgs: cstringArray
|
||||||
workingDir: cstring
|
sysEnv: cstringArray
|
||||||
pStdin, pStdout, pStderr, pErrorPipe: array[0..1, cint]
|
workingDir: cstring
|
||||||
options: set[ProcessOption]
|
pStdin, pStdout, pStderr, pErrorPipe: array[0..1, cint]
|
||||||
{.deprecated: [TStartProcessData: StartProcessData].}
|
options: set[ProcessOption]
|
||||||
|
|
||||||
const useProcessAuxSpawn = declared(posix_spawn) and not defined(useFork) and
|
const useProcessAuxSpawn = declared(posix_spawn) and not defined(useFork) and
|
||||||
not defined(useClone) and not defined(linux)
|
not defined(useClone) and not defined(linux)
|
||||||
|
|
|
||||||
|
|
@ -125,9 +125,6 @@ type
|
||||||
tok: Token
|
tok: Token
|
||||||
filename: string
|
filename: string
|
||||||
|
|
||||||
{.deprecated: [TCfgEventKind: CfgEventKind, TCfgEvent: CfgEvent,
|
|
||||||
TTokKind: TokKind, TToken: Token, TCfgParser: CfgParser].}
|
|
||||||
|
|
||||||
# implementation
|
# implementation
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,6 @@ type
|
||||||
CsvError* = object of IOError ## exception that is raised if
|
CsvError* = object of IOError ## exception that is raised if
|
||||||
## a parsing error occurs
|
## a parsing error occurs
|
||||||
|
|
||||||
{.deprecated: [TCsvRow: CsvRow, TCsvParser: CsvParser, EInvalidCsv: CsvError].}
|
|
||||||
|
|
||||||
proc raiseEInvalidCsv(filename: string, line, col: int,
|
proc raiseEInvalidCsv(filename: string, line, col: int,
|
||||||
msg: string) {.noreturn.} =
|
msg: string) {.noreturn.} =
|
||||||
var e: ref CsvError
|
var e: ref CsvError
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,6 @@ type
|
||||||
## or the argument, ``value`` is not "" if
|
## or the argument, ``value`` is not "" if
|
||||||
## the option was given a value
|
## the option was given a value
|
||||||
|
|
||||||
{.deprecated: [TCmdLineKind: CmdLineKind, TOptParser: OptParser].}
|
|
||||||
|
|
||||||
proc parseWord(s: string, i: int, w: var string,
|
proc parseWord(s: string, i: int, w: var string,
|
||||||
delim: set[char] = {'\x09', ' '}): int =
|
delim: set[char] = {'\x09', ' '}): int =
|
||||||
result = i
|
result = i
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,6 @@ type
|
||||||
## or the argument, ``value`` is not "" if
|
## or the argument, ``value`` is not "" if
|
||||||
## the option was given a value
|
## the option was given a value
|
||||||
|
|
||||||
{.deprecated: [TCmdLineKind: CmdLineKind, TOptParser: OptParser].}
|
|
||||||
|
|
||||||
proc initOptParser*(cmdline: seq[string]): OptParser {.rtl.} =
|
proc initOptParser*(cmdline: seq[string]): OptParser {.rtl.} =
|
||||||
## Initalizes option parses with cmdline. cmdline should not contain
|
## Initalizes option parses with cmdline. cmdline should not contain
|
||||||
## argument 0 - program name.
|
## argument 0 - program name.
|
||||||
|
|
@ -122,8 +120,6 @@ proc cmdLineRest*(p: OptParser): TaintedString {.rtl, extern: "npo2$1", deprecat
|
||||||
type
|
type
|
||||||
GetoptResult* = tuple[kind: CmdLineKind, key, val: TaintedString]
|
GetoptResult* = tuple[kind: CmdLineKind, key, val: TaintedString]
|
||||||
|
|
||||||
{.deprecated: [TGetoptResult: GetoptResult].}
|
|
||||||
|
|
||||||
iterator getopt*(p: var OptParser): GetoptResult =
|
iterator getopt*(p: var OptParser): GetoptResult =
|
||||||
## This is an convenience iterator for iterating over the given OptParser object.
|
## This is an convenience iterator for iterating over the given OptParser object.
|
||||||
## Example:
|
## Example:
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,6 @@ type
|
||||||
SqlLexer* = object of BaseLexer ## the parser object.
|
SqlLexer* = object of BaseLexer ## the parser object.
|
||||||
filename: string
|
filename: string
|
||||||
|
|
||||||
{.deprecated: [TToken: Token, TSqlLexer: SqlLexer].}
|
|
||||||
|
|
||||||
const
|
const
|
||||||
tokKindToStr: array[TokKind, string] = [
|
tokKindToStr: array[TokKind, string] = [
|
||||||
"invalid", "[EOF]", "identifier", "quoted identifier", "string constant",
|
"invalid", "[EOF]", "identifier", "quoted identifier", "string constant",
|
||||||
|
|
|
||||||
|
|
@ -365,8 +365,6 @@ type
|
||||||
ikVar, ## ``var`` part of the interpolated string
|
ikVar, ## ``var`` part of the interpolated string
|
||||||
ikExpr ## ``expr`` part of the interpolated string
|
ikExpr ## ``expr`` part of the interpolated string
|
||||||
|
|
||||||
{.deprecated: [TInterpolatedKind: InterpolatedKind].}
|
|
||||||
|
|
||||||
iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind,
|
iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind,
|
||||||
value: string] =
|
value: string] =
|
||||||
## Tokenizes the string `s` into substrings for interpolation purposes.
|
## Tokenizes the string `s` into substrings for interpolation purposes.
|
||||||
|
|
|
||||||
|
|
@ -98,9 +98,6 @@ type
|
||||||
filename: string
|
filename: string
|
||||||
options: set[XmlParseOption]
|
options: set[XmlParseOption]
|
||||||
|
|
||||||
{.deprecated: [TXmlParser: XmlParser, TXmlParseOptions: XmlParseOption,
|
|
||||||
TXmlError: XmlErrorKind, TXmlEventKind: XmlEventKind].}
|
|
||||||
|
|
||||||
const
|
const
|
||||||
errorMessages: array[XmlErrorKind, string] = [
|
errorMessages: array[XmlErrorKind, string] = [
|
||||||
"no error",
|
"no error",
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,8 @@ type
|
||||||
line: int ## line the symbol has been declared/used in
|
line: int ## line the symbol has been declared/used in
|
||||||
col: int ## column the symbol has been declared/used in
|
col: int ## column the symbol has been declared/used in
|
||||||
flags: set[NonTerminalFlag] ## the nonterminal's flags
|
flags: set[NonTerminalFlag] ## the nonterminal's flags
|
||||||
rule: Node ## the rule that the symbol refers to
|
rule: Peg ## the rule that the symbol refers to
|
||||||
Node {.shallow.} = object
|
Peg* {.shallow.} = object ## type that represents a PEG
|
||||||
case kind: PegKind
|
case kind: PegKind
|
||||||
of pkEmpty..pkWhitespace: nil
|
of pkEmpty..pkWhitespace: nil
|
||||||
of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle: term: string
|
of pkTerminal, pkTerminalIgnoreCase, pkTerminalIgnoreStyle: term: string
|
||||||
|
|
@ -83,13 +83,9 @@ type
|
||||||
of pkCharChoice, pkGreedyRepSet: charChoice: ref set[char]
|
of pkCharChoice, pkGreedyRepSet: charChoice: ref set[char]
|
||||||
of pkNonTerminal: nt: NonTerminal
|
of pkNonTerminal: nt: NonTerminal
|
||||||
of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns]
|
of pkBackRef..pkBackRefIgnoreStyle: index: range[0..MaxSubpatterns]
|
||||||
else: sons: seq[Node]
|
else: sons: seq[Peg]
|
||||||
NonTerminal* = ref NonTerminalObj
|
NonTerminal* = ref NonTerminalObj
|
||||||
|
|
||||||
Peg* = Node ## type that represents a PEG
|
|
||||||
|
|
||||||
{.deprecated: [TPeg: Peg, TNode: Node].}
|
|
||||||
|
|
||||||
proc term*(t: string): Peg {.nosideEffect, rtl, extern: "npegs$1Str".} =
|
proc term*(t: string): Peg {.nosideEffect, rtl, extern: "npegs$1Str".} =
|
||||||
## constructs a PEG from a terminal string
|
## constructs a PEG from a terminal string
|
||||||
if t.len != 1:
|
if t.len != 1:
|
||||||
|
|
@ -621,7 +617,7 @@ proc rawMatch*(s: string, p: Peg, start: int, c: var Captures): int {.
|
||||||
a, b: Rune
|
a, b: Rune
|
||||||
result = start
|
result = start
|
||||||
while i < len(p.term):
|
while i < len(p.term):
|
||||||
while true:
|
while i < len(p.term):
|
||||||
fastRuneAt(p.term, i, a)
|
fastRuneAt(p.term, i, a)
|
||||||
if a != Rune('_'): break
|
if a != Rune('_'): break
|
||||||
while result < s.len:
|
while result < s.len:
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,6 @@ type
|
||||||
length: int
|
length: int
|
||||||
data: string # != nil if a leaf
|
data: string # != nil if a leaf
|
||||||
|
|
||||||
{.deprecated: [PRope: Rope].}
|
|
||||||
|
|
||||||
proc isConc(r: Rope): bool {.inline.} = return isNil(r.data)
|
proc isConc(r: Rope): bool {.inline.} = return isNil(r.data)
|
||||||
|
|
||||||
# Note that the left and right pointers are not needed for leafs.
|
# Note that the left and right pointers are not needed for leafs.
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,6 @@ type
|
||||||
disp: Dispatcher
|
disp: Dispatcher
|
||||||
AsyncScgiState* = ref AsyncScgiStateObj
|
AsyncScgiState* = ref AsyncScgiStateObj
|
||||||
|
|
||||||
{.deprecated: [EScgi: ScgiError, TScgiState: ScgiState,
|
|
||||||
PAsyncScgiState: AsyncScgiState].}
|
|
||||||
|
|
||||||
proc recvBuffer(s: var ScgiState, L: int) =
|
proc recvBuffer(s: var ScgiState, L: int) =
|
||||||
if L > s.bufLen:
|
if L > s.bufLen:
|
||||||
s.bufLen = L
|
s.bufLen = L
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ else:
|
||||||
msg.add("Internal Error\n")
|
msg.add("Internal Error\n")
|
||||||
var err = newException(IOSelectorsException, msg)
|
var err = newException(IOSelectorsException, msg)
|
||||||
raise err
|
raise err
|
||||||
|
|
||||||
proc setNonBlocking(fd: cint) {.inline.} =
|
proc setNonBlocking(fd: cint) {.inline.} =
|
||||||
setBlocking(fd.SocketHandle, false)
|
setBlocking(fd.SocketHandle, false)
|
||||||
|
|
||||||
|
|
@ -316,18 +316,18 @@ else:
|
||||||
include ioselects/ioselectors_poll
|
include ioselects/ioselectors_poll
|
||||||
|
|
||||||
proc register*[T](s: Selector[T], fd: int | SocketHandle,
|
proc register*[T](s: Selector[T], fd: int | SocketHandle,
|
||||||
events: set[Event], data: T) {.deprecated.} =
|
events: set[Event], data: T) {.deprecated: "use registerHandle instead".} =
|
||||||
## **Deprecated since v0.18.0:** Use ``registerHandle`` instead.
|
## **Deprecated since v0.18.0:** Use ``registerHandle`` instead.
|
||||||
s.registerHandle(fd, events, data)
|
s.registerHandle(fd, events, data)
|
||||||
|
|
||||||
proc setEvent*(ev: SelectEvent) {.deprecated.} =
|
proc setEvent*(ev: SelectEvent) {.deprecated: "use trigger instead".} =
|
||||||
## Trigger event ``ev``.
|
## Trigger event ``ev``.
|
||||||
##
|
##
|
||||||
## **Deprecated since v0.18.0:** Use ``trigger`` instead.
|
## **Deprecated since v0.18.0:** Use ``trigger`` instead.
|
||||||
ev.trigger()
|
ev.trigger()
|
||||||
|
|
||||||
proc update*[T](s: Selector[T], fd: int | SocketHandle,
|
proc update*[T](s: Selector[T], fd: int | SocketHandle,
|
||||||
events: set[Event]) {.deprecated.} =
|
events: set[Event]) {.deprecated: "use updateHandle instead".} =
|
||||||
## Update file/socket descriptor ``fd``, registered in selector
|
## Update file/socket descriptor ``fd``, registered in selector
|
||||||
## ``s`` with new events set ``event``.
|
## ``s`` with new events set ``event``.
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,6 @@ type
|
||||||
Smtp* = SmtpBase[Socket]
|
Smtp* = SmtpBase[Socket]
|
||||||
AsyncSmtp* = SmtpBase[AsyncSocket]
|
AsyncSmtp* = SmtpBase[AsyncSocket]
|
||||||
|
|
||||||
{.deprecated: [EInvalidReply: ReplyError, TMessage: Message, TSMTP: Smtp].}
|
|
||||||
|
|
||||||
proc debugSend(smtp: Smtp | AsyncSmtp, cmd: string) {.multisync.} =
|
proc debugSend(smtp: Smtp | AsyncSmtp, cmd: string) {.multisync.} =
|
||||||
if smtp.debug:
|
if smtp.debug:
|
||||||
echo("C:" & cmd)
|
echo("C:" & cmd)
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,6 @@ type
|
||||||
y_stats*: RunningStat ## stats for second set of data
|
y_stats*: RunningStat ## stats for second set of data
|
||||||
s_xy: float ## accumulated data for combined xy
|
s_xy: float ## accumulated data for combined xy
|
||||||
|
|
||||||
{.deprecated: [TFloatClass: FloatClass, TRunningStat: RunningStat].}
|
|
||||||
|
|
||||||
# ----------- RunningStat --------------------------
|
# ----------- RunningStat --------------------------
|
||||||
proc clear*(s: var RunningStat) =
|
proc clear*(s: var RunningStat) =
|
||||||
## reset `s`
|
## reset `s`
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,6 @@ type
|
||||||
tags: [WriteIOEffect], gcsafe.}
|
tags: [WriteIOEffect], gcsafe.}
|
||||||
flushImpl*: proc (s: Stream) {.nimcall, tags: [WriteIOEffect], gcsafe.}
|
flushImpl*: proc (s: Stream) {.nimcall, tags: [WriteIOEffect], gcsafe.}
|
||||||
|
|
||||||
{.deprecated: [PStream: Stream, TStream: StreamObj].}
|
|
||||||
|
|
||||||
proc flush*(s: Stream) =
|
proc flush*(s: Stream) =
|
||||||
## flushes the buffers that the stream `s` might use.
|
## flushes the buffers that the stream `s` might use.
|
||||||
if not isNil(s.flushImpl): s.flushImpl(s)
|
if not isNil(s.flushImpl): s.flushImpl(s)
|
||||||
|
|
@ -76,27 +74,14 @@ proc atEnd*(s: Stream): bool =
|
||||||
## been read.
|
## been read.
|
||||||
result = s.atEndImpl(s)
|
result = s.atEndImpl(s)
|
||||||
|
|
||||||
proc atEnd*(s, unused: Stream): bool {.deprecated.} =
|
|
||||||
## checks if more data can be read from `f`. Returns true if all data has
|
|
||||||
## been read.
|
|
||||||
result = s.atEndImpl(s)
|
|
||||||
|
|
||||||
proc setPosition*(s: Stream, pos: int) =
|
proc setPosition*(s: Stream, pos: int) =
|
||||||
## sets the position `pos` of the stream `s`.
|
## sets the position `pos` of the stream `s`.
|
||||||
s.setPositionImpl(s, pos)
|
s.setPositionImpl(s, pos)
|
||||||
|
|
||||||
proc setPosition*(s, unused: Stream, pos: int) {.deprecated.} =
|
|
||||||
## sets the position `pos` of the stream `s`.
|
|
||||||
s.setPositionImpl(s, pos)
|
|
||||||
|
|
||||||
proc getPosition*(s: Stream): int =
|
proc getPosition*(s: Stream): int =
|
||||||
## retrieves the current position in the stream `s`.
|
## retrieves the current position in the stream `s`.
|
||||||
result = s.getPositionImpl(s)
|
result = s.getPositionImpl(s)
|
||||||
|
|
||||||
proc getPosition*(s, unused: Stream): int {.deprecated.} =
|
|
||||||
## retrieves the current position in the stream `s`.
|
|
||||||
result = s.getPositionImpl(s)
|
|
||||||
|
|
||||||
proc readData*(s: Stream, buffer: pointer, bufLen: int): int =
|
proc readData*(s: Stream, buffer: pointer, bufLen: int): int =
|
||||||
## low level proc that reads data into an untyped `buffer` of `bufLen` size.
|
## low level proc that reads data into an untyped `buffer` of `bufLen` size.
|
||||||
result = s.readDataImpl(s, buffer, bufLen)
|
result = s.readDataImpl(s, buffer, bufLen)
|
||||||
|
|
@ -114,11 +99,6 @@ proc readAll*(s: Stream): string =
|
||||||
inc r, bufferSize
|
inc r, bufferSize
|
||||||
setLen(result, r+bufferSize)
|
setLen(result, r+bufferSize)
|
||||||
|
|
||||||
proc readData*(s, unused: Stream, buffer: pointer,
|
|
||||||
bufLen: int): int {.deprecated.} =
|
|
||||||
## low level proc that reads data into an untyped `buffer` of `bufLen` size.
|
|
||||||
result = s.readDataImpl(s, buffer, bufLen)
|
|
||||||
|
|
||||||
proc peekData*(s: Stream, buffer: pointer, bufLen: int): int =
|
proc peekData*(s: Stream, buffer: pointer, bufLen: int): int =
|
||||||
## low level proc that reads data into an untyped `buffer` of `bufLen` size
|
## low level proc that reads data into an untyped `buffer` of `bufLen` size
|
||||||
## without moving stream position
|
## without moving stream position
|
||||||
|
|
@ -153,11 +133,6 @@ proc write*(s: Stream, x: string) =
|
||||||
else:
|
else:
|
||||||
if x.len > 0: writeData(s, unsafeAddr x[0], x.len)
|
if x.len > 0: writeData(s, unsafeAddr x[0], x.len)
|
||||||
|
|
||||||
proc writeLn*(s: Stream, args: varargs[string, `$`]) {.deprecated.} =
|
|
||||||
## **Deprecated since version 0.11.4:** Use **writeLine** instead.
|
|
||||||
for str in args: write(s, str)
|
|
||||||
write(s, "\n")
|
|
||||||
|
|
||||||
proc writeLine*(s: Stream, args: varargs[string, `$`]) =
|
proc writeLine*(s: Stream, args: varargs[string, `$`]) =
|
||||||
## writes one or more strings to the the stream `s` followed
|
## writes one or more strings to the the stream `s` followed
|
||||||
## by a new line. No length field or terminating zero is written.
|
## by a new line. No length field or terminating zero is written.
|
||||||
|
|
@ -348,8 +323,6 @@ when not defined(js):
|
||||||
data*: string
|
data*: string
|
||||||
pos: int
|
pos: int
|
||||||
|
|
||||||
{.deprecated: [PStringStream: StringStream, TStringStream: StringStreamObj].}
|
|
||||||
|
|
||||||
proc ssAtEnd(s: Stream): bool =
|
proc ssAtEnd(s: Stream): bool =
|
||||||
var s = StringStream(s)
|
var s = StringStream(s)
|
||||||
return s.pos >= s.data.len
|
return s.pos >= s.data.len
|
||||||
|
|
@ -409,7 +382,6 @@ when not defined(js):
|
||||||
FileStream* = ref FileStreamObj ## a stream that encapsulates a `File`
|
FileStream* = ref FileStreamObj ## a stream that encapsulates a `File`
|
||||||
FileStreamObj* = object of Stream
|
FileStreamObj* = object of Stream
|
||||||
f: File
|
f: File
|
||||||
{.deprecated: [PFileStream: FileStream, TFileStream: FileStreamObj].}
|
|
||||||
|
|
||||||
proc fsClose(s: Stream) =
|
proc fsClose(s: Stream) =
|
||||||
if FileStream(s).f != nil:
|
if FileStream(s).f != nil:
|
||||||
|
|
@ -472,9 +444,6 @@ else:
|
||||||
handle*: FileHandle
|
handle*: FileHandle
|
||||||
pos: int
|
pos: int
|
||||||
|
|
||||||
{.deprecated: [PFileHandleStream: FileHandleStream,
|
|
||||||
TFileHandleStream: FileHandleStreamObj].}
|
|
||||||
|
|
||||||
proc newEOS(msg: string): ref OSError =
|
proc newEOS(msg: string): ref OSError =
|
||||||
new(result)
|
new(result)
|
||||||
result.msg = msg
|
result.msg = msg
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,7 @@ import
|
||||||
|
|
||||||
when defined(js):
|
when defined(js):
|
||||||
{.pragma: rtlFunc.}
|
{.pragma: rtlFunc.}
|
||||||
{.pragma: deprecatedGetFunc.}
|
|
||||||
else:
|
else:
|
||||||
{.pragma: deprecatedGetFunc, deprecatedGet.}
|
|
||||||
{.pragma: rtlFunc, rtl.}
|
{.pragma: rtlFunc, rtl.}
|
||||||
import os
|
import os
|
||||||
include "system/inclrtl"
|
include "system/inclrtl"
|
||||||
|
|
@ -38,9 +36,6 @@ type
|
||||||
|
|
||||||
StringTableRef* = ref StringTableObj ## use this type to declare string tables
|
StringTableRef* = ref StringTableObj ## use this type to declare string tables
|
||||||
|
|
||||||
{.deprecated: [TStringTableMode: StringTableMode,
|
|
||||||
TStringTable: StringTableObj, PStringTable: StringTableRef].}
|
|
||||||
|
|
||||||
proc len*(t: StringTableRef): int {.rtlFunc, extern: "nst$1".} =
|
proc len*(t: StringTableRef): int {.rtlFunc, extern: "nst$1".} =
|
||||||
## returns the number of keys in `t`.
|
## returns the number of keys in `t`.
|
||||||
result = t.counter
|
result = t.counter
|
||||||
|
|
@ -73,10 +68,6 @@ type
|
||||||
useKey ## do not replace ``$key`` if it is not found
|
useKey ## do not replace ``$key`` if it is not found
|
||||||
## in the table (or in the environment)
|
## in the table (or in the environment)
|
||||||
|
|
||||||
{.deprecated: [TFormatFlag: FormatFlag].}
|
|
||||||
|
|
||||||
# implementation
|
|
||||||
|
|
||||||
const
|
const
|
||||||
growthFactor = 2
|
growthFactor = 2
|
||||||
startSize = 64
|
startSize = 64
|
||||||
|
|
@ -118,17 +109,12 @@ template get(t: StringTableRef, key: string) =
|
||||||
raise newException(KeyError, "key not found")
|
raise newException(KeyError, "key not found")
|
||||||
|
|
||||||
proc `[]`*(t: StringTableRef, key: string): var string {.
|
proc `[]`*(t: StringTableRef, key: string): var string {.
|
||||||
rtlFunc, extern: "nstTake", deprecatedGetFunc.} =
|
rtlFunc, extern: "nstTake".} =
|
||||||
## retrieves the location at ``t[key]``. If `key` is not in `t`, the
|
## retrieves the location at ``t[key]``. If `key` is not in `t`, the
|
||||||
## ``KeyError`` exception is raised. One can check with ``hasKey`` whether
|
## ``KeyError`` exception is raised. One can check with ``hasKey`` whether
|
||||||
## the key exists.
|
## the key exists.
|
||||||
get(t, key)
|
get(t, key)
|
||||||
|
|
||||||
proc mget*(t: StringTableRef, key: string): var string {.deprecated.} =
|
|
||||||
## retrieves the location at ``t[key]``. If `key` is not in `t`, the
|
|
||||||
## ``KeyError`` exception is raised. Use ```[]``` instead.
|
|
||||||
get(t, key)
|
|
||||||
|
|
||||||
proc getOrDefault*(t: StringTableRef; key: string, default: string = ""): string =
|
proc getOrDefault*(t: StringTableRef; key: string, default: string = ""): string =
|
||||||
var index = rawGet(t, key)
|
var index = rawGet(t, key)
|
||||||
if index >= 0: result = t.data[index].val
|
if index >= 0: result = t.data[index].val
|
||||||
|
|
@ -193,7 +179,8 @@ proc newStringTable*(mode: StringTableMode): StringTableRef {.
|
||||||
result.counter = 0
|
result.counter = 0
|
||||||
newSeq(result.data, startSize)
|
newSeq(result.data, startSize)
|
||||||
|
|
||||||
proc clear*(s: StringTableRef, mode: StringTableMode) =
|
proc clear*(s: StringTableRef, mode: StringTableMode) {.
|
||||||
|
rtlFunc, extern: "nst$1".} =
|
||||||
## resets a string table to be empty again.
|
## resets a string table to be empty again.
|
||||||
s.mode = mode
|
s.mode = mode
|
||||||
s.counter = 0
|
s.counter = 0
|
||||||
|
|
|
||||||
|
|
@ -1262,21 +1262,20 @@ proc initSkipTable*(a: var SkipTable, sub: string)
|
||||||
{.noSideEffect, rtl, extern: "nsuInitSkipTable".} =
|
{.noSideEffect, rtl, extern: "nsuInitSkipTable".} =
|
||||||
## Preprocess table `a` for `sub`.
|
## Preprocess table `a` for `sub`.
|
||||||
let m = len(sub)
|
let m = len(sub)
|
||||||
let m1 = m + 1
|
|
||||||
var i = 0
|
var i = 0
|
||||||
while i <= 0xff-7:
|
while i <= 0xff-7:
|
||||||
a[chr(i + 0)] = m1
|
a[chr(i + 0)] = m
|
||||||
a[chr(i + 1)] = m1
|
a[chr(i + 1)] = m
|
||||||
a[chr(i + 2)] = m1
|
a[chr(i + 2)] = m
|
||||||
a[chr(i + 3)] = m1
|
a[chr(i + 3)] = m
|
||||||
a[chr(i + 4)] = m1
|
a[chr(i + 4)] = m
|
||||||
a[chr(i + 5)] = m1
|
a[chr(i + 5)] = m
|
||||||
a[chr(i + 6)] = m1
|
a[chr(i + 6)] = m
|
||||||
a[chr(i + 7)] = m1
|
a[chr(i + 7)] = m
|
||||||
i += 8
|
i += 8
|
||||||
|
|
||||||
for i in 0..m-1:
|
for i in 0 ..< m - 1:
|
||||||
a[sub[i]] = m-i
|
a[sub[i]] = m - 1 - i
|
||||||
|
|
||||||
proc find*(a: SkipTable, s, sub: string, start: Natural = 0, last: Natural = 0): int
|
proc find*(a: SkipTable, s, sub: string, start: Natural = 0, last: Natural = 0): int
|
||||||
{.noSideEffect, rtl, extern: "nsuFindStrA".} =
|
{.noSideEffect, rtl, extern: "nsuFindStrA".} =
|
||||||
|
|
@ -1284,18 +1283,29 @@ proc find*(a: SkipTable, s, sub: string, start: Natural = 0, last: Natural = 0):
|
||||||
## If `last` is unspecified, it defaults to `s.high`.
|
## If `last` is unspecified, it defaults to `s.high`.
|
||||||
##
|
##
|
||||||
## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned.
|
## Searching is case-sensitive. If `sub` is not in `s`, -1 is returned.
|
||||||
|
|
||||||
let
|
let
|
||||||
last = if last==0: s.high else: last
|
last = if last==0: s.high else: last
|
||||||
m = len(sub)
|
sLen = last - start + 1
|
||||||
n = last + 1
|
subLast = sub.len - 1
|
||||||
# search:
|
|
||||||
var j = start
|
if subLast == -1:
|
||||||
while j <= n - m:
|
# this was an empty needle string,
|
||||||
block match:
|
# we count this as match in the first possible position:
|
||||||
for k in 0..m-1:
|
return start
|
||||||
if sub[k] != s[k+j]: break match
|
|
||||||
return j
|
# This is an implementation of the Boyer-Moore Horspool algorithms
|
||||||
inc(j, a[s[j+m]])
|
# https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore%E2%80%93Horspool_algorithm
|
||||||
|
var skip = start
|
||||||
|
|
||||||
|
while last - skip >= subLast:
|
||||||
|
var i = subLast
|
||||||
|
while s[skip + i] == sub[i]:
|
||||||
|
if i == 0:
|
||||||
|
return skip
|
||||||
|
dec i
|
||||||
|
inc skip, a[s[skip + subLast]]
|
||||||
|
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
when not (defined(js) or defined(nimdoc) or defined(nimscript)):
|
when not (defined(js) or defined(nimdoc) or defined(nimscript)):
|
||||||
|
|
@ -1455,23 +1465,41 @@ proc contains*(s: string, chars: set[char]): bool {.noSideEffect.} =
|
||||||
proc replace*(s, sub: string, by = ""): string {.noSideEffect,
|
proc replace*(s, sub: string, by = ""): string {.noSideEffect,
|
||||||
rtl, extern: "nsuReplaceStr".} =
|
rtl, extern: "nsuReplaceStr".} =
|
||||||
## Replaces `sub` in `s` by the string `by`.
|
## Replaces `sub` in `s` by the string `by`.
|
||||||
var a {.noinit.}: SkipTable
|
|
||||||
result = ""
|
result = ""
|
||||||
initSkipTable(a, sub)
|
let subLen = sub.len
|
||||||
let last = s.high
|
if subLen == 0:
|
||||||
var i = 0
|
for c in s:
|
||||||
while true:
|
add result, by
|
||||||
let j = find(a, s, sub, i, last)
|
add result, c
|
||||||
if j < 0: break
|
|
||||||
add result, substr(s, i, j - 1)
|
|
||||||
add result, by
|
add result, by
|
||||||
if sub.len == 0:
|
return
|
||||||
if i < s.len: add result, s[i]
|
elif subLen == 1:
|
||||||
i = j + 1
|
# when the pattern is a single char, we use a faster
|
||||||
else:
|
# char-based search that doesn't need a skip table:
|
||||||
i = j + sub.len
|
var c = sub[0]
|
||||||
# copy the rest:
|
let last = s.high
|
||||||
add result, substr(s, i)
|
var i = 0
|
||||||
|
while true:
|
||||||
|
let j = find(s, c, i, last)
|
||||||
|
if j < 0: break
|
||||||
|
add result, substr(s, i, j - 1)
|
||||||
|
add result, by
|
||||||
|
i = j + subLen
|
||||||
|
# copy the rest:
|
||||||
|
add result, substr(s, i)
|
||||||
|
else:
|
||||||
|
var a {.noinit.}: SkipTable
|
||||||
|
initSkipTable(a, sub)
|
||||||
|
let last = s.high
|
||||||
|
var i = 0
|
||||||
|
while true:
|
||||||
|
let j = find(a, s, sub, i, last)
|
||||||
|
if j < 0: break
|
||||||
|
add result, substr(s, i, j - 1)
|
||||||
|
add result, by
|
||||||
|
i = j + subLen
|
||||||
|
# copy the rest:
|
||||||
|
add result, substr(s, i)
|
||||||
|
|
||||||
proc replace*(s: string, sub, by: char): string {.noSideEffect,
|
proc replace*(s: string, sub, by: char): string {.noSideEffect,
|
||||||
rtl, extern: "nsuReplaceChar".} =
|
rtl, extern: "nsuReplaceChar".} =
|
||||||
|
|
@ -1492,6 +1520,7 @@ proc replaceWord*(s, sub: string, by = ""): string {.noSideEffect,
|
||||||
## Each occurrence of `sub` has to be surrounded by word boundaries
|
## Each occurrence of `sub` has to be surrounded by word boundaries
|
||||||
## (comparable to ``\\w`` in regular expressions), otherwise it is not
|
## (comparable to ``\\w`` in regular expressions), otherwise it is not
|
||||||
## replaced.
|
## replaced.
|
||||||
|
if sub.len == 0: return s
|
||||||
const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'}
|
const wordChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'}
|
||||||
var a {.noinit.}: SkipTable
|
var a {.noinit.}: SkipTable
|
||||||
result = ""
|
result = ""
|
||||||
|
|
@ -2326,236 +2355,243 @@ proc removePrefix*(s: var string, prefix: string) {.
|
||||||
s.delete(0, prefix.len - 1)
|
s.delete(0, prefix.len - 1)
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
doAssert align("abc", 4) == " abc"
|
proc nonStaticTests =
|
||||||
doAssert align("a", 0) == "a"
|
doAssert formatBiggestFloat(1234.567, ffDecimal, -1) == "1234.567000"
|
||||||
doAssert align("1232", 6) == " 1232"
|
doAssert formatBiggestFloat(1234.567, ffDecimal, 0) == "1235."
|
||||||
doAssert align("1232", 6, '#') == "##1232"
|
doAssert formatBiggestFloat(1234.567, ffDecimal, 1) == "1234.6"
|
||||||
|
doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001"
|
||||||
|
doAssert formatBiggestFloat(0.00000000001, ffScientific, 1, ',') in
|
||||||
|
["1,0e-11", "1,0e-011"]
|
||||||
|
# bug #6589
|
||||||
|
doAssert formatFloat(123.456, ffScientific, precision = -1) == "1.234560e+02"
|
||||||
|
|
||||||
doAssert alignLeft("abc", 4) == "abc "
|
doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c"
|
||||||
doAssert alignLeft("a", 0) == "a"
|
doAssert "${1}12 ${-1}$2" % ["a", "b"] == "a12 bb"
|
||||||
doAssert alignLeft("1232", 6) == "1232 "
|
|
||||||
doAssert alignLeft("1232", 6, '#') == "1232##"
|
|
||||||
|
|
||||||
let
|
block: # formatSize tests
|
||||||
inp = """ this is a long text -- muchlongerthan10chars and here
|
doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB"
|
||||||
it goes"""
|
doAssert formatSize((2.234*1024*1024).int) == "2.234MiB"
|
||||||
outp = " this is a\nlong text\n--\nmuchlongerthan10chars\nand here\nit goes"
|
doAssert formatSize(4096) == "4KiB"
|
||||||
doAssert wordWrap(inp, 10, false) == outp
|
doAssert formatSize(4096, prefix=bpColloquial, includeSpace=true) == "4 kB"
|
||||||
|
doAssert formatSize(4096, includeSpace=true) == "4 KiB"
|
||||||
|
doAssert formatSize(5_378_934, prefix=bpColloquial, decimalSep=',') == "5,13MB"
|
||||||
|
|
||||||
let
|
block: # formatEng tests
|
||||||
longInp = """ThisIsOneVeryLongStringWhichWeWillSplitIntoEightSeparatePartsNow"""
|
doAssert formatEng(0, 2, trim=false) == "0.00"
|
||||||
longOutp = "ThisIsOn\neVeryLon\ngStringW\nhichWeWi\nllSplitI\nntoEight\nSeparate\nPartsNow"
|
doAssert formatEng(0, 2) == "0"
|
||||||
doAssert wordWrap(longInp, 8, true) == longOutp
|
doAssert formatEng(53, 2, trim=false) == "53.00"
|
||||||
|
doAssert formatEng(0.053, 2, trim=false) == "53.00e-3"
|
||||||
|
doAssert formatEng(0.053, 4, trim=false) == "53.0000e-3"
|
||||||
|
doAssert formatEng(0.053, 4, trim=true) == "53e-3"
|
||||||
|
doAssert formatEng(0.053, 0) == "53e-3"
|
||||||
|
doAssert formatEng(52731234) == "52.731234e6"
|
||||||
|
doAssert formatEng(-52731234) == "-52.731234e6"
|
||||||
|
doAssert formatEng(52731234, 1) == "52.7e6"
|
||||||
|
doAssert formatEng(-52731234, 1) == "-52.7e6"
|
||||||
|
doAssert formatEng(52731234, 1, decimalSep=',') == "52,7e6"
|
||||||
|
doAssert formatEng(-52731234, 1, decimalSep=',') == "-52,7e6"
|
||||||
|
|
||||||
doAssert formatBiggestFloat(1234.567, ffDecimal, -1) == "1234.567000"
|
doAssert formatEng(4100, siPrefix=true, unit="V") == "4.1 kV"
|
||||||
doAssert formatBiggestFloat(1234.567, ffDecimal, 0) == "1235."
|
doAssert formatEng(4.1, siPrefix=true, unit="V", useUnitSpace=true) == "4.1 V"
|
||||||
doAssert formatBiggestFloat(1234.567, ffDecimal, 1) == "1234.6"
|
doAssert formatEng(4.1, siPrefix=true) == "4.1" # Note lack of space
|
||||||
doAssert formatBiggestFloat(0.00000000001, ffDecimal, 11) == "0.00000000001"
|
doAssert formatEng(4100, siPrefix=true) == "4.1 k"
|
||||||
doAssert formatBiggestFloat(0.00000000001, ffScientific, 1, ',') in
|
doAssert formatEng(4.1, siPrefix=true, unit="", useUnitSpace=true) == "4.1 " # Includes space
|
||||||
["1,0e-11", "1,0e-011"]
|
doAssert formatEng(4100, siPrefix=true, unit="") == "4.1 k"
|
||||||
# bug #6589
|
doAssert formatEng(4100) == "4.1e3"
|
||||||
doAssert formatFloat(123.456, ffScientific, precision = -1) == "1.234560e+02"
|
doAssert formatEng(4100, unit="V", useUnitSpace=true) == "4.1e3 V"
|
||||||
|
doAssert formatEng(4100, unit="", useUnitSpace=true) == "4.1e3 "
|
||||||
|
# Don't use SI prefix as number is too big
|
||||||
|
doAssert formatEng(3.1e22, siPrefix=true, unit="a", useUnitSpace=true) == "31e21 a"
|
||||||
|
# Don't use SI prefix as number is too small
|
||||||
|
doAssert formatEng(3.1e-25, siPrefix=true, unit="A", useUnitSpace=true) == "310e-27 A"
|
||||||
|
|
||||||
doAssert "$# $3 $# $#" % ["a", "b", "c"] == "a c b c"
|
proc staticTests =
|
||||||
doAssert "${1}12 ${-1}$2" % ["a", "b"] == "a12 bb"
|
doAssert align("abc", 4) == " abc"
|
||||||
|
doAssert align("a", 0) == "a"
|
||||||
|
doAssert align("1232", 6) == " 1232"
|
||||||
|
doAssert align("1232", 6, '#') == "##1232"
|
||||||
|
|
||||||
block: # formatSize tests
|
doAssert alignLeft("abc", 4) == "abc "
|
||||||
doAssert formatSize((1'i64 shl 31) + (300'i64 shl 20)) == "2.293GiB"
|
doAssert alignLeft("a", 0) == "a"
|
||||||
doAssert formatSize((2.234*1024*1024).int) == "2.234MiB"
|
doAssert alignLeft("1232", 6) == "1232 "
|
||||||
doAssert formatSize(4096) == "4KiB"
|
doAssert alignLeft("1232", 6, '#') == "1232##"
|
||||||
doAssert formatSize(4096, prefix=bpColloquial, includeSpace=true) == "4 kB"
|
|
||||||
doAssert formatSize(4096, includeSpace=true) == "4 KiB"
|
|
||||||
doAssert formatSize(5_378_934, prefix=bpColloquial, decimalSep=',') == "5,13MB"
|
|
||||||
|
|
||||||
doAssert "$animal eats $food." % ["animal", "The cat", "food", "fish"] ==
|
let
|
||||||
"The cat eats fish."
|
inp = """ this is a long text -- muchlongerthan10chars and here
|
||||||
|
it goes"""
|
||||||
|
outp = " this is a\nlong text\n--\nmuchlongerthan10chars\nand here\nit goes"
|
||||||
|
doAssert wordWrap(inp, 10, false) == outp
|
||||||
|
|
||||||
doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz "
|
let
|
||||||
doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc"
|
longInp = """ThisIsOneVeryLongStringWhichWeWillSplitIntoEightSeparatePartsNow"""
|
||||||
|
longOutp = "ThisIsOn\neVeryLon\ngStringW\nhichWeWi\nllSplitI\nntoEight\nSeparate\nPartsNow"
|
||||||
|
doAssert wordWrap(longInp, 8, true) == longOutp
|
||||||
|
|
||||||
doAssert "-lda-ldz -ld abc".replaceWord("") == "lda-ldz ld abc"
|
doAssert "$animal eats $food." % ["animal", "The cat", "food", "fish"] ==
|
||||||
doAssert "oo".replace("", "abc") == "abcoabcoabc"
|
"The cat eats fish."
|
||||||
|
|
||||||
type MyEnum = enum enA, enB, enC, enuD, enE
|
doAssert "-ld a-ldz -ld".replaceWord("-ld") == " a-ldz "
|
||||||
doAssert parseEnum[MyEnum]("enu_D") == enuD
|
doAssert "-lda-ldz -ld abc".replaceWord("-ld") == "-lda-ldz abc"
|
||||||
|
|
||||||
doAssert parseEnum("invalid enum value", enC) == enC
|
doAssert "-lda-ldz -ld abc".replaceWord("") == "-lda-ldz -ld abc"
|
||||||
|
doAssert "oo".replace("", "abc") == "abcoabcoabc"
|
||||||
|
|
||||||
doAssert center("foo", 13) == " foo "
|
type MyEnum = enum enA, enB, enC, enuD, enE
|
||||||
doAssert center("foo", 0) == "foo"
|
doAssert parseEnum[MyEnum]("enu_D") == enuD
|
||||||
doAssert center("foo", 3, fillChar = 'a') == "foo"
|
|
||||||
doAssert center("foo", 10, fillChar = '\t') == "\t\t\tfoo\t\t\t\t"
|
|
||||||
|
|
||||||
doAssert count("foofoofoo", "foofoo") == 1
|
doAssert parseEnum("invalid enum value", enC) == enC
|
||||||
doAssert count("foofoofoo", "foofoo", overlapping = true) == 2
|
|
||||||
doAssert count("foofoofoo", 'f') == 3
|
|
||||||
doAssert count("foofoofoobar", {'f','b'}) == 4
|
|
||||||
|
|
||||||
doAssert strip(" foofoofoo ") == "foofoofoo"
|
doAssert center("foo", 13) == " foo "
|
||||||
doAssert strip("sfoofoofoos", chars = {'s'}) == "foofoofoo"
|
doAssert center("foo", 0) == "foo"
|
||||||
doAssert strip("barfoofoofoobar", chars = {'b', 'a', 'r'}) == "foofoofoo"
|
doAssert center("foo", 3, fillChar = 'a') == "foo"
|
||||||
doAssert strip("stripme but don't strip this stripme",
|
doAssert center("foo", 10, fillChar = '\t') == "\t\t\tfoo\t\t\t\t"
|
||||||
chars = {'s', 't', 'r', 'i', 'p', 'm', 'e'}) ==
|
|
||||||
" but don't strip this "
|
|
||||||
doAssert strip("sfoofoofoos", leading = false, chars = {'s'}) == "sfoofoofoo"
|
|
||||||
doAssert strip("sfoofoofoos", trailing = false, chars = {'s'}) == "foofoofoos"
|
|
||||||
|
|
||||||
doAssert " foo\n bar".indent(4, "Q") == "QQQQ foo\nQQQQ bar"
|
doAssert count("foofoofoo", "foofoo") == 1
|
||||||
|
doAssert count("foofoofoo", "foofoo", overlapping = true) == 2
|
||||||
|
doAssert count("foofoofoo", 'f') == 3
|
||||||
|
doAssert count("foofoofoobar", {'f','b'}) == 4
|
||||||
|
|
||||||
doAssert "abba".multiReplace(("a", "b"), ("b", "a")) == "baab"
|
doAssert strip(" foofoofoo ") == "foofoofoo"
|
||||||
doAssert "Hello World.".multiReplace(("ello", "ELLO"), ("World.", "PEOPLE!")) == "HELLO PEOPLE!"
|
doAssert strip("sfoofoofoos", chars = {'s'}) == "foofoofoo"
|
||||||
doAssert "aaaa".multiReplace(("a", "aa"), ("aa", "bb")) == "aaaaaaaa"
|
doAssert strip("barfoofoofoobar", chars = {'b', 'a', 'r'}) == "foofoofoo"
|
||||||
|
doAssert strip("stripme but don't strip this stripme",
|
||||||
|
chars = {'s', 't', 'r', 'i', 'p', 'm', 'e'}) ==
|
||||||
|
" but don't strip this "
|
||||||
|
doAssert strip("sfoofoofoos", leading = false, chars = {'s'}) == "sfoofoofoo"
|
||||||
|
doAssert strip("sfoofoofoos", trailing = false, chars = {'s'}) == "foofoofoos"
|
||||||
|
|
||||||
doAssert isAlphaAscii('r')
|
doAssert " foo\n bar".indent(4, "Q") == "QQQQ foo\nQQQQ bar"
|
||||||
doAssert isAlphaAscii('A')
|
|
||||||
doAssert(not isAlphaAscii('$'))
|
|
||||||
|
|
||||||
doAssert isAlphaAscii("Rasp")
|
doAssert "abba".multiReplace(("a", "b"), ("b", "a")) == "baab"
|
||||||
doAssert isAlphaAscii("Args")
|
doAssert "Hello World.".multiReplace(("ello", "ELLO"), ("World.", "PEOPLE!")) == "HELLO PEOPLE!"
|
||||||
doAssert(not isAlphaAscii("$Tomato"))
|
doAssert "aaaa".multiReplace(("a", "aa"), ("aa", "bb")) == "aaaaaaaa"
|
||||||
|
|
||||||
doAssert isAlphaNumeric('3')
|
doAssert isAlphaAscii('r')
|
||||||
doAssert isAlphaNumeric('R')
|
doAssert isAlphaAscii('A')
|
||||||
doAssert(not isAlphaNumeric('!'))
|
doAssert(not isAlphaAscii('$'))
|
||||||
|
|
||||||
doAssert isAlphaNumeric("34ABc")
|
doAssert isAlphaAscii("Rasp")
|
||||||
doAssert isAlphaNumeric("Rad")
|
doAssert isAlphaAscii("Args")
|
||||||
doAssert isAlphaNumeric("1234")
|
doAssert(not isAlphaAscii("$Tomato"))
|
||||||
doAssert(not isAlphaNumeric("@nose"))
|
|
||||||
|
|
||||||
doAssert isDigit('3')
|
doAssert isAlphaNumeric('3')
|
||||||
doAssert(not isDigit('a'))
|
doAssert isAlphaNumeric('R')
|
||||||
doAssert(not isDigit('%'))
|
doAssert(not isAlphaNumeric('!'))
|
||||||
|
|
||||||
doAssert isDigit("12533")
|
doAssert isAlphaNumeric("34ABc")
|
||||||
doAssert(not isDigit("12.33"))
|
doAssert isAlphaNumeric("Rad")
|
||||||
doAssert(not isDigit("A45b"))
|
doAssert isAlphaNumeric("1234")
|
||||||
|
doAssert(not isAlphaNumeric("@nose"))
|
||||||
|
|
||||||
doAssert isSpaceAscii('\t')
|
doAssert isDigit('3')
|
||||||
doAssert isSpaceAscii('\l')
|
doAssert(not isDigit('a'))
|
||||||
doAssert(not isSpaceAscii('A'))
|
doAssert(not isDigit('%'))
|
||||||
|
|
||||||
doAssert isSpaceAscii("\t\l \v\r\f")
|
doAssert isDigit("12533")
|
||||||
doAssert isSpaceAscii(" ")
|
doAssert(not isDigit("12.33"))
|
||||||
doAssert(not isSpaceAscii("ABc \td"))
|
doAssert(not isDigit("A45b"))
|
||||||
|
|
||||||
doAssert(isNilOrWhitespace(""))
|
doAssert isSpaceAscii('\t')
|
||||||
doAssert(isNilOrWhitespace(" "))
|
doAssert isSpaceAscii('\l')
|
||||||
doAssert(isNilOrWhitespace("\t\l \v\r\f"))
|
doAssert(not isSpaceAscii('A'))
|
||||||
doAssert(not isNilOrWhitespace("ABc \td"))
|
|
||||||
|
|
||||||
doAssert isLowerAscii('a')
|
doAssert isSpaceAscii("\t\l \v\r\f")
|
||||||
doAssert isLowerAscii('z')
|
doAssert isSpaceAscii(" ")
|
||||||
doAssert(not isLowerAscii('A'))
|
doAssert(not isSpaceAscii("ABc \td"))
|
||||||
doAssert(not isLowerAscii('5'))
|
|
||||||
doAssert(not isLowerAscii('&'))
|
|
||||||
|
|
||||||
doAssert isLowerAscii("abcd")
|
doAssert(isNilOrWhitespace(""))
|
||||||
doAssert(not isLowerAscii("abCD"))
|
doAssert(isNilOrWhitespace(" "))
|
||||||
doAssert(not isLowerAscii("33aa"))
|
doAssert(isNilOrWhitespace("\t\l \v\r\f"))
|
||||||
|
doAssert(not isNilOrWhitespace("ABc \td"))
|
||||||
|
|
||||||
doAssert isUpperAscii('A')
|
doAssert isLowerAscii('a')
|
||||||
doAssert(not isUpperAscii('b'))
|
doAssert isLowerAscii('z')
|
||||||
doAssert(not isUpperAscii('5'))
|
doAssert(not isLowerAscii('A'))
|
||||||
doAssert(not isUpperAscii('%'))
|
doAssert(not isLowerAscii('5'))
|
||||||
|
doAssert(not isLowerAscii('&'))
|
||||||
|
|
||||||
doAssert isUpperAscii("ABC")
|
doAssert isLowerAscii("abcd")
|
||||||
doAssert(not isUpperAscii("AAcc"))
|
doAssert(not isLowerAscii("abCD"))
|
||||||
doAssert(not isUpperAscii("A#$"))
|
doAssert(not isLowerAscii("33aa"))
|
||||||
|
|
||||||
doAssert rsplit("foo bar", seps=Whitespace) == @["foo", "bar"]
|
doAssert isUpperAscii('A')
|
||||||
doAssert rsplit(" foo bar", seps=Whitespace, maxsplit=1) == @[" foo", "bar"]
|
doAssert(not isUpperAscii('b'))
|
||||||
doAssert rsplit(" foo bar ", seps=Whitespace, maxsplit=1) == @[" foo bar", ""]
|
doAssert(not isUpperAscii('5'))
|
||||||
doAssert rsplit(":foo:bar", sep=':') == @["", "foo", "bar"]
|
doAssert(not isUpperAscii('%'))
|
||||||
doAssert rsplit(":foo:bar", sep=':', maxsplit=2) == @["", "foo", "bar"]
|
|
||||||
doAssert rsplit(":foo:bar", sep=':', maxsplit=3) == @["", "foo", "bar"]
|
|
||||||
doAssert rsplit("foothebar", sep="the") == @["foo", "bar"]
|
|
||||||
|
|
||||||
doAssert(unescape(r"\x013", "", "") == "\x013")
|
doAssert isUpperAscii("ABC")
|
||||||
|
doAssert(not isUpperAscii("AAcc"))
|
||||||
|
doAssert(not isUpperAscii("A#$"))
|
||||||
|
|
||||||
doAssert join(["foo", "bar", "baz"]) == "foobarbaz"
|
doAssert rsplit("foo bar", seps=Whitespace) == @["foo", "bar"]
|
||||||
doAssert join(@["foo", "bar", "baz"], ", ") == "foo, bar, baz"
|
doAssert rsplit(" foo bar", seps=Whitespace, maxsplit=1) == @[" foo", "bar"]
|
||||||
doAssert join([1, 2, 3]) == "123"
|
doAssert rsplit(" foo bar ", seps=Whitespace, maxsplit=1) == @[" foo bar", ""]
|
||||||
doAssert join(@[1, 2, 3], ", ") == "1, 2, 3"
|
doAssert rsplit(":foo:bar", sep=':') == @["", "foo", "bar"]
|
||||||
|
doAssert rsplit(":foo:bar", sep=':', maxsplit=2) == @["", "foo", "bar"]
|
||||||
|
doAssert rsplit(":foo:bar", sep=':', maxsplit=3) == @["", "foo", "bar"]
|
||||||
|
doAssert rsplit("foothebar", sep="the") == @["foo", "bar"]
|
||||||
|
|
||||||
doAssert """~~!!foo
|
doAssert(unescape(r"\x013", "", "") == "\x013")
|
||||||
|
|
||||||
|
doAssert join(["foo", "bar", "baz"]) == "foobarbaz"
|
||||||
|
doAssert join(@["foo", "bar", "baz"], ", ") == "foo, bar, baz"
|
||||||
|
doAssert join([1, 2, 3]) == "123"
|
||||||
|
doAssert join(@[1, 2, 3], ", ") == "1, 2, 3"
|
||||||
|
|
||||||
|
doAssert """~~!!foo
|
||||||
~~!!bar
|
~~!!bar
|
||||||
~~!!baz""".unindent(2, "~~!!") == "foo\nbar\nbaz"
|
~~!!baz""".unindent(2, "~~!!") == "foo\nbar\nbaz"
|
||||||
|
|
||||||
doAssert """~~!!foo
|
doAssert """~~!!foo
|
||||||
~~!!bar
|
~~!!bar
|
||||||
~~!!baz""".unindent(2, "~~!!aa") == "~~!!foo\n~~!!bar\n~~!!baz"
|
~~!!baz""".unindent(2, "~~!!aa") == "~~!!foo\n~~!!bar\n~~!!baz"
|
||||||
doAssert """~~foo
|
doAssert """~~foo
|
||||||
~~ bar
|
~~ bar
|
||||||
~~ baz""".unindent(4, "~") == "foo\n bar\n baz"
|
~~ baz""".unindent(4, "~") == "foo\n bar\n baz"
|
||||||
doAssert """foo
|
doAssert """foo
|
||||||
bar
|
bar
|
||||||
baz
|
baz
|
||||||
""".unindent(4) == "foo\nbar\nbaz\n"
|
""".unindent(4) == "foo\nbar\nbaz\n"
|
||||||
doAssert """foo
|
doAssert """foo
|
||||||
bar
|
bar
|
||||||
baz
|
baz
|
||||||
""".unindent(2) == "foo\n bar\n baz\n"
|
""".unindent(2) == "foo\n bar\n baz\n"
|
||||||
doAssert """foo
|
doAssert """foo
|
||||||
bar
|
bar
|
||||||
baz
|
baz
|
||||||
""".unindent(100) == "foo\nbar\nbaz\n"
|
""".unindent(100) == "foo\nbar\nbaz\n"
|
||||||
|
|
||||||
doAssert """foo
|
doAssert """foo
|
||||||
foo
|
foo
|
||||||
bar
|
bar
|
||||||
""".unindent() == "foo\nfoo\nbar\n"
|
""".unindent() == "foo\nfoo\nbar\n"
|
||||||
|
|
||||||
let s = " this is an example "
|
let s = " this is an example "
|
||||||
let s2 = ":this;is;an:example;;"
|
let s2 = ":this;is;an:example;;"
|
||||||
|
|
||||||
doAssert s.split() == @["", "this", "is", "an", "example", "", ""]
|
doAssert s.split() == @["", "this", "is", "an", "example", "", ""]
|
||||||
doAssert s2.split(seps={':', ';'}) == @["", "this", "is", "an", "example", "", ""]
|
doAssert s2.split(seps={':', ';'}) == @["", "this", "is", "an", "example", "", ""]
|
||||||
doAssert s.split(maxsplit=4) == @["", "this", "is", "an", "example "]
|
doAssert s.split(maxsplit=4) == @["", "this", "is", "an", "example "]
|
||||||
doAssert s.split(' ', maxsplit=1) == @["", "this is an example "]
|
doAssert s.split(' ', maxsplit=1) == @["", "this is an example "]
|
||||||
doAssert s.split(" ", maxsplit=4) == @["", "this", "is", "an", "example "]
|
doAssert s.split(" ", maxsplit=4) == @["", "this", "is", "an", "example "]
|
||||||
|
|
||||||
doAssert s.splitWhitespace() == @["this", "is", "an", "example"]
|
doAssert s.splitWhitespace() == @["this", "is", "an", "example"]
|
||||||
doAssert s.splitWhitespace(maxsplit=1) == @["this", "is an example "]
|
doAssert s.splitWhitespace(maxsplit=1) == @["this", "is an example "]
|
||||||
doAssert s.splitWhitespace(maxsplit=2) == @["this", "is", "an example "]
|
doAssert s.splitWhitespace(maxsplit=2) == @["this", "is", "an example "]
|
||||||
doAssert s.splitWhitespace(maxsplit=3) == @["this", "is", "an", "example "]
|
doAssert s.splitWhitespace(maxsplit=3) == @["this", "is", "an", "example "]
|
||||||
doAssert s.splitWhitespace(maxsplit=4) == @["this", "is", "an", "example"]
|
doAssert s.splitWhitespace(maxsplit=4) == @["this", "is", "an", "example"]
|
||||||
|
|
||||||
block: # formatEng tests
|
block: # startsWith / endsWith char tests
|
||||||
doAssert formatEng(0, 2, trim=false) == "0.00"
|
var s = "abcdef"
|
||||||
doAssert formatEng(0, 2) == "0"
|
doAssert s.startsWith('a')
|
||||||
doAssert formatEng(53, 2, trim=false) == "53.00"
|
doAssert s.startsWith('b') == false
|
||||||
doAssert formatEng(0.053, 2, trim=false) == "53.00e-3"
|
doAssert s.endsWith('f')
|
||||||
doAssert formatEng(0.053, 4, trim=false) == "53.0000e-3"
|
doAssert s.endsWith('a') == false
|
||||||
doAssert formatEng(0.053, 4, trim=true) == "53e-3"
|
doAssert s.endsWith('\0') == false
|
||||||
doAssert formatEng(0.053, 0) == "53e-3"
|
|
||||||
doAssert formatEng(52731234) == "52.731234e6"
|
|
||||||
doAssert formatEng(-52731234) == "-52.731234e6"
|
|
||||||
doAssert formatEng(52731234, 1) == "52.7e6"
|
|
||||||
doAssert formatEng(-52731234, 1) == "-52.7e6"
|
|
||||||
doAssert formatEng(52731234, 1, decimalSep=',') == "52,7e6"
|
|
||||||
doAssert formatEng(-52731234, 1, decimalSep=',') == "-52,7e6"
|
|
||||||
|
|
||||||
doAssert formatEng(4100, siPrefix=true, unit="V") == "4.1 kV"
|
#echo("strutils tests passed")
|
||||||
doAssert formatEng(4.1, siPrefix=true, unit="V", useUnitSpace=true) == "4.1 V"
|
|
||||||
doAssert formatEng(4.1, siPrefix=true) == "4.1" # Note lack of space
|
|
||||||
doAssert formatEng(4100, siPrefix=true) == "4.1 k"
|
|
||||||
doAssert formatEng(4.1, siPrefix=true, unit="", useUnitSpace=true) == "4.1 " # Includes space
|
|
||||||
doAssert formatEng(4100, siPrefix=true, unit="") == "4.1 k"
|
|
||||||
doAssert formatEng(4100) == "4.1e3"
|
|
||||||
doAssert formatEng(4100, unit="V", useUnitSpace=true) == "4.1e3 V"
|
|
||||||
doAssert formatEng(4100, unit="", useUnitSpace=true) == "4.1e3 "
|
|
||||||
# Don't use SI prefix as number is too big
|
|
||||||
doAssert formatEng(3.1e22, siPrefix=true, unit="a", useUnitSpace=true) == "31e21 a"
|
|
||||||
# Don't use SI prefix as number is too small
|
|
||||||
doAssert formatEng(3.1e-25, siPrefix=true, unit="A", useUnitSpace=true) == "310e-27 A"
|
|
||||||
|
|
||||||
block: # startsWith / endsWith char tests
|
nonStaticTests()
|
||||||
var s = "abcdef"
|
staticTests()
|
||||||
doAssert s.startsWith('a')
|
static: staticTests()
|
||||||
doAssert s.startsWith('b') == false
|
|
||||||
doAssert s.endsWith('f')
|
|
||||||
doAssert s.endsWith('a') == false
|
|
||||||
doAssert s.endsWith('\0') == false
|
|
||||||
|
|
||||||
#echo("strutils tests passed")
|
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,6 @@ type
|
||||||
SubexError* = object of ValueError ## exception that is raised for
|
SubexError* = object of ValueError ## exception that is raised for
|
||||||
## an invalid subex
|
## an invalid subex
|
||||||
|
|
||||||
{.deprecated: [EInvalidSubex: SubexError].}
|
|
||||||
|
|
||||||
proc raiseInvalidFormat(msg: string) {.noinline.} =
|
proc raiseInvalidFormat(msg: string) {.noinline.} =
|
||||||
raise newException(SubexError, "invalid format string: " & msg)
|
raise newException(SubexError, "invalid format string: " & msg)
|
||||||
|
|
||||||
|
|
@ -44,7 +42,6 @@ type
|
||||||
else:
|
else:
|
||||||
f: cstring
|
f: cstring
|
||||||
num, i, lineLen: int
|
num, i, lineLen: int
|
||||||
{.deprecated: [TFormatParser: FormatParser].}
|
|
||||||
|
|
||||||
template call(x: untyped): untyped =
|
template call(x: untyped): untyped =
|
||||||
p.i = i
|
p.i = i
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,7 @@ when not hasThreadSupport:
|
||||||
var
|
var
|
||||||
colorsFGCache = initTable[Color, string]()
|
colorsFGCache = initTable[Color, string]()
|
||||||
colorsBGCache = initTable[Color, string]()
|
colorsBGCache = initTable[Color, string]()
|
||||||
when not defined(windows):
|
styleCache = initTable[int, string]()
|
||||||
var
|
|
||||||
styleCache = initTable[int, string]()
|
|
||||||
|
|
||||||
var
|
var
|
||||||
trueColorIsSupported: bool
|
trueColorIsSupported: bool
|
||||||
|
|
@ -41,10 +39,8 @@ var
|
||||||
const
|
const
|
||||||
fgPrefix = "\x1b[38;2;"
|
fgPrefix = "\x1b[38;2;"
|
||||||
bgPrefix = "\x1b[48;2;"
|
bgPrefix = "\x1b[48;2;"
|
||||||
|
ansiResetCode* = "\e[0m"
|
||||||
when not defined(windows):
|
stylePrefix = "\e["
|
||||||
const
|
|
||||||
stylePrefix = "\e["
|
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
import winlean, os
|
import winlean, os
|
||||||
|
|
@ -468,7 +464,7 @@ proc resetAttributes*(f: File) =
|
||||||
else:
|
else:
|
||||||
discard setConsoleTextAttribute(hStdout, oldStdoutAttr)
|
discard setConsoleTextAttribute(hStdout, oldStdoutAttr)
|
||||||
else:
|
else:
|
||||||
f.write("\e[0m")
|
f.write(ansiResetCode)
|
||||||
|
|
||||||
type
|
type
|
||||||
Style* = enum ## different styles for text output
|
Style* = enum ## different styles for text output
|
||||||
|
|
@ -487,15 +483,22 @@ when not defined(windows):
|
||||||
gFG {.threadvar.}: int
|
gFG {.threadvar.}: int
|
||||||
gBG {.threadvar.}: int
|
gBG {.threadvar.}: int
|
||||||
|
|
||||||
proc getStyleStr(style: int): string =
|
proc ansiStyleCode*(style: int): string =
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
result = fmt"{stylePrefix}{style}m"
|
result = fmt"{stylePrefix}{style}m"
|
||||||
|
else:
|
||||||
|
if styleCache.hasKey(style):
|
||||||
|
result = styleCache[style]
|
||||||
else:
|
else:
|
||||||
if styleCache.hasKey(style):
|
result = fmt"{stylePrefix}{style}m"
|
||||||
result = styleCache[style]
|
styleCache[style] = result
|
||||||
else:
|
|
||||||
result = fmt"{stylePrefix}{style}m"
|
template ansiStyleCode*(style: Style): string =
|
||||||
styleCache[style] = result
|
ansiStyleCode(style.int)
|
||||||
|
|
||||||
|
# The styleCache can be skipped when `style` is known at compile-time
|
||||||
|
template ansiStyleCode*(style: static[Style]): string =
|
||||||
|
(static(stylePrefix & $style.int & "m"))
|
||||||
|
|
||||||
proc setStyle*(f: File, style: set[Style]) =
|
proc setStyle*(f: File, style: set[Style]) =
|
||||||
## Sets the terminal style.
|
## Sets the terminal style.
|
||||||
|
|
@ -510,7 +513,7 @@ proc setStyle*(f: File, style: set[Style]) =
|
||||||
discard setConsoleTextAttribute(h, old or a)
|
discard setConsoleTextAttribute(h, old or a)
|
||||||
else:
|
else:
|
||||||
for s in items(style):
|
for s in items(style):
|
||||||
f.write(getStyleStr(ord(s)))
|
f.write(ansiStyleCode(s))
|
||||||
|
|
||||||
proc writeStyled*(txt: string, style: set[Style] = {styleBright}) =
|
proc writeStyled*(txt: string, style: set[Style] = {styleBright}) =
|
||||||
## Writes the text `txt` in a given `style` to stdout.
|
## Writes the text `txt` in a given `style` to stdout.
|
||||||
|
|
@ -524,9 +527,9 @@ proc writeStyled*(txt: string, style: set[Style] = {styleBright}) =
|
||||||
stdout.write(txt)
|
stdout.write(txt)
|
||||||
stdout.resetAttributes()
|
stdout.resetAttributes()
|
||||||
if gFG != 0:
|
if gFG != 0:
|
||||||
stdout.write(getStyleStr(gFG))
|
stdout.write(ansiStyleCode(gFG))
|
||||||
if gBG != 0:
|
if gBG != 0:
|
||||||
stdout.write(getStyleStr(gBG))
|
stdout.write(ansiStyleCode(gBG))
|
||||||
|
|
||||||
type
|
type
|
||||||
ForegroundColor* = enum ## terminal's foreground colors
|
ForegroundColor* = enum ## terminal's foreground colors
|
||||||
|
|
@ -572,7 +575,7 @@ proc setForegroundColor*(f: File, fg: ForegroundColor, bright=false) =
|
||||||
else:
|
else:
|
||||||
gFG = ord(fg)
|
gFG = ord(fg)
|
||||||
if bright: inc(gFG, 60)
|
if bright: inc(gFG, 60)
|
||||||
f.write(getStyleStr(gFG))
|
f.write(ansiStyleCode(gFG))
|
||||||
|
|
||||||
proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
|
proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
|
||||||
## Sets the terminal's background color.
|
## Sets the terminal's background color.
|
||||||
|
|
@ -594,10 +597,18 @@ proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) =
|
||||||
else:
|
else:
|
||||||
gBG = ord(bg)
|
gBG = ord(bg)
|
||||||
if bright: inc(gBG, 60)
|
if bright: inc(gBG, 60)
|
||||||
f.write(getStyleStr(gBG))
|
f.write(ansiStyleCode(gBG))
|
||||||
|
|
||||||
|
proc ansiForegroundColorCode*(fg: ForegroundColor, bright=false): string =
|
||||||
|
var style = ord(fg)
|
||||||
|
if bright: inc(style, 60)
|
||||||
|
return ansiStyleCode(style)
|
||||||
|
|
||||||
proc getFGColorStr(color: Color): string =
|
template ansiForegroundColorCode*(fg: static[ForegroundColor],
|
||||||
|
bright: static[bool] = false): string =
|
||||||
|
ansiStyleCode(fg.int + bright.int * 60)
|
||||||
|
|
||||||
|
proc ansiForegroundColorCode*(color: Color): string =
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
let rgb = extractRGB(color)
|
let rgb = extractRGB(color)
|
||||||
result = fmt"{fgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
result = fmt"{fgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
||||||
|
|
@ -609,7 +620,11 @@ proc getFGColorStr(color: Color): string =
|
||||||
result = fmt"{fgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
result = fmt"{fgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
||||||
colorsFGCache[color] = result
|
colorsFGCache[color] = result
|
||||||
|
|
||||||
proc getBGColorStr(color: Color): string =
|
template ansiForegroundColorCode*(color: static[Color]): string =
|
||||||
|
const rgb = extractRGB(color)
|
||||||
|
(static(fmt"{fgPrefix}{rgb.r};{rgb.g};{rgb.b}m"))
|
||||||
|
|
||||||
|
proc ansiBackgroundColorCode*(color: Color): string =
|
||||||
when hasThreadSupport:
|
when hasThreadSupport:
|
||||||
let rgb = extractRGB(color)
|
let rgb = extractRGB(color)
|
||||||
result = fmt"{bgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
result = fmt"{bgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
||||||
|
|
@ -621,15 +636,19 @@ proc getBGColorStr(color: Color): string =
|
||||||
result = fmt"{bgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
result = fmt"{bgPrefix}{rgb.r};{rgb.g};{rgb.b}m"
|
||||||
colorsFGCache[color] = result
|
colorsFGCache[color] = result
|
||||||
|
|
||||||
|
template ansiBackgroundColorCode*(color: static[Color]): string =
|
||||||
|
const rgb = extractRGB(color)
|
||||||
|
(static(fmt"{bgPrefix}{rgb.r};{rgb.g};{rgb.b}m"))
|
||||||
|
|
||||||
proc setForegroundColor*(f: File, color: Color) =
|
proc setForegroundColor*(f: File, color: Color) =
|
||||||
## Sets the terminal's foreground true color.
|
## Sets the terminal's foreground true color.
|
||||||
if trueColorIsEnabled:
|
if trueColorIsEnabled:
|
||||||
f.write(getFGColorStr(color))
|
f.write(ansiForegroundColorCode(color))
|
||||||
|
|
||||||
proc setBackgroundColor*(f: File, color: Color) =
|
proc setBackgroundColor*(f: File, color: Color) =
|
||||||
## Sets the terminal's background true color.
|
## Sets the terminal's background true color.
|
||||||
if trueColorIsEnabled:
|
if trueColorIsEnabled:
|
||||||
f.write(getBGColorStr(color))
|
f.write(ansiBackgroundColorCode(color))
|
||||||
|
|
||||||
proc setTrueColor(f: File, color: Color) =
|
proc setTrueColor(f: File, color: Color) =
|
||||||
if fgSetColor:
|
if fgSetColor:
|
||||||
|
|
@ -759,6 +778,10 @@ when defined(windows):
|
||||||
x = runeLenAt(password.string, i)
|
x = runeLenAt(password.string, i)
|
||||||
inc i, x
|
inc i, x
|
||||||
password.string.setLen(max(password.len - x, 0))
|
password.string.setLen(max(password.len - x, 0))
|
||||||
|
of chr(0x0):
|
||||||
|
# modifier key - ignore - for details see
|
||||||
|
# https://github.com/nim-lang/Nim/issues/7764
|
||||||
|
continue
|
||||||
else:
|
else:
|
||||||
password.string.add(toUTF8(c.Rune))
|
password.string.add(toUTF8(c.Rune))
|
||||||
stdout.write "\n"
|
stdout.write "\n"
|
||||||
|
|
|
||||||
|
|
@ -1173,12 +1173,16 @@ proc formatToken(dt: DateTime, token: string, buf: var string) =
|
||||||
of "dddd":
|
of "dddd":
|
||||||
buf.add($dt.weekday)
|
buf.add($dt.weekday)
|
||||||
of "h":
|
of "h":
|
||||||
buf.add($(if dt.hour > 12: dt.hour - 12 else: dt.hour))
|
if dt.hour == 0: buf.add("12")
|
||||||
|
else: buf.add($(if dt.hour > 12: dt.hour - 12 else: dt.hour))
|
||||||
of "hh":
|
of "hh":
|
||||||
let amerHour = if dt.hour > 12: dt.hour - 12 else: dt.hour
|
if dt.hour == 0:
|
||||||
if amerHour < 10:
|
buf.add("12")
|
||||||
buf.add('0')
|
else:
|
||||||
buf.add($amerHour)
|
let amerHour = if dt.hour > 12: dt.hour - 12 else: dt.hour
|
||||||
|
if amerHour < 10:
|
||||||
|
buf.add('0')
|
||||||
|
buf.add($amerHour)
|
||||||
of "H":
|
of "H":
|
||||||
buf.add($dt.hour)
|
buf.add($dt.hour)
|
||||||
of "HH":
|
of "HH":
|
||||||
|
|
@ -1503,11 +1507,15 @@ proc parseToken(dt: var DateTime; token, value: string; j: var int) =
|
||||||
dt.second = value[j..j+1].parseInt()
|
dt.second = value[j..j+1].parseInt()
|
||||||
j += 2
|
j += 2
|
||||||
of "t":
|
of "t":
|
||||||
if value[j] == 'P' and dt.hour > 0 and dt.hour < 12:
|
if value[j] == 'A' and dt.hour == 12:
|
||||||
|
dt.hour = 0
|
||||||
|
elif value[j] == 'P' and dt.hour > 0 and dt.hour < 12:
|
||||||
dt.hour += 12
|
dt.hour += 12
|
||||||
j += 1
|
j += 1
|
||||||
of "tt":
|
of "tt":
|
||||||
if value[j..j+1] == "PM" and dt.hour > 0 and dt.hour < 12:
|
if value[j..j+1] == "AM" and dt.hour == 12:
|
||||||
|
dt.hour = 0
|
||||||
|
elif value[j..j+1] == "PM" and dt.hour > 0 and dt.hour < 12:
|
||||||
dt.hour += 12
|
dt.hour += 12
|
||||||
j += 2
|
j += 2
|
||||||
of "yy":
|
of "yy":
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,12 @@ type
|
||||||
hostname*, port*, path*, query*, anchor*: string
|
hostname*, port*, path*, query*, anchor*: string
|
||||||
opaque*: bool
|
opaque*: bool
|
||||||
|
|
||||||
{.deprecated: [TUrl: Url, TUri: Uri].}
|
|
||||||
|
|
||||||
{.push warning[deprecated]: off.}
|
{.push warning[deprecated]: off.}
|
||||||
proc `$`*(url: Url): string {.deprecated.} =
|
proc `$`*(url: Url): string {.deprecated: "use Uri instead".} =
|
||||||
## **Deprecated since 0.9.6**: Use ``Uri`` instead.
|
## **Deprecated since 0.9.6**: Use ``Uri`` instead.
|
||||||
return string(url)
|
return string(url)
|
||||||
|
|
||||||
proc `/`*(a, b: Url): Url {.deprecated.} =
|
proc `/`*(a, b: Url): Url {.deprecated: "use Uri instead".} =
|
||||||
## Joins two URLs together, separating them with / if needed.
|
## Joins two URLs together, separating them with / if needed.
|
||||||
##
|
##
|
||||||
## **Deprecated since 0.9.6**: Use ``Uri`` instead.
|
## **Deprecated since 0.9.6**: Use ``Uri`` instead.
|
||||||
|
|
@ -40,32 +38,43 @@ proc `/`*(a, b: Url): Url {.deprecated.} =
|
||||||
urlS.add(bs)
|
urlS.add(bs)
|
||||||
result = Url(urlS)
|
result = Url(urlS)
|
||||||
|
|
||||||
proc add*(url: var Url, a: Url) {.deprecated.} =
|
proc add*(url: var Url, a: Url) {.deprecated: "use Uri instead".} =
|
||||||
## Appends url to url.
|
## Appends url to url.
|
||||||
##
|
##
|
||||||
## **Deprecated since 0.9.6**: Use ``Uri`` instead.
|
## **Deprecated since 0.9.6**: Use ``Uri`` instead.
|
||||||
url = url / a
|
url = url / a
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
proc encodeUrl*(s: string): string =
|
proc encodeUrl*(s: string, usePlus=true): string =
|
||||||
## Encodes a value to be HTTP safe: This means that characters in the set
|
## Encodes a URL according to RFC3986.
|
||||||
## ``{'A'..'Z', 'a'..'z', '0'..'9', '_'}`` are carried over to the result,
|
##
|
||||||
## a space is converted to ``'+'`` and every other character is encoded as
|
## This means that characters in the set
|
||||||
## ``'%xx'`` where ``xx`` denotes its hexadecimal value.
|
## ``{'a'..'z', 'A'..'Z', '0'..'9', '-', '.', '_', '~'}`` are
|
||||||
|
## carried over to the result.
|
||||||
|
## All other characters are encoded as ``''%xx'`` where ``xx``
|
||||||
|
## denotes its hexadecimal value.
|
||||||
|
##
|
||||||
|
## As a special rule, when the value of ``usePlus`` is true,
|
||||||
|
## spaces are encoded as ``'+'`` instead of ``'%20'``.
|
||||||
result = newStringOfCap(s.len + s.len shr 2) # assume 12% non-alnum-chars
|
result = newStringOfCap(s.len + s.len shr 2) # assume 12% non-alnum-chars
|
||||||
for i in 0..s.len-1:
|
let fromSpace = if usePlus: "+" else: "%20"
|
||||||
case s[i]
|
for c in s:
|
||||||
of 'a'..'z', 'A'..'Z', '0'..'9', '_': add(result, s[i])
|
case c
|
||||||
of ' ': add(result, '+')
|
of 'a'..'z', 'A'..'Z', '0'..'9', '-', '.', '_', '~': add(result, c)
|
||||||
|
of ' ': add(result, fromSpace)
|
||||||
else:
|
else:
|
||||||
add(result, '%')
|
add(result, '%')
|
||||||
add(result, toHex(ord(s[i]), 2))
|
add(result, toHex(ord(c), 2))
|
||||||
|
|
||||||
proc decodeUrl*(s: string): string =
|
proc decodeUrl*(s: string, decodePlus=true): string =
|
||||||
## Decodes a value from its HTTP representation: This means that a ``'+'``
|
## Decodes a URL according to RFC3986.
|
||||||
## is converted to a space, ``'%xx'`` (where ``xx`` denotes a hexadecimal
|
##
|
||||||
## value) is converted to the character with ordinal number ``xx``, and
|
## This means that any ``'%xx'`` (where ``xx`` denotes a hexadecimal
|
||||||
|
## value) are converted to the character with ordinal number ``xx``,
|
||||||
## and every other character is carried over.
|
## and every other character is carried over.
|
||||||
|
##
|
||||||
|
## As a special rule, when the value of ``decodePlus`` is true, ``'+'``
|
||||||
|
## characters are converted to a space.
|
||||||
proc handleHexChar(c: char, x: var int) {.inline.} =
|
proc handleHexChar(c: char, x: var int) {.inline.} =
|
||||||
case c
|
case c
|
||||||
of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
|
of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
|
||||||
|
|
@ -84,7 +93,11 @@ proc decodeUrl*(s: string): string =
|
||||||
handleHexChar(s[i+2], x)
|
handleHexChar(s[i+2], x)
|
||||||
inc(i, 2)
|
inc(i, 2)
|
||||||
result[j] = chr(x)
|
result[j] = chr(x)
|
||||||
of '+': result[j] = ' '
|
of '+':
|
||||||
|
if decodePlus:
|
||||||
|
result[j] = ' '
|
||||||
|
else:
|
||||||
|
result[j] = s[i]
|
||||||
else: result[j] = s[i]
|
else: result[j] = s[i]
|
||||||
inc(i)
|
inc(i)
|
||||||
inc(j)
|
inc(j)
|
||||||
|
|
@ -370,6 +383,9 @@ when isMainModule:
|
||||||
const test1 = "abc\L+def xyz"
|
const test1 = "abc\L+def xyz"
|
||||||
doAssert encodeUrl(test1) == "abc%0A%2Bdef+xyz"
|
doAssert encodeUrl(test1) == "abc%0A%2Bdef+xyz"
|
||||||
doAssert decodeUrl(encodeUrl(test1)) == test1
|
doAssert decodeUrl(encodeUrl(test1)) == test1
|
||||||
|
doAssert encodeUrl(test1, false) == "abc%0A%2Bdef%20xyz"
|
||||||
|
doAssert decodeUrl(encodeUrl(test1, false), false) == test1
|
||||||
|
doAssert decodeUrl(encodeUrl(test1)) == test1
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let str = "http://localhost"
|
let str = "http://localhost"
|
||||||
|
|
|
||||||
|
|
@ -1069,17 +1069,15 @@ proc splitData*(textNode: PText, offset: int): PText =
|
||||||
var newNode: PText = textNode.fOwnerDocument.createTextNode(right)
|
var newNode: PText = textNode.fOwnerDocument.createTextNode(right)
|
||||||
return newNode
|
return newNode
|
||||||
|
|
||||||
|
|
||||||
# ProcessingInstruction
|
# ProcessingInstruction
|
||||||
proc target*(pi: PProcessingInstruction): string =
|
proc target*(pi: PProcessingInstruction): string =
|
||||||
## Returns the Processing Instructions target
|
## Returns the Processing Instructions target
|
||||||
|
|
||||||
return pi.fTarget
|
return pi.fTarget
|
||||||
|
|
||||||
|
proc escapeXml*(s: string; result: var string) =
|
||||||
# --Other stuff--
|
## Prepares a string for insertion into a XML document
|
||||||
# Writer
|
## by escaping the XML special characters.
|
||||||
proc addEscaped(s: string): string =
|
|
||||||
result = ""
|
result = ""
|
||||||
for c in items(s):
|
for c in items(s):
|
||||||
case c
|
case c
|
||||||
|
|
@ -1089,11 +1087,20 @@ proc addEscaped(s: string): string =
|
||||||
of '"': result.add(""")
|
of '"': result.add(""")
|
||||||
else: result.add(c)
|
else: result.add(c)
|
||||||
|
|
||||||
|
proc escapeXml*(s: string): string =
|
||||||
|
## Prepares a string for insertion into a XML document
|
||||||
|
## by escaping the XML special characters.
|
||||||
|
result = newStringOfCap(s.len + s.len shr 4)
|
||||||
|
escapeXml(s, result)
|
||||||
|
|
||||||
|
# --Other stuff--
|
||||||
|
# Writer
|
||||||
|
|
||||||
proc nodeToXml(n: PNode, indent: int = 0): string =
|
proc nodeToXml(n: PNode, indent: int = 0): string =
|
||||||
result = spaces(indent) & "<" & n.nodeName
|
result = spaces(indent) & "<" & n.nodeName
|
||||||
if not isNil(n.attributes):
|
if not isNil(n.attributes):
|
||||||
for i in items(n.attributes):
|
for i in items(n.attributes):
|
||||||
result.add(" " & i.name & "=\"" & addEscaped(i.value) & "\"")
|
result.add(" " & i.name & "=\"" & escapeXml(i.value) & "\"")
|
||||||
|
|
||||||
if isNil(n.childNodes) or n.childNodes.len() == 0:
|
if isNil(n.childNodes) or n.childNodes.len() == 0:
|
||||||
result.add("/>") # No idea why this doesn't need a \n :O
|
result.add("/>") # No idea why this doesn't need a \n :O
|
||||||
|
|
@ -1106,7 +1113,7 @@ proc nodeToXml(n: PNode, indent: int = 0): string =
|
||||||
result.add(nodeToXml(i, indent + 2))
|
result.add(nodeToXml(i, indent + 2))
|
||||||
of TextNode:
|
of TextNode:
|
||||||
result.add(spaces(indent * 2))
|
result.add(spaces(indent * 2))
|
||||||
result.add(addEscaped(i.nodeValue))
|
result.add(escapeXml(i.nodeValue))
|
||||||
of CDataSectionNode:
|
of CDataSectionNode:
|
||||||
result.add(spaces(indent * 2))
|
result.add(spaces(indent * 2))
|
||||||
result.add("<![CDATA[" & i.nodeValue & "]]>")
|
result.add("<![CDATA[" & i.nodeValue & "]]>")
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@ type
|
||||||
## for invalid XML.
|
## for invalid XML.
|
||||||
errors*: seq[string] ## All detected parsing errors.
|
errors*: seq[string] ## All detected parsing errors.
|
||||||
|
|
||||||
{.deprecated: [EInvalidXml: XmlError].}
|
|
||||||
|
|
||||||
proc raiseInvalidXml(errors: seq[string]) =
|
proc raiseInvalidXml(errors: seq[string]) =
|
||||||
var e: ref XmlError
|
var e: ref XmlError
|
||||||
new(e)
|
new(e)
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,6 @@ type
|
||||||
fAttr: XmlAttributes
|
fAttr: XmlAttributes
|
||||||
fClientData: int ## for other clients
|
fClientData: int ## for other clients
|
||||||
|
|
||||||
{.deprecated: [PXmlNode: XmlNode, TXmlNodeKind: XmlNodeKind, PXmlAttributes:
|
|
||||||
XmlAttributes, TXmlNode: XmlNodeObj].}
|
|
||||||
|
|
||||||
proc newXmlNode(kind: XmlNodeKind): XmlNode =
|
proc newXmlNode(kind: XmlNodeKind): XmlNode =
|
||||||
## creates a new ``XmlNode``.
|
## creates a new ``XmlNode``.
|
||||||
new(result)
|
new(result)
|
||||||
|
|
@ -155,11 +152,6 @@ proc `[]`* (n: var XmlNode, i: int): var XmlNode {.inline.} =
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
result = n.s[i]
|
result = n.s[i]
|
||||||
|
|
||||||
proc mget*(n: var XmlNode, i: int): var XmlNode {.inline, deprecated.} =
|
|
||||||
## returns the `i`'th child of `n` so that it can be modified. Use ```[]```
|
|
||||||
## instead.
|
|
||||||
n[i]
|
|
||||||
|
|
||||||
iterator items*(n: XmlNode): XmlNode {.inline.} =
|
iterator items*(n: XmlNode): XmlNode {.inline.} =
|
||||||
## iterates over any child of `n`.
|
## iterates over any child of `n`.
|
||||||
assert n.k == xnElement
|
assert n.k == xnElement
|
||||||
|
|
@ -319,8 +311,8 @@ proc xmlConstructor(a: NimNode): NimNode {.compileTime.} =
|
||||||
if a.kind == nnkCall:
|
if a.kind == nnkCall:
|
||||||
result = newCall("newXmlTree", toStrLit(a[0]))
|
result = newCall("newXmlTree", toStrLit(a[0]))
|
||||||
var attrs = newNimNode(nnkBracket, a)
|
var attrs = newNimNode(nnkBracket, a)
|
||||||
var newStringTabCall = newCall("newStringTable", attrs,
|
var newStringTabCall = newCall(bindSym"newStringTable", attrs,
|
||||||
newIdentNode("modeCaseSensitive"))
|
bindSym"modeCaseSensitive")
|
||||||
var elements = newNimNode(nnkBracket, a)
|
var elements = newNimNode(nnkBracket, a)
|
||||||
for i in 1..a.len-1:
|
for i in 1..a.len-1:
|
||||||
if a[i].kind == nnkExprEqExpr:
|
if a[i].kind == nnkExprEqExpr:
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue