mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-10 15:04:59 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user