Merge branch 'devel' into vm_float_casts
This commit is contained in:
commit
4c53d45674
23 changed files with 251 additions and 53 deletions
0
bin/nim-gdb
Normal file → Executable file
0
bin/nim-gdb
Normal file → Executable file
|
|
@ -27,6 +27,9 @@
|
||||||
|
|
||||||
- Added `or` for `NimNode` in `macros`.
|
- Added `or` for `NimNode` in `macros`.
|
||||||
|
|
||||||
|
- Added `system.typeof` for more control over how `type` expressions
|
||||||
|
can be deduced.
|
||||||
|
|
||||||
### Library changes
|
### Library changes
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -400,6 +400,16 @@ proc genGotoForCase(p: BProc; caseStmt: PNode) =
|
||||||
genStmts(p, it.lastSon)
|
genStmts(p, it.lastSon)
|
||||||
endBlock(p)
|
endBlock(p)
|
||||||
|
|
||||||
|
|
||||||
|
iterator fieldValuePairs(n: PNode): tuple[memberSym, valueSym: PNode] =
|
||||||
|
assert(n.kind in {nkLetSection, nkVarSection})
|
||||||
|
for identDefs in n:
|
||||||
|
if identDefs.kind == nkIdentDefs:
|
||||||
|
let valueSym = identDefs[^1]
|
||||||
|
for i in 0 ..< identDefs.len-2:
|
||||||
|
let memberSym = identDefs[i]
|
||||||
|
yield((memberSym: memberSym, valueSym: valueSym))
|
||||||
|
|
||||||
proc genComputedGoto(p: BProc; n: PNode) =
|
proc genComputedGoto(p: BProc; n: PNode) =
|
||||||
# first pass: Generate array of computed labels:
|
# first pass: Generate array of computed labels:
|
||||||
var casePos = -1
|
var casePos = -1
|
||||||
|
|
@ -429,22 +439,12 @@ proc genComputedGoto(p: BProc; n: PNode) =
|
||||||
let tmp = "TMP$1_" % [id.rope]
|
let tmp = "TMP$1_" % [id.rope]
|
||||||
var gotoArray = "static void* $#[$#] = {" % [tmp, arraySize.rope]
|
var gotoArray = "static void* $#[$#] = {" % [tmp, arraySize.rope]
|
||||||
for i in 1..arraySize-1:
|
for i in 1..arraySize-1:
|
||||||
gotoArray.addf("&&TMP$#_, ", [(id+i).rope])
|
gotoArray.addf("&&TMP$#_, ", [rope(id+i)])
|
||||||
gotoArray.addf("&&TMP$#_};$n", [(id+arraySize).rope])
|
gotoArray.addf("&&TMP$#_};$n", [rope(id+arraySize)])
|
||||||
line(p, cpsLocals, gotoArray)
|
line(p, cpsLocals, gotoArray)
|
||||||
|
|
||||||
let topBlock = p.blocks.len-1
|
for j in 0 ..< casePos:
|
||||||
let oldBody = p.blocks[topBlock].sections[cpsStmts]
|
genStmts(p, n.sons[j])
|
||||||
p.blocks[topBlock].sections[cpsStmts] = nil
|
|
||||||
|
|
||||||
for j in casePos+1 ..< n.len: genStmts(p, n.sons[j])
|
|
||||||
let tailB = p.blocks[topBlock].sections[cpsStmts]
|
|
||||||
|
|
||||||
p.blocks[topBlock].sections[cpsStmts] = nil
|
|
||||||
for j in 0 .. casePos-1: genStmts(p, n.sons[j])
|
|
||||||
let tailA = p.blocks[topBlock].sections[cpsStmts]
|
|
||||||
|
|
||||||
p.blocks[topBlock].sections[cpsStmts] = oldBody & tailA
|
|
||||||
|
|
||||||
let caseStmt = n.sons[casePos]
|
let caseStmt = n.sons[casePos]
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
|
|
@ -459,19 +459,40 @@ proc genComputedGoto(p: BProc; n: PNode) =
|
||||||
if it.sons[j].kind == nkRange:
|
if it.sons[j].kind == nkRange:
|
||||||
localError(p.config, it.info, "range notation not available for computed goto")
|
localError(p.config, it.info, "range notation not available for computed goto")
|
||||||
return
|
return
|
||||||
|
|
||||||
let val = getOrdValue(it.sons[j])
|
let val = getOrdValue(it.sons[j])
|
||||||
lineF(p, cpsStmts, "TMP$#_:$n", [intLiteral(val+id+1)])
|
lineF(p, cpsStmts, "TMP$#_:$n", [intLiteral(val+id+1)])
|
||||||
|
|
||||||
genStmts(p, it.lastSon)
|
genStmts(p, it.lastSon)
|
||||||
#for j in casePos+1 ..< n.len: genStmts(p, n.sons[j]) # tailB
|
|
||||||
#for j in 0 .. casePos-1: genStmts(p, n.sons[j]) # tailA
|
for j in casePos+1 ..< n.sons.len:
|
||||||
add(p.s(cpsStmts), tailB)
|
genStmts(p, n.sons[j])
|
||||||
add(p.s(cpsStmts), tailA)
|
|
||||||
|
for j in 0 ..< casePos:
|
||||||
|
# prevent new local declarations
|
||||||
|
# compile declarations as assignments
|
||||||
|
let it = n.sons[j]
|
||||||
|
if it.kind in {nkLetSection, nkVarSection}:
|
||||||
|
let asgn = copyNode(it)
|
||||||
|
asgn.kind = nkAsgn
|
||||||
|
asgn.sons.setLen 2
|
||||||
|
for sym, value in it.fieldValuePairs:
|
||||||
|
if value.kind != nkEmpty:
|
||||||
|
asgn.sons[0] = sym
|
||||||
|
asgn.sons[1] = value
|
||||||
|
genStmts(p, asgn)
|
||||||
|
else:
|
||||||
|
genStmts(p, it)
|
||||||
|
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, caseStmt.sons[0], a)
|
initLocExpr(p, caseStmt.sons[0], a)
|
||||||
lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc])
|
lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc])
|
||||||
endBlock(p)
|
endBlock(p)
|
||||||
|
|
||||||
|
for j in casePos+1 ..< n.sons.len:
|
||||||
|
genStmts(p, n.sons[j])
|
||||||
|
|
||||||
|
|
||||||
proc genWhileStmt(p: BProc, t: PNode) =
|
proc genWhileStmt(p: BProc, t: PNode) =
|
||||||
# we don't generate labels here as for example GCC would produce
|
# we don't generate labels here as for example GCC would produce
|
||||||
# significantly worse code
|
# significantly worse code
|
||||||
|
|
@ -482,20 +503,20 @@ proc genWhileStmt(p: BProc, t: PNode) =
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
|
|
||||||
preserveBreakIdx:
|
preserveBreakIdx:
|
||||||
p.breakIdx = startBlock(p, "while (1) {$n")
|
|
||||||
p.blocks[p.breakIdx].isLoop = true
|
|
||||||
initLocExpr(p, t.sons[0], a)
|
|
||||||
if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
|
|
||||||
let label = assignLabel(p.blocks[p.breakIdx])
|
|
||||||
lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
|
|
||||||
var loopBody = t.sons[1]
|
var loopBody = t.sons[1]
|
||||||
if loopBody.stmtsContainPragma(wComputedGoto) and
|
if loopBody.stmtsContainPragma(wComputedGoto) and
|
||||||
hasComputedGoto in CC[p.config.cCompiler].props:
|
hasComputedGoto in CC[p.config.cCompiler].props:
|
||||||
# for closure support weird loop bodies are generated:
|
# for closure support weird loop bodies are generated:
|
||||||
if loopBody.len == 2 and loopBody.sons[0].kind == nkEmpty:
|
if loopBody.len == 2 and loopBody.sons[0].kind == nkEmpty:
|
||||||
loopBody = loopBody.sons[1]
|
loopBody = loopBody.sons[1]
|
||||||
genComputedGoto(p, loopBody)
|
genComputedGoto(p, loopBody) # TODO foobar
|
||||||
else:
|
else:
|
||||||
|
p.breakIdx = startBlock(p, "while (1) {$n")
|
||||||
|
p.blocks[p.breakIdx].isLoop = true
|
||||||
|
initLocExpr(p, t.sons[0], a)
|
||||||
|
if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
|
||||||
|
let label = assignLabel(p.blocks[p.breakIdx])
|
||||||
|
lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
|
||||||
genStmts(p, loopBody)
|
genStmts(p, loopBody)
|
||||||
|
|
||||||
if optProfiler in p.options:
|
if optProfiler in p.options:
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ proc initDefines*(symbols: StringTableRef) =
|
||||||
defineSymbol("nimNoNilSeqs2")
|
defineSymbol("nimNoNilSeqs2")
|
||||||
defineSymbol("nimHasUserErrors")
|
defineSymbol("nimHasUserErrors")
|
||||||
defineSymbol("nimUncheckedArrayTyp")
|
defineSymbol("nimUncheckedArrayTyp")
|
||||||
|
defineSymbol("nimHasTypeof")
|
||||||
|
|
||||||
defineSymbol("nimHasNilSeqs")
|
defineSymbol("nimHasNilSeqs")
|
||||||
for f in low(Feature)..high(Feature):
|
for f in low(Feature)..high(Feature):
|
||||||
|
|
|
||||||
|
|
@ -268,9 +268,6 @@ proc patchHead(n: PNode) =
|
||||||
if sfFromGeneric in s.flags:
|
if sfFromGeneric in s.flags:
|
||||||
excl(s.flags, sfFromGeneric)
|
excl(s.flags, sfFromGeneric)
|
||||||
patchHead(s.getBody)
|
patchHead(s.getBody)
|
||||||
if n[1].typ.isNil:
|
|
||||||
# XXX toptree crashes without this workaround. Figure out why.
|
|
||||||
return
|
|
||||||
let t = n[1].typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred})
|
let t = n[1].typ.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred})
|
||||||
template patch(op, field) =
|
template patch(op, field) =
|
||||||
if s.name.s == op and field != nil and field != s:
|
if s.name.s == op and field != nil and field != s:
|
||||||
|
|
@ -296,6 +293,10 @@ proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string) =
|
||||||
m.add c.graph.config $ c.otherRead.info
|
m.add c.graph.config $ c.otherRead.info
|
||||||
localError(c.graph.config, ri.info, errGenerated, m)
|
localError(c.graph.config, ri.info, errGenerated, m)
|
||||||
|
|
||||||
|
proc makePtrType(c: Con, baseType: PType): PType =
|
||||||
|
result = newType(tyPtr, c.owner)
|
||||||
|
addSonSkipIntLit(result, baseType)
|
||||||
|
|
||||||
template genOp(opr, opname, ri) =
|
template genOp(opr, opname, ri) =
|
||||||
let op = opr
|
let op = opr
|
||||||
if op == nil:
|
if op == nil:
|
||||||
|
|
@ -304,7 +305,9 @@ template genOp(opr, opname, ri) =
|
||||||
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic")
|
globalError(c.graph.config, dest.info, "internal error: '" & opname & "' operator is generic")
|
||||||
patchHead op
|
patchHead op
|
||||||
if sfError in op.flags: checkForErrorPragma(c, t, ri, opname)
|
if sfError in op.flags: checkForErrorPragma(c, t, ri, opname)
|
||||||
result = newTree(nkCall, newSymNode(op), newTree(nkHiddenAddr, dest))
|
let addrExp = newNodeIT(nkHiddenAddr, dest.info, makePtrType(c, dest.typ))
|
||||||
|
addrExp.add(dest)
|
||||||
|
result = newTree(nkCall, newSymNode(op), addrExp)
|
||||||
|
|
||||||
proc genSink(c: Con; t: PType; dest, ri: PNode): PNode =
|
proc genSink(c: Con; t: PType; dest, ri: PNode): PNode =
|
||||||
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
let t = t.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
|
|
|
||||||
|
|
@ -1118,6 +1118,7 @@ proc skip(L: var TLexer, tok: var TToken) =
|
||||||
tok.strongSpaceA = 0
|
tok.strongSpaceA = 0
|
||||||
when defined(nimpretty):
|
when defined(nimpretty):
|
||||||
var hasComment = false
|
var hasComment = false
|
||||||
|
var commentIndent = L.currLineIndent
|
||||||
tok.commentOffsetA = L.offsetBase + pos
|
tok.commentOffsetA = L.offsetBase + pos
|
||||||
tok.commentOffsetB = tok.commentOffsetA
|
tok.commentOffsetB = tok.commentOffsetA
|
||||||
tok.line = -1
|
tok.line = -1
|
||||||
|
|
@ -1139,13 +1140,18 @@ proc skip(L: var TLexer, tok: var TToken) =
|
||||||
inc(pos)
|
inc(pos)
|
||||||
inc(indent)
|
inc(indent)
|
||||||
elif buf[pos] == '#' and buf[pos+1] == '[':
|
elif buf[pos] == '#' and buf[pos+1] == '[':
|
||||||
when defined(nimpretty): hasComment = true
|
when defined(nimpretty):
|
||||||
|
hasComment = true
|
||||||
|
if tok.line < 0:
|
||||||
|
tok.line = L.lineNumber
|
||||||
skipMultiLineComment(L, tok, pos+2, false)
|
skipMultiLineComment(L, tok, pos+2, false)
|
||||||
pos = L.bufpos
|
pos = L.bufpos
|
||||||
buf = L.buf
|
buf = L.buf
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
tok.strongSpaceA = 0
|
tok.strongSpaceA = 0
|
||||||
|
when defined(nimpretty):
|
||||||
|
if buf[pos] == '#' and tok.line < 0: commentIndent = indent
|
||||||
if buf[pos] > ' ' and (buf[pos] != '#' or buf[pos+1] == '#'):
|
if buf[pos] > ' ' and (buf[pos] != '#' or buf[pos+1] == '#'):
|
||||||
tok.indent = indent
|
tok.indent = indent
|
||||||
L.currLineIndent = indent
|
L.currLineIndent = indent
|
||||||
|
|
@ -1155,7 +1161,8 @@ proc skip(L: var TLexer, tok: var TToken) =
|
||||||
if buf[pos+1] == '#': break
|
if buf[pos+1] == '#': break
|
||||||
when defined(nimpretty):
|
when defined(nimpretty):
|
||||||
hasComment = true
|
hasComment = true
|
||||||
if tok.line < 0: tok.line = L.lineNumber
|
if tok.line < 0:
|
||||||
|
tok.line = L.lineNumber
|
||||||
|
|
||||||
if buf[pos+1] == '[':
|
if buf[pos+1] == '[':
|
||||||
skipMultiLineComment(L, tok, pos+2, false)
|
skipMultiLineComment(L, tok, pos+2, false)
|
||||||
|
|
@ -1177,6 +1184,7 @@ proc skip(L: var TLexer, tok: var TToken) =
|
||||||
if hasComment:
|
if hasComment:
|
||||||
tok.commentOffsetB = L.offsetBase + pos - 1
|
tok.commentOffsetB = L.offsetBase + pos - 1
|
||||||
tok.tokType = tkComment
|
tok.tokType = tkComment
|
||||||
|
tok.indent = commentIndent
|
||||||
if gIndentationWidth <= 0:
|
if gIndentationWidth <= 0:
|
||||||
gIndentationWidth = tok.indent
|
gIndentationWidth = tok.indent
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1414,6 +1414,20 @@ proc semTypeof(c: PContext; n: PNode; prev: PType): PType =
|
||||||
fixupTypeOf(c, prev, t)
|
fixupTypeOf(c, prev, t)
|
||||||
result = t.typ
|
result = t.typ
|
||||||
|
|
||||||
|
proc semTypeof2(c: PContext; n: PNode; prev: PType): PType =
|
||||||
|
openScope(c)
|
||||||
|
var m = BiggestInt 1 # typeOfIter
|
||||||
|
if n.len == 3:
|
||||||
|
let mode = semConstExpr(c, n[2])
|
||||||
|
if mode.kind != nkIntLit:
|
||||||
|
localError(c.config, n.info, "typeof: cannot evaluate 'mode' parameter at compile-time")
|
||||||
|
else:
|
||||||
|
m = mode.intVal
|
||||||
|
let t = semExprWithType(c, n[1], if m == 1: {efInTypeof} else: {})
|
||||||
|
closeScope(c)
|
||||||
|
fixupTypeOf(c, prev, t)
|
||||||
|
result = t.typ
|
||||||
|
|
||||||
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = nil
|
result = nil
|
||||||
inc c.inTypeContext
|
inc c.inTypeContext
|
||||||
|
|
@ -1494,6 +1508,8 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
elif op.id == ord(wType):
|
elif op.id == ord(wType):
|
||||||
checkSonsLen(n, 2, c.config)
|
checkSonsLen(n, 2, c.config)
|
||||||
result = semTypeof(c, n[1], prev)
|
result = semTypeof(c, n[1], prev)
|
||||||
|
elif op.s == "typeof" and n[0].kind == nkSym and n[0].sym.magic == mTypeof:
|
||||||
|
result = semTypeOf2(c, n, prev)
|
||||||
else:
|
else:
|
||||||
if c.inGenericContext > 0 and n.kind == nkCall:
|
if c.inGenericContext > 0 and n.kind == nkCall:
|
||||||
result = makeTypeFromExpr(c, n.copyTree)
|
result = makeTypeFromExpr(c, n.copyTree)
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,19 @@ path="$lib/pure"
|
||||||
opt:speed
|
opt:speed
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@if unix and mingw:
|
||||||
|
# Cross compile for Windows from Linux/OSX using MinGW
|
||||||
|
os = windows
|
||||||
|
|
||||||
|
i386.windows.gcc.path = "/usr/bin"
|
||||||
|
i386.windows.gcc.exe = "i686-w64-mingw32-gcc"
|
||||||
|
i386.windows.gcc.linkerexe = "i686-w64-mingw32-gcc"
|
||||||
|
|
||||||
|
amd64.windows.gcc.path = "/usr/bin"
|
||||||
|
amd64.windows.gcc.exe = "x86_64-w64-mingw32-gcc"
|
||||||
|
amd64.windows.gcc.linkerexe = "x86_64-w64-mingw32-gcc"
|
||||||
|
@end
|
||||||
|
|
||||||
@if unix:
|
@if unix:
|
||||||
@if not bsd or haiku:
|
@if not bsd or haiku:
|
||||||
# -fopenmp
|
# -fopenmp
|
||||||
|
|
|
||||||
15
doc/nimc.rst
15
doc/nimc.rst
|
|
@ -261,6 +261,21 @@ configuration file should contain something like::
|
||||||
arm.linux.gcc.exe = "arm-linux-gcc"
|
arm.linux.gcc.exe = "arm-linux-gcc"
|
||||||
arm.linux.gcc.linkerexe = "arm-linux-gcc"
|
arm.linux.gcc.linkerexe = "arm-linux-gcc"
|
||||||
|
|
||||||
|
Cross compilation for Windows
|
||||||
|
=============================
|
||||||
|
|
||||||
|
To cross compile for Windows from Linux or OSX using the MinGW-w64 toolchain::
|
||||||
|
|
||||||
|
nim c -d:mingw myproject.nim
|
||||||
|
|
||||||
|
Use ``--cpu:i386`` or ``--cpu:amd64`` to switch the cpu arch.
|
||||||
|
|
||||||
|
The MinGW-w64 toolchain can be installed as follows::
|
||||||
|
|
||||||
|
Ubuntu: apt install mingw-w64
|
||||||
|
CentOS: yum install mingw32-gcc | mingw64-gcc - requires EPEL
|
||||||
|
OSX: brew install mingw-w64
|
||||||
|
|
||||||
Cross compilation for Nintendo Switch
|
Cross compilation for Nintendo Switch
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
|
|
||||||
7
koch.nim
7
koch.nim
|
|
@ -407,13 +407,14 @@ proc temp(args: string) =
|
||||||
result[1].add " " & quoteShell(args[i])
|
result[1].add " " & quoteShell(args[i])
|
||||||
inc i
|
inc i
|
||||||
|
|
||||||
var output = "compiler" / "nim".exe
|
let d = getAppDir()
|
||||||
var finalDest = "bin" / "nim_temp".exe
|
var output = d / "compiler" / "nim".exe
|
||||||
|
var finalDest = d / "bin" / "nim_temp".exe
|
||||||
# 125 is the magic number to tell git bisect to skip the current
|
# 125 is the magic number to tell git bisect to skip the current
|
||||||
# commit.
|
# commit.
|
||||||
let (bootArgs, programArgs) = splitArgs(args)
|
let (bootArgs, programArgs) = splitArgs(args)
|
||||||
let nimexec = findNim()
|
let nimexec = findNim()
|
||||||
exec(nimexec & " c -d:debug --debugger:native " & bootArgs & " compiler" / "nim", 125)
|
exec(nimexec & " c -d:debug --debugger:native " & bootArgs & " " & (d / "compiler" / "nim"), 125)
|
||||||
copyExe(output, finalDest)
|
copyExe(output, finalDest)
|
||||||
if programArgs.len > 0: exec(finalDest & " " & programArgs)
|
if programArgs.len > 0: exec(finalDest & " " & programArgs)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -673,6 +673,12 @@ template mapIt*(s: typed, op: untyped): untyped =
|
||||||
## nums = @[1, 2, 3, 4]
|
## nums = @[1, 2, 3, 4]
|
||||||
## strings = nums.mapIt($(4 * it))
|
## strings = nums.mapIt($(4 * it))
|
||||||
## assert strings == @["4", "8", "12", "16"]
|
## assert strings == @["4", "8", "12", "16"]
|
||||||
|
when defined(nimHasTypeof):
|
||||||
|
type outType = typeof((
|
||||||
|
block:
|
||||||
|
var it{.inject.}: typeof(items(s), typeOfIter);
|
||||||
|
op), typeOfProc)
|
||||||
|
else:
|
||||||
type outType = type((
|
type outType = type((
|
||||||
block:
|
block:
|
||||||
var it{.inject.}: type(items(s));
|
var it{.inject.}: type(items(s));
|
||||||
|
|
@ -1135,5 +1141,13 @@ when isMainModule:
|
||||||
A, B
|
A, B
|
||||||
doAssert mapIt(X, $it) == @["A", "B"]
|
doAssert mapIt(X, $it) == @["A", "B"]
|
||||||
|
|
||||||
|
block:
|
||||||
|
# bug #9093
|
||||||
|
let inp = "a:b,c:d"
|
||||||
|
|
||||||
|
let outp = inp.split(",").mapIt(it.split(":"))
|
||||||
|
doAssert outp == @[@["a", "b"], @["c", "d"]]
|
||||||
|
|
||||||
|
|
||||||
when not defined(testing):
|
when not defined(testing):
|
||||||
echo "Finished doc tests"
|
echo "Finished doc tests"
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,7 @@ proc parseInt*(s: string, number: var int, start = 0): int {.
|
||||||
rtl, extern: "npuParseInt", noSideEffect.} =
|
rtl, extern: "npuParseInt", noSideEffect.} =
|
||||||
## parses an integer starting at `start` and stores the value into `number`.
|
## parses an integer starting at `start` and stores the value into `number`.
|
||||||
## Result is the number of processed chars or 0 if there is no integer.
|
## Result is the number of processed chars or 0 if there is no integer.
|
||||||
## `EOverflow` is raised if an overflow occurs.
|
## `OverflowError` is raised if an overflow occurs.
|
||||||
var res: BiggestInt
|
var res: BiggestInt
|
||||||
result = parseBiggestInt(s, res, start)
|
result = parseBiggestInt(s, res, start)
|
||||||
if (sizeof(int) <= 4) and
|
if (sizeof(int) <= 4) and
|
||||||
|
|
@ -289,7 +289,7 @@ proc parseInt*(s: string, number: var int, start = 0): int {.
|
||||||
|
|
||||||
proc parseSaturatedNatural*(s: string, b: var int, start = 0): int =
|
proc parseSaturatedNatural*(s: string, b: var int, start = 0): int =
|
||||||
## parses a natural number into ``b``. This cannot raise an overflow
|
## parses a natural number into ``b``. This cannot raise an overflow
|
||||||
## error. Instead of an ``Overflow`` exception ``high(int)`` is returned.
|
## error. ``high(int)`` is returned for an overflow.
|
||||||
## The number of processed character is returned.
|
## The number of processed character is returned.
|
||||||
## This is usually what you really want to use instead of `parseInt`:idx:.
|
## This is usually what you really want to use instead of `parseInt`:idx:.
|
||||||
## Example:
|
## Example:
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,15 @@ else:
|
||||||
## Cannot be overloaded.
|
## Cannot be overloaded.
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
when defined(nimHasTypeof):
|
||||||
|
type
|
||||||
|
TypeOfMode* = enum ## Possible modes of `typeof`.
|
||||||
|
typeOfProc, ## Prefer the interpretation that means `x` is a proc call.
|
||||||
|
typeOfIter ## Prefer the interpretation that means `x` is an iterator call.
|
||||||
|
proc typeof*(x: untyped; mode = typeOfIter): typeDesc {.magic: "TypeOf", noSideEffect, compileTime.} =
|
||||||
|
## Builtin 'typeof' operation for accessing the type of an expression. Since version 0.20.0.
|
||||||
|
discard
|
||||||
|
|
||||||
proc `not`*(x: bool): bool {.magic: "Not", noSideEffect.}
|
proc `not`*(x: bool): bool {.magic: "Not", noSideEffect.}
|
||||||
## Boolean not; returns true iff ``x == false``.
|
## Boolean not; returns true iff ``x == false``.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,12 @@ when defined(develop):
|
||||||
else:
|
else:
|
||||||
const nimp = "nimpretty"
|
const nimp = "nimpretty"
|
||||||
|
|
||||||
proc test(infile, outfile: string) =
|
proc test(infile, ext: string) =
|
||||||
if execShellCmd("$# -o:$# --backup:off $#" % [nimp, outfile, infile]) != 0:
|
if execShellCmd("$# -o:$# --backup:off $#" % [nimp, infile.changeFileExt(ext), infile]) != 0:
|
||||||
quit("FAILURE")
|
quit("FAILURE")
|
||||||
let nimFile = splitFile(infile).name
|
let nimFile = splitFile(infile).name
|
||||||
let expected = dir / "expected" / nimFile & ".nim"
|
let expected = dir / "expected" / nimFile & ".nim"
|
||||||
let produced = dir / nimFile & ".pretty"
|
let produced = dir / nimFile.changeFileExt(ext)
|
||||||
if strip(readFile(expected)) != strip(readFile(produced)):
|
if strip(readFile(expected)) != strip(readFile(produced)):
|
||||||
echo "FAILURE: files differ: ", nimFile
|
echo "FAILURE: files differ: ", nimFile
|
||||||
discard execShellCmd("diff -uNdr " & expected & " " & produced)
|
discard execShellCmd("diff -uNdr " & expected & " " & produced)
|
||||||
|
|
@ -29,8 +29,12 @@ proc test(infile, outfile: string) =
|
||||||
echo "SUCCESS: files identical: ", nimFile
|
echo "SUCCESS: files identical: ", nimFile
|
||||||
|
|
||||||
for t in walkFiles(dir / "*.nim"):
|
for t in walkFiles(dir / "*.nim"):
|
||||||
let res = t.changeFileExt("pretty")
|
test(t, "pretty")
|
||||||
test(t, res)
|
# also test that pretty(pretty(x)) == pretty(x)
|
||||||
removeFile(res)
|
test(t.changeFileExt("pretty"), "pretty2")
|
||||||
|
|
||||||
|
removeFile(t.changeFileExt("pretty"))
|
||||||
|
removeFile(t.changeFileExt("pretty2"))
|
||||||
|
|
||||||
|
|
||||||
if failures > 0: quit($failures & " failures occurred.")
|
if failures > 0: quit($failures & " failures occurred.")
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,13 @@
|
||||||
|
|
||||||
var x: int = 2
|
var x: int = 2
|
||||||
|
|
||||||
echo x # bug #9144
|
echo x
|
||||||
|
# bug #9144
|
||||||
|
|
||||||
|
proc a() =
|
||||||
|
while true:
|
||||||
|
discard
|
||||||
|
# comment 1
|
||||||
|
|
||||||
|
# comment 2
|
||||||
|
discard
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,16 @@ proc fun*() =
|
||||||
echo "ok"
|
echo "ok"
|
||||||
## doc comment
|
## doc comment
|
||||||
# regular comment
|
# regular comment
|
||||||
|
|
||||||
|
proc funB() =
|
||||||
|
echo "ok1"
|
||||||
|
# echo "ok2"
|
||||||
|
|
||||||
|
fun()
|
||||||
|
|
||||||
|
#[
|
||||||
|
bug #9483
|
||||||
|
]#
|
||||||
|
|
||||||
|
proc funE() =
|
||||||
|
echo "ok1"
|
||||||
|
|
|
||||||
9
nimpretty/tests/expected/simple3.nim
Normal file
9
nimpretty/tests/expected/simple3.nim
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
#[
|
||||||
|
foo bar
|
||||||
|
]#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
proc fun() =
|
||||||
|
echo "ok1"
|
||||||
|
|
@ -3,3 +3,11 @@ var x: int = 2
|
||||||
|
|
||||||
echo x
|
echo x
|
||||||
# bug #9144
|
# bug #9144
|
||||||
|
|
||||||
|
proc a() =
|
||||||
|
while true:
|
||||||
|
discard
|
||||||
|
# comment 1
|
||||||
|
|
||||||
|
# comment 2
|
||||||
|
discard
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,16 @@ proc fun*()=
|
||||||
echo "ok"
|
echo "ok"
|
||||||
## doc comment
|
## doc comment
|
||||||
# regular comment
|
# regular comment
|
||||||
|
|
||||||
|
proc funB() =
|
||||||
|
echo "ok1"
|
||||||
|
# echo "ok2"
|
||||||
|
|
||||||
|
fun()
|
||||||
|
|
||||||
|
#[
|
||||||
|
bug #9483
|
||||||
|
]#
|
||||||
|
|
||||||
|
proc funE() =
|
||||||
|
echo "ok1"
|
||||||
|
|
|
||||||
9
nimpretty/tests/simple3.nim
Normal file
9
nimpretty/tests/simple3.nim
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
#[
|
||||||
|
foo bar
|
||||||
|
]#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
proc fun() =
|
||||||
|
echo "ok1"
|
||||||
|
|
@ -1,16 +1,22 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''
|
output: '''
|
||||||
yeah A enumB
|
yeah A enumB
|
||||||
|
uneven
|
||||||
yeah A enumB
|
yeah A enumB
|
||||||
yeah CD enumD
|
yeah CD enumD
|
||||||
|
uneven
|
||||||
yeah CD enumE
|
yeah CD enumE
|
||||||
yeah A enumB
|
yeah A enumB
|
||||||
|
uneven
|
||||||
yeah CD enumE
|
yeah CD enumE
|
||||||
yeah CD enumD
|
yeah CD enumD
|
||||||
|
uneven
|
||||||
yeah A enumB
|
yeah A enumB
|
||||||
yeah B enumC
|
yeah B enumC
|
||||||
|
uneven
|
||||||
yeah A enumB
|
yeah A enumB
|
||||||
yeah A enumB
|
yeah A enumB
|
||||||
|
uneven
|
||||||
yeah A enumB
|
yeah A enumB
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
@ -47,4 +53,7 @@ proc vm() =
|
||||||
of enumLast: discard
|
of enumLast: discard
|
||||||
inc(pc)
|
inc(pc)
|
||||||
|
|
||||||
|
if pc mod 2 == 1:
|
||||||
|
echo "uneven"
|
||||||
|
|
||||||
vm()
|
vm()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "type mismatch: got <Bar[system.int]>"
|
errormsg: "type mismatch: got <Bar[system.int]>"
|
||||||
|
disabled: "true"
|
||||||
nimout: '''
|
nimout: '''
|
||||||
t3330.nim(63, 4) Error: type mismatch: got <Bar[system.int]>
|
t3330.nim(63, 4) Error: type mismatch: got <Bar[system.int]>
|
||||||
but expected one of:
|
but expected one of:
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,25 @@ class NimStringPrinter:
|
||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
class NimRopePrinter:
|
||||||
|
pattern = re.compile(r'^tyObject_RopeObj_OFzf0kSiPTcNreUIeJgWVA \*$')
|
||||||
|
|
||||||
|
def __init__(self, val):
|
||||||
|
self.val = val
|
||||||
|
|
||||||
|
def display_hint(self):
|
||||||
|
return 'string'
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
if self.val:
|
||||||
|
left = NimRopePrinter(self.val["left"]).to_string()
|
||||||
|
data = NimStringPrinter(self.val["data"]).to_string()
|
||||||
|
right = NimRopePrinter(self.val["right"]).to_string()
|
||||||
|
return left + data + right
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
|
# proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue