This commit is contained in:
Arne Döring 2018-10-24 13:10:44 +02:00 • committed by Andreas Rumpf
commit eb6225ad8c
5 changed files with 84 additions and 34 deletions

0
bin/nim-gdb Normal file → Executable file
View file

View file

@ -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,26 +503,26 @@ 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:
# invoke at loop body exit: # invoke at loop body exit:
linefmt(p, cpsStmts, "#nimProfile();$n") linefmt(p, cpsStmts, "#nimProfile();$n")
endBlock(p) endBlock(p)
dec(p.withinLoop) dec(p.withinLoop)

View file

@ -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)

View file

@ -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()

View file

@ -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.} =