parent
16d82c82e3
commit
eb6225ad8c
5 changed files with 84 additions and 34 deletions
0
bin/nim-gdb
Normal file → Executable file
0
bin/nim-gdb
Normal file → Executable 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)
|
||||||
|
|
||||||
|
|
|
||||||
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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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