cbuilder: add for range statements (#24391)

Finishes `genEnumInfo` as followup to #24351. As #24381 mentions this
covers every use of `for` loops in the codegen.

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
metagn
2024-11-03 19:57:31 +03:00
committed by GitHub
parent f5d80ede80
commit f98964d99f
2 changed files with 41 additions and 7 deletions

View File

@@ -93,6 +93,32 @@ template addElseBranch(builder: var Builder, stmt: var IfStmt, body: typed) =
body
builder.add("}")
proc addForRangeHeader(builder: var Builder, i, start, bound: Snippet, inclusive: bool = false) =
builder.add("for (")
builder.add(i)
builder.add(" = ")
builder.add(start)
builder.add("; ")
builder.add(i)
if inclusive:
builder.add(" <= ")
else:
builder.add(" < ")
builder.add(bound)
builder.add("; ")
builder.add(i)
builder.add("++) {\n")
template addForRangeExclusive(builder: var Builder, i, start, bound: Snippet, body: typed) =
addForRangeHeader(builder, i, start, bound, false)
body
builder.add("}\n")
template addForRangeInclusive(builder: var Builder, i, start, bound: Snippet, body: typed) =
addForRangeHeader(builder, i, start, bound, true)
body
builder.add("}\n")
template addScope(builder: var Builder, body: typed) =
builder.add("{")
body

View File

@@ -1503,13 +1503,20 @@ proc genEnumInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) =
m.s[cfsTypeInit1].addArrayVarWithInitializer(
kind = Global,
name = enumArray,
elementType = "char* NIM_CONST", # XXX maybe do this in `addVar`
elementType = constPtrType("char"),
len = typ.n.len):
m.s[cfsTypeInit1].add(extract(enumNames))
m.s[cfsTypeInit3].addf("for ($1 = 0; $1 < $2; $1++) {$n" &
"$3[$1+$4].kind = 1;$n" & "$3[$1+$4].offset = $1;$n" &
"$3[$1+$4].name = $5[$1];$n" & "$6[$1] = &$3[$1+$4];$n" & "}$n", [counter,
rope(typ.n.len), m.typeNodesName, rope(firstNimNode), enumArray, nodePtrs])
m.s[cfsTypeInit3].addForRangeExclusive(i = counter,
start = cIntValue(0),
bound = cIntValue(typ.n.len)):
let nodeLoc = subscript(m.typeNodesName,
cOp(Add, "NI", counter, cIntValue(firstNimNode)))
m.s[cfsTypeInit3].addFieldAssignment(nodeLoc, "kind", cIntValue(1))
m.s[cfsTypeInit3].addFieldAssignment(nodeLoc, "offset", counter)
m.s[cfsTypeInit3].addFieldAssignment(nodeLoc, "name",
subscript(enumArray, counter))
m.s[cfsTypeInit3].addSubscriptAssignment(nodePtrs, counter,
cAddr(nodeLoc))
m.s[cfsTypeInit3].add(extract(specialCases))
let n = getNimNode(m)
m.s[cfsTypeInit3].addFieldAssignment(n, "len", typ.n.len)
@@ -1518,8 +1525,9 @@ proc genEnumInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) =
cAddr(subscript(nodePtrs, cIntValue(0))))
m.s[cfsTypeInit3].addFieldAssignment(tiNameForHcr(m, name), "node", cAddr(n))
if hasHoles:
# 1 << 2 is {ntfEnumHole}
m.s[cfsTypeInit3].addf("$1.flags = 1<<2;$n", [tiNameForHcr(m, name)])
m.s[cfsTypeInit3].addFieldAssignment(tiNameForHcr(m, name), "flags",
# 1 << 2 is {ntfEnumHole}
cOp(Shl, "NU8", cIntValue(1), cIntValue(2)))
proc genSetInfo(m: BModule; typ: PType, name: Rope; info: TLineInfo) =
assert(typ.elementType != nil)