Merge pull request #2483 from def-/ropes

Get rid of deprecation warnings
This commit is contained in:
Andreas Rumpf
2015-04-08 09:48:55 +02:00
22 changed files with 1449 additions and 1482 deletions

View File

@@ -685,8 +685,8 @@ type
s*: TStorageLoc
flags*: TLocFlags # location's flags
t*: PType # type of location
r*: PRope # rope value of location (code generators)
heapRoot*: PRope # keeps track of the enclosing heap object that
r*: Rope # rope value of location (code generators)
heapRoot*: Rope # keeps track of the enclosing heap object that
# owns this location (required by GC algorithms
# employing heap snapshots or sliding views)
@@ -698,7 +698,7 @@ type
kind*: TLibKind
generated*: bool # needed for the backends:
isOverriden*: bool
name*: PRope
name*: Rope
path*: PNode # can be a string literal!
TInstantiation* = object

View File

@@ -15,13 +15,13 @@ import
ast, hashes, intsets, strutils, options, msgs, ropes, idents, rodutils
proc hashNode*(p: RootRef): THash
proc treeToYaml*(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope
proc treeToYaml*(n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope
# Convert a tree into its YAML representation; this is used by the
# YAML code generator and it is invaluable for debugging purposes.
# If maxRecDepht <> -1 then it won't print the whole graph.
proc typeToYaml*(n: PType, indent: int = 0, maxRecDepth: int = - 1): PRope
proc symToYaml*(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope
proc lineInfoToStr*(info: TLineInfo): PRope
proc typeToYaml*(n: PType, indent: int = 0, maxRecDepth: int = - 1): Rope
proc symToYaml*(n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope
proc lineInfoToStr*(info: TLineInfo): Rope
# ----------------------- node sets: ---------------------------------------
proc objectSetContains*(t: TObjectSet, obj: RootRef): bool
@@ -203,9 +203,9 @@ proc mustRehash(length, counter: int): bool =
assert(length > counter)
result = (length * 2 < counter * 3) or (length - counter < 4)
proc rspaces(x: int): PRope =
proc rspaces(x: int): Rope =
# returns x spaces
result = toRope(spaces(x))
result = rope(spaces(x))
proc toYamlChar(c: char): string =
case c
@@ -213,7 +213,7 @@ proc toYamlChar(c: char): string =
of '\'', '\"', '\\': result = '\\' & c
else: result = $c
proc makeYamlString*(s: string): PRope =
proc makeYamlString*(s: string): Rope =
# We have to split long strings into many ropes. Otherwise
# this could trigger InternalError(111). See the ropes module for
# further information.
@@ -224,227 +224,227 @@ proc makeYamlString*(s: string): PRope =
if (i + 1) mod MaxLineLength == 0:
add(res, '\"')
add(res, "\n")
app(result, toRope(res))
add(result, rope(res))
res = "\"" # reset
add(res, toYamlChar(s[i]))
add(res, '\"')
app(result, toRope(res))
add(result, rope(res))
proc flagsToStr[T](flags: set[T]): PRope =
proc flagsToStr[T](flags: set[T]): Rope =
if flags == {}:
result = toRope("[]")
result = rope("[]")
else:
result = nil
for x in items(flags):
if result != nil: app(result, ", ")
app(result, makeYamlString($x))
result = con("[", con(result, "]"))
if result != nil: add(result, ", ")
add(result, makeYamlString($x))
result = "[" & result & "]"
proc lineInfoToStr(info: TLineInfo): PRope =
result = ropef("[$1, $2, $3]", [makeYamlString(toFilename(info)),
toRope(toLinenumber(info)),
toRope(toColumn(info))])
proc lineInfoToStr(info: TLineInfo): Rope =
result = "[$1, $2, $3]" % [makeYamlString(toFilename(info)),
rope(toLinenumber(info)),
rope(toColumn(info))]
proc treeToYamlAux(n: PNode, marker: var IntSet,
indent, maxRecDepth: int): PRope
indent, maxRecDepth: int): Rope
proc symToYamlAux(n: PSym, marker: var IntSet,
indent, maxRecDepth: int): PRope
indent, maxRecDepth: int): Rope
proc typeToYamlAux(n: PType, marker: var IntSet,
indent, maxRecDepth: int): PRope
indent, maxRecDepth: int): Rope
proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int,
maxRecDepth: int): PRope =
maxRecDepth: int): Rope =
var istr = rspaces(indent + 2)
result = toRope("[")
result = rope("[")
var mycount = 0
for i in countup(0, high(n.data)):
if n.data[i] != nil:
if mycount > 0: app(result, ",")
appf(result, "$N$1$2",
if mycount > 0: add(result, ",")
addf(result, "$N$1$2",
[istr, symToYamlAux(n.data[i], marker, indent + 2, maxRecDepth - 1)])
inc(mycount)
if mycount > 0: appf(result, "$N$1", [rspaces(indent)])
app(result, "]")
if mycount > 0: addf(result, "$N$1", [rspaces(indent)])
add(result, "]")
assert(mycount == n.counter)
proc ropeConstr(indent: int, c: openArray[PRope]): PRope =
proc ropeConstr(indent: int, c: openArray[Rope]): Rope =
# array of (name, value) pairs
var istr = rspaces(indent + 2)
result = toRope("{")
result = rope("{")
var i = 0
while i <= high(c):
if i > 0: app(result, ",")
appf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]])
if i > 0: add(result, ",")
addf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]])
inc(i, 2)
appf(result, "$N$1}", [rspaces(indent)])
addf(result, "$N$1}", [rspaces(indent)])
proc symToYamlAux(n: PSym, marker: var IntSet, indent: int,
maxRecDepth: int): PRope =
maxRecDepth: int): Rope =
if n == nil:
result = toRope("null")
result = rope("null")
elif containsOrIncl(marker, n.id):
result = ropef("\"$1 @$2\"", [toRope(n.name.s), toRope(
strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))])
result = "\"$1 @$2\"" % [rope(n.name.s), rope(
strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))]
else:
var ast = treeToYamlAux(n.ast, marker, indent + 2, maxRecDepth - 1)
result = ropeConstr(indent, [toRope("kind"),
result = ropeConstr(indent, [rope("kind"),
makeYamlString($n.kind),
toRope("name"), makeYamlString(n.name.s),
toRope("typ"), typeToYamlAux(n.typ, marker,
rope("name"), makeYamlString(n.name.s),
rope("typ"), typeToYamlAux(n.typ, marker,
indent + 2, maxRecDepth - 1),
toRope("info"), lineInfoToStr(n.info),
toRope("flags"), flagsToStr(n.flags),
toRope("magic"), makeYamlString($n.magic),
toRope("ast"), ast, toRope("options"),
flagsToStr(n.options), toRope("position"),
toRope(n.position)])
rope("info"), lineInfoToStr(n.info),
rope("flags"), flagsToStr(n.flags),
rope("magic"), makeYamlString($n.magic),
rope("ast"), ast, rope("options"),
flagsToStr(n.options), rope("position"),
rope(n.position)])
proc typeToYamlAux(n: PType, marker: var IntSet, indent: int,
maxRecDepth: int): PRope =
maxRecDepth: int): Rope =
if n == nil:
result = toRope("null")
result = rope("null")
elif containsOrIncl(marker, n.id):
result = ropef("\"$1 @$2\"", [toRope($n.kind), toRope(
strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))])
result = "\"$1 @$2\"" % [rope($n.kind), rope(
strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))]
else:
if sonsLen(n) > 0:
result = toRope("[")
result = rope("[")
for i in countup(0, sonsLen(n) - 1):
if i > 0: app(result, ",")
appf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(n.sons[i],
if i > 0: add(result, ",")
addf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(n.sons[i],
marker, indent + 4, maxRecDepth - 1)])
appf(result, "$N$1]", [rspaces(indent + 2)])
addf(result, "$N$1]", [rspaces(indent + 2)])
else:
result = toRope("null")
result = ropeConstr(indent, [toRope("kind"),
result = rope("null")
result = ropeConstr(indent, [rope("kind"),
makeYamlString($n.kind),
toRope("sym"), symToYamlAux(n.sym, marker,
indent + 2, maxRecDepth - 1), toRope("n"), treeToYamlAux(n.n, marker,
indent + 2, maxRecDepth - 1), toRope("flags"), flagsToStr(n.flags),
toRope("callconv"),
rope("sym"), symToYamlAux(n.sym, marker,
indent + 2, maxRecDepth - 1), rope("n"), treeToYamlAux(n.n, marker,
indent + 2, maxRecDepth - 1), rope("flags"), flagsToStr(n.flags),
rope("callconv"),
makeYamlString(CallingConvToStr[n.callConv]),
toRope("size"), toRope(n.size),
toRope("align"), toRope(n.align),
toRope("sons"), result])
rope("size"), rope(n.size),
rope("align"), rope(n.align),
rope("sons"), result])
proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int,
maxRecDepth: int): PRope =
maxRecDepth: int): Rope =
if n == nil:
result = toRope("null")
result = rope("null")
else:
var istr = rspaces(indent + 2)
result = ropef("{$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
result = "{$N$1\"kind\": $2" % [istr, makeYamlString($n.kind)]
if maxRecDepth != 0:
appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
case n.kind
of nkCharLit..nkInt64Lit:
appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)])
addf(result, ",$N$1\"intVal\": $2", [istr, rope(n.intVal)])
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
appf(result, ",$N$1\"floatVal\": $2",
[istr, toRope(n.floatVal.toStrMaxPrecision)])
addf(result, ",$N$1\"floatVal\": $2",
[istr, rope(n.floatVal.toStrMaxPrecision)])
of nkStrLit..nkTripleStrLit:
if n.strVal.isNil:
appf(result, ",$N$1\"strVal\": null", [istr])
addf(result, ",$N$1\"strVal\": null", [istr])
else:
appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
addf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
of nkSym:
appf(result, ",$N$1\"sym\": $2",
addf(result, ",$N$1\"sym\": $2",
[istr, symToYamlAux(n.sym, marker, indent + 2, maxRecDepth)])
of nkIdent:
if n.ident != nil:
appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
addf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
else:
appf(result, ",$N$1\"ident\": null", [istr])
addf(result, ",$N$1\"ident\": null", [istr])
else:
if sonsLen(n) > 0:
appf(result, ",$N$1\"sons\": [", [istr])
addf(result, ",$N$1\"sons\": [", [istr])
for i in countup(0, sonsLen(n) - 1):
if i > 0: app(result, ",")
appf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(n.sons[i],
if i > 0: add(result, ",")
addf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(n.sons[i],
marker, indent + 4, maxRecDepth - 1)])
appf(result, "$N$1]", [istr])
appf(result, ",$N$1\"typ\": $2",
addf(result, "$N$1]", [istr])
addf(result, ",$N$1\"typ\": $2",
[istr, typeToYamlAux(n.typ, marker, indent + 2, maxRecDepth)])
appf(result, "$N$1}", [rspaces(indent)])
addf(result, "$N$1}", [rspaces(indent)])
proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope =
proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope =
var marker = initIntSet()
result = treeToYamlAux(n, marker, indent, maxRecDepth)
proc typeToYaml(n: PType, indent: int = 0, maxRecDepth: int = - 1): PRope =
proc typeToYaml(n: PType, indent: int = 0, maxRecDepth: int = - 1): Rope =
var marker = initIntSet()
result = typeToYamlAux(n, marker, indent, maxRecDepth)
proc symToYaml(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope =
proc symToYaml(n: PSym, indent: int = 0, maxRecDepth: int = - 1): Rope =
var marker = initIntSet()
result = symToYamlAux(n, marker, indent, maxRecDepth)
proc debugTree*(n: PNode, indent: int, maxRecDepth: int; renderType=false): PRope
proc debugType(n: PType, maxRecDepth=100): PRope =
proc debugTree*(n: PNode, indent: int, maxRecDepth: int; renderType=false): Rope
proc debugType(n: PType, maxRecDepth=100): Rope =
if n == nil:
result = toRope("null")
result = rope("null")
else:
result = toRope($n.kind)
result = rope($n.kind)
if n.sym != nil:
app(result, " ")
app(result, n.sym.name.s)
add(result, " ")
add(result, n.sym.name.s)
if n.kind in IntegralTypes and n.n != nil:
app(result, ", node: ")
app(result, debugTree(n.n, 2, maxRecDepth-1, renderType=true))
add(result, ", node: ")
add(result, debugTree(n.n, 2, maxRecDepth-1, renderType=true))
if (n.kind != tyString) and (sonsLen(n) > 0) and maxRecDepth != 0:
app(result, "(")
add(result, "(")
for i in countup(0, sonsLen(n) - 1):
if i > 0: app(result, ", ")
if i > 0: add(result, ", ")
if n.sons[i] == nil:
app(result, "null")
add(result, "null")
else:
app(result, debugType(n.sons[i], maxRecDepth-1))
add(result, debugType(n.sons[i], maxRecDepth-1))
if n.kind == tyObject and n.n != nil:
app(result, ", node: ")
app(result, debugTree(n.n, 2, maxRecDepth-1, renderType=true))
app(result, ")")
add(result, ", node: ")
add(result, debugTree(n.n, 2, maxRecDepth-1, renderType=true))
add(result, ")")
proc debugTree(n: PNode, indent: int, maxRecDepth: int;
renderType=false): PRope =
renderType=false): Rope =
if n == nil:
result = toRope("null")
result = rope("null")
else:
var istr = rspaces(indent + 2)
result = ropef("{$N$1\"kind\": $2",
[istr, makeYamlString($n.kind)])
result = "{$N$1\"kind\": $2" %
[istr, makeYamlString($n.kind)]
if maxRecDepth != 0:
case n.kind
of nkCharLit..nkUInt64Lit:
appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)])
addf(result, ",$N$1\"intVal\": $2", [istr, rope(n.intVal)])
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
appf(result, ",$N$1\"floatVal\": $2",
[istr, toRope(n.floatVal.toStrMaxPrecision)])
addf(result, ",$N$1\"floatVal\": $2",
[istr, rope(n.floatVal.toStrMaxPrecision)])
of nkStrLit..nkTripleStrLit:
if n.strVal.isNil:
appf(result, ",$N$1\"strVal\": null", [istr])
addf(result, ",$N$1\"strVal\": null", [istr])
else:
appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
addf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
of nkSym:
appf(result, ",$N$1\"sym\": $2_$3",
[istr, toRope(n.sym.name.s), toRope(n.sym.id)])
addf(result, ",$N$1\"sym\": $2_$3",
[istr, rope(n.sym.name.s), rope(n.sym.id)])
# [istr, symToYaml(n.sym, indent, maxRecDepth),
# toRope(n.sym.id)])
# rope(n.sym.id)])
if renderType and n.sym.typ != nil:
appf(result, ",$N$1\"typ\": $2", [istr, debugType(n.sym.typ, 2)])
addf(result, ",$N$1\"typ\": $2", [istr, debugType(n.sym.typ, 2)])
of nkIdent:
if n.ident != nil:
appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
addf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
else:
appf(result, ",$N$1\"ident\": null", [istr])
addf(result, ",$N$1\"ident\": null", [istr])
else:
if sonsLen(n) > 0:
appf(result, ",$N$1\"sons\": [", [istr])
addf(result, ",$N$1\"sons\": [", [istr])
for i in countup(0, sonsLen(n) - 1):
if i > 0: app(result, ",")
appf(result, "$N$1$2", [rspaces(indent + 4), debugTree(n.sons[i],
if i > 0: add(result, ",")
addf(result, "$N$1$2", [rspaces(indent + 4), debugTree(n.sons[i],
indent + 4, maxRecDepth - 1, renderType)])
appf(result, "$N$1]", [istr])
appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
appf(result, "$N$1}", [rspaces(indent)])
addf(result, "$N$1]", [istr])
addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
addf(result, "$N$1}", [rspaces(indent)])
proc debug(n: PSym) =
if n == nil:

View File

@@ -19,13 +19,13 @@ proc hasNoInit(call: PNode): bool {.inline.} =
result = call.sons[0].kind == nkSym and sfNoInit in call.sons[0].sym.flags
proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
callee, params: PRope) =
var pl = con(callee, ~"(", params)
callee, params: Rope) =
var pl = callee & ~"(" & params
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
if typ.sons[0] != nil:
if isInvalidReturnType(typ.sons[0]):
if params != nil: pl.app(~", ")
if params != nil: pl.add(~", ")
# beware of 'result = p(result)'. We may need to allocate a temporary:
if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri):
# Great, we can use 'd':
@@ -33,18 +33,18 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
elif d.k notin {locExpr, locTemp} and not hasNoInit(ri):
# reset before pass as 'result' var:
resetLoc(p, d)
app(pl, addrLoc(d))
app(pl, ~");$n")
add(pl, addrLoc(d))
add(pl, ~");$n")
line(p, cpsStmts, pl)
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp, needsInit=true)
app(pl, addrLoc(tmp))
app(pl, ~");$n")
add(pl, addrLoc(tmp))
add(pl, ~");$n")
line(p, cpsStmts, pl)
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
app(pl, ~")")
add(pl, ~")")
if p.module.compileToCpp and lfSingleUse in d.flags:
# do not generate spurious temporaries for C++! For C we're better off
# with them to prevent undefined behaviour and because the codegen
@@ -60,7 +60,7 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
app(pl, ~");$n")
add(pl, ~");$n")
line(p, cpsStmts, pl)
proc isInCurrentFrame(p: BProc, n: PNode): bool =
@@ -83,7 +83,7 @@ proc isInCurrentFrame(p: BProc, n: PNode): bool =
result = isInCurrentFrame(p, n.sons[0])
else: discard
proc openArrayLoc(p: BProc, n: PNode): PRope =
proc openArrayLoc(p: BProc, n: PNode): Rope =
var a: TLoc
let q = skipConv(n)
@@ -104,28 +104,28 @@ proc openArrayLoc(p: BProc, n: PNode): PRope =
else:
"$1->data+($2), ($3)-($2)+1"
else: (internalError("openArrayLoc: " & typeToString(a.t)); "")
result = ropef(fmt, [rdLoc(a), rdLoc(b), rdLoc(c)])
result = fmt % [rdLoc(a), rdLoc(b), rdLoc(c)]
else:
initLocExpr(p, n, a)
case skipTypes(a.t, abstractVar).kind
of tyOpenArray, tyVarargs:
result = ropef("$1, $1Len0", [rdLoc(a)])
result = "$1, $1Len0" % [rdLoc(a)]
of tyString, tySequence:
if skipTypes(n.typ, abstractInst).kind == tyVar and
not compileToCpp(p.module):
result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField(p)])
result = "(*$1)->data, (*$1)->$2" % [a.rdLoc, lenField(p)]
else:
result = ropef("$1->data, $1->$2", [a.rdLoc, lenField(p)])
result = "$1->data, $1->$2" % [a.rdLoc, lenField(p)]
of tyArray, tyArrayConstr:
result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])
result = "$1, $2" % [rdLoc(a), rope(lengthOrd(a.t))]
else: internalError("openArrayLoc: " & typeToString(a.t))
proc genArgStringToCString(p: BProc, n: PNode): PRope {.inline.} =
proc genArgStringToCString(p: BProc, n: PNode): Rope {.inline.} =
var a: TLoc
initLocExpr(p, n.sons[0], a)
result = ropef("$1->data", [a.rdLoc])
result = "$1->data" % [a.rdLoc]
proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): PRope =
proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): Rope =
var a: TLoc
if n.kind == nkStringToCString:
result = genArgStringToCString(p, n)
@@ -151,7 +151,7 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): PRope =
initLocExprSingleUse(p, n, a)
result = rdLoc(a)
proc genArgNoParam(p: BProc, n: PNode): PRope =
proc genArgNoParam(p: BProc, n: PNode): Rope =
var a: TLoc
if n.kind == nkStringToCString:
result = genArgStringToCString(p, n)
@@ -163,7 +163,7 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op: TLoc
# this is a hotspot in the compiler
initLocExpr(p, ri.sons[0], op)
var params: PRope
var params: Rope
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
assert(typ.kind == tyProc)
@@ -171,27 +171,27 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var length = sonsLen(ri)
for i in countup(1, length - 1):
if ri.sons[i].typ.isCompileTimeOnly: continue
if params != nil: app(params, ~", ")
if params != nil: add(params, ~", ")
if i < sonsLen(typ):
assert(typ.n.sons[i].kind == nkSym)
app(params, genArg(p, ri.sons[i], typ.n.sons[i].sym, ri))
add(params, genArg(p, ri.sons[i], typ.n.sons[i].sym, ri))
else:
app(params, genArgNoParam(p, ri.sons[i]))
add(params, genArgNoParam(p, ri.sons[i]))
fixupCall(p, le, ri, d, op.r, params)
proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
proc getRawProcType(p: BProc, t: PType): PRope =
proc getRawProcType(p: BProc, t: PType): Rope =
result = getClosureType(p.module, t, clHalf)
proc addComma(r: PRope): PRope =
result = if r == nil: r else: con(r, ~", ")
proc addComma(r: Rope): Rope =
result = if r == nil: r else: r & ~", "
const PatProc = "$1.ClEnv? $1.ClPrc($3$1.ClEnv):(($4)($1.ClPrc))($2)"
const PatIter = "$1.ClPrc($3$1.ClEnv)" # we know the env exists
var op: TLoc
initLocExpr(p, ri.sons[0], op)
var pl: PRope
var pl: Rope
var typ = skipTypes(ri.sons[0].typ, abstractInst)
assert(typ.kind == tyProc)
@@ -201,19 +201,19 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
if ri.sons[i].typ.isCompileTimeOnly: continue
if i < sonsLen(typ):
assert(typ.n.sons[i].kind == nkSym)
app(pl, genArg(p, ri.sons[i], typ.n.sons[i].sym, ri))
add(pl, genArg(p, ri.sons[i], typ.n.sons[i].sym, ri))
else:
app(pl, genArgNoParam(p, ri.sons[i]))
if i < length - 1: app(pl, ~", ")
add(pl, genArgNoParam(p, ri.sons[i]))
if i < length - 1: add(pl, ~", ")
template genCallPattern {.dirty.} =
lineF(p, cpsStmts, callPattern & ";$n", op.r, pl, pl.addComma, rawProc)
lineF(p, cpsStmts, callPattern & ";$n", [op.r, pl, pl.addComma, rawProc])
let rawProc = getRawProcType(p, typ)
let callPattern = if tfIterator in typ.flags: PatIter else: PatProc
if typ.sons[0] != nil:
if isInvalidReturnType(typ.sons[0]):
if sonsLen(ri) > 1: app(pl, ~", ")
if sonsLen(ri) > 1: add(pl, ~", ")
# beware of 'result = p(result)'. We may need to allocate a temporary:
if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri):
# Great, we can use 'd':
@@ -222,12 +222,12 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
elif d.k notin {locExpr, locTemp} and not hasNoInit(ri):
# reset before pass as 'result' var:
resetLoc(p, d)
app(pl, addrLoc(d))
add(pl, addrLoc(d))
genCallPattern()
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp, needsInit=true)
app(pl, addrLoc(tmp))
add(pl, addrLoc(tmp))
genCallPattern()
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
@@ -235,12 +235,12 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
initLoc(list, locCall, d.t, OnUnknown)
list.r = ropef(callPattern, op.r, pl, pl.addComma, rawProc)
list.r = callPattern % [op.r, pl, pl.addComma, rawProc]
genAssignment(p, d, list, {}) # no need for deep copying
else:
genCallPattern()
proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType): PRope =
proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType): Rope =
if ri.sons[i].typ.isCompileTimeOnly:
result = nil
elif i < sonsLen(typ):
@@ -309,7 +309,7 @@ proc skipAddrDeref(node: PNode): PNode =
else:
result = node
proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): PRope =
proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): Rope =
# for better or worse c2nim translates the 'this' argument to a 'var T'.
# However manual wrappers may also use 'ptr T'. In any case we support both
# for convenience.
@@ -324,64 +324,64 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): PRope =
let x = if ri.kind == nkHiddenAddr: ri[0] else: ri
if x.typ.kind == tyPtr:
result = genArgNoParam(p, x)
result.app("->")
result.add("->")
elif x.kind in {nkHiddenDeref, nkDerefExpr} and x[0].typ.kind == tyPtr:
result = genArgNoParam(p, x[0])
result.app("->")
result.add("->")
else:
result = genArgNoParam(p, x)
result.app(".")
result.add(".")
elif t.kind == tyPtr:
if ri.kind in {nkAddr, nkHiddenAddr}:
result = genArgNoParam(p, ri[0])
result.app(".")
result.add(".")
else:
result = genArgNoParam(p, ri)
result.app("->")
result.add("->")
else:
ri = skipAddrDeref(ri)
if ri.kind in {nkAddr, nkHiddenAddr}: ri = ri[0]
result = genArgNoParam(p, ri) #, typ.n.sons[i].sym)
result.app(".")
result.add(".")
proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): PRope =
proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
var i = 0
var j = 1
while i < pat.len:
case pat[i]
of '@':
if j < ri.len:
result.app genOtherArg(p, ri, j, typ)
result.add genOtherArg(p, ri, j, typ)
for k in j+1 .. < ri.len:
result.app(~", ")
result.app genOtherArg(p, ri, k, typ)
result.add(~", ")
result.add genOtherArg(p, ri, k, typ)
inc i
of '#':
if pat[i+1] in {'+', '@'}:
let ri = ri[j]
if ri.kind in nkCallKinds:
let typ = skipTypes(ri.sons[0].typ, abstractInst)
if pat[i+1] == '+': result.app genArgNoParam(p, ri.sons[0])
result.app(~"(")
if pat[i+1] == '+': result.add genArgNoParam(p, ri.sons[0])
result.add(~"(")
if 1 < ri.len:
result.app genOtherArg(p, ri, 1, typ)
result.add genOtherArg(p, ri, 1, typ)
for k in j+1 .. < ri.len:
result.app(~", ")
result.app genOtherArg(p, ri, k, typ)
result.app(~")")
result.add(~", ")
result.add genOtherArg(p, ri, k, typ)
result.add(~")")
else:
localError(ri.info, "call expression expected for C++ pattern")
inc i
elif pat[i+1] == '.':
result.app genThisArg(p, ri, j, typ)
result.add genThisArg(p, ri, j, typ)
inc i
elif pat[i+1] == '[':
var arg = ri.sons[j].skipAddrDeref
while arg.kind in {nkAddr, nkHiddenAddr, nkObjDownConv}: arg = arg[0]
result.app genArgNoParam(p, arg)
#result.app debugTree(arg, 0, 10)
result.add genArgNoParam(p, arg)
#result.add debugTree(arg, 0, 10)
else:
result.app genOtherArg(p, ri, j, typ)
result.add genOtherArg(p, ri, j, typ)
inc j
inc i
of '\'':
@@ -394,8 +394,8 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): PRope =
for k in 1..i-stars:
if t != nil and t.len > 0:
t = if t.kind == tyGenericInst: t.sons[1] else: t.elemType
if t == nil: result.app(~"void")
else: result.app(getTypeDesc(p.module, t))
if t == nil: result.add(~"void")
else: result.add(getTypeDesc(p.module, t))
inc i
else:
let start = i
@@ -403,7 +403,7 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): PRope =
if pat[i] notin {'@', '#', '\''}: inc(i)
else: break
if i - 1 >= start:
app(result, substr(pat, start, i - 1))
add(result, substr(pat, start, i - 1))
proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op, a: TLoc
@@ -436,19 +436,19 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
app(pl, ~";$n")
add(pl, ~";$n")
line(p, cpsStmts, pl)
else:
var pl: PRope = nil
var pl: Rope = nil
#var param = typ.n.sons[1].sym
if 1 < ri.len:
app(pl, genThisArg(p, ri, 1, typ))
app(pl, op.r)
var params: PRope
add(pl, genThisArg(p, ri, 1, typ))
add(pl, op.r)
var params: Rope
for i in countup(2, length - 1):
if params != nil: params.app(~", ")
if params != nil: params.add(~", ")
assert(sonsLen(typ) == sonsLen(typ.n))
app(params, genOtherArg(p, ri, i, typ))
add(params, genOtherArg(p, ri, i, typ))
fixupCall(p, le, ri, d, pl, params)
proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
@@ -468,49 +468,49 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
var start = 3
if ' ' in pat:
start = 1
app(pl, op.r)
add(pl, op.r)
if length > 1:
app(pl, ~": ")
app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri))
add(pl, ~": ")
add(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri))
start = 2
else:
if length > 1:
app(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri))
app(pl, ~" ")
app(pl, op.r)
add(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri))
add(pl, ~" ")
add(pl, op.r)
if length > 2:
app(pl, ~": ")
app(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri))
add(pl, ~": ")
add(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri))
for i in countup(start, length-1):
assert(sonsLen(typ) == sonsLen(typ.n))
if i >= sonsLen(typ):
internalError(ri.info, "varargs for objective C method?")
assert(typ.n.sons[i].kind == nkSym)
var param = typ.n.sons[i].sym
app(pl, ~" ")
app(pl, param.name.s)
app(pl, ~": ")
app(pl, genArg(p, ri.sons[i], param, ri))
add(pl, ~" ")
add(pl, param.name.s)
add(pl, ~": ")
add(pl, genArg(p, ri.sons[i], param, ri))
if typ.sons[0] != nil:
if isInvalidReturnType(typ.sons[0]):
if sonsLen(ri) > 1: app(pl, ~" ")
if sonsLen(ri) > 1: add(pl, ~" ")
# beware of 'result = p(result)'. We always allocate a temporary:
if d.k in {locTemp, locNone}:
# We already got a temp. Great, special case it:
if d.k == locNone: getTemp(p, typ.sons[0], d, needsInit=true)
app(pl, ~"Result: ")
app(pl, addrLoc(d))
app(pl, ~"];$n")
add(pl, ~"Result: ")
add(pl, addrLoc(d))
add(pl, ~"];$n")
line(p, cpsStmts, pl)
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp, needsInit=true)
app(pl, addrLoc(tmp))
app(pl, ~"];$n")
add(pl, addrLoc(tmp))
add(pl, ~"];$n")
line(p, cpsStmts, pl)
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
app(pl, ~"]")
add(pl, ~"]")
if d.k == locNone: getTemp(p, typ.sons[0], d)
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
@@ -518,7 +518,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
app(pl, ~"];$n")
add(pl, ~"];$n")
line(p, cpsStmts, pl)
proc genCall(p: BProc, e: PNode, d: var TLoc) =

View File

@@ -11,45 +11,45 @@
# -------------------------- constant expressions ------------------------
proc int64Literal(i: BiggestInt): PRope =
proc int64Literal(i: BiggestInt): Rope =
if i > low(int64):
result = rfmt(nil, "IL64($1)", toRope(i))
result = rfmt(nil, "IL64($1)", rope(i))
else:
result = ~"(IL64(-9223372036854775807) - IL64(1))"
proc uint64Literal(i: uint64): PRope = toRope($i & "ULL")
proc uint64Literal(i: uint64): Rope = rope($i & "ULL")
proc intLiteral(i: BiggestInt): PRope =
proc intLiteral(i: BiggestInt): Rope =
if i > low(int32) and i <= high(int32):
result = toRope(i)
result = rope(i)
elif i == low(int32):
# Nim has the same bug for the same reasons :-)
result = ~"(-2147483647 -1)"
elif i > low(int64):
result = rfmt(nil, "IL64($1)", toRope(i))
result = rfmt(nil, "IL64($1)", rope(i))
else:
result = ~"(IL64(-9223372036854775807) - IL64(1))"
proc int32Literal(i: int): PRope =
proc int32Literal(i: int): Rope =
if i == int(low(int32)):
result = ~"(-2147483647 -1)"
else:
result = toRope(i)
result = rope(i)
proc genHexLiteral(v: PNode): PRope =
proc genHexLiteral(v: PNode): Rope =
# hex literals are unsigned in C
# so we don't generate hex literals any longer.
if v.kind notin {nkIntLit..nkUInt64Lit}:
internalError(v.info, "genHexLiteral")
result = intLiteral(v.intVal)
proc getStrLit(m: BModule, s: string): PRope =
proc getStrLit(m: BModule, s: string): Rope =
discard cgsym(m, "TGenericSeq")
result = con("TMP", toRope(backendId()))
appf(m.s[cfsData], "STRING_LITERAL($1, $2, $3);$n",
[result, makeCString(s), toRope(len(s))])
result = "TMP" & rope(backendId())
addf(m.s[cfsData], "STRING_LITERAL($1, $2, $3);$n",
[result, makeCString(s), rope(len(s))])
proc genLiteral(p: BProc, n: PNode, ty: PType): PRope =
proc genLiteral(p: BProc, n: PNode, ty: PType): Rope =
if ty == nil: internalError(n.info, "genLiteral: ty is nil")
case n.kind
of nkCharLit..nkUInt64Lit:
@@ -62,21 +62,21 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope =
of tyInt64: result = int64Literal(n.intVal)
of tyUInt64: result = uint64Literal(uint64(n.intVal))
else:
result = ropef("(($1) $2)", [getTypeDesc(p.module,
skipTypes(ty, abstractVarRange)), intLiteral(n.intVal)])
result = "(($1) $2)" % [getTypeDesc(p.module,
skipTypes(ty, abstractVarRange)), intLiteral(n.intVal)]
of nkNilLit:
let t = skipTypes(ty, abstractVarRange)
if t.kind == tyProc and t.callConv == ccClosure:
var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
result = con("TMP", toRope(id))
result = "TMP" & rope(id)
if id == gBackendId:
# not found in cache:
inc(gBackendId)
appf(p.module.s[cfsData],
addf(p.module.s[cfsData],
"static NIM_CONST $1 $2 = {NIM_NIL,NIM_NIL};$n",
[getTypeDesc(p.module, t), result])
else:
result = toRope("NIM_NIL")
result = rope("NIM_NIL")
of nkStrLit..nkTripleStrLit:
if n.strVal.isNil:
result = ropecg(p.module, "((#NimStringDesc*) NIM_NIL)", [])
@@ -87,16 +87,16 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): PRope =
result = ropecg(p.module, "((#NimStringDesc*) &$1)",
[getStrLit(p.module, n.strVal)])
else:
result = ropecg(p.module, "((#NimStringDesc*) &TMP$1)", [toRope(id)])
result = ropecg(p.module, "((#NimStringDesc*) &TMP$1)", [rope(id)])
else:
result = makeCString(n.strVal)
of nkFloatLit..nkFloat64Lit:
result = toRope(n.floatVal.toStrMaxPrecision)
result = rope(n.floatVal.toStrMaxPrecision)
else:
internalError(n.info, "genLiteral(" & $n.kind & ')')
result = nil
proc genLiteral(p: BProc, n: PNode): PRope =
proc genLiteral(p: BProc, n: PNode): Rope =
result = genLiteral(p, n, n.typ)
proc bitSetToWord(s: TBitSet, size: int): BiggestInt =
@@ -113,10 +113,10 @@ proc bitSetToWord(s: TBitSet, size: int): BiggestInt =
for j in countup(0, size - 1):
if j < len(s): result = result or `shl`(Ze64(s[j]), (Size - 1 - j) * 8)
proc genRawSetData(cs: TBitSet, size: int): PRope =
var frmt: TFormatStr
proc genRawSetData(cs: TBitSet, size: int): Rope =
var frmt: FormatStr
if size > 8:
result = ropef("{$n")
result = "{$n" % []
for i in countup(0, size - 1):
if i < size - 1:
# not last iteration?
@@ -124,22 +124,22 @@ proc genRawSetData(cs: TBitSet, size: int): PRope =
else: frmt = "0x$1, "
else:
frmt = "0x$1}$n"
appf(result, frmt, [toRope(toHex(ze64(cs[i]), 2))])
addf(result, frmt, [rope(toHex(ze64(cs[i]), 2))])
else:
result = intLiteral(bitSetToWord(cs, size))
# result := toRope('0x' + ToHex(bitSetToWord(cs, size), size * 2))
# result := rope('0x' + ToHex(bitSetToWord(cs, size), size * 2))
proc genSetNode(p: BProc, n: PNode): PRope =
proc genSetNode(p: BProc, n: PNode): Rope =
var cs: TBitSet
var size = int(getSize(n.typ))
toBitSet(n, cs)
if size > 8:
var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
result = con("TMP", toRope(id))
result = "TMP" & rope(id)
if id == gBackendId:
# not found in cache:
inc(gBackendId)
appf(p.module.s[cfsData], "static NIM_CONST $1 $2 = $3;$n",
addf(p.module.s[cfsData], "static NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(p.module, n.typ), result, genRawSetData(cs, size)])
else:
result = genRawSetData(cs, size)
@@ -211,12 +211,12 @@ proc asgnComplexity(n: PNode): int =
result += asgnComplexity(t)
else: discard
proc optAsgnLoc(a: TLoc, t: PType, field: PRope): TLoc =
proc optAsgnLoc(a: TLoc, t: PType, field: Rope): TLoc =
assert field != nil
result.k = locField
result.s = a.s
result.t = t
result.r = rdLoc(a).con(".").con(field)
result.r = rdLoc(a) & "." & field
result.heapRoot = a.heapRoot
proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
@@ -230,7 +230,7 @@ proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
let t = skipTypes(dest.t, abstractInst).getUniqueType()
for i in 0 .. <t.len:
let t = t.sons[i]
let field = ropef("Field$1", i.toRope)
let field = "Field$1" % [i.rope]
genAssignment(p, optAsgnLoc(dest, t, field),
optAsgnLoc(src, t, field), newflags)
@@ -313,8 +313,8 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
of tyProc:
if needsComplexAssignment(dest.t):
# optimize closure assignment:
let a = optAsgnLoc(dest, dest.t, "ClEnv".toRope)
let b = optAsgnLoc(src, dest.t, "ClEnv".toRope)
let a = optAsgnLoc(dest, dest.t, "ClEnv".rope)
let b = optAsgnLoc(src, dest.t, "ClEnv".rope)
genRefAssign(p, a, b, flags)
linefmt(p, cpsStmts, "$1.ClPrc = $2.ClPrc;$n", rdLoc(dest), rdLoc(src))
else:
@@ -365,7 +365,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
if mapType(ty) == ctArray:
useStringh(p.module)
linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n",
rdLoc(dest), rdLoc(src), toRope(getSize(dest.t)))
rdLoc(dest), rdLoc(src), rope(getSize(dest.t)))
else:
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString,
@@ -391,7 +391,7 @@ proc genDeepCopy(p: BProc; dest, src: TLoc) =
if mapType(ty) == ctArray:
useStringh(p.module)
linefmt(p, cpsStmts, "memcpy((void*)$1, (NIM_CONST void*)$2, $3);$n",
rdLoc(dest), rdLoc(src), toRope(getSize(dest.t)))
rdLoc(dest), rdLoc(src), rope(getSize(dest.t)))
else:
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
of tyPointer, tyChar, tyBool, tyEnum, tyCString,
@@ -409,7 +409,7 @@ proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc) =
else:
d = s # ``d`` is free, so fill it with ``s``
proc putDataIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) =
proc putDataIntoDest(p: BProc, d: var TLoc, t: PType, r: Rope) =
var a: TLoc
if d.k != locNone:
# need to generate an assignment here
@@ -424,7 +424,7 @@ proc putDataIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) =
d.t = t
d.r = r
proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: PRope) =
proc putIntoDest(p: BProc, d: var TLoc, t: PType, r: Rope) =
var a: TLoc
if d.k != locNone:
# need to generate an assignment here
@@ -486,9 +486,9 @@ proc unaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdCharLoc(a)]))
proc binaryArithOverflowRaw(p: BProc, t: PType, a, b: TLoc;
frmt: string): PRope =
frmt: string): Rope =
var size = getSize(t)
let storage = if size < platform.intSize: toRope("NI")
let storage = if size < platform.intSize: rope("NI")
else: getTypeDesc(p.module, t)
result = getTempName()
linefmt(p, cpsLocals, "$1 $2;$n", storage, result)
@@ -522,11 +522,11 @@ proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
# later via 'chckRange'
let t = e.typ.skipTypes(abstractRange)
if optOverflowCheck notin p.options:
let res = ropef(opr[m], [getTypeDesc(p.module, t), rdLoc(a), rdLoc(b)])
let res = opr[m] % [getTypeDesc(p.module, t), rdLoc(a), rdLoc(b)]
putIntoDest(p, d, e.typ, res)
else:
let res = binaryArithOverflowRaw(p, t, a, b, prc[m])
putIntoDest(p, d, e.typ, ropef("($#)($#)", [getTypeDesc(p.module, t), res]))
putIntoDest(p, d, e.typ, "($#)($#)" % [getTypeDesc(p.module, t), res])
proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
const
@@ -544,7 +544,7 @@ proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
if optOverflowCheck in p.options:
linefmt(p, cpsStmts, "if ($1 == $2) #raiseOverflow();$n",
rdLoc(a), intLiteral(firstOrd(t)))
putIntoDest(p, d, e.typ, ropef(opr[m], [rdLoc(a), toRope(getSize(t) * 8)]))
putIntoDest(p, d, e.typ, opr[m] % [rdLoc(a), rope(getSize(t) * 8)])
proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
const
@@ -613,8 +613,8 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
# BUGFIX: cannot use result-type here, as it may be a boolean
s = max(getSize(a.t), getSize(b.t)) * 8
putIntoDest(p, d, e.typ,
ropef(binArithTab[op], [rdLoc(a), rdLoc(b), toRope(s),
getSimpleTypeDesc(p.module, e.typ)]))
binArithTab[op] % [rdLoc(a), rdLoc(b), rope(s),
getSimpleTypeDesc(p.module, e.typ)])
proc genEqProc(p: BProc, e: PNode, d: var TLoc) =
var a, b: TLoc
@@ -624,10 +624,9 @@ proc genEqProc(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[2], b)
if a.t.callConv == ccClosure:
putIntoDest(p, d, e.typ,
ropef("($1.ClPrc == $2.ClPrc && $1.ClEnv == $2.ClEnv)", [
rdLoc(a), rdLoc(b)]))
"($1.ClPrc == $2.ClPrc && $1.ClEnv == $2.ClEnv)" % [rdLoc(a), rdLoc(b)])
else:
putIntoDest(p, d, e.typ, ropef("($1 == $2)", [rdLoc(a), rdLoc(b)]))
putIntoDest(p, d, e.typ, "($1 == $2)" % [rdLoc(a), rdLoc(b)])
proc genIsNil(p: BProc, e: PNode, d: var TLoc) =
let t = skipTypes(e.sons[1].typ, abstractRange)
@@ -667,8 +666,8 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
initLocExpr(p, e.sons[1], a)
t = skipTypes(e.typ, abstractRange)
putIntoDest(p, d, e.typ,
ropef(unArithTab[op], [rdLoc(a), toRope(getSize(t) * 8),
getSimpleTypeDesc(p.module, e.typ)]))
unArithTab[op] % [rdLoc(a), rope(getSize(t) * 8),
getSimpleTypeDesc(p.module, e.typ)])
proc isCppRef(p: BProc; typ: PType): bool {.inline.} =
result = p.module.compileToCpp and
@@ -707,14 +706,14 @@ proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false) =
# so the '&' and '*' cancel out:
putIntoDest(p, d, a.t.sons[0], rdLoc(a))
else:
putIntoDest(p, d, e.typ, ropef("(*$1)", [rdLoc(a)]))
putIntoDest(p, d, e.typ, "(*$1)" % [rdLoc(a)])
proc genAddr(p: BProc, e: PNode, d: var TLoc) =
# careful 'addr(myptrToArray)' needs to get the ampersand:
if e.sons[0].typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}:
var a: TLoc
initLocExpr(p, e.sons[0], a)
putIntoDest(p, d, e.typ, con("&", a.r))
putIntoDest(p, d, e.typ, "&" & a.r)
#Message(e.info, warnUser, "HERE NEW &")
elif mapType(e.sons[0].typ) == ctArray or isCppRef(p, e.sons[0].typ):
expr(p, e.sons[0], d)
@@ -747,7 +746,7 @@ proc genTupleElem(p: BProc, e: PNode, d: var TLoc) =
case e.sons[1].kind
of nkIntLit..nkUInt64Lit: i = int(e.sons[1].intVal)
else: internalError(e.info, "genTupleElem")
appf(r, ".Field$1", [toRope(i)])
addf(r, ".Field$1", [rope(i)])
putIntoDest(p, d, ty.sons[i], r)
proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
@@ -758,7 +757,7 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
if ty.kind == tyTuple:
# we found a unique tuple type which lacks field information
# so we use Field$i
appf(r, ".Field$1", [toRope(f.position)])
addf(r, ".Field$1", [rope(f.position)])
putIntoDest(p, d, f.typ, r)
else:
var field: PSym = nil
@@ -767,17 +766,17 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
internalError(e.info, "genRecordField")
field = lookupInRecord(ty.n, f.name)
if field != nil: break
if not p.module.compileToCpp: app(r, ".Sup")
if not p.module.compileToCpp: add(r, ".Sup")
ty = getUniqueType(ty.sons[0])
if field == nil: internalError(e.info, "genRecordField 2 ")
if field.loc.r == nil: internalError(e.info, "genRecordField 3")
appf(r, ".$1", [field.loc.r])
addf(r, ".$1", [field.loc.r])
putIntoDest(p, d, field.typ, r)
#d.s = a.s
proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc)
proc genFieldCheck(p: BProc, e: PNode, obj: PRope, field: PSym) =
proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) =
var test, u, v: TLoc
for i in countup(1, sonsLen(e) - 1):
var it = e.sons[i]
@@ -790,12 +789,12 @@ proc genFieldCheck(p: BProc, e: PNode, obj: PRope, field: PSym) =
initLoc(test, locNone, it.typ, OnStack)
initLocExpr(p, it.sons[1], u)
initLoc(v, locExpr, disc.typ, OnUnknown)
v.r = ropef("$1.$2", [obj, disc.sym.loc.r])
v.r = "$1.$2" % [obj, disc.sym.loc.r]
genInExprAux(p, it, u, v, test)
let id = nodeTableTestOrSet(p.module.dataCache,
newStrNode(nkStrLit, field.name.s), gBackendId)
let strLit = if id == gBackendId: getStrLit(p.module, field.name.s)
else: con("TMP", toRope(id))
else: "TMP" & rope(id)
if op.magic == mNot:
linefmt(p, cpsStmts,
"if ($1) #raiseFieldError(((#NimStringDesc*) &$2));$n",
@@ -811,7 +810,7 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
a: TLoc
f, field: PSym
ty: PType
r: PRope
r: Rope
ty = genRecordFieldAux(p, e.sons[0], d, a)
r = rdLoc(a)
f = e.sons[0].sons[1].sym
@@ -820,13 +819,13 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
assert(ty.kind in {tyTuple, tyObject})
field = lookupInRecord(ty.n, f.name)
if field != nil: break
if not p.module.compileToCpp: app(r, ".Sup")
if not p.module.compileToCpp: add(r, ".Sup")
ty = getUniqueType(ty.sons[0])
if field == nil: internalError(e.info, "genCheckedRecordField")
if field.loc.r == nil:
internalError(e.info, "genCheckedRecordField") # generate the checks:
genFieldCheck(p, e, r, field)
app(r, rfmt(nil, ".$1", field.loc.r))
add(r, rfmt(nil, ".$1", field.loc.r))
putIntoDest(p, d, field.typ, r)
else:
genRecordField(p, e.sons[0], d)
@@ -955,11 +954,11 @@ proc genEcho(p: BProc, n: PNode) =
# is threadsafe.
internalAssert n.kind == nkBracket
discard lists.includeStr(p.module.headerFiles, "<stdio.h>")
var args: PRope = nil
var args: Rope = nil
var a: TLoc
for i in countup(0, n.len-1):
initLocExpr(p, n.sons[i], a)
appf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)])
addf(args, ", $1? ($1)->data:\"nil\"", [rdLoc(a)])
linefmt(p, cpsStmts, "printf($1$2);$n",
makeCString(repeat("%s", n.len) & tnl), args)
@@ -986,22 +985,22 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
var a, tmp: TLoc
getTemp(p, e.typ, tmp)
var L = 0
var appends: PRope = nil
var lens: PRope = nil
var appends: Rope = nil
var lens: Rope = nil
for i in countup(0, sonsLen(e) - 2):
# compute the length expression:
initLocExpr(p, e.sons[i + 1], a)
if skipTypes(e.sons[i + 1].typ, abstractVarRange).kind == tyChar:
inc(L)
app(appends, rfmt(p.module, "#appendChar($1, $2);$n", tmp.r, rdLoc(a)))
add(appends, rfmt(p.module, "#appendChar($1, $2);$n", tmp.r, rdLoc(a)))
else:
if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
inc(L, len(e.sons[i + 1].strVal))
else:
appf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
app(appends, rfmt(p.module, "#appendString($1, $2);$n", tmp.r, rdLoc(a)))
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, toRope(L))
app(p.s(cpsStmts), appends)
addf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
add(appends, rfmt(p.module, "#appendString($1, $2);$n", tmp.r, rdLoc(a)))
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, rope(L))
add(p.s(cpsStmts), appends)
if d.k == locNone:
d = tmp
keepAlive(p, tmp)
@@ -1023,7 +1022,7 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
# }
var
a, dest: TLoc
appends, lens: PRope
appends, lens: Rope
assert(d.k == locNone)
var L = 0
initLocExpr(p, e.sons[1], dest)
@@ -1032,19 +1031,19 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[i + 2], a)
if skipTypes(e.sons[i + 2].typ, abstractVarRange).kind == tyChar:
inc(L)
app(appends, rfmt(p.module, "#appendChar($1, $2);$n",
add(appends, rfmt(p.module, "#appendChar($1, $2);$n",
rdLoc(dest), rdLoc(a)))
else:
if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}:
inc(L, len(e.sons[i + 2].strVal))
else:
appf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
app(appends, rfmt(p.module, "#appendString($1, $2);$n",
addf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
add(appends, rfmt(p.module, "#appendString($1, $2);$n",
rdLoc(dest), rdLoc(a)))
linefmt(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
rdLoc(dest), lens, toRope(L))
rdLoc(dest), lens, rope(L))
keepAlive(p, dest)
app(p.s(cpsStmts), appends)
add(p.s(cpsStmts), appends)
gcUsage(e)
proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
@@ -1074,14 +1073,14 @@ proc genReset(p: BProc, n: PNode) =
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
addrLoc(a), genTypeInfo(p.module, skipTypes(a.t, abstractVarRange)))
proc rawGenNew(p: BProc, a: TLoc, sizeExpr: PRope) =
proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
var sizeExpr = sizeExpr
let refType = skipTypes(a.t, abstractVarRange)
var b: TLoc
initLoc(b, locExpr, a.t, OnHeap)
if sizeExpr.isNil:
sizeExpr = ropef("sizeof($1)",
getTypeDesc(p.module, skipTypes(refType.sons[0], abstractRange)))
sizeExpr = "sizeof($1)" %
[getTypeDesc(p.module, skipTypes(refType.sons[0], abstractRange))]
let args = [getTypeDesc(p.module, refType),
genTypeInfo(p.module, refType),
sizeExpr]
@@ -1111,7 +1110,7 @@ proc genNew(p: BProc, e: PNode) =
rawGenNew(p, a, nil)
gcUsage(e)
proc genNewSeqAux(p: BProc, dest: TLoc, length: PRope) =
proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope) =
let seqtype = skipTypes(dest.t, abstractVarRange)
let args = [getTypeDesc(p.module, seqtype),
genTypeInfo(p.module, seqtype), length]
@@ -1144,7 +1143,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
if isRef:
rawGenNew(p, tmp, nil)
t = t.lastSon.skipTypes(abstractInst)
r = ropef("(*$1)", r)
r = "(*$1)" % [r]
gcUsage(e)
else:
constructLoc(p, tmp)
@@ -1158,13 +1157,13 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
while ty != nil:
field = lookupInRecord(ty.n, it.sons[0].sym.name)
if field != nil: break
if not p.module.compileToCpp: app(tmp2.r, ".Sup")
if not p.module.compileToCpp: add(tmp2.r, ".Sup")
ty = getUniqueType(ty.sons[0])
if field == nil or field.loc.r == nil: internalError(e.info, "genObjConstr")
if it.len == 3 and optFieldCheck in p.options:
genFieldCheck(p, it.sons[2], tmp2.r, field)
app(tmp2.r, ".")
app(tmp2.r, field.loc.r)
add(tmp2.r, ".")
add(tmp2.r, field.loc.r)
tmp2.k = locTemp
tmp2.t = field.loc.t
tmp2.s = if isRef: OnHeap else: OnStack
@@ -1214,14 +1213,14 @@ proc genNewFinalize(p: BProc, e: PNode) =
var
a, b, f: TLoc
refType, bt: PType
ti: PRope
ti: Rope
oldModule: BModule
refType = skipTypes(e.sons[1].typ, abstractVarRange)
initLocExpr(p, e.sons[1], a)
initLocExpr(p, e.sons[2], f)
initLoc(b, locExpr, a.t, OnHeap)
ti = genTypeInfo(p.module, refType)
appf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
addf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)])
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
getTypeDesc(p.module, refType),
ti, getTypeDesc(p.module, skipTypes(refType.lastSon, abstractRange))])
@@ -1230,18 +1229,18 @@ proc genNewFinalize(p: BProc, e: PNode) =
genObjectInit(p, cpsStmts, bt, a, false)
gcUsage(e)
proc genOfHelper(p: BProc; dest: PType; a: PRope): PRope =
proc genOfHelper(p: BProc; dest: PType; a: Rope): Rope =
# unfortunately 'genTypeInfo' sets tfObjHasKids as a side effect, so we
# have to call it here first:
let ti = genTypeInfo(p.module, dest)
if tfFinal in dest.flags or (p.module.objHasKidsValid and
tfObjHasKids notin dest.flags):
result = ropef("$1.m_type == $2", a, ti)
result = "$1.m_type == $2" % [a, ti]
else:
discard cgsym(p.module, "TNimType")
inc p.module.labels
let cache = con("Nim_OfCheck_CACHE", p.module.labels.toRope)
appf(p.module.s[cfsVars], "static TNimType* $#[2];$n", cache)
let cache = "Nim_OfCheck_CACHE" & p.module.labels.rope
addf(p.module.s[cfsVars], "static TNimType* $#[2];$n", [cache])
result = rfmt(p.module, "#isObjWithCache($#.m_type, $#, $#)", a, ti, cache)
when false:
# former version:
@@ -1253,7 +1252,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
initLocExpr(p, x, a)
var dest = skipTypes(typ, typedescPtrs)
var r = rdLoc(a)
var nilCheck: PRope = nil
var nilCheck: Rope = nil
var t = skipTypes(a.t, abstractInst)
while t.kind in {tyVar, tyPtr, tyRef}:
if t.kind != tyVar: nilCheck = r
@@ -1262,7 +1261,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
t = skipTypes(t.lastSon, typedescInst)
if not p.module.compileToCpp:
while t.kind == tyObject and t.sons[0] != nil:
app(r, ~".Sup")
add(r, ~".Sup")
t = skipTypes(t.sons[0], typedescInst)
if isObjLackingTypeField(t):
globalError(x.info, errGenerated,
@@ -1303,13 +1302,13 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
var b: TLoc
case a.t.kind
of tyOpenArray, tyVarargs:
putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
putIntoDest(p, b, e.typ, "$1, $1Len0" % [rdLoc(a)])
of tyString, tySequence:
putIntoDest(p, b, e.typ,
ropef("$1->data, $1->$2", [rdLoc(a), lenField(p)]))
"$1->data, $1->$2" % [rdLoc(a), lenField(p)])
of tyArray, tyArrayConstr:
putIntoDest(p, b, e.typ,
ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
"$1, $2" % [rdLoc(a), rope(lengthOrd(a.t))])
else: internalError(e.sons[0].info, "genRepr()")
putIntoDest(p, d, e.typ,
ropecg(p.module, "#reprOpenArray($1, $2)", [rdLoc(b),
@@ -1357,8 +1356,8 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
else: unaryExpr(p, e, d, "$1->len")
of tyArray, tyArrayConstr:
# YYY: length(sideeffect) is optimized away incorrectly?
if op == mHigh: putIntoDest(p, d, e.typ, toRope(lastOrd(typ)))
else: putIntoDest(p, d, e.typ, toRope(lengthOrd(typ)))
if op == mHigh: putIntoDest(p, d, e.typ, rope(lastOrd(typ)))
else: putIntoDest(p, d, e.typ, rope(lengthOrd(typ)))
else: internalError(e.info, "genArrayLen()")
proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
@@ -1396,13 +1395,13 @@ proc genSwap(p: BProc, e: PNode, d: var TLoc) =
genAssignment(p, a, b, {})
genAssignment(p, b, tmp, {})
proc rdSetElemLoc(a: TLoc, setType: PType): PRope =
proc rdSetElemLoc(a: TLoc, setType: PType): Rope =
# read a location of an set element; it may need a subtraction operation
# before the set operation
result = rdCharLoc(a)
assert(setType.kind == tySet)
if firstOrd(setType) != 0:
result = ropef("($1- $2)", [result, toRope(firstOrd(setType))])
result = "($1- $2)" % [result, rope(firstOrd(setType))]
proc fewCmps(s: PNode): bool =
# this function estimates whether it is better to emit code
@@ -1416,7 +1415,7 @@ proc fewCmps(s: PNode): bool =
result = sonsLen(s) <= 8 # 8 seems to be a good value
proc binaryExprIn(p: BProc, e: PNode, a, b, d: var TLoc, frmt: string) =
putIntoDest(p, d, e.typ, ropef(frmt, [rdLoc(a), rdSetElemLoc(b, a.t)]))
putIntoDest(p, d, e.typ, frmt % [rdLoc(a), rdSetElemLoc(b, a.t)])
proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) =
case int(getSize(skipTypes(e.sons[1].typ, abstractVar)))
@@ -1446,19 +1445,19 @@ proc genInOp(p: BProc, e: PNode, d: var TLoc) =
e.sons[2]
initLocExpr(p, ea, a)
initLoc(b, locExpr, e.typ, OnUnknown)
b.r = toRope("(")
b.r = rope("(")
var length = sonsLen(e.sons[1])
for i in countup(0, length - 1):
if e.sons[1].sons[i].kind == nkRange:
initLocExpr(p, e.sons[1].sons[i].sons[0], x)
initLocExpr(p, e.sons[1].sons[i].sons[1], y)
appf(b.r, "$1 >= $2 && $1 <= $3",
addf(b.r, "$1 >= $2 && $1 <= $3",
[rdCharLoc(a), rdCharLoc(x), rdCharLoc(y)])
else:
initLocExpr(p, e.sons[1].sons[i], x)
appf(b.r, "$1 == $2", [rdCharLoc(a), rdCharLoc(x)])
if i < length - 1: app(b.r, " || ")
app(b.r, ")")
addf(b.r, "$1 == $2", [rdCharLoc(a), rdCharLoc(x)])
if i < length - 1: add(b.r, " || ")
add(b.r, ")")
putIntoDest(p, d, e.typ, b.r)
else:
assert(e.sons[1].typ != nil)
@@ -1514,7 +1513,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
initLocExpr(p, e.sons[2], b)
if d.k == locNone: getTemp(p, getSysType(tyBool), d)
lineF(p, cpsStmts, lookupOpr[op],
[rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b)])
[rdLoc(i), rope(size), rdLoc(d), rdLoc(a), rdLoc(b)])
of mEqSet:
useStringh(p.module)
binaryExprChar(p, e, d, "(memcmp($1, $2, " & $(size) & ")==0)")
@@ -1527,8 +1526,8 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
lineF(p, cpsStmts,
"for ($1 = 0; $1 < $2; $1++) $n" &
" $3[$1] = $4[$1] $6 $5[$1];$n", [
rdLoc(i), toRope(size), rdLoc(d), rdLoc(a), rdLoc(b),
toRope(lookupOpr[op])])
rdLoc(i), rope(size), rdLoc(d), rdLoc(a), rdLoc(b),
rope(lookupOpr[op])])
of mInSet: genInOp(p, e, d)
else: internalError(e.info, "genSetOp")
@@ -1545,14 +1544,14 @@ proc genSomeCast(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[1], a)
let etyp = skipTypes(e.typ, abstractRange)
if etyp.kind in ValueTypes and lfIndirect notin a.flags:
putIntoDest(p, d, e.typ, ropef("(*($1*) ($2))",
[getTypeDesc(p.module, e.typ), addrLoc(a)]))
putIntoDest(p, d, e.typ, "(*($1*) ($2))" %
[getTypeDesc(p.module, e.typ), addrLoc(a)])
elif etyp.kind == tyProc and etyp.callConv == ccClosure:
putIntoDest(p, d, e.typ, ropef("(($1) ($2))",
[getClosureType(p.module, etyp, clHalfWithEnv), rdCharLoc(a)]))
putIntoDest(p, d, e.typ, "(($1) ($2))" %
[getClosureType(p.module, etyp, clHalfWithEnv), rdCharLoc(a)])
else:
putIntoDest(p, d, e.typ, ropef("(($1) ($2))",
[getTypeDesc(p.module, e.typ), rdCharLoc(a)]))
putIntoDest(p, d, e.typ, "(($1) ($2))" %
[getTypeDesc(p.module, e.typ), rdCharLoc(a)])
proc genCast(p: BProc, e: PNode, d: var TLoc) =
const floatTypes = {tyFloat..tyFloat128}
@@ -1562,9 +1561,9 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) =
if destt.kind in floatTypes or srct.kind in floatTypes:
# 'cast' and some float type involved? --> use a union.
inc(p.labels)
var lbl = p.labels.toRope
var lbl = p.labels.rope
var tmp: TLoc
tmp.r = ropef("LOC$1.source", lbl)
tmp.r = "LOC$1.source" % [lbl]
linefmt(p, cpsLocals, "union { $1 source; $2 dest; } LOC$3;$n",
getTypeDesc(p.module, srct), getTypeDesc(p.module, destt), lbl)
tmp.k = locExpr
@@ -1572,7 +1571,7 @@ proc genCast(p: BProc, e: PNode, d: var TLoc) =
tmp.s = OnStack
tmp.flags = {}
expr(p, e.sons[1], tmp)
putIntoDest(p, d, e.typ, ropef("LOC$#.dest", lbl))
putIntoDest(p, d, e.typ, "LOC$#.dest" % [lbl])
else:
# I prefer the shorter cast version for pointer types -> generate less
# C code; plus it's the right thing to do for closures:
@@ -1584,8 +1583,8 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
# range checks for unsigned turned out to be buggy and annoying:
if optRangeCheck notin p.options or dest.kind in {tyUInt..tyUInt64}:
initLocExpr(p, n.sons[0], a)
putIntoDest(p, d, n.typ, ropef("(($1) ($2))",
[getTypeDesc(p.module, dest), rdCharLoc(a)]))
putIntoDest(p, d, n.typ, "(($1) ($2))" %
[getTypeDesc(p.module, dest), rdCharLoc(a)])
else:
initLocExpr(p, n.sons[0], a)
if leValue(n.sons[2], n.sons[1]):
@@ -1593,7 +1592,7 @@ proc genRangeChck(p: BProc, n: PNode, d: var TLoc, magic: string) =
putIntoDest(p, d, dest, ropecg(p.module, "(($1)#$5($2, $3, $4))", [
getTypeDesc(p.module, dest), rdCharLoc(a),
genLiteral(p, n.sons[1], dest), genLiteral(p, n.sons[2], dest),
toRope(magic)]))
rope(magic)]))
proc genConv(p: BProc, e: PNode, d: var TLoc) =
let destType = e.typ.skipTypes({tyVar, tyGenericInst})
@@ -1605,8 +1604,7 @@ proc genConv(p: BProc, e: PNode, d: var TLoc) =
proc convStrToCStr(p: BProc, n: PNode, d: var TLoc) =
var a: TLoc
initLocExpr(p, n.sons[0], a)
putIntoDest(p, d, skipTypes(n.typ, abstractVar), ropef("$1->data",
[rdLoc(a)]))
putIntoDest(p, d, skipTypes(n.typ, abstractVar), "$1->data" % [rdLoc(a)])
proc convCStrToStr(p: BProc, n: PNode, d: var TLoc) =
var a: TLoc
@@ -1641,7 +1639,7 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
initLocExpr(p, e.sons[1], a)
initLocExpr(p, e.sons[2], b)
putIntoDest(p, d, e.typ, rfmt(nil, "(($4)($2) $1 ($4)($3))",
toRope(opr[m]), rdLoc(a), rdLoc(b),
rope(opr[m]), rdLoc(a), rdLoc(b),
getSimpleTypeDesc(p.module, e[1].typ)))
if optNaNCheck in p.options:
linefmt(p, cpsStmts, "#nanCheck($1);$n", rdLoc(d))
@@ -1651,7 +1649,7 @@ proc binaryFloatArith(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
binaryArith(p, e, d, m)
proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
var line, filen: PRope
var line, filen: Rope
case op
of mOr, mAnd: genAndOr(p, e, d, op)
of mNot..mToBiggestInt: unaryArith(p, e, d, op)
@@ -1685,8 +1683,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
let ranged = skipTypes(e.sons[1].typ, {tyGenericInst, tyVar})
let res = binaryArithOverflowRaw(p, ranged, a, b,
if underlying.kind == tyInt64: fun64[op] else: fun[op])
putIntoDest(p, a, ranged, ropef("($#)($#)", [
getTypeDesc(p.module, ranged), res]))
putIntoDest(p, a, ranged, "($#)($#)" % [
getTypeDesc(p.module, ranged), res])
of mConStrStr: genStrConcat(p, e, d)
of mAppendStrCh:
@@ -1713,8 +1711,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mNewSeq: genNewSeq(p, e)
of mSizeOf:
let t = e.sons[1].typ.skipTypes({tyTypeDesc})
putIntoDest(p, d, e.typ, ropef("((NI)sizeof($1))",
[getTypeDesc(p.module, t)]))
putIntoDest(p, d, e.typ, "((NI)sizeof($1))" % [getTypeDesc(p.module, t)])
of mChr: genSomeCast(p, e, d)
of mOrd: genOrd(p, e, d)
of mLengthArray, mHigh, mLengthStr, mLengthSeq, mLengthOpenArray:
@@ -1752,17 +1749,17 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mDotDot: genCall(p, e, d)
else: internalError(e.info, "genMagicExpr: " & $op)
proc genConstExpr(p: BProc, n: PNode): PRope
proc genConstExpr(p: BProc, n: PNode): Rope
proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool =
if nfAllConst in n.flags and d.k == locNone and n.len > 0 and n.isDeepConstExpr:
var t = getUniqueType(n.typ)
discard getTypeDesc(p.module, t) # so that any fields are initialized
var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
fillLoc(d, locData, t, con("TMP", toRope(id)), OnHeap)
fillLoc(d, locData, t, "TMP" & rope(id), OnHeap)
if id == gBackendId:
# expression not found in the cache:
inc(gBackendId)
appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
addf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(p.module, t), d.r, genConstExpr(p, n)])
result = true
else:
@@ -1824,13 +1821,12 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
var it = n.sons[i]
if it.kind == nkExprColonExpr: it = it.sons[1]
initLoc(rec, locExpr, it.typ, d.s)
rec.r = ropef("$1.Field$2", [rdLoc(d), toRope(i)])
rec.r = "$1.Field$2" % [rdLoc(d), rope(i)]
expr(p, it, rec)
when false:
initLoc(rec, locExpr, it.typ, d.s)
if (t.n.sons[i].kind != nkSym): InternalError(n.info, "genTupleConstr")
rec.r = ropef("$1.$2",
[rdLoc(d), mangleRecFieldName(t.n.sons[i].sym, t)])
rec.r = "$1.$2" % [rdLoc(d), mangleRecFieldName(t.n.sons[i].sym, t)]
expr(p, it, rec)
proc isConstClosure(n: PNode): bool {.inline.} =
@@ -1842,8 +1838,8 @@ proc genClosure(p: BProc, n: PNode, d: var TLoc) =
if isConstClosure(n):
inc(p.labels)
var tmp = con("LOC", toRope(p.labels))
appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
var tmp = "LOC" & rope(p.labels)
addf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(p.module, n.typ), tmp, genConstExpr(p, n)])
putIntoDest(p, d, n.typ, tmp)
else:
@@ -1861,7 +1857,7 @@ proc genArrayConstr(p: BProc, n: PNode, d: var TLoc) =
if d.k == locNone: getTemp(p, n.typ, d)
for i in countup(0, sonsLen(n) - 1):
initLoc(arr, locExpr, elemType(skipTypes(n.typ, abstractInst)), d.s)
arr.r = ropef("$1[$2]", [rdLoc(d), intLiteral(i)])
arr.r = "$1[$2]" % [rdLoc(d), intLiteral(i)]
expr(p, n.sons[i], arr)
proc genComplexConst(p: BProc, sym: PSym, d: var TLoc) =
@@ -1880,16 +1876,16 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
var dest = skipTypes(n.typ, abstractPtrs)
if optObjCheck in p.options and not isObjLackingTypeField(dest):
var r = rdLoc(a)
var nilCheck: PRope = nil
var nilCheck: Rope = nil
var t = skipTypes(a.t, abstractInst)
while t.kind in {tyVar, tyPtr, tyRef}:
if t.kind != tyVar: nilCheck = r
if t.kind != tyVar or not p.module.compileToCpp:
r = ropef("(*$1)", [r])
r = "(*$1)" % [r]
t = skipTypes(t.lastSon, abstractInst)
if not p.module.compileToCpp:
while t.kind == tyObject and t.sons[0] != nil:
app(r, ".Sup")
add(r, ".Sup")
t = skipTypes(t.sons[0], abstractInst)
if nilCheck != nil:
linefmt(p, cpsStmts, "if ($1) #chckObj($2.m_type, $3);$n",
@@ -1899,10 +1895,10 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
r, genTypeInfo(p.module, dest))
if n.sons[0].typ.kind != tyObject:
putIntoDest(p, d, n.typ,
ropef("(($1) ($2))", [getTypeDesc(p.module, n.typ), rdLoc(a)]))
"(($1) ($2))" % [getTypeDesc(p.module, n.typ), rdLoc(a)])
else:
putIntoDest(p, d, n.typ, ropef("(*($1*) ($2))",
[getTypeDesc(p.module, dest), addrLoc(a)]))
putIntoDest(p, d, n.typ, "(*($1*) ($2))" %
[getTypeDesc(p.module, dest), addrLoc(a)])
proc downConv(p: BProc, n: PNode, d: var TLoc) =
if p.module.compileToCpp:
@@ -1919,10 +1915,10 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
var r = rdLoc(a)
let isRef = skipTypes(arg.typ, abstractInst).kind in {tyRef, tyPtr, tyVar}
if isRef:
app(r, "->Sup")
add(r, "->Sup")
else:
app(r, ".Sup")
for i in countup(2, abs(inheritanceDiff(dest, src))): app(r, ".Sup")
add(r, ".Sup")
for i in countup(2, abs(inheritanceDiff(dest, src))): add(r, ".Sup")
if isRef:
# it can happen that we end up generating '&&x->Sup' here, so we pack
# the '&x->Sup' into a temporary and then those address is taken
@@ -1933,7 +1929,7 @@ proc downConv(p: BProc, n: PNode, d: var TLoc) =
getTemp(p, n.typ, d)
linefmt(p, cpsStmts, "$1 = &$2;$n", rdLoc(d), r)
else:
r = con("&", r)
r = "&" & r
putIntoDest(p, d, n.typ, r)
else:
putIntoDest(p, d, n.typ, r)
@@ -1942,12 +1938,12 @@ proc exprComplexConst(p: BProc, n: PNode, d: var TLoc) =
var t = getUniqueType(n.typ)
discard getTypeDesc(p.module, t) # so that any fields are initialized
var id = nodeTableTestOrSet(p.module.dataCache, n, gBackendId)
var tmp = con("TMP", toRope(id))
var tmp = "TMP" & rope(id)
if id == gBackendId:
# expression not found in the cache:
inc(gBackendId)
appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
addf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(p.module, t), tmp, genConstExpr(p, n)])
if d.k == locNone:
@@ -1982,7 +1978,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
else:
genComplexConst(p, sym, d)
of skEnumField:
putIntoDest(p, d, n.typ, toRope(sym.position))
putIntoDest(p, d, n.typ, rope(sym.position))
of skVar, skForVar, skResult, skLet:
if sfGlobal in sym.flags: genVarPrototype(p.module, sym)
if sym.loc.r == nil or sym.loc.t == nil:
@@ -1991,7 +1987,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
if sfThread in sym.flags:
accessThreadLocalVar(p, sym)
if emulatedThreadVars():
putIntoDest(p, d, sym.loc.t, con("NimTV->", sym.loc.r))
putIntoDest(p, d, sym.loc.t, "NimTV->" & sym.loc.r)
else:
putLocIntoDest(p, d, sym.loc)
else:
@@ -2134,42 +2130,42 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
of nkBreakState: genBreakState(p, n)
else: internalError(n.info, "expr(" & $n.kind & "); unknown node kind")
proc genNamedConstExpr(p: BProc, n: PNode): PRope =
proc genNamedConstExpr(p: BProc, n: PNode): Rope =
if n.kind == nkExprColonExpr: result = genConstExpr(p, n.sons[1])
else: result = genConstExpr(p, n)
proc genConstSimpleList(p: BProc, n: PNode): PRope =
proc genConstSimpleList(p: BProc, n: PNode): Rope =
var length = sonsLen(n)
result = toRope("{")
result = rope("{")
for i in countup(0, length - 2):
appf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])])
if length > 0: app(result, genNamedConstExpr(p, n.sons[length - 1]))
appf(result, "}$n")
addf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])])
if length > 0: add(result, genNamedConstExpr(p, n.sons[length - 1]))
addf(result, "}$n", [])
proc genConstSeq(p: BProc, n: PNode, t: PType): PRope =
var data = ropef("{{$1, $1}", n.len.toRope)
proc genConstSeq(p: BProc, n: PNode, t: PType): Rope =
var data = "{{$1, $1}" % [n.len.rope]
if n.len > 0:
# array part needs extra curlies:
data.app(", {")
data.add(", {")
for i in countup(0, n.len - 1):
if i > 0: data.appf(",$n")
data.app genConstExpr(p, n.sons[i])
data.app("}")
data.app("}")
if i > 0: data.addf(",$n", [])
data.add genConstExpr(p, n.sons[i])
data.add("}")
data.add("}")
inc(gBackendId)
result = con("CNSTSEQ", gBackendId.toRope)
result = "CNSTSEQ" & gBackendId.rope
appcg(p.module, cfsData,
"NIM_CONST struct {$n" &
" #TGenericSeq Sup;$n" &
" $1 data[$2];$n" &
"} $3 = $4;$n", [
getTypeDesc(p.module, t.sons[0]), n.len.toRope, result, data])
getTypeDesc(p.module, t.sons[0]), n.len.rope, result, data])
result = ropef("(($1)&$2)", [getTypeDesc(p.module, t), result])
result = "(($1)&$2)" % [getTypeDesc(p.module, t), result]
proc genConstExpr(p: BProc, n: PNode): PRope =
proc genConstExpr(p: BProc, n: PNode): Rope =
case n.kind
of nkHiddenStdConv, nkHiddenSubConv:
result = genConstExpr(p, n.sons[1])

View File

@@ -45,29 +45,29 @@ const
]
NimMergeEndMark = "/*\tNIM_merge_END:*/"
proc genSectionStart*(fs: TCFileSection): PRope =
proc genSectionStart*(fs: TCFileSection): Rope =
if compilationCachePresent:
result = toRope(tnl)
app(result, "/*\t")
app(result, CFileSectionNames[fs])
app(result, ":*/")
app(result, tnl)
result = rope(tnl)
add(result, "/*\t")
add(result, CFileSectionNames[fs])
add(result, ":*/")
add(result, tnl)
proc genSectionEnd*(fs: TCFileSection): PRope =
proc genSectionEnd*(fs: TCFileSection): Rope =
if compilationCachePresent:
result = toRope(NimMergeEndMark & tnl)
result = rope(NimMergeEndMark & tnl)
proc genSectionStart*(ps: TCProcSection): PRope =
proc genSectionStart*(ps: TCProcSection): Rope =
if compilationCachePresent:
result = toRope(tnl)
app(result, "/*\t")
app(result, CProcSectionNames[ps])
app(result, ":*/")
app(result, tnl)
result = rope(tnl)
add(result, "/*\t")
add(result, CProcSectionNames[ps])
add(result, ":*/")
add(result, tnl)
proc genSectionEnd*(ps: TCProcSection): PRope =
proc genSectionEnd*(ps: TCProcSection): Rope =
if compilationCachePresent:
result = toRope(NimMergeEndMark & tnl)
result = rope(NimMergeEndMark & tnl)
proc writeTypeCache(a: TIdTable, s: var string) =
var i = 0
@@ -79,7 +79,7 @@ proc writeTypeCache(a: TIdTable, s: var string) =
s.add(' ')
encodeVInt(id, s)
s.add(':')
encodeStr($PRope(value), s)
encodeStr($Rope(value), s)
inc i
s.add('}')
@@ -95,7 +95,7 @@ proc writeIntSet(a: IntSet, s: var string) =
inc i
s.add('}')
proc genMergeInfo*(m: BModule): PRope =
proc genMergeInfo*(m: BModule): Rope =
if optSymbolFiles notin gGlobalOptions: return nil
var s = "/*\tNIM_merge_INFO:"
s.add(tnl)
@@ -111,7 +111,7 @@ proc genMergeInfo*(m: BModule): PRope =
encodeVInt(ord(m.frameDeclared), s)
s.add(tnl)
s.add("*/")
result = s.toRope
result = s.rope
template `^`(pos: int): expr = L.buf[pos]
@@ -145,7 +145,7 @@ proc atEndMark(buf: cstring, pos: int): bool =
while s < NimMergeEndMark.len and buf[pos+s] == NimMergeEndMark[s]: inc s
result = s == NimMergeEndMark.len
proc readVerbatimSection(L: var TBaseLexer): PRope =
proc readVerbatimSection(L: var TBaseLexer): Rope =
var pos = L.bufpos
var buf = L.buf
var r = newStringOfCap(30_000)
@@ -169,7 +169,7 @@ proc readVerbatimSection(L: var TBaseLexer): PRope =
r.add(buf[pos])
inc pos
L.bufpos = pos
result = r.toRope
result = r.rope
proc readKey(L: var TBaseLexer, result: var string) =
var pos = L.bufpos
@@ -197,7 +197,7 @@ proc readTypeCache(L: var TBaseLexer, result: var TIdTable) =
# XXX little hack: we create a "fake" type object with the correct Id
# better would be to adapt the data structure to not even store the
# object as key, but only the Id
idTablePut(result, newFakeType(key), value.toRope)
idTablePut(result, newFakeType(key), value.rope)
inc L.bufpos
proc readIntSet(L: var TBaseLexer, result: var IntSet) =
@@ -293,6 +293,6 @@ proc mergeFiles*(cfilename: string, m: BModule) =
readMergeSections(cfilename, old)
# do the merge; old section before new section:
for i in low(TCFileSection)..high(TCFileSection):
m.s[i] = con(old.f[i], m.s[i])
m.s[i] = old.f[i] & m.s[i]
for i in low(TCProcSection)..high(TCProcSection):
m.initProc.s(i) = con(old.p[i], m.initProc.s(i))
m.initProc.s(i) = old.p[i] & m.initProc.s(i)

View File

@@ -61,11 +61,10 @@ proc genVarTuple(p: BProc, n: PNode) =
initLocalVar(p, v, immediateAsgn=isAssignedImmediately(n[L-1]))
initLoc(field, locExpr, t.sons[i], tup.s)
if t.kind == tyTuple:
field.r = ropef("$1.Field$2", [rdLoc(tup), toRope(i)])
field.r = "$1.Field$2" % [rdLoc(tup), rope(i)]
else:
if t.n.sons[i].kind != nkSym: internalError(n.info, "genVarTuple")
field.r = ropef("$1.$2",
[rdLoc(tup), mangleRecFieldName(t.n.sons[i].sym, t)])
field.r = "$1.$2" % [rdLoc(tup), mangleRecFieldName(t.n.sons[i].sym, t)]
putLocIntoDest(p, v.loc, field)
proc genDeref(p: BProc, e: PNode, d: var TLoc; enforceDeref=false)
@@ -86,8 +85,8 @@ proc loadInto(p: BProc, le, ri: PNode, a: var TLoc) {.inline.} =
else:
expr(p, ri, a)
proc startBlock(p: BProc, start: TFormatStr = "{$n",
args: varargs[PRope]): int {.discardable.} =
proc startBlock(p: BProc, start: FormatStr = "{$n",
args: varargs[Rope]): int {.discardable.} =
lineCg(p, cpsStmts, start, args)
inc(p.labels)
result = len(p.blocks)
@@ -96,21 +95,21 @@ proc startBlock(p: BProc, start: TFormatStr = "{$n",
p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16
p.blocks[result].nestedExceptStmts = p.inExceptBlock.int16
proc assignLabel(b: var TBlock): PRope {.inline.} =
b.label = con("LA", b.id.toRope)
proc assignLabel(b: var TBlock): Rope {.inline.} =
b.label = "LA" & b.id.rope
result = b.label
proc blockBody(b: var TBlock): PRope =
proc blockBody(b: var TBlock): Rope =
result = b.sections[cpsLocals]
if b.frameLen > 0:
result.appf("F.len+=$1;$n", b.frameLen.toRope)
result.app(b.sections[cpsInit])
result.app(b.sections[cpsStmts])
result.addf("F.len+=$1;$n", [b.frameLen.rope])
result.add(b.sections[cpsInit])
result.add(b.sections[cpsStmts])
proc endBlock(p: BProc, blockEnd: PRope) =
proc endBlock(p: BProc, blockEnd: Rope) =
let topBlock = p.blocks.len-1
# the block is merged into the parent block
app(p.blocks[topBlock-1].sections[cpsStmts], p.blocks[topBlock].blockBody)
add(p.blocks[topBlock-1].sections[cpsStmts], p.blocks[topBlock].blockBody)
setLen(p.blocks, topBlock)
# this is done after the block is popped so $n is
# properly indented when pretty printing is enabled
@@ -124,7 +123,7 @@ proc endBlock(p: BProc) =
~"}$n"
let frameLen = p.blocks[topBlock].frameLen
if frameLen > 0:
blockEnd.appf("F.len-=$1;$n", frameLen.toRope)
blockEnd.addf("F.len-=$1;$n", [frameLen.rope])
endBlock(p, blockEnd)
proc genSimpleBlock(p: BProc, stmts: PNode) {.inline.} =
@@ -145,7 +144,7 @@ template preserveBreakIdx(body: stmt): stmt {.immediate.} =
proc genState(p: BProc, n: PNode) =
internalAssert n.len == 1 and n.sons[0].kind == nkIntLit
let idx = n.sons[0].intVal
linefmt(p, cpsStmts, "STATE$1: ;$n", idx.toRope)
linefmt(p, cpsStmts, "STATE$1: ;$n", idx.rope)
proc genGotoState(p: BProc, n: PNode) =
# we resist the temptation to translate it into duff's device as it later
@@ -159,7 +158,7 @@ proc genGotoState(p: BProc, n: PNode) =
p.beforeRetNeeded = true
lineF(p, cpsStmts, "case -1: goto BeforeRet;$n", [])
for i in 0 .. lastOrd(n.sons[0].typ):
lineF(p, cpsStmts, "case $1: goto STATE$1;$n", [toRope(i)])
lineF(p, cpsStmts, "case $1: goto STATE$1;$n", [rope(i)])
lineF(p, cpsStmts, "}$n", [])
proc genBreakState(p: BProc, n: PNode) =
@@ -214,17 +213,17 @@ proc genSingleVar(p: BProc, a: PNode) =
var tmp: TLoc
if value.kind in nkCallKinds and value[0].kind == nkSym and
sfConstructor in value[0].sym.flags:
var params: PRope
var params: Rope
let typ = skipTypes(value.sons[0].typ, abstractInst)
assert(typ.kind == tyProc)
for i in 1.. <value.len:
if params != nil: params.app(~", ")
if params != nil: params.add(~", ")
assert(sonsLen(typ) == sonsLen(typ.n))
app(params, genOtherArg(p, value, i, typ))
lineF(p, cpsStmts, "$#($#);$n", decl, params)
add(params, genOtherArg(p, value, i, typ))
lineF(p, cpsStmts, "$#($#);$n", [decl, params])
else:
initLocExprSingleUse(p, value, tmp)
lineF(p, cpsStmts, "$# = $#;$n", decl, tmp.rdLoc)
lineF(p, cpsStmts, "$# = $#;$n", [decl, tmp.rdLoc])
return
assignLocalVar(p, v)
initLocalVar(p, v, imm)
@@ -298,9 +297,9 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
when not newScopeForIf: startBlock(p)
if p.module.compileToCpp:
# avoid "jump to label crosses initialization" error:
app(p.s(cpsStmts), "{")
add(p.s(cpsStmts), "{")
expr(p, it.sons[1], d)
app(p.s(cpsStmts), "}")
add(p.s(cpsStmts), "}")
else:
expr(p, it.sons[1], d)
endBlock(p)
@@ -389,11 +388,11 @@ proc genComputedGoto(p: BProc; n: PNode) =
localError(n.info, "no case statement found for computed goto"); return
var id = p.labels+1
inc p.labels, arraySize+1
let tmp = ropef("TMP$1", id.toRope)
var gotoArray = ropef("static void* $#[$#] = {", tmp, arraySize.toRope)
let tmp = "TMP$1" % [id.rope]
var gotoArray = "static void* $#[$#] = {" % [tmp, arraySize.rope]
for i in 1..arraySize-1:
gotoArray.appf("&&TMP$#, ", (id+i).toRope)
gotoArray.appf("&&TMP$#};$n", (id+arraySize).toRope)
gotoArray.addf("&&TMP$#, ", [(id+i).rope])
gotoArray.addf("&&TMP$#};$n", [(id+arraySize).rope])
line(p, cpsLocals, gotoArray)
let topBlock = p.blocks.len-1
@@ -407,13 +406,13 @@ proc genComputedGoto(p: BProc; n: PNode) =
for j in 0 .. casePos-1: genStmts(p, n.sons[j])
let tailA = p.blocks[topBlock].sections[cpsStmts]
p.blocks[topBlock].sections[cpsStmts] = oldBody.con(tailA)
p.blocks[topBlock].sections[cpsStmts] = oldBody & tailA
let caseStmt = n.sons[casePos]
var a: TLoc
initLocExpr(p, caseStmt.sons[0], a)
# first goto:
lineF(p, cpsStmts, "goto *$#[$#];$n", tmp, a.rdLoc)
lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc])
for i in 1 .. <caseStmt.len:
startBlock(p)
@@ -423,16 +422,16 @@ proc genComputedGoto(p: BProc; n: PNode) =
localError(it.info, "range notation not available for computed goto")
return
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)
#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
app(p.s(cpsStmts), tailB)
app(p.s(cpsStmts), tailA)
add(p.s(cpsStmts), tailB)
add(p.s(cpsStmts), tailA)
var a: TLoc
initLocExpr(p, caseStmt.sons[0], a)
lineF(p, cpsStmts, "goto *$#[$#];$n", tmp, a.rdLoc)
lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc])
endBlock(p)
proc genWhileStmt(p: BProc, t: PNode) =
@@ -498,9 +497,9 @@ proc genParForStmt(p: BProc, t: PNode) =
lineF(p, cpsStmts, "#pragma omp parallel for $4$n" &
"for ($1 = $2; $1 <= $3; ++$1)",
forLoopVar.loc.rdLoc,
[forLoopVar.loc.rdLoc,
rangeA.rdLoc, rangeB.rdLoc,
call.sons[3].getStr.toRope)
call.sons[3].getStr.rope])
p.breakIdx = startBlock(p)
p.blocks[p.breakIdx].isLoop = true
@@ -560,7 +559,7 @@ proc genRaiseStmt(p: BProc, t: PNode) =
linefmt(p, cpsStmts, "#reraiseException();$n")
proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
rangeFormat, eqFormat: TFormatStr, labl: TLabel) =
rangeFormat, eqFormat: FormatStr, labl: TLabel) =
var
x, y: TLoc
var length = sonsLen(b)
@@ -578,7 +577,7 @@ proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc,
labId, until: int): TLabel =
var lend = getLabel(p)
for i in 1..until:
lineF(p, cpsStmts, "LA$1: ;$n", [toRope(labId + i)])
lineF(p, cpsStmts, "LA$1: ;$n", [rope(labId + i)])
if t.sons[i].kind == nkOfBranch:
var length = sonsLen(t.sons[i])
exprBlock(p, t.sons[i].sons[length - 1], d)
@@ -588,7 +587,7 @@ proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc,
result = lend
proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
rangeFormat, eqFormat: TFormatStr,
rangeFormat, eqFormat: FormatStr,
until: int, a: TLoc): TLabel =
# generate a C-if statement for a Nim case statement
var labId = p.labels
@@ -596,27 +595,27 @@ proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
inc(p.labels)
if t.sons[i].kind == nkOfBranch: # else statement
genCaseGenericBranch(p, t.sons[i], a, rangeFormat, eqFormat,
con("LA", toRope(p.labels)))
"LA" & rope(p.labels))
else:
lineF(p, cpsStmts, "goto LA$1;$n", [toRope(p.labels)])
lineF(p, cpsStmts, "goto LA$1;$n", [rope(p.labels)])
if until < t.len-1:
inc(p.labels)
var gotoTarget = p.labels
lineF(p, cpsStmts, "goto LA$1;$n", [toRope(gotoTarget)])
lineF(p, cpsStmts, "goto LA$1;$n", [rope(gotoTarget)])
result = genCaseSecondPass(p, t, d, labId, until)
lineF(p, cpsStmts, "LA$1: ;$n", [toRope(gotoTarget)])
lineF(p, cpsStmts, "LA$1: ;$n", [rope(gotoTarget)])
else:
result = genCaseSecondPass(p, t, d, labId, until)
proc genCaseGeneric(p: BProc, t: PNode, d: var TLoc,
rangeFormat, eqFormat: TFormatStr) =
rangeFormat, eqFormat: FormatStr) =
var a: TLoc
initLocExpr(p, t.sons[0], a)
var lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, sonsLen(t)-1, a)
fixLabel(p, lend)
proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel,
branches: var openArray[PRope]) =
branches: var openArray[Rope]) =
var x: TLoc
var length = sonsLen(b)
for i in countup(0, length - 2):
@@ -634,7 +633,7 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) =
if t.sons[i].kind == nkOfBranch: inc(strings, sonsLen(t.sons[i]) - 1)
if strings > stringCaseThreshold:
var bitMask = math.nextPowerOfTwo(strings) - 1
var branches: seq[PRope]
var branches: seq[Rope]
newSeq(branches, bitMask + 1)
var a: TLoc
initLocExpr(p, t.sons[0], a) # fist pass: gnerate ifs+goto:
@@ -642,21 +641,21 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) =
for i in countup(1, sonsLen(t) - 1):
inc(p.labels)
if t.sons[i].kind == nkOfBranch:
genCaseStringBranch(p, t.sons[i], a, con("LA", toRope(p.labels)),
genCaseStringBranch(p, t.sons[i], a, "LA" & rope(p.labels),
branches)
else:
# else statement: nothing to do yet
# but we reserved a label, which we use later
discard
linefmt(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
rdLoc(a), toRope(bitMask))
rdLoc(a), rope(bitMask))
for j in countup(0, high(branches)):
if branches[j] != nil:
lineF(p, cpsStmts, "case $1: $n$2break;$n",
[intLiteral(j), branches[j]])
lineF(p, cpsStmts, "}$n") # else statement:
lineF(p, cpsStmts, "}$n", []) # else statement:
if t.sons[sonsLen(t)-1].kind != nkOfBranch:
lineF(p, cpsStmts, "goto LA$1;$n", [toRope(p.labels)])
lineF(p, cpsStmts, "goto LA$1;$n", [rope(p.labels)])
# third pass: generate statements
var lend = genCaseSecondPass(p, t, d, labId, sonsLen(t)-1)
fixLabel(p, lend)
@@ -718,13 +717,13 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) =
genCaseRange(p, branch)
else:
# else part of case statement:
lineF(p, cpsStmts, "default:$n")
lineF(p, cpsStmts, "default:$n", [])
hasDefault = true
exprBlock(p, branch.lastSon, d)
lineF(p, cpsStmts, "break;$n")
lineF(p, cpsStmts, "break;$n", [])
if (hasAssume in CC[cCompiler].props) and not hasDefault:
lineF(p, cpsStmts, "default: __assume(0);$n")
lineF(p, cpsStmts, "}$n")
lineF(p, cpsStmts, "default: __assume(0);$n", [])
lineF(p, cpsStmts, "}$n", [])
if lend != nil: fixLabel(p, lend)
proc genCase(p: BProc, t: PNode, d: var TLoc) =
@@ -774,7 +773,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
if not isEmptyType(t.typ) and d.k == locNone:
getTemp(p, t.typ, d)
var
exc: PRope
exc: Rope
i, length, blen: int
genLineDir(p, t)
exc = getTempName()
@@ -794,16 +793,16 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
var catchAllPresent = false
while (i < length) and (t.sons[i].kind == nkExceptBranch):
blen = sonsLen(t.sons[i])
if i > 1: appf(p.s(cpsStmts), "else ")
if i > 1: addf(p.s(cpsStmts), "else ", [])
if blen == 1:
# general except section:
catchAllPresent = true
exprBlock(p, t.sons[i].sons[0], d)
else:
var orExpr: PRope = nil
var orExpr: Rope = nil
for j in countup(0, blen - 2):
assert(t.sons[i].sons[j].kind == nkType)
if orExpr != nil: app(orExpr, "||")
if orExpr != nil: add(orExpr, "||")
appcg(p.module, orExpr,
"#isObj($1.exp->m_type, $2)",
[exc, genTypeInfo(p.module, t.sons[i].sons[j].typ)])
@@ -814,7 +813,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
# reraise the exception if there was no catch all
# and none of the handlers matched
if not catchAllPresent:
if i > 1: lineF(p, cpsStmts, "else ")
if i > 1: lineF(p, cpsStmts, "else ", [])
startBlock(p)
var finallyBlock = t.lastSon
if finallyBlock.kind == nkFinally:
@@ -824,7 +823,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
line(p, cpsStmts, ~"throw;$n")
endBlock(p)
lineF(p, cpsStmts, "}$n") # end of catch block
lineF(p, cpsStmts, "}$n", []) # end of catch block
dec p.inExceptBlock
discard pop(p.nestedTryStmts)
@@ -895,17 +894,17 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
var blen = sonsLen(t.sons[i])
if blen == 1:
# general except section:
if i > 1: lineF(p, cpsStmts, "else")
if i > 1: lineF(p, cpsStmts, "else", [])
startBlock(p)
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
expr(p, t.sons[i].sons[0], d)
linefmt(p, cpsStmts, "#popCurrentException();$n")
endBlock(p)
else:
var orExpr: PRope = nil
var orExpr: Rope = nil
for j in countup(0, blen - 2):
assert(t.sons[i].sons[j].kind == nkType)
if orExpr != nil: app(orExpr, "||")
if orExpr != nil: add(orExpr, "||")
appcg(p.module, orExpr,
"#isObj(#getCurrentException()->Sup.m_type, $1)",
[genTypeInfo(p.module, t.sons[i].sons[j].typ)])
@@ -925,7 +924,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
discard pop(p.finallySafePoints)
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", safePoint)
proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope =
proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope =
var res = ""
for i in countup(0, sonsLen(t) - 1):
case t.sons[i].kind
@@ -954,15 +953,15 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope =
if x[j] in {'"', ':'}:
# don't modify the line if already in quotes or
# some clobber register list:
app(result, x); app(result, tnl)
add(result, x); add(result, tnl)
elif x[j] != '\0':
# ignore empty lines
app(result, "\"")
app(result, x)
app(result, "\\n\"\n")
add(result, "\"")
add(result, x)
add(result, "\\n\"\n")
else:
res.add(tnl)
result = res.toRope
result = res.rope
proc genAsmStmt(p: BProc, t: PNode) =
assert(t.kind == nkAsmStmt)
@@ -973,7 +972,7 @@ proc genAsmStmt(p: BProc, t: PNode) =
# work:
if p.prc == nil:
# top level asm statement?
appf(p.module.s[cfsProcHeaders], CC[cCompiler].asmStmtFrmt, [s])
addf(p.module.s[cfsProcHeaders], CC[cCompiler].asmStmtFrmt, [s])
else:
lineF(p, cpsStmts, CC[cCompiler].asmStmtFrmt, [s])
@@ -982,14 +981,14 @@ proc genEmit(p: BProc, t: PNode) =
if p.prc == nil:
# top level emit pragma?
genCLineDir(p.module.s[cfsProcHeaders], t.info)
app(p.module.s[cfsProcHeaders], s)
add(p.module.s[cfsProcHeaders], s)
else:
genLineDir(p, t)
line(p, cpsStmts, s)
var
breakPointId: int = 0
gBreakpoints: PRope # later the breakpoints are inserted into the main proc
gBreakpoints: Rope # later the breakpoints are inserted into the main proc
proc genBreakPoint(p: BProc, t: PNode) =
var name: string
@@ -1003,7 +1002,7 @@ proc genBreakPoint(p: BProc, t: PNode) =
genLineDir(p, t) # BUGFIX
appcg(p.module, gBreakpoints,
"#dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n", [
toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)),
rope(toLinenumber(t.info)), makeCString(toFilename(t.info)),
makeCString(name)])
proc genWatchpoint(p: BProc, n: PNode) =

View File

@@ -7,7 +7,7 @@
# distribution, for details about the copyright.
#
## Thread var support for crappy architectures that lack native support for
## Thread var support for crappy architectures that lack native support for
## thread local storage. (**Thank you Mac OS X!**)
# included from cgen.nim
@@ -19,12 +19,12 @@ proc accessThreadLocalVar(p: BProc, s: PSym) =
if emulatedThreadVars() and not p.threadVarAccessed:
p.threadVarAccessed = true
p.module.usesThreadVars = true
appf(p.procSec(cpsLocals), "\tNimThreadVars* NimTV;$n")
app(p.procSec(cpsInit),
addf(p.procSec(cpsLocals), "\tNimThreadVars* NimTV;$n", [])
add(p.procSec(cpsInit),
ropecg(p.module, "\tNimTV = (NimThreadVars*) #GetThreadLocalVars();$n"))
var
nimtv: PRope # nimrod thread vars; the struct body
nimtv: Rope # nimrod thread vars; the struct body
nimtvDeps: seq[PType] = @[] # type deps: every module needs whole struct
nimtvDeclared = initIntSet() # so that every var/field exists only once
# in the struct
@@ -43,23 +43,23 @@ proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) =
# allocator for it :-(
if not containsOrIncl(nimtvDeclared, s.id):
nimtvDeps.add(s.loc.t)
appf(nimtv, "$1 $2;$n", [getTypeDesc(m, s.loc.t), s.loc.r])
addf(nimtv, "$1 $2;$n", [getTypeDesc(m, s.loc.t), s.loc.r])
else:
if isExtern: app(m.s[cfsVars], "extern ")
if optThreads in gGlobalOptions: app(m.s[cfsVars], "NIM_THREADVAR ")
app(m.s[cfsVars], getTypeDesc(m, s.loc.t))
appf(m.s[cfsVars], " $1;$n", [s.loc.r])
if isExtern: add(m.s[cfsVars], "extern ")
if optThreads in gGlobalOptions: add(m.s[cfsVars], "NIM_THREADVAR ")
add(m.s[cfsVars], getTypeDesc(m, s.loc.t))
addf(m.s[cfsVars], " $1;$n", [s.loc.r])
proc generateThreadLocalStorage(m: BModule) =
if nimtv != nil and (m.usesThreadVars or sfMainModule in m.module.flags):
for t in items(nimtvDeps): discard getTypeDesc(m, t)
appf(m.s[cfsSeqTypes], "typedef struct {$1} NimThreadVars;$n", [nimtv])
addf(m.s[cfsSeqTypes], "typedef struct {$1} NimThreadVars;$n", [nimtv])
proc generateThreadVarsSize(m: BModule) =
if nimtv != nil:
let externc = if gCmd != cmdCompileToCpp and
sfCompileToCpp in m.module.flags: "extern \"C\""
else: ""
appf(m.s[cfsProcs],
addf(m.s[cfsProcs],
"$#NI NimThreadVarsSize(){return (NI)sizeof(NimThreadVars);}$n",
[externc.toRope])
[externc.rope])

View File

@@ -17,11 +17,11 @@ type
p: BProc
visitorFrmt: string
proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType)
proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, typ: PType)
proc genCaseRange(p: BProc, branch: PNode)
proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false)
proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, n: PNode) =
proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, n: PNode) =
if n == nil: return
case n.kind
of nkRecList:
@@ -31,31 +31,31 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, n: PNode) =
if (n.sons[0].kind != nkSym): internalError(n.info, "genTraverseProc")
var p = c.p
let disc = n.sons[0].sym
lineF(p, cpsStmts, "switch ($1.$2) {$n", accessor, disc.loc.r)
lineF(p, cpsStmts, "switch ($1.$2) {$n", [accessor, disc.loc.r])
for i in countup(1, sonsLen(n) - 1):
let branch = n.sons[i]
assert branch.kind in {nkOfBranch, nkElse}
if branch.kind == nkOfBranch:
genCaseRange(c.p, branch)
else:
lineF(p, cpsStmts, "default:$n")
lineF(p, cpsStmts, "default:$n", [])
genTraverseProc(c, accessor, lastSon(branch))
lineF(p, cpsStmts, "break;$n")
lineF(p, cpsStmts, "} $n")
lineF(p, cpsStmts, "break;$n", [])
lineF(p, cpsStmts, "} $n", [])
of nkSym:
let field = n.sym
if field.loc.t == nil:
internalError(n.info, "genTraverseProc()")
genTraverseProc(c, ropef("$1.$2", accessor, field.loc.r), field.loc.t)
genTraverseProc(c, "$1.$2" % [accessor, field.loc.r], field.loc.t)
else: internalError(n.info, "genTraverseProc()")
proc parentObj(accessor: PRope; m: BModule): PRope {.inline.} =
proc parentObj(accessor: Rope; m: BModule): Rope {.inline.} =
if not m.compileToCpp:
result = ropef("$1.Sup", accessor)
result = "$1.Sup" % [accessor]
else:
result = accessor
proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, typ: PType) =
if typ == nil: return
var p = c.p
case typ.kind
@@ -66,9 +66,9 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
var i: TLoc
getTemp(p, getSysType(tyInt), i)
linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
i.r, arraySize.toRope)
i.r, arraySize.rope)
genTraverseProc(c, rfmt(nil, "$1[$2]", accessor, i.r), typ.sons[1])
lineF(p, cpsStmts, "}$n")
lineF(p, cpsStmts, "}$n", [])
of tyObject:
for i in countup(0, sonsLen(typ) - 1):
genTraverseProc(c, accessor.parentObj(c.p.module), typ.sons[i])
@@ -76,7 +76,7 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
of tyTuple:
let typ = getUniqueType(typ)
for i in countup(0, sonsLen(typ) - 1):
genTraverseProc(c, rfmt(nil, "$1.Field$2", accessor, i.toRope), typ.sons[i])
genTraverseProc(c, rfmt(nil, "$1.Field$2", accessor, i.rope), typ.sons[i])
of tyRef, tyString, tySequence:
lineCg(p, cpsStmts, c.visitorFrmt, accessor)
of tyProc:
@@ -85,67 +85,67 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
else:
discard
proc genTraverseProcSeq(c: var TTraversalClosure, accessor: PRope, typ: PType) =
proc genTraverseProcSeq(c: var TTraversalClosure, accessor: Rope, typ: PType) =
var p = c.p
assert typ.kind == tySequence
assert typ.kind == tySequence
var i: TLoc
getTemp(p, getSysType(tyInt), i)
lineF(p, cpsStmts, "for ($1 = 0; $1 < $2->$3; $1++) {$n",
i.r, accessor, toRope(if c.p.module.compileToCpp: "len" else: "Sup.len"))
genTraverseProc(c, ropef("$1->data[$2]", accessor, i.r), typ.sons[0])
lineF(p, cpsStmts, "}$n")
proc genTraverseProc(m: BModule, typ: PType, reason: TTypeInfoReason): PRope =
[i.r, accessor, rope(if c.p.module.compileToCpp: "len" else: "Sup.len")])
genTraverseProc(c, "$1->data[$2]" % [accessor, i.r], typ.sons[0])
lineF(p, cpsStmts, "}$n", [])
proc genTraverseProc(m: BModule, typ: PType, reason: TTypeInfoReason): Rope =
var c: TTraversalClosure
var p = newProc(nil, m)
result = getGlobalTempName()
case reason
of tiNew: c.visitorFrmt = "#nimGCvisit((void*)$1, op);$n"
else: assert false
let header = ropef("N_NIMCALL(void, $1)(void* p, NI op)", result)
let header = "N_NIMCALL(void, $1)(void* p, NI op)" % [result]
let t = getTypeDesc(m, typ)
lineF(p, cpsLocals, "$1 a;$n", t)
lineF(p, cpsInit, "a = ($1)p;$n", t)
lineF(p, cpsLocals, "$1 a;$n", [t])
lineF(p, cpsInit, "a = ($1)p;$n", [t])
c.p = p
assert typ.kind != tyTypeDesc
if typ.kind == tySequence:
genTraverseProcSeq(c, "a".toRope, typ)
genTraverseProcSeq(c, "a".rope, typ)
else:
if skipTypes(typ.sons[0], typedescInst).kind in {tyArrayConstr, tyArray}:
# C's arrays are broken beyond repair:
genTraverseProc(c, "a".toRope, typ.sons[0])
genTraverseProc(c, "a".rope, typ.sons[0])
else:
genTraverseProc(c, "(*a)".toRope, typ.sons[0])
let generatedProc = ropef("$1 {$n$2$3$4}$n",
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)])
m.s[cfsProcHeaders].appf("$1;$n", header)
m.s[cfsProcs].app(generatedProc)
genTraverseProc(c, "(*a)".rope, typ.sons[0])
proc genTraverseProcForGlobal(m: BModule, s: PSym): PRope =
let generatedProc = "$1 {$n$2$3$4}$n" %
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)]
m.s[cfsProcHeaders].addf("$1;$n", [header])
m.s[cfsProcs].add(generatedProc)
proc genTraverseProcForGlobal(m: BModule, s: PSym): Rope =
discard genTypeInfo(m, s.loc.t)
var c: TTraversalClosure
var p = newProc(nil, m)
var sLoc = s.loc.r
result = getGlobalTempName()
if sfThread in s.flags and emulatedThreadVars():
accessThreadLocalVar(p, s)
sLoc = con("NimTV->", sLoc)
sLoc = "NimTV->" & sLoc
c.visitorFrmt = "#nimGCvisit((void*)$1, 0);$n"
c.p = p
let header = ropef("N_NIMCALL(void, $1)()", result)
let header = "N_NIMCALL(void, $1)()" % [result]
genTraverseProc(c, sLoc, s.loc.t)
let generatedProc = ropef("$1 {$n$2$3$4}$n",
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)])
m.s[cfsProcHeaders].appf("$1;$n", header)
m.s[cfsProcs].app(generatedProc)
let generatedProc = "$1 {$n$2$3$4}$n" %
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)]
m.s[cfsProcHeaders].addf("$1;$n", [header])
m.s[cfsProcs].add(generatedProc)

View File

@@ -25,7 +25,7 @@ proc isKeyword(w: PIdent): bool =
ord(wInline): return true
else: return false
proc mangleName(s: PSym): PRope =
proc mangleName(s: PSym): Rope =
result = s.loc.r
if result == nil:
when oKeepVariableNames:
@@ -77,27 +77,27 @@ proc mangleName(s: PSym): PRope =
# These are not properly scoped now - we need to add blocks
# around for loops in transf
if keepOrigName:
result = s.name.s.mangle.toRope
result = s.name.s.mangle.rope
else:
app(result, toRope(mangle(s.name.s)))
app(result, ~"_")
app(result, toRope(s.id))
add(result, rope(mangle(s.name.s)))
add(result, ~"_")
add(result, rope(s.id))
else:
app(result, toRope(mangle(s.name.s)))
app(result, ~"_")
app(result, toRope(s.id))
add(result, rope(mangle(s.name.s)))
add(result, ~"_")
add(result, rope(s.id))
s.loc.r = result
proc typeName(typ: PType): PRope =
result = if typ.sym != nil: typ.sym.name.s.mangle.toRope
proc typeName(typ: PType): Rope =
result = if typ.sym != nil: typ.sym.name.s.mangle.rope
else: ~"TY"
proc getTypeName(typ: PType): PRope =
proc getTypeName(typ: PType): Rope =
if typ.sym != nil and {sfImportc, sfExportc} * typ.sym.flags != {}:
result = typ.sym.loc.r
else:
if typ.loc.r == nil:
typ.loc.r = con(typ.typeName, typ.id.toRope)
typ.loc.r = typ.typeName & typ.id.rope
result = typ.loc.r
if result == nil: internalError("getTypeName: " & $typ.kind)
@@ -156,7 +156,7 @@ proc isImportedType(t: PType): bool =
proc isImportedCppType(t: PType): bool =
result = t.sym != nil and sfInfixCall in t.sym.flags
proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope
proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope
proc needsComplexAssignment(typ: PType): bool =
result = containsGarbageCollectedRef(typ)
@@ -189,17 +189,17 @@ const
# but one can #define it to what one wants
"N_INLINE", "N_NOINLINE", "N_FASTCALL", "N_CLOSURE", "N_NOCONV"]
proc cacheGetType(tab: TIdTable, key: PType): PRope =
proc cacheGetType(tab: TIdTable, key: PType): Rope =
# returns nil if we need to declare this type
# since types are now unique via the ``getUniqueType`` mechanism, this slow
# linear search is not necessary anymore:
result = PRope(idTableGet(tab, key))
result = Rope(idTableGet(tab, key))
proc getTempName(): PRope =
result = rfmt(nil, "TMP$1", toRope(backendId()))
proc getTempName(): Rope =
result = rfmt(nil, "TMP$1", rope(backendId()))
proc getGlobalTempName(): PRope =
result = rfmt(nil, "TMP$1", toRope(backendId()))
proc getGlobalTempName(): Rope =
result = rfmt(nil, "TMP$1", rope(backendId()))
proc ccgIntroducedPtr(s: PSym): bool =
var pt = skipTypes(s.typ, typedescInst)
@@ -226,13 +226,13 @@ proc fillResult(param: PSym) =
incl(param.loc.flags, lfIndirect)
param.loc.s = OnUnknown
proc typeNameOrLiteral(t: PType, literal: string): PRope =
proc typeNameOrLiteral(t: PType, literal: string): Rope =
if t.sym != nil and sfImportc in t.sym.flags and t.sym.magic == mNone:
result = getTypeName(t)
else:
result = toRope(literal)
result = rope(literal)
proc getSimpleTypeDesc(m: BModule, typ: PType): PRope =
proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
const
NumericalTypeToStr: array[tyInt..tyUInt64, string] = [
"NI", "NI8", "NI16", "NI32", "NI64",
@@ -268,20 +268,20 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): PRope =
proc pushType(m: BModule, typ: PType) =
add(m.typeStack, typ)
proc getTypePre(m: BModule, typ: PType): PRope =
if typ == nil: result = toRope("void")
proc getTypePre(m: BModule, typ: PType): Rope =
if typ == nil: result = rope("void")
else:
result = getSimpleTypeDesc(m, typ)
if result == nil: result = cacheGetType(m.typeCache, typ)
proc structOrUnion(t: PType): PRope =
(if tfUnion in t.flags: toRope("union") else: toRope("struct"))
proc structOrUnion(t: PType): Rope =
(if tfUnion in t.flags: rope("union") else: rope("struct"))
proc getForwardStructFormat(m: BModule): string =
if m.compileToCpp: result = "$1 $2;$n"
else: result = "typedef $1 $2 $2;$n"
proc getTypeForward(m: BModule, typ: PType): PRope =
proc getTypeForward(m: BModule, typ: PType): Rope =
result = cacheGetType(m.forwTypeCache, typ)
if result != nil: return
result = getTypePre(m, typ)
@@ -290,12 +290,12 @@ proc getTypeForward(m: BModule, typ: PType): PRope =
of tySequence, tyTuple, tyObject:
result = getTypeName(typ)
if not isImportedType(typ):
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
addf(m.s[cfsForwardTypes], getForwardStructFormat(m),
[structOrUnion(typ), result])
idTablePut(m.forwTypeCache, typ, result)
else: internalError("getTypeForward(" & $typ.kind & ')')
proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet): PRope =
proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet): Rope =
## like getTypeDescAux but creates only a *weak* dependency. In other words
## we know we only need a pointer to it so we only generate a struct forward
## declaration:
@@ -310,7 +310,7 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet): PRope =
pushType(m, x)
of tySequence:
let x = getUniqueType(etB)
result = getTypeForward(m, x).con("*")
result = getTypeForward(m, x) & "*"
pushType(m, x)
else:
result = getTypeDescAux(m, t, check)
@@ -321,7 +321,7 @@ proc paramStorageLoc(param: PSym): TStorageLoc =
else:
result = OnUnknown
proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
check: var IntSet, declareEnvironment=true) =
params = nil
if (t.sons[0] == nil) or isInvalidReturnType(t.sons[0]):
@@ -332,18 +332,18 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
if t.n.sons[i].kind != nkSym: internalError(t.n.info, "genProcParams")
var param = t.n.sons[i].sym
if isCompileTimeOnly(param.typ): continue
if params != nil: app(params, ~", ")
if params != nil: add(params, ~", ")
fillLoc(param.loc, locParam, param.typ, mangleName(param),
param.paramStorageLoc)
if ccgIntroducedPtr(param):
app(params, getTypeDescWeak(m, param.typ, check))
app(params, ~"*")
add(params, getTypeDescWeak(m, param.typ, check))
add(params, ~"*")
incl(param.loc.flags, lfIndirect)
param.loc.s = OnUnknown
else:
app(params, getTypeDescAux(m, param.typ, check))
app(params, ~" ")
app(params, param.loc.r)
add(params, getTypeDescAux(m, param.typ, check))
add(params, ~" ")
add(params, param.loc.r)
# declare the len field for open arrays:
var arr = param.typ
if arr.kind == tyVar: arr = arr.sons[0]
@@ -352,78 +352,78 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var PRope,
# this fixes the 'sort' bug:
if param.typ.kind == tyVar: param.loc.s = OnUnknown
# need to pass hidden parameter:
appf(params, ", NI $1Len$2", [param.loc.r, j.toRope])
addf(params, ", NI $1Len$2", [param.loc.r, j.rope])
inc(j)
arr = arr.sons[0]
if (t.sons[0] != nil) and isInvalidReturnType(t.sons[0]):
var arr = t.sons[0]
if params != nil: app(params, ", ")
if params != nil: add(params, ", ")
if (mapReturnType(t.sons[0]) != ctArray):
app(params, getTypeDescWeak(m, arr, check))
app(params, "*")
add(params, getTypeDescWeak(m, arr, check))
add(params, "*")
else:
app(params, getTypeDescAux(m, arr, check))
appf(params, " Result", [])
add(params, getTypeDescAux(m, arr, check))
addf(params, " Result", [])
if t.callConv == ccClosure and declareEnvironment:
if params != nil: app(params, ", ")
app(params, "void* ClEnv")
if params != nil: add(params, ", ")
add(params, "void* ClEnv")
if tfVarargs in t.flags:
if params != nil: app(params, ", ")
app(params, "...")
if params == nil: app(params, "void)")
else: app(params, ")")
params = con("(", params)
if params != nil: add(params, ", ")
add(params, "...")
if params == nil: add(params, "void)")
else: add(params, ")")
params = "(" & params
proc mangleRecFieldName(field: PSym, rectype: PType): PRope =
proc mangleRecFieldName(field: PSym, rectype: PType): Rope =
if (rectype.sym != nil) and
({sfImportc, sfExportc} * rectype.sym.flags != {}):
result = field.loc.r
else:
result = toRope(mangleField(field.name.s))
result = rope(mangleField(field.name.s))
if result == nil: internalError(field.info, "mangleRecFieldName")
proc genRecordFieldsAux(m: BModule, n: PNode,
accessExpr: PRope, rectype: PType,
check: var IntSet): PRope =
accessExpr: Rope, rectype: PType,
check: var IntSet): Rope =
var
ae, uname, sname, a: PRope
ae, uname, sname, a: Rope
k: PNode
field: PSym
result = nil
case n.kind
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
app(result, genRecordFieldsAux(m, n.sons[i], accessExpr, rectype, check))
add(result, genRecordFieldsAux(m, n.sons[i], accessExpr, rectype, check))
of nkRecCase:
if n.sons[0].kind != nkSym: internalError(n.info, "genRecordFieldsAux")
app(result, genRecordFieldsAux(m, n.sons[0], accessExpr, rectype, check))
uname = toRope(mangle(n.sons[0].sym.name.s) & 'U')
if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, uname])
add(result, genRecordFieldsAux(m, n.sons[0], accessExpr, rectype, check))
uname = rope(mangle(n.sons[0].sym.name.s) & 'U')
if accessExpr != nil: ae = "$1.$2" % [accessExpr, uname]
else: ae = uname
var unionBody: PRope = nil
var unionBody: Rope = nil
for i in countup(1, sonsLen(n) - 1):
case n.sons[i].kind
of nkOfBranch, nkElse:
k = lastSon(n.sons[i])
if k.kind != nkSym:
sname = con("S", toRope(i))
a = genRecordFieldsAux(m, k, ropef("$1.$2", [ae, sname]), rectype,
sname = "S" & rope(i)
a = genRecordFieldsAux(m, k, "$1.$2" % [ae, sname], rectype,
check)
if a != nil:
app(unionBody, "struct {")
app(unionBody, a)
appf(unionBody, "} $1;$n", [sname])
add(unionBody, "struct {")
add(unionBody, a)
addf(unionBody, "} $1;$n", [sname])
else:
app(unionBody, genRecordFieldsAux(m, k, ae, rectype, check))
add(unionBody, genRecordFieldsAux(m, k, ae, rectype, check))
else: internalError("genRecordFieldsAux(record case branch)")
if unionBody != nil:
appf(result, "union{$n$1} $2;$n", [unionBody, uname])
addf(result, "union{$n$1} $2;$n", [unionBody, uname])
of nkSym:
field = n.sym
if field.typ.kind == tyEmpty: return
#assert(field.ast == nil)
sname = mangleRecFieldName(field, rectype)
if accessExpr != nil: ae = ropef("$1.$2", [accessExpr, sname])
if accessExpr != nil: ae = "$1.$2" % [accessExpr, sname]
else: ae = sname
fillLoc(field.loc, locField, field.typ, ae, OnUnknown)
# for importcpp'ed objects, we only need to set field.loc, but don't
@@ -432,27 +432,27 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
if not isImportedCppType(rectype):
let fieldType = field.loc.t.skipTypes(abstractInst)
if fieldType.kind == tyArray and tfUncheckedArray in fieldType.flags:
appf(result, "$1 $2[SEQ_DECL_SIZE];$n",
addf(result, "$1 $2[SEQ_DECL_SIZE];$n",
[getTypeDescAux(m, fieldType.elemType, check), sname])
elif fieldType.kind == tySequence:
# we need to use a weak dependency here for trecursive_table.
appf(result, "$1 $2;$n", [getTypeDescWeak(m, field.loc.t, check), sname])
addf(result, "$1 $2;$n", [getTypeDescWeak(m, field.loc.t, check), sname])
else:
# don't use fieldType here because we need the
# tyGenericInst for C++ template support
appf(result, "$1 $2;$n", [getTypeDescAux(m, field.loc.t, check), sname])
addf(result, "$1 $2;$n", [getTypeDescAux(m, field.loc.t, check), sname])
else: internalError(n.info, "genRecordFieldsAux()")
proc getRecordFields(m: BModule, typ: PType, check: var IntSet): PRope =
proc getRecordFields(m: BModule, typ: PType, check: var IntSet): Rope =
result = genRecordFieldsAux(m, typ.n, nil, typ, check)
proc getRecordDesc(m: BModule, typ: PType, name: PRope,
check: var IntSet): PRope =
proc getRecordDesc(m: BModule, typ: PType, name: Rope,
check: var IntSet): Rope =
# declare the record:
var hasField = false
var attribute: PRope =
if tfPacked in typ.flags: toRope(CC[cCompiler].packedPragma)
var attribute: Rope =
if tfPacked in typ.flags: rope(CC[cCompiler].packedPragma)
else: nil
result = ropecg(m, CC[cCompiler].structStmtFmt,
@@ -475,27 +475,27 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope,
[getTypeDescAux(m, typ.sons[0], check)])
hasField = true
else:
appf(result, " {$n", [name])
addf(result, " {$n", [name])
var desc = getRecordFields(m, typ, check)
if desc == nil and not hasField:
appf(result, "char dummy;$n", [])
addf(result, "char dummy;$n", [])
else:
app(result, desc)
app(result, "};" & tnl)
add(result, desc)
add(result, "};" & tnl)
proc getTupleDesc(m: BModule, typ: PType, name: PRope,
check: var IntSet): PRope =
result = ropef("$1 $2 {$n", [structOrUnion(typ), name])
var desc: PRope = nil
proc getTupleDesc(m: BModule, typ: PType, name: Rope,
check: var IntSet): Rope =
result = "$1 $2 {$n" % [structOrUnion(typ), name]
var desc: Rope = nil
for i in countup(0, sonsLen(typ) - 1):
appf(desc, "$1 Field$2;$n",
[getTypeDescAux(m, typ.sons[i], check), toRope(i)])
if desc == nil: app(result, "char dummy;" & tnl)
else: app(result, desc)
app(result, "};" & tnl)
addf(desc, "$1 Field$2;$n",
[getTypeDescAux(m, typ.sons[i], check), rope(i)])
if desc == nil: add(result, "char dummy;" & tnl)
else: add(result, desc)
add(result, "};" & tnl)
proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope =
# returns only the type's name
var t = getUniqueType(typ)
if t == nil: internalError("getTypeDescAux: t == nil")
@@ -523,39 +523,39 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
case etB.kind
of tyObject, tyTuple:
if isImportedCppType(etB) and et.kind == tyGenericInst:
result = con(getTypeDescAux(m, et, check), star)
result = getTypeDescAux(m, et, check) & star
else:
# no restriction! We have a forward declaration for structs
let x = getUniqueType(etB)
let name = getTypeForward(m, x)
result = con(name, star)
result = name & star
idTablePut(m.typeCache, t, result)
pushType(m, x)
of tySequence:
# no restriction! We have a forward declaration for structs
let x = getUniqueType(etB)
let name = getTypeForward(m, x)
result = con(name, "*" & star)
result = name & "*" & star
idTablePut(m.typeCache, t, result)
pushType(m, x)
else:
# else we have a strong dependency :-(
result = con(getTypeDescAux(m, et, check), star)
result = getTypeDescAux(m, et, check) & star
idTablePut(m.typeCache, t, result)
of tyOpenArray, tyVarargs:
result = con(getTypeDescAux(m, t.sons[0], check), "*")
result = getTypeDescAux(m, t.sons[0], check) & "*"
idTablePut(m.typeCache, t, result)
of tyProc:
result = getTypeName(t)
idTablePut(m.typeCache, t, result)
var rettype, desc: PRope
var rettype, desc: Rope
genProcParams(m, t, rettype, desc, check)
if not isImportedType(t):
if t.callConv != ccClosure: # procedure vars may need a closure!
appf(m.s[cfsTypes], "typedef $1_PTR($2, $3) $4;$n",
[toRope(CallingConvToStr[t.callConv]), rettype, result, desc])
addf(m.s[cfsTypes], "typedef $1_PTR($2, $3) $4;$n",
[rope(CallingConvToStr[t.callConv]), rettype, result, desc])
else:
appf(m.s[cfsTypes], "typedef struct {$n" &
addf(m.s[cfsTypes], "typedef struct {$n" &
"N_NIMCALL_PTR($2, ClPrc) $3;$n" &
"void* ClEnv;$n} $1;$n",
[result, rettype, desc])
@@ -566,11 +566,11 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
if result == nil:
result = getTypeName(t)
if not isImportedType(t):
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
addf(m.s[cfsForwardTypes], getForwardStructFormat(m),
[structOrUnion(t), result])
idTablePut(m.forwTypeCache, t, result)
assert(cacheGetType(m.typeCache, t) == nil)
idTablePut(m.typeCache, t, con(result, "*"))
idTablePut(m.typeCache, t, result & "*")
if not isImportedType(t):
if skipTypes(t.sons[0], typedescInst).kind != tyEmpty:
const
@@ -582,8 +582,8 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
" $1 data[SEQ_DECL_SIZE];$n" &
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
else:
result = toRope("TGenericSeq")
app(result, "*")
result = rope("TGenericSeq")
add(result, "*")
of tyArrayConstr, tyArray:
var n: BiggestInt = lengthOrd(t)
if n <= 0: n = 1 # make an array of at least one element
@@ -591,17 +591,17 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
idTablePut(m.typeCache, t, result)
if not isImportedType(t):
let foo = getTypeDescAux(m, t.sons[1], check)
appf(m.s[cfsTypes], "typedef $1 $2[$3];$n",
[foo, result, toRope(n)])
addf(m.s[cfsTypes], "typedef $1 $2[$3];$n",
[foo, result, rope(n)])
of tyObject, tyTuple:
if isImportedCppType(t) and typ.kind == tyGenericInst:
# for instantiated templates we do not go through the type cache as the
# the type cache is not aware of 'tyGenericInst'.
result = getTypeName(t).con("<")
result = getTypeName(t) & "<"
for i in 1 .. typ.len-2:
if i > 1: result.app(", ")
result.app(getTypeDescAux(m, typ.sons[i], check))
result.app("> ")
if i > 1: result.add(", ")
result.add(getTypeDescAux(m, typ.sons[i], check))
result.add("> ")
# always call for sideeffects:
assert t.kind != tyTuple
discard getRecordDesc(m, t, result, check)
@@ -610,25 +610,25 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
if result == nil:
result = getTypeName(t)
if not isImportedType(t):
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
addf(m.s[cfsForwardTypes], getForwardStructFormat(m),
[structOrUnion(t), result])
idTablePut(m.forwTypeCache, t, result)
idTablePut(m.typeCache, t, result) # always call for sideeffects:
let recdesc = if t.kind != tyTuple: getRecordDesc(m, t, result, check)
else: getTupleDesc(m, t, result, check)
if not isImportedType(t): app(m.s[cfsTypes], recdesc)
if not isImportedType(t): add(m.s[cfsTypes], recdesc)
of tySet:
case int(getSize(t))
of 1: result = toRope("NU8")
of 2: result = toRope("NU16")
of 4: result = toRope("NU32")
of 8: result = toRope("NU64")
of 1: result = rope("NU8")
of 2: result = rope("NU16")
of 4: result = rope("NU32")
of 8: result = rope("NU64")
else:
result = getTypeName(t)
idTablePut(m.typeCache, t, result)
if not isImportedType(t):
appf(m.s[cfsTypes], "typedef NU8 $1[$2];$n",
[result, toRope(getSize(t))])
addf(m.s[cfsTypes], "typedef NU8 $1[$2];$n",
[result, rope(getSize(t))])
of tyGenericInst, tyDistinct, tyOrdinal, tyConst, tyMutable,
tyIter, tyTypeDesc:
result = getTypeDescAux(m, lastSon(t), check)
@@ -638,7 +638,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
# fixes bug #145:
excl(check, t.id)
proc getTypeDesc(m: BModule, typ: PType): PRope =
proc getTypeDesc(m: BModule, typ: PType): Rope =
var check = initIntSet()
result = getTypeDescAux(m, typ, check)
@@ -646,23 +646,23 @@ type
TClosureTypeKind = enum
clHalf, clHalfWithEnv, clFull
proc getClosureType(m: BModule, t: PType, kind: TClosureTypeKind): PRope =
proc getClosureType(m: BModule, t: PType, kind: TClosureTypeKind): Rope =
assert t.kind == tyProc
var check = initIntSet()
result = getTempName()
var rettype, desc: PRope
var rettype, desc: Rope
genProcParams(m, t, rettype, desc, check, declareEnvironment=kind != clHalf)
if not isImportedType(t):
if t.callConv != ccClosure or kind != clFull:
appf(m.s[cfsTypes], "typedef $1_PTR($2, $3) $4;$n",
[toRope(CallingConvToStr[t.callConv]), rettype, result, desc])
addf(m.s[cfsTypes], "typedef $1_PTR($2, $3) $4;$n",
[rope(CallingConvToStr[t.callConv]), rettype, result, desc])
else:
appf(m.s[cfsTypes], "typedef struct {$n" &
addf(m.s[cfsTypes], "typedef struct {$n" &
"N_NIMCALL_PTR($2, ClPrc) $3;$n" &
"void* ClEnv;$n} $1;$n",
[result, rettype, desc])
proc getTypeDesc(m: BModule, magic: string): PRope =
proc getTypeDesc(m: BModule, magic: string): Rope =
var sym = magicsys.getCompilerProc(magic)
if sym != nil:
result = getTypeDesc(m, sym.typ)
@@ -678,38 +678,38 @@ proc finishTypeDescriptions(m: BModule) =
template cgDeclFrmt*(s: PSym): string = s.constraint.strVal
proc genProcHeader(m: BModule, prc: PSym): PRope =
proc genProcHeader(m: BModule, prc: PSym): Rope =
var
rettype, params: PRope
rettype, params: Rope
genCLineDir(result, prc.info)
# using static is needed for inline procs
if lfExportLib in prc.loc.flags:
if m.isHeaderFile:
result.app "N_LIB_IMPORT "
result.add "N_LIB_IMPORT "
else:
result.app "N_LIB_EXPORT "
result.add "N_LIB_EXPORT "
elif prc.typ.callConv == ccInline:
result.app "static "
result.add "static "
var check = initIntSet()
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnUnknown)
genProcParams(m, prc.typ, rettype, params, check)
# careful here! don't access ``prc.ast`` as that could reload large parts of
# the object graph!
if prc.constraint.isNil:
appf(result, "$1($2, $3)$4",
[toRope(CallingConvToStr[prc.typ.callConv]), rettype, prc.loc.r,
addf(result, "$1($2, $3)$4",
[rope(CallingConvToStr[prc.typ.callConv]), rettype, prc.loc.r,
params])
else:
result = ropef(prc.cgDeclFrmt, [rettype, prc.loc.r, params])
result = prc.cgDeclFrmt % [rettype, prc.loc.r, params]
# ------------------ type info generation -------------------------------------
proc genTypeInfo(m: BModule, t: PType): PRope
proc getNimNode(m: BModule): PRope =
result = ropef("$1[$2]", [m.typeNodesName, toRope(m.typeNodes)])
proc genTypeInfo(m: BModule, t: PType): Rope
proc getNimNode(m: BModule): Rope =
result = "$1[$2]" % [m.typeNodesName, rope(m.typeNodes)]
inc(m.typeNodes)
proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; name, base: PRope) =
proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; name, base: Rope) =
var nimtypeKind: int
#allocMemTI(m, typ, name)
if isObjLackingTypeField(typ):
@@ -717,48 +717,47 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; name, base: PRope) =
else:
nimtypeKind = ord(typ.kind)
var size: PRope
if tfIncompleteStruct in typ.flags: size = toRope"void*"
var size: Rope
if tfIncompleteStruct in typ.flags: size = rope"void*"
elif m.compileToCpp: size = getTypeDesc(m, origType)
else: size = getTypeDesc(m, typ)
appf(m.s[cfsTypeInit3],
addf(m.s[cfsTypeInit3],
"$1.size = sizeof($2);$n" & "$1.kind = $3;$n" & "$1.base = $4;$n",
[name, size, toRope(nimtypeKind), base])
[name, size, rope(nimtypeKind), base])
# compute type flags for GC optimization
var flags = 0
if not containsGarbageCollectedRef(typ): flags = flags or 1
if not canFormAcycle(typ): flags = flags or 2
#else MessageOut("can contain a cycle: " & typeToString(typ))
if flags != 0:
appf(m.s[cfsTypeInit3], "$1.flags = $2;$n", [name, toRope(flags)])
addf(m.s[cfsTypeInit3], "$1.flags = $2;$n", [name, rope(flags)])
discard cgsym(m, "TNimType")
appf(m.s[cfsVars], "TNimType $1; /* $2 */$n",
[name, toRope(typeToString(typ))])
addf(m.s[cfsVars], "TNimType $1; /* $2 */$n",
[name, rope(typeToString(typ))])
proc genTypeInfoAux(m: BModule, typ, origType: PType, name: PRope) =
var base: PRope
proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope) =
var base: Rope
if (sonsLen(typ) > 0) and (typ.sons[0] != nil):
base = genTypeInfo(m, typ.sons[0])
else:
base = toRope("0")
base = rope("0")
genTypeInfoAuxBase(m, typ, origType, name, base)
proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): PRope =
proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): Rope =
# bugfix: we need to search the type that contains the discriminator:
var objtype = objtype
while lookupInRecord(objtype.n, d.name) == nil:
objtype = objtype.sons[0]
if objtype.sym == nil:
internalError(d.info, "anonymous obj with discriminator")
result = ropef("NimDT_$1_$2", [
toRope(objtype.id), toRope(d.name.s.mangle)])
result = "NimDT_$1_$2" % [rope(objtype.id), rope(d.name.s.mangle)]
proc discriminatorTableDecl(m: BModule, objtype: PType, d: PSym): PRope =
proc discriminatorTableDecl(m: BModule, objtype: PType, d: PSym): Rope =
discard cgsym(m, "TNimNode")
var tmp = discriminatorTableName(m, objtype, d)
result = ropef("TNimNode* $1[$2];$n", [tmp, toRope(lengthOrd(d.typ)+1)])
result = "TNimNode* $1[$2];$n" % [tmp, rope(lengthOrd(d.typ)+1)]
proc genObjectFields(m: BModule, typ: PType, n: PNode, expr: PRope) =
proc genObjectFields(m: BModule, typ: PType, n: PNode, expr: Rope) =
case n.kind
of nkRecList:
var L = sonsLen(n)
@@ -766,29 +765,29 @@ proc genObjectFields(m: BModule, typ: PType, n: PNode, expr: PRope) =
genObjectFields(m, typ, n.sons[0], expr)
elif L > 0:
var tmp = getTempName()
appf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", [tmp, toRope(L)])
addf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", [tmp, rope(L)])
for i in countup(0, L-1):
var tmp2 = getNimNode(m)
appf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, toRope(i), tmp2])
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, rope(i), tmp2])
genObjectFields(m, typ, n.sons[i], tmp2)
appf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
[expr, toRope(L), tmp])
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
[expr, rope(L), tmp])
else:
appf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2;$n", [expr, toRope(L)])
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2;$n", [expr, rope(L)])
of nkRecCase:
assert(n.sons[0].kind == nkSym)
var field = n.sons[0].sym
var tmp = discriminatorTableName(m, typ, field)
var L = lengthOrd(field.typ)
assert L > 0
appf(m.s[cfsTypeInit3], "$1.kind = 3;$n" &
addf(m.s[cfsTypeInit3], "$1.kind = 3;$n" &
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
"$1.name = $5;$n" & "$1.sons = &$6[0];$n" &
"$1.len = $7;$n", [expr, getTypeDesc(m, typ), field.loc.r,
genTypeInfo(m, field.typ),
makeCString(field.name.s),
tmp, toRope(L)])
appf(m.s[cfsData], "TNimNode* $1[$2];$n", [tmp, toRope(L+1)])
tmp, rope(L)])
addf(m.s[cfsData], "TNimNode* $1[$2];$n", [tmp, rope(L+1)])
for i in countup(1, sonsLen(n)-1):
var b = n.sons[i] # branch
var tmp2 = getNimNode(m)
@@ -802,60 +801,60 @@ proc genObjectFields(m: BModule, typ: PType, n: PNode, expr: PRope) =
var x = int(getOrdValue(b.sons[j].sons[0]))
var y = int(getOrdValue(b.sons[j].sons[1]))
while x <= y:
appf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, toRope(x), tmp2])
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, rope(x), tmp2])
inc(x)
else:
appf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n",
[tmp, toRope(getOrdValue(b.sons[j])), tmp2])
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n",
[tmp, rope(getOrdValue(b.sons[j])), tmp2])
of nkElse:
appf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n",
[tmp, toRope(L), tmp2])
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n",
[tmp, rope(L), tmp2])
else: internalError(n.info, "genObjectFields(nkRecCase)")
of nkSym:
var field = n.sym
appf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
addf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
"$1.name = $5;$n", [expr, getTypeDesc(m, typ),
field.loc.r, genTypeInfo(m, field.typ), makeCString(field.name.s)])
else: internalError(n.info, "genObjectFields")
proc genObjectInfo(m: BModule, typ, origType: PType, name: PRope) =
proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope) =
if typ.kind == tyObject: genTypeInfoAux(m, typ, origType, name)
else: genTypeInfoAuxBase(m, typ, origType, name, toRope("0"))
else: genTypeInfoAuxBase(m, typ, origType, name, rope("0"))
var tmp = getNimNode(m)
if not isImportedCppType(typ):
genObjectFields(m, typ, typ.n, tmp)
appf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, tmp])
addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, tmp])
var t = typ.sons[0]
while t != nil:
t = t.skipTypes(abstractInst)
t.flags.incl tfObjHasKids
t = t.sons[0]
proc genTupleInfo(m: BModule, typ: PType, name: PRope) =
genTypeInfoAuxBase(m, typ, typ, name, toRope("0"))
proc genTupleInfo(m: BModule, typ: PType, name: Rope) =
genTypeInfoAuxBase(m, typ, typ, name, rope("0"))
var expr = getNimNode(m)
var length = sonsLen(typ)
if length > 0:
var tmp = getTempName()
appf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", [tmp, toRope(length)])
addf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", [tmp, rope(length)])
for i in countup(0, length - 1):
var a = typ.sons[i]
var tmp2 = getNimNode(m)
appf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, toRope(i), tmp2])
appf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, rope(i), tmp2])
addf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
"$1.offset = offsetof($2, Field$3);$n" &
"$1.typ = $4;$n" &
"$1.name = \"Field$3\";$n",
[tmp2, getTypeDesc(m, typ), toRope(i), genTypeInfo(m, a)])
appf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
[expr, toRope(length), tmp])
[tmp2, getTypeDesc(m, typ), rope(i), genTypeInfo(m, a)])
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
[expr, rope(length), tmp])
else:
appf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2;$n",
[expr, toRope(length)])
appf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, expr])
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2;$n",
[expr, rope(length)])
addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [name, expr])
proc genEnumInfo(m: BModule, typ: PType, name: PRope) =
proc genEnumInfo(m: BModule, typ: PType, name: Rope) =
# Type information for enumerations is quite heavy, so we do some
# optimizations here: The ``typ`` field is never set, as it is redundant
# anyway. We generate a cstring array and a loop over it. Exceptional
@@ -863,9 +862,9 @@ proc genEnumInfo(m: BModule, typ: PType, name: PRope) =
genTypeInfoAux(m, typ, typ, name)
var nodePtrs = getTempName()
var length = sonsLen(typ.n)
appf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n",
[nodePtrs, toRope(length)])
var enumNames, specialCases: PRope
addf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n",
[nodePtrs, rope(length)])
var enumNames, specialCases: Rope
var firstNimNode = m.typeNodes
var hasHoles = false
for i in countup(0, length - 1):
@@ -874,38 +873,38 @@ proc genEnumInfo(m: BModule, typ: PType, name: PRope) =
var elemNode = getNimNode(m)
if field.ast == nil:
# no explicit string literal for the enum field, so use field.name:
app(enumNames, makeCString(field.name.s))
add(enumNames, makeCString(field.name.s))
else:
app(enumNames, makeCString(field.ast.strVal))
if i < length - 1: app(enumNames, ", " & tnl)
add(enumNames, makeCString(field.ast.strVal))
if i < length - 1: add(enumNames, ", " & tnl)
if field.position != i or tfEnumHasHoles in typ.flags:
appf(specialCases, "$1.offset = $2;$n", [elemNode, toRope(field.position)])
addf(specialCases, "$1.offset = $2;$n", [elemNode, rope(field.position)])
hasHoles = true
var enumArray = getTempName()
var counter = getTempName()
appf(m.s[cfsTypeInit1], "NI $1;$n", [counter])
appf(m.s[cfsTypeInit1], "static char* NIM_CONST $1[$2] = {$n$3};$n",
[enumArray, toRope(length), enumNames])
appf(m.s[cfsTypeInit3], "for ($1 = 0; $1 < $2; $1++) {$n" &
addf(m.s[cfsTypeInit1], "NI $1;$n", [counter])
addf(m.s[cfsTypeInit1], "static char* NIM_CONST $1[$2] = {$n$3};$n",
[enumArray, rope(length), enumNames])
addf(m.s[cfsTypeInit3], "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,
toRope(length), m.typeNodesName, toRope(firstNimNode), enumArray, nodePtrs])
app(m.s[cfsTypeInit3], specialCases)
appf(m.s[cfsTypeInit3],
rope(length), m.typeNodesName, rope(firstNimNode), enumArray, nodePtrs])
add(m.s[cfsTypeInit3], specialCases)
addf(m.s[cfsTypeInit3],
"$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n$4.node = &$1;$n",
[getNimNode(m), toRope(length), nodePtrs, name])
[getNimNode(m), rope(length), nodePtrs, name])
if hasHoles:
# 1 << 2 is {ntfEnumHole}
appf(m.s[cfsTypeInit3], "$1.flags = 1<<2;$n", [name])
addf(m.s[cfsTypeInit3], "$1.flags = 1<<2;$n", [name])
proc genSetInfo(m: BModule, typ: PType, name: PRope) =
proc genSetInfo(m: BModule, typ: PType, name: Rope) =
assert(typ.sons[0] != nil)
genTypeInfoAux(m, typ, typ, name)
var tmp = getNimNode(m)
appf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 0;$n" & "$3.node = &$1;$n",
[tmp, toRope(firstOrd(typ)), name])
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 0;$n" & "$3.node = &$1;$n",
[tmp, rope(firstOrd(typ)), name])
proc genArrayInfo(m: BModule, typ: PType, name: PRope) =
proc genArrayInfo(m: BModule, typ: PType, name: Rope) =
genTypeInfoAuxBase(m, typ, typ, name, genTypeInfo(m, typ.sons[1]))
proc fakeClosureType(owner: PSym): PType =
@@ -925,17 +924,17 @@ type
include ccgtrav
proc genDeepCopyProc(m: BModule; s: PSym; result: PRope) =
proc genDeepCopyProc(m: BModule; s: PSym; result: Rope) =
genProc(m, s)
appf(m.s[cfsTypeInit3], "$1.deepcopy =(void* (N_RAW_NIMCALL*)(void*))$2;$n",
addf(m.s[cfsTypeInit3], "$1.deepcopy =(void* (N_RAW_NIMCALL*)(void*))$2;$n",
[result, s.loc.r])
proc genTypeInfo(m: BModule, t: PType): PRope =
proc genTypeInfo(m: BModule, t: PType): Rope =
let origType = t
var t = getUniqueType(t)
result = ropef("NTI$1", [toRope(t.id)])
result = "NTI$1" % [rope(t.id)]
if containsOrIncl(m.typeInfoMarker, t.id):
return con("(&".toRope, result, ")".toRope)
return "(&".rope & result & ")".rope
# getUniqueType doesn't skip tyDistinct when that has an overriden operation:
while t.kind == tyDistinct: t = t.lastSon
@@ -946,23 +945,23 @@ proc genTypeInfo(m: BModule, t: PType): PRope =
# reference the type info as extern here
discard cgsym(m, "TNimType")
discard cgsym(m, "TNimNode")
appf(m.s[cfsVars], "extern TNimType $1; /* $2 */$n",
[result, toRope(typeToString(t))])
return con("(&".toRope, result, ")".toRope)
addf(m.s[cfsVars], "extern TNimType $1; /* $2 */$n",
[result, rope(typeToString(t))])
return "(&".rope & result & ")".rope
case t.kind
of tyEmpty: result = toRope"0"
of tyEmpty: result = rope"0"
of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar:
genTypeInfoAuxBase(m, t, t, result, toRope"0")
genTypeInfoAuxBase(m, t, t, result, rope"0")
of tyProc:
if t.callConv != ccClosure:
genTypeInfoAuxBase(m, t, t, result, toRope"0")
genTypeInfoAuxBase(m, t, t, result, rope"0")
else:
genTupleInfo(m, fakeClosureType(t.owner), result)
of tySequence, tyRef:
genTypeInfoAux(m, t, t, result)
if gSelectedGC >= gcMarkAndSweep:
let markerProc = genTraverseProc(m, t, tiNew)
appf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc])
addf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc])
of tyPtr, tyRange: genTypeInfoAux(m, t, t, result)
of tyArrayConstr, tyArray: genArrayInfo(m, t, result)
of tySet: genSetInfo(m, t, result)
@@ -979,7 +978,7 @@ proc genTypeInfo(m: BModule, t: PType): PRope =
genDeepCopyProc(m, t.deepCopy, result)
elif origType.deepCopy != nil:
genDeepCopyProc(m, origType.deepCopy, result)
result = con("(&".toRope, result, ")".toRope)
result = "(&".rope & result & ")".rope
proc genTypeSection(m: BModule, n: PNode) =
discard

View File

@@ -193,13 +193,13 @@ proc mangle*(name: string): string =
else:
add(result, "HEX" & toHex(ord(c), 2))
proc makeLLVMString*(s: string): PRope =
proc makeLLVMString*(s: string): Rope =
const MaxLineLength = 64
result = nil
var res = "c\""
for i in countup(0, len(s) - 1):
if (i + 1) mod MaxLineLength == 0:
app(result, toRope(res))
add(result, rope(res))
setLen(res, 0)
case s[i]
of '\0'..'\x1F', '\x80'..'\xFF', '\"', '\\':
@@ -207,6 +207,6 @@ proc makeLLVMString*(s: string): PRope =
add(res, toHex(ord(s[i]), 2))
else: add(res, s[i])
add(res, "\\00\"")
app(result, toRope(res))
add(result, rope(res))
initTypeTables()

View File

@@ -10,13 +10,15 @@
## This module implements the C code generator.
import
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
ast, astalgo, hashes, trees, platform, magicsys, extccomp,
options, intsets,
nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os,
ropes, math, passes, rodread, wordrecg, treetab, cgmeth, condsyms,
rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases, lowerings,
semparallel
import strutils except `%` # collides with ropes.`%`
when options.hasTinyCBackend:
import tccgen
@@ -48,7 +50,7 @@ proc initLoc(result: var TLoc, k: TLocKind, typ: PType, s: TStorageLoc) =
result.r = nil
result.flags = {}
proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: PRope, s: TStorageLoc) =
proc fillLoc(a: var TLoc, k: TLocKind, typ: PType, r: Rope, s: TStorageLoc) =
# fills the loc if it is not already initialized
if a.k == locNone:
a.k = k
@@ -72,9 +74,9 @@ proc useHeader(m: BModule, sym: PSym) =
assert(sym.annex != nil)
discard lists.includeStr(m.headerFiles, getStr(sym.annex.path))
proc cgsym(m: BModule, name: string): PRope
proc cgsym(m: BModule, name: string): Rope
proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
proc ropecg(m: BModule, frmt: FormatStr, args: varargs[Rope]): Rope =
var i = 0
var length = len(frmt)
result = nil
@@ -84,11 +86,11 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
inc(i) # skip '$'
case frmt[i]
of '$':
app(result, "$")
add(result, "$")
inc(i)
of '#':
inc(i)
app(result, args[num])
add(result, args[num])
inc(num)
of '0'..'9':
var j = 0
@@ -99,12 +101,12 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
num = j
if j > high(args) + 1:
internalError("ropes: invalid format string $" & $j)
app(result, args[j-1])
add(result, args[j-1])
of 'n':
if optLineDir notin gOptions: app(result, rnl)
if optLineDir notin gOptions: add(result, rnl)
inc(i)
of 'N':
app(result, rnl)
add(result, rnl)
inc(i)
else: internalError("ropes: invalid format string $" & frmt[i])
elif frmt[i] == '#' and frmt[i+1] in IdentStartChars:
@@ -113,74 +115,74 @@ proc ropecg(m: BModule, frmt: TFormatStr, args: varargs[PRope]): PRope =
while frmt[j] in IdentChars: inc(j)
var ident = substr(frmt, i, j-1)
i = j
app(result, cgsym(m, ident))
add(result, cgsym(m, ident))
elif frmt[i] == '#' and frmt[i+1] == '$':
inc(i, 2)
var j = 0
while frmt[i] in Digits:
j = (j * 10) + ord(frmt[i]) - ord('0')
inc(i)
app(result, cgsym(m, $args[j-1]))
add(result, cgsym(m, $args[j-1]))
var start = i
while i < length:
if frmt[i] != '$' and frmt[i] != '#': inc(i)
else: break
if i - 1 >= start:
app(result, substr(frmt, start, i - 1))
add(result, substr(frmt, start, i - 1))
template rfmt(m: BModule, fmt: string, args: varargs[PRope]): expr =
template rfmt(m: BModule, fmt: string, args: varargs[Rope]): expr =
ropecg(m, fmt, args)
proc appcg(m: BModule, c: var PRope, frmt: TFormatStr,
args: varargs[PRope]) =
app(c, ropecg(m, frmt, args))
proc appcg(m: BModule, c: var Rope, frmt: FormatStr,
args: varargs[Rope]) =
add(c, ropecg(m, frmt, args))
proc appcg(m: BModule, s: TCFileSection, frmt: TFormatStr,
args: varargs[PRope]) =
app(m.s[s], ropecg(m, frmt, args))
proc appcg(m: BModule, s: TCFileSection, frmt: FormatStr,
args: varargs[Rope]) =
add(m.s[s], ropecg(m, frmt, args))
proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: varargs[PRope]) =
app(p.s(s), ropecg(p.module, frmt, args))
proc appcg(p: BProc, s: TCProcSection, frmt: FormatStr,
args: varargs[Rope]) =
add(p.s(s), ropecg(p.module, frmt, args))
var indent = "\t".toRope
proc indentLine(p: BProc, r: PRope): PRope =
var indent = "\t".rope
proc indentLine(p: BProc, r: Rope): Rope =
result = r
for i in countup(0, p.blocks.len-1): prepend(result, indent)
proc line(p: BProc, s: TCProcSection, r: PRope) =
app(p.s(s), indentLine(p, r))
proc line(p: BProc, s: TCProcSection, r: Rope) =
add(p.s(s), indentLine(p, r))
proc line(p: BProc, s: TCProcSection, r: string) =
app(p.s(s), indentLine(p, r.toRope))
add(p.s(s), indentLine(p, r.rope))
proc lineF(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: varargs[PRope]) =
app(p.s(s), indentLine(p, ropef(frmt, args)))
proc lineF(p: BProc, s: TCProcSection, frmt: FormatStr,
args: openarray[Rope]) =
add(p.s(s), indentLine(p, frmt % args))
proc lineCg(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: varargs[PRope]) =
app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
proc lineCg(p: BProc, s: TCProcSection, frmt: FormatStr,
args: varargs[Rope]) =
add(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
proc linefmt(p: BProc, s: TCProcSection, frmt: TFormatStr,
args: varargs[PRope]) =
app(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
proc linefmt(p: BProc, s: TCProcSection, frmt: FormatStr,
args: varargs[Rope]) =
add(p.s(s), indentLine(p, ropecg(p.module, frmt, args)))
proc appLineCg(p: BProc, r: var PRope, frmt: TFormatStr,
args: varargs[PRope]) =
app(r, indentLine(p, ropecg(p.module, frmt, args)))
proc appLineCg(p: BProc, r: var Rope, frmt: FormatStr,
args: varargs[Rope]) =
add(r, indentLine(p, ropecg(p.module, frmt, args)))
proc safeLineNm(info: TLineInfo): int =
result = toLinenumber(info)
if result < 0: result = 0 # negative numbers are not allowed in #line
proc genCLineDir(r: var PRope, filename: string, line: int) =
proc genCLineDir(r: var Rope, filename: string, line: int) =
assert line >= 0
if optLineDir in gOptions:
appf(r, "$N#line $2 $1$N",
[toRope(makeSingleLineCString(filename)), toRope(line)])
addf(r, "$N#line $2 $1$N",
[rope(makeSingleLineCString(filename)), rope(line)])
proc genCLineDir(r: var PRope, info: TLineInfo) =
proc genCLineDir(r: var Rope, info: TLineInfo) =
genCLineDir(r, info.toFullPath, info.safeLineNm)
proc freshLineInfo(p: BProc; info: TLineInfo): bool =
@@ -193,22 +195,22 @@ proc freshLineInfo(p: BProc; info: TLineInfo): bool =
proc genLineDir(p: BProc, t: PNode) =
var line = t.info.safeLineNm
if optEmbedOrigSrc in gGlobalOptions:
app(p.s(cpsStmts), con(~"//", t.info.sourceLine, rnl))
add(p.s(cpsStmts), ~"//" & t.info.sourceLine & rnl)
genCLineDir(p.s(cpsStmts), t.info.toFullPath, line)
if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and
(p.prc == nil or sfPure notin p.prc.flags):
if freshLineInfo(p, t.info):
linefmt(p, cpsStmts, "#endb($1, $2);$n",
line.toRope, makeCString(toFilename(t.info)))
line.rope, makeCString(toFilename(t.info)))
elif ({optLineTrace, optStackTrace} * p.options ==
{optLineTrace, optStackTrace}) and
(p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex >= 0:
if freshLineInfo(p, t.info):
linefmt(p, cpsStmts, "nimln($1, $2);$n",
line.toRope, t.info.quotedFilename)
line.rope, t.info.quotedFilename)
proc postStmtActions(p: BProc) {.inline.} =
app(p.s(cpsStmts), p.module.injectStmt)
add(p.s(cpsStmts), p.module.injectStmt)
proc accessThreadLocalVar(p: BProc, s: PSym)
proc emulatedThreadVars(): bool {.inline.}
@@ -221,21 +223,21 @@ include "ccgtypes.nim"
# ------------------------------ Manager of temporaries ------------------
proc rdLoc(a: TLoc): PRope =
proc rdLoc(a: TLoc): Rope =
# 'read' location (deref if indirect)
result = a.r
if lfIndirect in a.flags: result = ropef("(*$1)", [result])
if lfIndirect in a.flags: result = "(*$1)" % [result]
proc addrLoc(a: TLoc): PRope =
proc addrLoc(a: TLoc): Rope =
result = a.r
if lfIndirect notin a.flags and mapType(a.t) != ctArray:
result = con("(&", result).con(")")
result = "(&" & result & ")"
proc rdCharLoc(a: TLoc): PRope =
proc rdCharLoc(a: TLoc): Rope =
# read a location that may need a char-cast:
result = rdLoc(a)
if skipTypes(a.t, abstractRange).kind == tyChar:
result = ropef("((NU8)($1))", [result])
result = "((NU8)($1))" % [result]
proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
takeAddr: bool) =
@@ -244,11 +246,11 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
discard
of frHeader:
var r = rdLoc(a)
if not takeAddr: r = ropef("(*$1)", [r])
if not takeAddr: r = "(*$1)" % [r]
var s = skipTypes(t, abstractInst)
if not p.module.compileToCpp:
while (s.kind == tyObject) and (s.sons[0] != nil):
app(r, ".Sup")
add(r, ".Sup")
s = skipTypes(s.sons[0], abstractInst)
linefmt(p, section, "$1.m_type = $2;$n", r, genTypeInfo(p.module, t))
of frEmbedded:
@@ -276,7 +278,7 @@ proc resetLoc(p: BProc, loc: var TLoc) =
if containsGcRef:
var nilLoc: TLoc
initLoc(nilLoc, locTemp, loc.t, OnStack)
nilLoc.r = toRope("NIM_NIL")
nilLoc.r = rope("NIM_NIL")
genRefAssign(p, loc, nilLoc, {afSrcIsNil})
else:
linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc))
@@ -325,7 +327,7 @@ proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) =
inc(p.labels)
result.r = con("LOC", toRope(p.labels))
result.r = "LOC" & rope(p.labels)
linefmt(p, cpsLocals, "$1 $2;$n", getTypeDesc(p.module, t), result.r)
result.k = locTemp
#result.a = - 1
@@ -340,9 +342,9 @@ proc keepAlive(p: BProc, toKeepAlive: TLoc) =
# of interior pointers instead
if optRefcGC notin gGlobalOptions: return
var result: TLoc
var fid = toRope(p.gcFrameId)
result.r = con("GCFRAME.F", fid)
appf(p.gcFrameType, " $1 F$2;$n",
var fid = rope(p.gcFrameId)
result.r = "GCFRAME.F" & fid
addf(p.gcFrameType, " $1 F$2;$n",
[getTypeDesc(p.module, toKeepAlive.t), fid])
inc(p.gcFrameId)
result.k = locTemp
@@ -359,10 +361,10 @@ proc keepAlive(p: BProc, toKeepAlive: TLoc) =
"memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
addrLoc(result), addrLoc(toKeepAlive), rdLoc(result))
proc initGCFrame(p: BProc): PRope =
if p.gcFrameId > 0: result = ropef("struct {$1} GCFRAME;$n", p.gcFrameType)
proc initGCFrame(p: BProc): Rope =
if p.gcFrameId > 0: result = "struct {$1} GCFRAME;$n" % [p.gcFrameType]
proc deinitGCFrame(p: BProc): PRope =
proc deinitGCFrame(p: BProc): Rope =
if p.gcFrameId > 0:
result = ropecg(p.module,
"if (((NU)&GCFRAME) < 4096) #nimGCFrame(&GCFRAME);$n")
@@ -371,42 +373,42 @@ proc localDebugInfo(p: BProc, s: PSym) =
if {optStackTrace, optEndb} * p.options != {optStackTrace, optEndb}: return
# XXX work around a bug: No type information for open arrays possible:
if skipTypes(s.typ, abstractVar).kind in {tyOpenArray, tyVarargs}: return
var a = con("&", s.loc.r)
var a = "&" & s.loc.r
if s.kind == skParam and ccgIntroducedPtr(s): a = s.loc.r
lineF(p, cpsInit,
"F.s[$1].address = (void*)$3; F.s[$1].typ = $4; F.s[$1].name = $2;$n",
[p.maxFrameLen.toRope, makeCString(normalize(s.name.s)), a,
[p.maxFrameLen.rope, makeCString(normalize(s.name.s)), a,
genTypeInfo(p.module, s.loc.t)])
inc(p.maxFrameLen)
inc p.blocks[p.blocks.len-1].frameLen
proc localVarDecl(p: BProc; s: PSym): PRope =
proc localVarDecl(p: BProc; s: PSym): Rope =
if s.loc.k == locNone:
fillLoc(s.loc, locLocalVar, s.typ, mangleName(s), OnStack)
if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy)
result = getTypeDesc(p.module, s.loc.t)
if s.constraint.isNil:
if sfRegister in s.flags: app(result, " register")
if sfRegister in s.flags: add(result, " register")
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
# app(decl, " GC_GUARD")
if sfVolatile in s.flags: app(result, " volatile")
app(result, " ")
app(result, s.loc.r)
# add(decl, " GC_GUARD")
if sfVolatile in s.flags: add(result, " volatile")
add(result, " ")
add(result, s.loc.r)
else:
result = ropef(s.cgDeclFrmt, result, s.loc.r)
result = s.cgDeclFrmt % [result, s.loc.r]
proc assignLocalVar(p: BProc, s: PSym) =
#assert(s.loc.k == locNone) # not yet assigned
# this need not be fulfilled for inline procs; they are regenerated
# for each module that uses them!
let decl = localVarDecl(p, s).con(";" & tnl)
let decl = localVarDecl(p, s) & ";" & tnl
line(p, cpsLocals, decl)
localDebugInfo(p, s)
include ccgthreadvars
proc varInDynamicLib(m: BModule, sym: PSym)
proc mangleDynLibProc(sym: PSym): PRope
proc mangleDynLibProc(sym: PSym): Rope
proc assignGlobalVar(p: BProc, s: PSym) =
if s.loc.k == locNone:
@@ -424,17 +426,17 @@ proc assignGlobalVar(p: BProc, s: PSym) =
if sfThread in s.flags:
declareThreadVar(p.module, s, sfImportc in s.flags)
else:
var decl: PRope = nil
var decl: Rope = nil
var td = getTypeDesc(p.module, s.loc.t)
if s.constraint.isNil:
if sfImportc in s.flags: app(decl, "extern ")
app(decl, td)
if sfRegister in s.flags: app(decl, " register")
if sfVolatile in s.flags: app(decl, " volatile")
appf(decl, " $1;$n", [s.loc.r])
if sfImportc in s.flags: add(decl, "extern ")
add(decl, td)
if sfRegister in s.flags: add(decl, " register")
if sfVolatile in s.flags: add(decl, " volatile")
addf(decl, " $1;$n", [s.loc.r])
else:
decl = ropef(s.cgDeclFrmt & ";$n", td, s.loc.r)
app(p.module.s[cfsVars], decl)
decl = (s.cgDeclFrmt & ";$n") % [td, s.loc.r]
add(p.module.s[cfsVars], decl)
if p.withinLoop > 0:
# fixes tests/run/tzeroarray:
resetLoc(p, s.loc)
@@ -455,7 +457,7 @@ proc fillProcLoc(sym: PSym) =
proc getLabel(p: BProc): TLabel =
inc(p.labels)
result = con("LA", toRope(p.labels))
result = "LA" & rope(p.labels)
proc fixLabel(p: BProc, labl: TLabel) =
lineF(p, cpsStmts, "$1: ;$n", [labl])
@@ -467,9 +469,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc)
proc genProcPrototype(m: BModule, sym: PSym)
proc putLocIntoDest(p: BProc, d: var TLoc, s: TLoc)
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags)
proc intLiteral(i: BiggestInt): PRope
proc genLiteral(p: BProc, n: PNode): PRope
proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType): PRope
proc intLiteral(i: BiggestInt): Rope
proc genLiteral(p: BProc, n: PNode): Rope
proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType): Rope
proc initLocExpr(p: BProc, e: PNode, result: var TLoc) =
initLoc(result, locNone, e.typ, OnUnknown)
@@ -480,8 +482,8 @@ proc initLocExprSingleUse(p: BProc, e: PNode, result: var TLoc) =
result.flags.incl lfSingleUse
expr(p, e, result)
proc lenField(p: BProc): PRope =
result = toRope(if p.module.compileToCpp: "len" else: "Sup.len")
proc lenField(p: BProc): Rope =
result = rope(if p.module.compileToCpp: "len" else: "Sup.len")
include ccgcalls, "ccgstmts.nim", "ccgexprs.nim"
@@ -500,16 +502,16 @@ proc loadDynamicLib(m: BModule, lib: PLib) =
var tmp = getGlobalTempName()
assert(lib.name == nil)
lib.name = tmp # BUGFIX: cgsym has awful side-effects
appf(m.s[cfsVars], "static void* $1;$n", [tmp])
addf(m.s[cfsVars], "static void* $1;$n", [tmp])
if lib.path.kind in {nkStrLit..nkTripleStrLit}:
var s: TStringSeq = @[]
libCandidates(lib.path.strVal, s)
if gVerbosity >= 2:
msgWriteln("Dependency: " & lib.path.strVal)
var loadlib: PRope = nil
var loadlib: Rope = nil
for i in countup(0, high(s)):
inc(m.labels)
if i > 0: app(loadlib, "||")
if i > 0: add(loadlib, "||")
appcg(m, loadlib, "($1 = #nimLoadLibrary((#NimStringDesc*) &$2))$n",
[tmp, getStrLit(m, s[i])])
appcg(m, m.s[cfsDynLibInit],
@@ -520,21 +522,21 @@ proc loadDynamicLib(m: BModule, lib: PLib) =
p.options = p.options - {optStackTrace, optEndb}
var dest: TLoc
initLocExpr(p, lib.path, dest)
app(m.s[cfsVars], p.s(cpsLocals))
app(m.s[cfsDynLibInit], p.s(cpsInit))
app(m.s[cfsDynLibInit], p.s(cpsStmts))
add(m.s[cfsVars], p.s(cpsLocals))
add(m.s[cfsDynLibInit], p.s(cpsInit))
add(m.s[cfsDynLibInit], p.s(cpsStmts))
appcg(m, m.s[cfsDynLibInit],
"if (!($1 = #nimLoadLibrary($2))) #nimLoadLibraryError($2);$n",
[tmp, rdLoc(dest)])
if lib.name == nil: internalError("loadDynamicLib")
proc mangleDynLibProc(sym: PSym): PRope =
proc mangleDynLibProc(sym: PSym): Rope =
if sfCompilerProc in sym.flags:
# NOTE: sym.loc.r is the external name!
result = toRope(sym.name.s)
result = rope(sym.name.s)
else:
result = ropef("Dl_$1", [toRope(sym.id)])
result = "Dl_$1" % [rope(sym.id)]
proc symInDynamicLib(m: BModule, sym: PSym) =
var lib = sym.annex
@@ -549,28 +551,28 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
let n = lib.path
var a: TLoc
initLocExpr(m.initProc, n[0], a)
var params = con(rdLoc(a), "(")
var params = rdLoc(a) & "("
for i in 1 .. n.len-2:
initLocExpr(m.initProc, n[i], a)
params.app(rdLoc(a))
params.app(", ")
let load = ropef("\t$1 = ($2) ($3$4));$n",
[tmp, getTypeDesc(m, sym.typ), params, makeCString($extname)])
params.add(rdLoc(a))
params.add(", ")
let load = "\t$1 = ($2) ($3$4));$n" %
[tmp, getTypeDesc(m, sym.typ), params, makeCString($extname)]
var last = lastSon(n)
if last.kind == nkHiddenStdConv: last = last.sons[1]
internalAssert(last.kind == nkStrLit)
let idx = last.strVal
if idx.len == 0:
app(m.initProc.s(cpsStmts), load)
add(m.initProc.s(cpsStmts), load)
elif idx.len == 1 and idx[0] in {'0'..'9'}:
app(m.extensionLoaders[idx[0]], load)
add(m.extensionLoaders[idx[0]], load)
else:
internalError(sym.info, "wrong index: " & idx)
else:
appcg(m, m.s[cfsDynLibInit],
"\t$1 = ($2) #nimGetProcAddr($3, $4);$n",
[tmp, getTypeDesc(m, sym.typ), lib.name, makeCString($extname)])
appf(m.s[cfsVars], "$2 $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)])
addf(m.s[cfsVars], "$2 $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)])
proc varInDynamicLib(m: BModule, sym: PSym) =
var lib = sym.annex
@@ -583,14 +585,14 @@ proc varInDynamicLib(m: BModule, sym: PSym) =
appcg(m, m.s[cfsDynLibInit],
"$1 = ($2*) #nimGetProcAddr($3, $4);$n",
[tmp, getTypeDesc(m, sym.typ), lib.name, makeCString($extname)])
appf(m.s[cfsVars], "$2* $1;$n",
addf(m.s[cfsVars], "$2* $1;$n",
[sym.loc.r, getTypeDesc(m, sym.loc.t)])
proc symInDynamicLibPartial(m: BModule, sym: PSym) =
sym.loc.r = mangleDynLibProc(sym)
sym.typ.sym = nil # generate a new name
proc cgsym(m: BModule, name: string): PRope =
proc cgsym(m: BModule, name: string): Rope =
var sym = magicsys.getCompilerProc(name)
if sym != nil:
case sym.kind
@@ -606,29 +608,29 @@ proc cgsym(m: BModule, name: string): PRope =
result = sym.loc.r
proc generateHeaders(m: BModule) =
app(m.s[cfsHeaders], tnl & "#include \"nimbase.h\"" & tnl)
add(m.s[cfsHeaders], tnl & "#include \"nimbase.h\"" & tnl)
var it = PStrEntry(m.headerFiles.head)
while it != nil:
if it.data[0] notin {'\"', '<'}:
appf(m.s[cfsHeaders], "$N#include \"$1\"$N", [toRope(it.data)])
addf(m.s[cfsHeaders], "$N#include \"$1\"$N", [rope(it.data)])
else:
appf(m.s[cfsHeaders], "$N#include $1$N", [toRope(it.data)])
addf(m.s[cfsHeaders], "$N#include $1$N", [rope(it.data)])
it = PStrEntry(it.next)
proc retIsNotVoid(s: PSym): bool =
result = (s.typ.sons[0] != nil) and not isInvalidReturnType(s.typ.sons[0])
proc initFrame(p: BProc, procname, filename: PRope): PRope =
proc initFrame(p: BProc, procname, filename: Rope): Rope =
discard cgsym(p.module, "nimFrame")
if p.maxFrameLen > 0:
discard cgsym(p.module, "TVarSlot")
result = rfmt(nil, "\tnimfrs($1, $2, $3, $4)$N",
procname, filename, p.maxFrameLen.toRope,
p.blocks[0].frameLen.toRope)
procname, filename, p.maxFrameLen.rope,
p.blocks[0].frameLen.rope)
else:
result = rfmt(nil, "\tnimfr($1, $2)$N", procname, filename)
proc deinitFrame(p: BProc): PRope =
proc deinitFrame(p: BProc): Rope =
result = rfmt(p.module, "\t#popFrame();$n")
proc closureSetup(p: BProc, prc: PSym) =
@@ -647,7 +649,7 @@ proc closureSetup(p: BProc, prc: PSym) =
proc genProcAux(m: BModule, prc: PSym) =
var p = newProc(prc, m)
var header = genProcHeader(m, prc)
var returnStmt: PRope = nil
var returnStmt: Rope = nil
assert(prc.ast != nil)
if sfPure notin prc.flags and prc.typ.sons[0] != nil:
if resultPos >= prc.ast.len:
@@ -673,33 +675,33 @@ proc genProcAux(m: BModule, prc: PSym) =
assignParam(p, param)
closureSetup(p, prc)
genStmts(p, prc.getBody) # modifies p.locals, p.init, etc.
var generatedProc: PRope
var generatedProc: Rope
if sfPure in prc.flags:
if hasNakedDeclspec in extccomp.CC[extccomp.cCompiler].props:
header = con("__declspec(naked) ", header)
header = "__declspec(naked) " & header
generatedProc = rfmt(nil, "$N$1 {$n$2$3$4}$N$N",
header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts))
else:
generatedProc = rfmt(nil, "$N$1 {$N", header)
app(generatedProc, initGCFrame(p))
add(generatedProc, initGCFrame(p))
if optStackTrace in prc.options:
app(generatedProc, p.s(cpsLocals))
add(generatedProc, p.s(cpsLocals))
var procname = makeCString(prc.name.s)
app(generatedProc, initFrame(p, procname, prc.info.quotedFilename))
add(generatedProc, initFrame(p, procname, prc.info.quotedFilename))
else:
app(generatedProc, p.s(cpsLocals))
add(generatedProc, p.s(cpsLocals))
if optProfiler in prc.options:
# invoke at proc entry for recursion:
appcg(p, cpsInit, "\t#nimProfile();$n", [])
if p.beforeRetNeeded: app(generatedProc, "{")
app(generatedProc, p.s(cpsInit))
app(generatedProc, p.s(cpsStmts))
if p.beforeRetNeeded: app(generatedProc, ~"\t}BeforeRet: ;$n")
app(generatedProc, deinitGCFrame(p))
if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
app(generatedProc, returnStmt)
app(generatedProc, ~"}$N")
app(m.s[cfsProcs], generatedProc)
if p.beforeRetNeeded: add(generatedProc, "{")
add(generatedProc, p.s(cpsInit))
add(generatedProc, p.s(cpsStmts))
if p.beforeRetNeeded: add(generatedProc, ~"\t}BeforeRet: ;$n")
add(generatedProc, deinitGCFrame(p))
if optStackTrace in prc.options: add(generatedProc, deinitFrame(p))
add(generatedProc, returnStmt)
add(generatedProc, ~"}$N")
add(m.s[cfsProcs], generatedProc)
proc crossesCppBoundary(m: BModule; sym: PSym): bool {.inline.} =
result = sfCompileToCpp in m.module.flags and
@@ -712,15 +714,15 @@ proc genProcPrototype(m: BModule, sym: PSym) =
if lfDynamicLib in sym.loc.flags:
if getModule(sym).id != m.module.id and
not containsOrIncl(m.declaredThings, sym.id):
app(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
add(m.s[cfsVars], rfmt(nil, "extern $1 $2;$n",
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)))
elif not containsOrIncl(m.declaredProtos, sym.id):
var header = genProcHeader(m, sym)
if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
header = con("extern \"C\" ", header)
header = "extern \"C\" " & header
if sfPure in sym.flags and hasNakedAttribute in CC[cCompiler].props:
header.app(" __attribute__((naked))")
app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header))
header.add(" __attribute__((naked))")
add(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header))
proc genProcNoForward(m: BModule, prc: PSym) =
fillProcLoc(prc)
@@ -757,16 +759,16 @@ proc requestConstImpl(p: BProc, sym: PSym) =
var q = findPendingModule(m, sym)
if q != nil and not containsOrIncl(q.declaredThings, sym.id):
assert q.initProc.module == q
appf(q.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
addf(q.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(q, sym.typ), sym.loc.r, genConstExpr(q.initProc, sym.ast)])
# declare header:
if q != m and not containsOrIncl(m.declaredThings, sym.id):
assert(sym.loc.r != nil)
let headerDecl = ropef("extern NIM_CONST $1 $2;$n",
[getTypeDesc(m, sym.loc.t), sym.loc.r])
app(m.s[cfsData], headerDecl)
let headerDecl = "extern NIM_CONST $1 $2;$n" %
[getTypeDesc(m, sym.loc.t), sym.loc.r]
add(m.s[cfsData], headerDecl)
if sfExportc in sym.flags and generatedHeader != nil:
app(generatedHeader.s[cfsData], headerDecl)
add(generatedHeader.s[cfsData], headerDecl)
proc isActivated(prc: PSym): bool = prc.typ != nil
@@ -795,47 +797,47 @@ proc genVarPrototypeAux(m: BModule, sym: PSym) =
if sfThread in sym.flags:
declareThreadVar(m, sym, true)
else:
app(m.s[cfsVars], "extern ")
app(m.s[cfsVars], getTypeDesc(m, sym.loc.t))
if lfDynamicLib in sym.loc.flags: app(m.s[cfsVars], "*")
if sfRegister in sym.flags: app(m.s[cfsVars], " register")
if sfVolatile in sym.flags: app(m.s[cfsVars], " volatile")
appf(m.s[cfsVars], " $1;$n", [sym.loc.r])
add(m.s[cfsVars], "extern ")
add(m.s[cfsVars], getTypeDesc(m, sym.loc.t))
if lfDynamicLib in sym.loc.flags: add(m.s[cfsVars], "*")
if sfRegister in sym.flags: add(m.s[cfsVars], " register")
if sfVolatile in sym.flags: add(m.s[cfsVars], " volatile")
addf(m.s[cfsVars], " $1;$n", [sym.loc.r])
proc genVarPrototype(m: BModule, sym: PSym) =
genVarPrototypeAux(m, sym)
proc addIntTypes(result: var PRope) {.inline.} =
appf(result, "#define NIM_INTBITS $1", [
platform.CPU[targetCPU].intSize.toRope])
proc addIntTypes(result: var Rope) {.inline.} =
addf(result, "#define NIM_INTBITS $1", [
platform.CPU[targetCPU].intSize.rope])
proc getCopyright(cfile: string): PRope =
proc getCopyright(cfile: string): Rope =
if optCompileOnly in gGlobalOptions:
result = ropef("/* Generated by Nim Compiler v$1 */$N" &
result = ("/* Generated by Nim Compiler v$1 */$N" &
"/* (c) 2015 Andreas Rumpf */$N" &
"/* The generated code is subject to the original license. */$N",
[toRope(VersionAsString)])
"/* The generated code is subject to the original license. */$N") %
[rope(VersionAsString)]
else:
result = ropef("/* Generated by Nim Compiler v$1 */$N" &
result = ("/* Generated by Nim Compiler v$1 */$N" &
"/* (c) 2015 Andreas Rumpf */$N" &
"/* The generated code is subject to the original license. */$N" &
"/* Compiled for: $2, $3, $4 */$N" &
"/* Command for C compiler:$n $5 */$N",
[toRope(VersionAsString),
toRope(platform.OS[targetOS].name),
toRope(platform.CPU[targetCPU].name),
toRope(extccomp.CC[extccomp.cCompiler].name),
toRope(getCompileCFileCmd(cfile))])
"/* Command for C compiler:$n $5 */$N") %
[rope(VersionAsString),
rope(platform.OS[targetOS].name),
rope(platform.CPU[targetCPU].name),
rope(extccomp.CC[extccomp.cCompiler].name),
rope(getCompileCFileCmd(cfile))]
proc getFileHeader(cfile: string): PRope =
proc getFileHeader(cfile: string): Rope =
result = getCopyright(cfile)
addIntTypes(result)
proc genFilenames(m: BModule): PRope =
proc genFilenames(m: BModule): Rope =
discard cgsym(m, "dbgRegisterFilename")
result = nil
for i in 0.. <fileInfos.len:
result.appf("dbgRegisterFilename($1);$N", fileInfos[i].projPath.makeCString)
result.addf("dbgRegisterFilename($1);$N", [fileInfos[i].projPath.makeCString])
proc genMainProc(m: BModule) =
const
@@ -917,7 +919,7 @@ proc genMainProc(m: BModule) =
MainProcs &
"}$N$N"
var nimMain, otherMain: TFormatStr
var nimMain, otherMain: FormatStr
if platform.targetOS == osWindows and
gGlobalOptions * {optGenGuiApp, optGenDynLib} != {}:
if optGenGuiApp in gGlobalOptions:
@@ -938,10 +940,10 @@ proc genMainProc(m: BModule) =
otherMain = PosixCMain
if gBreakpoints != nil: discard cgsym(m, "dbgRegisterBreakpoint")
if optEndb in gOptions:
gBreakpoints.app(m.genFilenames)
gBreakpoints.add(m.genFilenames)
let initStackBottomCall =
if platform.targetOS == osStandalone: "".toRope
if platform.targetOS == osStandalone: "".rope
else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N")
inc(m.labels)
appcg(m, m.s[cfsProcs], PreMainBody, [
@@ -949,56 +951,56 @@ proc genMainProc(m: BModule) =
if emulatedThreadVars() and platform.targetOS != osStandalone:
ropecg(m, "\t#initThreadVarsEmulation();$N")
else:
"".toRope,
"".rope,
initStackBottomCall])
appcg(m, m.s[cfsProcs], nimMain, [mainModInit, initStackBottomCall, toRope(m.labels)])
appcg(m, m.s[cfsProcs], nimMain, [mainModInit, initStackBottomCall, rope(m.labels)])
if optNoMain notin gGlobalOptions:
appcg(m, m.s[cfsProcs], otherMain, [])
proc getSomeInitName(m: PSym, suffix: string): PRope =
proc getSomeInitName(m: PSym, suffix: string): Rope =
assert m.kind == skModule
assert m.owner.kind == skPackage
if {sfSystemModule, sfMainModule} * m.flags == {}:
result = m.owner.name.s.mangle.toRope
result.app "_"
result.app m.name.s
result.app suffix
result = m.owner.name.s.mangle.rope
result.add "_"
result.add m.name.s
result.add suffix
proc getInitName(m: PSym): PRope = getSomeInitName(m, "Init")
proc getDatInitName(m: PSym): PRope = getSomeInitName(m, "DatInit")
proc getInitName(m: PSym): Rope = getSomeInitName(m, "Init")
proc getDatInitName(m: PSym): Rope = getSomeInitName(m, "DatInit")
proc registerModuleToMain(m: PSym) =
var
init = m.getInitName
datInit = m.getDatInitName
appf(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N", [init])
appf(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N", [datInit])
addf(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N", [init])
addf(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N", [datInit])
if sfSystemModule notin m.flags:
appf(mainDatInit, "\t$1();$N", [datInit])
let initCall = ropef("\t$1();$N", [init])
addf(mainDatInit, "\t$1();$N", [datInit])
let initCall = "\t$1();$N" % [init]
if sfMainModule in m.flags:
app(mainModInit, initCall)
add(mainModInit, initCall)
else:
app(otherModsInit, initCall)
add(otherModsInit, initCall)
proc genInitCode(m: BModule) =
var initname = getInitName(m.module)
var prc = ropef("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N", [initname])
var prc = "NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N" % [initname]
if m.typeNodes > 0:
appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
[m.typeNodesName, toRope(m.typeNodes)])
[m.typeNodesName, rope(m.typeNodes)])
if m.nimTypes > 0:
appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n",
[m.nimTypesName, toRope(m.nimTypes)])
[m.nimTypesName, rope(m.nimTypes)])
app(prc, initGCFrame(m.initProc))
add(prc, initGCFrame(m.initProc))
app(prc, genSectionStart(cpsLocals))
app(prc, m.preInitProc.s(cpsLocals))
app(prc, m.initProc.s(cpsLocals))
app(prc, m.postInitProc.s(cpsLocals))
app(prc, genSectionEnd(cpsLocals))
add(prc, genSectionStart(cpsLocals))
add(prc, m.preInitProc.s(cpsLocals))
add(prc, m.initProc.s(cpsLocals))
add(prc, m.postInitProc.s(cpsLocals))
add(prc, genSectionEnd(cpsLocals))
if optStackTrace in m.initProc.options and not m.frameDeclared:
# BUT: the generated init code might depend on a current frame, so
@@ -1006,58 +1008,58 @@ proc genInitCode(m: BModule) =
m.frameDeclared = true
if not m.preventStackTrace:
var procname = makeCString(m.module.name.s)
app(prc, initFrame(m.initProc, procname, m.module.info.quotedFilename))
add(prc, initFrame(m.initProc, procname, m.module.info.quotedFilename))
else:
app(prc, ~"\tTFrame F; F.len = 0;$N")
add(prc, ~"\tTFrame F; F.len = 0;$N")
app(prc, genSectionStart(cpsInit))
app(prc, m.preInitProc.s(cpsInit))
app(prc, m.initProc.s(cpsInit))
app(prc, m.postInitProc.s(cpsInit))
app(prc, genSectionEnd(cpsInit))
add(prc, genSectionStart(cpsInit))
add(prc, m.preInitProc.s(cpsInit))
add(prc, m.initProc.s(cpsInit))
add(prc, m.postInitProc.s(cpsInit))
add(prc, genSectionEnd(cpsInit))
app(prc, genSectionStart(cpsStmts))
app(prc, m.preInitProc.s(cpsStmts))
app(prc, m.initProc.s(cpsStmts))
app(prc, m.postInitProc.s(cpsStmts))
app(prc, genSectionEnd(cpsStmts))
add(prc, genSectionStart(cpsStmts))
add(prc, m.preInitProc.s(cpsStmts))
add(prc, m.initProc.s(cpsStmts))
add(prc, m.postInitProc.s(cpsStmts))
add(prc, genSectionEnd(cpsStmts))
if optStackTrace in m.initProc.options and not m.preventStackTrace:
app(prc, deinitFrame(m.initProc))
app(prc, deinitGCFrame(m.initProc))
appf(prc, "}$N$N")
add(prc, deinitFrame(m.initProc))
add(prc, deinitGCFrame(m.initProc))
addf(prc, "}$N$N", [])
prc.appf("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
prc.addf("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
[getDatInitName(m.module)])
for i in cfsTypeInit1..cfsDynLibInit:
app(prc, genSectionStart(i))
app(prc, m.s[i])
app(prc, genSectionEnd(i))
add(prc, genSectionStart(i))
add(prc, m.s[i])
add(prc, genSectionEnd(i))
appf(prc, "}$N$N")
addf(prc, "}$N$N", [])
# we cannot simply add the init proc to ``m.s[cfsProcs]`` anymore because
# that would lead to a *nesting* of merge sections which the merger does
# not support. So we add it to another special section: ``cfsInitProc``
app(m.s[cfsInitProc], prc)
add(m.s[cfsInitProc], prc)
for i, el in pairs(m.extensionLoaders):
if el != nil:
let ex = ropef("N_NIMCALL(void, nimLoadProcs$1)(void) {$2}$N$N",
(i.ord - '0'.ord).toRope, el)
app(m.s[cfsInitProc], ex)
let ex = "N_NIMCALL(void, nimLoadProcs$1)(void) {$2}$N$N" %
[(i.ord - '0'.ord).rope, el]
add(m.s[cfsInitProc], ex)
proc genModule(m: BModule, cfile: string): PRope =
proc genModule(m: BModule, cfile: string): Rope =
result = getFileHeader(cfile)
result.app(genMergeInfo(m))
result.add(genMergeInfo(m))
generateHeaders(m)
generateThreadLocalStorage(m)
for i in countup(cfsHeaders, cfsProcs):
app(result, genSectionStart(i))
app(result, m.s[i])
app(result, genSectionEnd(i))
app(result, m.s[cfsInitProc])
add(result, genSectionStart(i))
add(result, m.s[i])
add(result, genSectionEnd(i))
add(result, m.s[cfsInitProc])
proc newPreInitProc(m: BModule): BProc =
result = newProc(nil, m)
@@ -1169,22 +1171,22 @@ proc myOpen(module: PSym): PPassContext =
proc writeHeader(m: BModule) =
var result = getCopyright(m.filename)
var guard = ropef("__$1__", m.filename.splitFile.name.toRope)
result.appf("#ifndef $1$n#define $1$n", guard)
var guard = "__$1__" % [m.filename.splitFile.name.rope]
result.addf("#ifndef $1$n#define $1$n", [guard])
addIntTypes(result)
generateHeaders(m)
generateThreadLocalStorage(m)
for i in countup(cfsHeaders, cfsProcs):
app(result, genSectionStart(i))
app(result, m.s[i])
app(result, genSectionEnd(i))
app(result, m.s[cfsInitProc])
add(result, genSectionStart(i))
add(result, m.s[i])
add(result, genSectionEnd(i))
add(result, m.s[cfsInitProc])
if optGenDynLib in gGlobalOptions:
result.app("N_LIB_IMPORT ")
result.appf("N_CDECL(void, NimMain)(void);$n")
result.appf("#endif /* $1 */$n", guard)
result.add("N_LIB_IMPORT ")
result.addf("N_CDECL(void, NimMain)(void);$n", [])
result.addf("#endif /* $1 */$n", [guard])
writeRope(result, m.filename)
proc getCFile(m: BModule): string =
@@ -1221,7 +1223,7 @@ proc finishModule(m: BModule) =
dec(gForwardedProcsCounter, i)
setLen(m.forwardedProcs, 0)
proc shouldRecompile(code: PRope, cfile: string): bool =
proc shouldRecompile(code: Rope, cfile: string): bool =
result = true
if optForceFullMake notin gGlobalOptions:
var objFile = toObjFile(cfile)
@@ -1246,7 +1248,7 @@ proc writeModule(m: BModule, pending: bool) =
finishTypeDescriptions(m)
if sfMainModule in m.module.flags:
# generate main file:
app(m.s[cfsProcHeaders], mainModProcs)
add(m.s[cfsProcHeaders], mainModProcs)
generateThreadVarsSize(m)
var code = genModule(m, cfile)

View File

@@ -15,7 +15,7 @@ import
from msgs import TLineInfo
type
TLabel* = PRope # for the C generator a label is just a rope
TLabel* = Rope # for the C generator a label is just a rope
TCFileSection* = enum # the sections a generated C file consists of
cfsMergeInfo, # section containing merge information
cfsHeaders, # section for C include file headers
@@ -45,17 +45,17 @@ type
ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64,
ctArray, ctPtrToArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc,
ctCString
TCFileSections* = array[TCFileSection, PRope] # represents a generated C file
TCFileSections* = array[TCFileSection, Rope] # represents a generated C file
TCProcSection* = enum # the sections a generated C proc consists of
cpsLocals, # section of local variables for C proc
cpsInit, # section for init of variables for C proc
cpsStmts # section of local statements for C proc
TCProcSections* = array[TCProcSection, PRope] # represents a generated C proc
TCProcSections* = array[TCProcSection, Rope] # represents a generated C proc
BModule* = ref TCGen
BProc* = ref TCProc
TBlock*{.final.} = object
id*: int # the ID of the label; positive means that it
label*: PRope # generated text for the label
label*: Rope # generated text for the label
# nil if label is not used
sections*: TCProcSections # the code beloging
isLoop*: bool # whether block is a loop
@@ -73,7 +73,7 @@ type
inExceptBlock*: int # are we currently inside an except block?
# leaving such scopes by raise or by return must
# execute any applicable finally blocks
finallySafePoints*: seq[PRope] # For correctly cleaning up exceptions when
finallySafePoints*: seq[Rope] # For correctly cleaning up exceptions when
# using return in finally statements
labels*: Natural # for generating unique labels in the C proc
blocks*: seq[TBlock] # nested blocks
@@ -89,7 +89,7 @@ type
# requires 'T x = T()' to become 'T x; x = T()'
# (yes, C++ is weird like that)
gcFrameId*: Natural # for the GC stack marking
gcFrameType*: PRope # the struct {} we put the GC markers into
gcFrameType*: Rope # the struct {} we put the GC markers into
TTypeSeq* = seq[PType]
TCGen = object of TPassContext # represents a C source file
@@ -118,24 +118,24 @@ type
dataCache*: TNodeTable
forwardedProcs*: TSymSeq # keep forwarded procs here
typeNodes*, nimTypes*: int # used for type info generation
typeNodesName*, nimTypesName*: PRope # used for type info generation
typeNodesName*, nimTypesName*: Rope # used for type info generation
labels*: Natural # for generating unique module-scope names
extensionLoaders*: array['0'..'9', PRope] # special procs for the
extensionLoaders*: array['0'..'9', Rope] # special procs for the
# OpenGL wrapper
injectStmt*: PRope
injectStmt*: Rope
var
mainModProcs*, mainModInit*, otherModsInit*, mainDatInit*: PRope
mainModProcs*, mainModInit*, otherModsInit*, mainDatInit*: Rope
# varuious parts of the main module
gMapping*: PRope # the generated mapping file (if requested)
gMapping*: Rope # the generated mapping file (if requested)
gModules*: seq[BModule] = @[] # list of all compiled modules
gForwardedProcsCounter*: int = 0
proc s*(p: BProc, s: TCProcSection): var PRope {.inline.} =
proc s*(p: BProc, s: TCProcSection): var Rope {.inline.} =
# section in the current block
result = p.blocks[p.blocks.len - 1].sections[s]
proc procSec*(p: BProc, s: TCProcSection): var PRope {.inline.} =
proc procSec*(p: BProc, s: TCProcSection): var Rope {.inline.} =
# top level proc sections
result = p.blocks[0].sections[s]

View File

@@ -9,41 +9,41 @@
# This module implements a dependency file generator.
import
import
os, options, ast, astalgo, msgs, ropes, idents, passes, importer
proc generateDot*(project: string)
type
type
TGen = object of TPassContext
module*: PSym
PGen = ref TGen
var gDotGraph: PRope # the generated DOT file; we need a global variable
var gDotGraph: Rope # the generated DOT file; we need a global variable
proc addDependencyAux(importing, imported: string) =
appf(gDotGraph, "$1 -> $2;$n", [toRope(importing), toRope(imported)])
proc addDependencyAux(importing, imported: string) =
addf(gDotGraph, "$1 -> $2;$n", [rope(importing), rope(imported)])
# s1 -> s2_4[label="[0-9]"];
proc addDotDependency(c: PPassContext, n: PNode): PNode =
proc addDotDependency(c: PPassContext, n: PNode): PNode =
result = n
var g = PGen(c)
case n.kind
of nkImportStmt:
for i in countup(0, sonsLen(n) - 1):
of nkImportStmt:
for i in countup(0, sonsLen(n) - 1):
var imported = getModuleName(n.sons[i])
addDependencyAux(g.module.name.s, imported)
of nkFromStmt, nkImportExceptStmt:
of nkFromStmt, nkImportExceptStmt:
var imported = getModuleName(n.sons[0])
addDependencyAux(g.module.name.s, imported)
of nkStmtList, nkBlockStmt, nkStmtListExpr, nkBlockExpr:
of nkStmtList, nkBlockStmt, nkStmtListExpr, nkBlockExpr:
for i in countup(0, sonsLen(n) - 1): discard addDotDependency(c, n.sons[i])
else:
else:
discard
proc generateDot(project: string) =
writeRope(ropef("digraph $1 {$n$2}$n", [
toRope(changeFileExt(extractFilename(project), "")), gDotGraph]),
proc generateDot(project: string) =
writeRope("digraph $1 {$n$2}$n" % [
rope(changeFileExt(extractFilename(project), "")), gDotGraph],
changeFileExt(project, "dot"))
proc myOpen(module: PSym): PPassContext =

View File

@@ -17,9 +17,9 @@ import
importer, sempass2, json, xmltree, cgi, typesrenderer
type
TSections = array[TSymKind, PRope]
TSections = array[TSymKind, Rope]
TDocumentor = object of rstgen.TRstGenerator
modDesc: PRope # module description
modDesc: Rope # module description
id: int # for generating IDs
toc, section: TSections
indexValFilename: string
@@ -82,9 +82,9 @@ proc newDocumentor*(filename: string, config: StringTableRef): PDoc =
result.seenSymbols = newStringTable(modeCaseInsensitive)
result.id = 100
proc dispA(dest: var PRope, xml, tex: string, args: openArray[PRope]) =
if gCmd != cmdRst2tex: appf(dest, xml, args)
else: appf(dest, tex, args)
proc dispA(dest: var Rope, xml, tex: string, args: openArray[Rope]) =
if gCmd != cmdRst2tex: addf(dest, xml, args)
else: addf(dest, tex, args)
proc getVarIdx(varnames: openArray[string], id: string): int =
for i in countup(0, high(varnames)):
@@ -92,8 +92,8 @@ proc getVarIdx(varnames: openArray[string], id: string): int =
return i
result = -1
proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openArray[string],
varvalues: openArray[PRope]): PRope =
proc ropeFormatNamedVars(frmt: FormatStr, varnames: openArray[string],
varvalues: openArray[Rope]): Rope =
var i = 0
var L = len(frmt)
result = nil
@@ -103,11 +103,11 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openArray[string],
inc(i) # skip '$'
case frmt[i]
of '#':
app(result, varvalues[num])
add(result, varvalues[num])
inc(num)
inc(i)
of '$':
app(result, "$")
add(result, "$")
inc(i)
of '0'..'9':
var j = 0
@@ -117,7 +117,7 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openArray[string],
if (i > L + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
if j > high(varvalues) + 1: internalError("ropeFormatNamedVars")
num = j
app(result, varvalues[j - 1])
add(result, varvalues[j - 1])
of 'A'..'Z', 'a'..'z', '\x80'..'\xFF':
var id = ""
while true:
@@ -125,7 +125,7 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openArray[string],
inc(i)
if not (frmt[i] in {'A'..'Z', '_', 'a'..'z', '\x80'..'\xFF'}): break
var idx = getVarIdx(varnames, id)
if idx >= 0: app(result, varvalues[idx])
if idx >= 0: add(result, varvalues[idx])
else: rawMessage(errUnknownSubstitionVar, id)
of '{':
var id = ""
@@ -137,14 +137,14 @@ proc ropeFormatNamedVars(frmt: TFormatStr, varnames: openArray[string],
inc(i) # skip }
# search for the variable:
var idx = getVarIdx(varnames, id)
if idx >= 0: app(result, varvalues[idx])
if idx >= 0: add(result, varvalues[idx])
else: rawMessage(errUnknownSubstitionVar, id)
else: internalError("ropeFormatNamedVars")
var start = i
while i < L:
if frmt[i] != '$': inc(i)
else: break
if i - 1 >= start: app(result, substr(frmt, start, i - 1))
if i - 1 >= start: add(result, substr(frmt, start, i - 1))
proc genComment(d: PDoc, n: PNode): string =
result = ""
@@ -154,9 +154,9 @@ proc genComment(d: PDoc, n: PNode): string =
toLinenumber(n.info), toColumn(n.info),
dummyHasToc, d.options + {roSkipPounds}), result)
proc genRecComment(d: PDoc, n: PNode): PRope =
proc genRecComment(d: PDoc, n: PNode): Rope =
if n == nil: return nil
result = genComment(d, n).toRope
result = genComment(d, n).rope
if result == nil:
if n.kind notin {nkEmpty..nkNilLit}:
for i in countup(0, len(n)-1):
@@ -331,9 +331,9 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
if not isVisible(nameNode): return
let
name = getName(d, nameNode)
nameRope = name.toRope
nameRope = name.rope
plainDocstring = getPlainDocstring(n) # call here before genRecComment!
var result: PRope = nil
var result: Rope = nil
var literal, plainName = ""
var kind = tkEof
var comm = genRecComment(d, n) # call this here for the side-effect!
@@ -356,69 +356,69 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
break
of tkComment:
dispA(result, "<span class=\"Comment\">$1</span>", "\\spanComment{$1}",
[toRope(esc(d.target, literal))])
[rope(esc(d.target, literal))])
of tokKeywordLow..tokKeywordHigh:
dispA(result, "<span class=\"Keyword\">$1</span>", "\\spanKeyword{$1}",
[toRope(literal)])
[rope(literal)])
of tkOpr:
dispA(result, "<span class=\"Operator\">$1</span>", "\\spanOperator{$1}",
[toRope(esc(d.target, literal))])
[rope(esc(d.target, literal))])
of tkStrLit..tkTripleStrLit:
dispA(result, "<span class=\"StringLit\">$1</span>",
"\\spanStringLit{$1}", [toRope(esc(d.target, literal))])
"\\spanStringLit{$1}", [rope(esc(d.target, literal))])
of tkCharLit:
dispA(result, "<span class=\"CharLit\">$1</span>", "\\spanCharLit{$1}",
[toRope(esc(d.target, literal))])
[rope(esc(d.target, literal))])
of tkIntLit..tkUInt64Lit:
dispA(result, "<span class=\"DecNumber\">$1</span>",
"\\spanDecNumber{$1}", [toRope(esc(d.target, literal))])
"\\spanDecNumber{$1}", [rope(esc(d.target, literal))])
of tkFloatLit..tkFloat128Lit:
dispA(result, "<span class=\"FloatNumber\">$1</span>",
"\\spanFloatNumber{$1}", [toRope(esc(d.target, literal))])
"\\spanFloatNumber{$1}", [rope(esc(d.target, literal))])
of tkSymbol:
dispA(result, "<span class=\"Identifier\">$1</span>",
"\\spanIdentifier{$1}", [toRope(esc(d.target, literal))])
"\\spanIdentifier{$1}", [rope(esc(d.target, literal))])
of tkSpaces, tkInvalid:
app(result, literal)
add(result, literal)
of tkParLe, tkParRi, tkBracketLe, tkBracketRi, tkCurlyLe, tkCurlyRi,
tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi, tkParDotLe,
tkParDotRi, tkComma, tkSemiColon, tkColon, tkEquals, tkDot, tkDotDot,
tkAccent, tkColonColon,
tkGStrLit, tkGTripleStrLit, tkInfixOpr, tkPrefixOpr, tkPostfixOpr:
dispA(result, "<span class=\"Other\">$1</span>", "\\spanOther{$1}",
[toRope(esc(d.target, literal))])
[rope(esc(d.target, literal))])
inc(d.id)
let
plainNameRope = toRope(xmltree.escape(plainName.strip))
plainNameRope = rope(xmltree.escape(plainName.strip))
cleanPlainSymbol = renderPlainSymbolName(nameNode)
complexSymbol = complexName(k, n, cleanPlainSymbol)
plainSymbolRope = toRope(cleanPlainSymbol)
plainSymbolEncRope = toRope(encodeUrl(cleanPlainSymbol))
itemIDRope = toRope(d.id)
plainSymbolRope = rope(cleanPlainSymbol)
plainSymbolEncRope = rope(encodeUrl(cleanPlainSymbol))
itemIDRope = rope(d.id)
symbolOrId = d.newUniquePlainSymbol(complexSymbol)
symbolOrIdRope = symbolOrId.toRope
symbolOrIdEncRope = encodeUrl(symbolOrId).toRope
symbolOrIdRope = symbolOrId.rope
symbolOrIdEncRope = encodeUrl(symbolOrId).rope
var seeSrcRope: PRope = nil
var seeSrcRope: Rope = nil
let docItemSeeSrc = getConfigVar("doc.item.seesrc")
if docItemSeeSrc.len > 0 and options.docSeeSrcUrl.len > 0:
# XXX toFilename doesn't really work. We need to ensure that this keeps
# returning a relative path.
let urlRope = ropeFormatNamedVars(options.docSeeSrcUrl,
["path", "line"], [n.info.toFilename.toRope, toRope($n.info.line)])
["path", "line"], [n.info.toFilename.rope, rope($n.info.line)])
dispA(seeSrcRope, "$1", "", [ropeFormatNamedVars(docItemSeeSrc,
["path", "line", "url"], [n.info.toFilename.toRope,
toRope($n.info.line), urlRope])])
["path", "line", "url"], [n.info.toFilename.rope,
rope($n.info.line), urlRope])])
app(d.section[k], ropeFormatNamedVars(getConfigVar("doc.item"),
add(d.section[k], ropeFormatNamedVars(getConfigVar("doc.item"),
["name", "header", "desc", "itemID", "header_plain", "itemSym",
"itemSymOrID", "itemSymEnc", "itemSymOrIDEnc", "seeSrc"],
[nameRope, result, comm, itemIDRope, plainNameRope, plainSymbolRope,
symbolOrIdRope, plainSymbolEncRope, symbolOrIdEncRope, seeSrcRope]))
app(d.toc[k], ropeFormatNamedVars(getConfigVar("doc.item.toc"),
add(d.toc[k], ropeFormatNamedVars(getConfigVar("doc.item.toc"),
["name", "header", "desc", "itemID", "header_plain", "itemSym",
"itemSymOrID", "itemSymEnc", "itemSymOrIDEnc"],
[toRope(getName(d, nameNode, d.splitAfter)), result, comm,
[rope(getName(d, nameNode, d.splitAfter)), result, comm,
itemIDRope, plainNameRope, plainSymbolRope, symbolOrIdRope,
plainSymbolEncRope, symbolOrIdEncRope]))
@@ -453,14 +453,14 @@ proc checkForFalse(n: PNode): bool =
proc traceDeps(d: PDoc, n: PNode) =
const k = skModule
if d.section[k] != nil: app(d.section[k], ", ")
if d.section[k] != nil: add(d.section[k], ", ")
dispA(d.section[k],
"<a class=\"reference external\" href=\"$1.html\">$1</a>",
"$1", [toRope(getModuleName(n))])
"$1", [rope(getModuleName(n))])
proc generateDoc*(d: PDoc, n: PNode) =
case n.kind
of nkCommentStmt: app(d.modDesc, genComment(d, n))
of nkCommentStmt: add(d.modDesc, genComment(d, n))
of nkProcDef:
when useEffectSystem: documentRaises(n)
genItem(d, n, n.sons[namePos], skProc)
@@ -540,28 +540,28 @@ proc genSection(d: PDoc, kind: TSymKind) =
"Iterators", "Iterators", "Converters", "Macros", "Templates"
]
if d.section[kind] == nil: return
var title = sectionNames[kind].toRope
var title = sectionNames[kind].rope
d.section[kind] = ropeFormatNamedVars(getConfigVar("doc.section"), [
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
ord(kind).toRope, title, toRope(ord(kind) + 50), d.section[kind]])
ord(kind).rope, title, rope(ord(kind) + 50), d.section[kind]])
d.toc[kind] = ropeFormatNamedVars(getConfigVar("doc.section.toc"), [
"sectionid", "sectionTitle", "sectionTitleID", "content"], [
ord(kind).toRope, title, toRope(ord(kind) + 50), d.toc[kind]])
ord(kind).rope, title, rope(ord(kind) + 50), d.toc[kind]])
proc genOutFile(d: PDoc): PRope =
proc genOutFile(d: PDoc): Rope =
var
code, content: PRope
code, content: Rope
title = ""
var j = 0
var tmp = ""
renderTocEntries(d[], j, 1, tmp)
var toc = tmp.toRope
var toc = tmp.rope
for i in countup(low(TSymKind), high(TSymKind)):
genSection(d, i)
app(toc, d.toc[i])
add(toc, d.toc[i])
if toc != nil:
toc = ropeFormatNamedVars(getConfigVar("doc.toc"), ["content"], [toc])
for i in countup(low(TSymKind), high(TSymKind)): app(code, d.section[i])
for i in countup(low(TSymKind), high(TSymKind)): add(code, d.section[i])
# Extract the title. Non API modules generate an entry in the index table.
if d.meta[metaTitle].len != 0:
@@ -574,16 +574,16 @@ proc genOutFile(d: PDoc): PRope =
let bodyname = if d.hasToc: "doc.body_toc" else: "doc.body_no_toc"
content = ropeFormatNamedVars(getConfigVar(bodyname), ["title",
"tableofcontents", "moduledesc", "date", "time", "content"],
[title.toRope, toc, d.modDesc, toRope(getDateStr()),
toRope(getClockStr()), code])
[title.rope, toc, d.modDesc, rope(getDateStr()),
rope(getClockStr()), code])
if optCompileOnly notin gGlobalOptions:
# XXX what is this hack doing here? 'optCompileOnly' means raw output!?
code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
"tableofcontents", "moduledesc", "date", "time",
"content", "author", "version", "analytics"],
[title.toRope, toc, d.modDesc, toRope(getDateStr()),
toRope(getClockStr()), content, d.meta[metaAuthor].toRope,
d.meta[metaVersion].toRope, d.analytics.toRope])
[title.rope, toc, d.modDesc, rope(getDateStr()),
rope(getClockStr()), content, d.meta[metaAuthor].rope,
d.meta[metaVersion].rope, d.analytics.rope])
else:
code = content
result = code
@@ -618,7 +618,7 @@ proc commandRstAux(filename, outExt: string) =
#d.modDesc = newMutableRope(30_000)
renderRstToOut(d[], rst, modDesc)
#freezeMutableRope(d.modDesc)
d.modDesc = toRope(modDesc)
d.modDesc = rope(modDesc)
writeOutput(d, filename, outExt)
generateIndex(d)
@@ -635,7 +635,7 @@ proc commandJSON*() =
var d = newDocumentor(gProjectFull, options.gConfigVars)
d.hasToc = true
var json = generateJson(d, ast)
var content = toRope(pretty(json))
var content = rope(pretty(json))
if optStdout in gGlobalOptions:
writeRope(stdout, content)
@@ -644,12 +644,12 @@ proc commandJSON*() =
writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false)
proc commandBuildIndex*() =
var content = mergeIndexes(gProjectFull).toRope
var content = mergeIndexes(gProjectFull).rope
let code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",
"tableofcontents", "moduledesc", "date", "time",
"content", "author", "version", "analytics"],
["Index".toRope, nil, nil, toRope(getDateStr()),
toRope(getClockStr()), content, nil, nil, nil])
["Index".rope, nil, nil, rope(getDateStr()),
rope(getClockStr()), content, nil, nil, nil])
# no analytics because context is not available
writeRope(code, getOutFile("theindex", HtmlExt))

View File

@@ -449,7 +449,7 @@ proc execExternalProgram*(cmd: string, prettyCmd = "") =
if execWithEcho(cmd, prettyCmd) != 0:
rawMessage(errExecutionOfProgramFailed, "")
proc generateScript(projectFile: string, script: PRope) =
proc generateScript(projectFile: string, script: Rope) =
let (dir, name, ext) = splitFile(projectFile)
writeRope(script, dir / addFileExt("compile_" & name,
platform.OS[targetOS].scriptExt))
@@ -604,7 +604,7 @@ proc addExternalFileToCompile*(filename: string) =
if optForceFullMake in gGlobalOptions or externalFileChanged(filename):
appendStr(externalToCompile, filename)
proc compileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq,
proc compileCFile(list: TLinkedList, script: var Rope, cmds: var TStringSeq,
prettyCmds: var TStringSeq, isExternal: bool) =
var it = PStrEntry(list.head)
while it != nil:
@@ -615,8 +615,8 @@ proc compileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq,
let (dir, name, ext) = splitFile(it.data)
add(prettyCmds, "CC: " & name)
if optGenScript in gGlobalOptions:
app(script, compileCmd)
app(script, tnl)
add(script, compileCmd)
add(script, tnl)
it = PStrEntry(it.next)
proc callCCompiler*(projectfile: string) =
@@ -627,7 +627,7 @@ proc callCCompiler*(projectfile: string) =
# generated
fileCounter = 0
var c = cCompiler
var script: PRope = nil
var script: Rope = nil
var cmds: TStringSeq = @[]
var prettyCmds: TStringSeq = @[]
let prettyCb = proc (idx: int) =
@@ -710,30 +710,30 @@ proc callCCompiler*(projectfile: string) =
else:
linkCmd = ""
if optGenScript in gGlobalOptions:
app(script, linkCmd)
app(script, tnl)
add(script, linkCmd)
add(script, tnl)
generateScript(projectfile, script)
proc genMappingFiles(list: TLinkedList): PRope =
proc genMappingFiles(list: TLinkedList): Rope =
var it = PStrEntry(list.head)
while it != nil:
appf(result, "--file:r\"$1\"$N", [toRope(it.data)])
addf(result, "--file:r\"$1\"$N", [rope(it.data)])
it = PStrEntry(it.next)
proc writeMapping*(gSymbolMapping: PRope) =
proc writeMapping*(gSymbolMapping: Rope) =
if optGenMapping notin gGlobalOptions: return
var code = toRope("[C_Files]\n")
app(code, genMappingFiles(toCompile))
app(code, genMappingFiles(externalToCompile))
app(code, "\n[C_Compiler]\nFlags=")
app(code, strutils.escape(getCompileOptions()))
var code = rope("[C_Files]\n")
add(code, genMappingFiles(toCompile))
add(code, genMappingFiles(externalToCompile))
add(code, "\n[C_Compiler]\nFlags=")
add(code, strutils.escape(getCompileOptions()))
app(code, "\n[Linker]\nFlags=")
app(code, strutils.escape(getLinkOptions() & " " &
add(code, "\n[Linker]\nFlags=")
add(code, strutils.escape(getLinkOptions() & " " &
getConfigVar(cCompiler, ".options.linker")))
app(code, "\n[Environment]\nlibpath=")
app(code, strutils.escape(libpath))
add(code, "\n[Environment]\nlibpath=")
add(code, strutils.escape(libpath))
appf(code, "\n[Symbols]$n$1", [gSymbolMapping])
addf(code, "\n[Symbols]$n$1", [gSymbolMapping])
writeRope(code, joinPath(gProjectPath, "mapping.txt"))

File diff suppressed because it is too large Load Diff

View File

@@ -9,138 +9,138 @@
## Type info generation for the JS backend.
proc genTypeInfo(p: PProc, typ: PType): PRope
proc genObjectFields(p: PProc, typ: PType, n: PNode): PRope =
var
s, u: PRope
proc genTypeInfo(p: PProc, typ: PType): Rope
proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope =
var
s, u: Rope
length: int
field: PSym
b: PNode
result = nil
case n.kind
of nkRecList:
of nkRecList:
length = sonsLen(n)
if length == 1:
if length == 1:
result = genObjectFields(p, typ, n.sons[0])
else:
else:
s = nil
for i in countup(0, length - 1):
if i > 0: app(s, ", " & tnl)
app(s, genObjectFields(p, typ, n.sons[i]))
result = ropef("{kind: 2, len: $1, offset: 0, " &
"typ: null, name: null, sons: [$2]}", [toRope(length), s])
of nkSym:
for i in countup(0, length - 1):
if i > 0: add(s, ", " & tnl)
add(s, genObjectFields(p, typ, n.sons[i]))
result = ("{kind: 2, len: $1, offset: 0, " &
"typ: null, name: null, sons: [$2]}") % [rope(length), s]
of nkSym:
field = n.sym
s = genTypeInfo(p, field.typ)
result = ropef("{kind: 1, offset: \"$1\", len: 0, " &
"typ: $2, name: $3, sons: null}",
[mangleName(field), s, makeJSString(field.name.s)])
of nkRecCase:
result = ("{kind: 1, offset: \"$1\", len: 0, " &
"typ: $2, name: $3, sons: null}") %
[mangleName(field), s, makeJSString(field.name.s)]
of nkRecCase:
length = sonsLen(n)
if (n.sons[0].kind != nkSym): internalError(n.info, "genObjectFields")
field = n.sons[0].sym
s = genTypeInfo(p, field.typ)
for i in countup(1, length - 1):
for i in countup(1, length - 1):
b = n.sons[i] # branch
u = nil
case b.kind
of nkOfBranch:
if sonsLen(b) < 2:
of nkOfBranch:
if sonsLen(b) < 2:
internalError(b.info, "genObjectFields; nkOfBranch broken")
for j in countup(0, sonsLen(b) - 2):
if u != nil: app(u, ", ")
if b.sons[j].kind == nkRange:
appf(u, "[$1, $2]", [toRope(getOrdValue(b.sons[j].sons[0])),
toRope(getOrdValue(b.sons[j].sons[1]))])
else:
app(u, toRope(getOrdValue(b.sons[j])))
of nkElse:
u = toRope(lengthOrd(field.typ))
for j in countup(0, sonsLen(b) - 2):
if u != nil: add(u, ", ")
if b.sons[j].kind == nkRange:
addf(u, "[$1, $2]", [rope(getOrdValue(b.sons[j].sons[0])),
rope(getOrdValue(b.sons[j].sons[1]))])
else:
add(u, rope(getOrdValue(b.sons[j])))
of nkElse:
u = rope(lengthOrd(field.typ))
else: internalError(n.info, "genObjectFields(nkRecCase)")
if result != nil: app(result, ", " & tnl)
appf(result, "[SetConstr($1), $2]",
if result != nil: add(result, ", " & tnl)
addf(result, "[SetConstr($1), $2]",
[u, genObjectFields(p, typ, lastSon(b))])
result = ropef("{kind: 3, offset: \"$1\", len: $3, " &
"typ: $2, name: $4, sons: [$5]}", [mangleName(field), s,
toRope(lengthOrd(field.typ)), makeJSString(field.name.s), result])
result = ("{kind: 3, offset: \"$1\", len: $3, " &
"typ: $2, name: $4, sons: [$5]}") % [mangleName(field), s,
rope(lengthOrd(field.typ)), makeJSString(field.name.s), result]
else: internalError(n.info, "genObjectFields")
proc genObjectInfo(p: PProc, typ: PType, name: PRope) =
var s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n", [name, toRope(ord(typ.kind))])
proc genObjectInfo(p: PProc, typ: PType, name: Rope) =
var s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n") % [name, rope(ord(typ.kind))]
prepend(p.g.typeInfo, s)
appf(p.g.typeInfo, "var NNI$1 = $2;$n",
[toRope(typ.id), genObjectFields(p, typ, typ.n)])
appf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, toRope(typ.id)])
if (typ.kind == tyObject) and (typ.sons[0] != nil):
appf(p.g.typeInfo, "$1.base = $2;$n",
addf(p.g.typeInfo, "var NNI$1 = $2;$n",
[rope(typ.id), genObjectFields(p, typ, typ.n)])
addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)])
if (typ.kind == tyObject) and (typ.sons[0] != nil):
addf(p.g.typeInfo, "$1.base = $2;$n",
[name, genTypeInfo(p, typ.sons[0])])
proc genTupleFields(p: PProc, typ: PType): PRope =
var s: PRope = nil
proc genTupleFields(p: PProc, typ: PType): Rope =
var s: Rope = nil
for i in 0 .. <typ.len:
if i > 0: app(s, ", " & tnl)
s.appf("{kind: 1, offset: \"Field$1\", len: 0, " &
if i > 0: add(s, ", " & tnl)
s.addf("{kind: 1, offset: \"Field$1\", len: 0, " &
"typ: $2, name: \"Field$1\", sons: null}",
[i.toRope, genTypeInfo(p, typ.sons[i])])
result = ropef("{kind: 2, len: $1, offset: 0, " &
"typ: null, name: null, sons: [$2]}", [toRope(typ.len), s])
[i.rope, genTypeInfo(p, typ.sons[i])])
result = ("{kind: 2, len: $1, offset: 0, " &
"typ: null, name: null, sons: [$2]}") % [rope(typ.len), s]
proc genTupleInfo(p: PProc, typ: PType, name: PRope) =
var s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n", [name, toRope(ord(typ.kind))])
proc genTupleInfo(p: PProc, typ: PType, name: Rope) =
var s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n") % [name, rope(ord(typ.kind))]
prepend(p.g.typeInfo, s)
appf(p.g.typeInfo, "var NNI$1 = $2;$n",
[toRope(typ.id), genTupleFields(p, typ)])
appf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, toRope(typ.id)])
addf(p.g.typeInfo, "var NNI$1 = $2;$n",
[rope(typ.id), genTupleFields(p, typ)])
addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)])
proc genEnumInfo(p: PProc, typ: PType, name: PRope) =
proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
let length = sonsLen(typ.n)
var s: PRope = nil
for i in countup(0, length - 1):
var s: Rope = nil
for i in countup(0, length - 1):
if (typ.n.sons[i].kind != nkSym): internalError(typ.n.info, "genEnumInfo")
let field = typ.n.sons[i].sym
if i > 0: app(s, ", " & tnl)
if i > 0: add(s, ", " & tnl)
let extName = if field.ast == nil: field.name.s else: field.ast.strVal
appf(s, "{kind: 1, offset: $1, typ: $2, name: $3, len: 0, sons: null}",
[toRope(field.position), name, makeJSString(extName)])
var n = ropef("var NNI$1 = {kind: 2, offset: 0, typ: null, " &
"name: null, len: $2, sons: [$3]};$n", [toRope(typ.id), toRope(length), s])
s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n", [name, toRope(ord(typ.kind))])
addf(s, "{kind: 1, offset: $1, typ: $2, name: $3, len: 0, sons: null}",
[rope(field.position), name, makeJSString(extName)])
var n = ("var NNI$1 = {kind: 2, offset: 0, typ: null, " &
"name: null, len: $2, sons: [$3]};$n") % [rope(typ.id), rope(length), s]
s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n") % [name, rope(ord(typ.kind))]
prepend(p.g.typeInfo, s)
app(p.g.typeInfo, n)
appf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, toRope(typ.id)])
add(p.g.typeInfo, n)
addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)])
if typ.sons[0] != nil:
appf(p.g.typeInfo, "$1.base = $2;$n",
addf(p.g.typeInfo, "$1.base = $2;$n",
[name, genTypeInfo(p, typ.sons[0])])
proc genTypeInfo(p: PProc, typ: PType): PRope =
proc genTypeInfo(p: PProc, typ: PType): Rope =
var t = typ
if t.kind == tyGenericInst: t = lastSon(t)
result = ropef("NTI$1", [toRope(t.id)])
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
result = "NTI$1" % [rope(t.id)]
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
case t.kind
of tyDistinct:
of tyDistinct:
result = genTypeInfo(p, typ.sons[0])
of tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64:
var s = ropef(
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
[result, toRope(ord(t.kind))])
var s =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
[result, rope(ord(t.kind))]
prepend(p.g.typeInfo, s)
of tyVar, tyRef, tyPtr, tySequence, tyRange, tySet:
var s = ropef(
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
[result, toRope(ord(t.kind))])
of tyVar, tyRef, tyPtr, tySequence, tyRange, tySet:
var s =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
[result, rope(ord(t.kind))]
prepend(p.g.typeInfo, s)
appf(p.g.typeInfo, "$1.base = $2;$n",
addf(p.g.typeInfo, "$1.base = $2;$n",
[result, genTypeInfo(p, typ.lastSon)])
of tyArrayConstr, tyArray:
var s = ropef(
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
[result, toRope(ord(t.kind))])
of tyArrayConstr, tyArray:
var s =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
[result, rope(ord(t.kind))]
prepend(p.g.typeInfo, s)
appf(p.g.typeInfo, "$1.base = $2;$n",
addf(p.g.typeInfo, "$1.base = $2;$n",
[result, genTypeInfo(p, typ.sons[1])])
of tyEnum: genEnumInfo(p, t, result)
of tyObject: genObjectInfo(p, t, result)

View File

@@ -449,10 +449,10 @@ type
fullPath: string # This is a canonical full filesystem path
projPath*: string # This is relative to the project's root
shortName*: string # short name of the module
quotedName*: PRope # cached quoted short name for codegen
quotedName*: Rope # cached quoted short name for codegen
# purposes
lines*: seq[PRope] # the source code of the module
lines*: seq[Rope] # the source code of the module
# used for better error messages and
# embedding the original source in the
# generated code
@@ -493,7 +493,7 @@ proc toCChar*(c: char): string =
of '\'', '\"', '\\': result = '\\' & c
else: result = $(c)
proc makeCString*(s: string): PRope =
proc makeCString*(s: string): Rope =
const
MaxLineLength = 64
result = nil
@@ -506,7 +506,7 @@ proc makeCString*(s: string): PRope =
add(res, '\"')
add(res, toCChar(s[i]))
add(res, '\"')
app(result, toRope(res))
add(result, rope(res))
proc newFileInfo(fullPath, projPath: string): TFileInfo =
@@ -564,7 +564,7 @@ var gCodegenLineInfo* = newLineInfo(int32(1), 1, 1)
proc raiseRecoverableError*(msg: string) {.noinline, noreturn.} =
raise newException(ERecoverableError, msg)
proc sourceLine*(i: TLineInfo): PRope
proc sourceLine*(i: TLineInfo): Rope
var
gNotes*: TNoteKinds = {low(TNoteKind)..high(TNoteKind)} -
@@ -848,9 +848,9 @@ template internalAssert*(e: bool): stmt =
if not e: internalError($instantiationInfo())
proc addSourceLine*(fileIdx: int32, line: string) =
fileInfos[fileIdx].lines.add line.toRope
fileInfos[fileIdx].lines.add line.rope
proc sourceLine*(i: TLineInfo): PRope =
proc sourceLine*(i: TLineInfo): Rope =
if i.fileIndex < 0: return nil
if not optPreserveOrigSource and fileInfos[i.fileIndex].lines.len == 0:
@@ -865,11 +865,11 @@ proc sourceLine*(i: TLineInfo): PRope =
result = fileInfos[i.fileIndex].lines[i.line-1]
proc quotedFilename*(i: TLineInfo): PRope =
proc quotedFilename*(i: TLineInfo): Rope =
internalAssert i.fileIndex >= 0
result = fileInfos[i.fileIndex].quotedName
ropes.errorHandler = proc (err: TRopesError, msg: string, useWarning: bool) =
ropes.errorHandler = proc (err: RopesError, msg: string, useWarning: bool) =
case err
of rInvalidFormatStr:
internalError("ropes: invalid format string: " & msg)

View File

@@ -89,7 +89,7 @@ proc pragmaAsm*(c: PContext, n: PNode): char =
invalidPragma(it)
proc setExternName(s: PSym, extname: string) =
s.loc.r = toRope(extname % s.name.s)
s.loc.r = rope(extname % s.name.s)
if gCmd == cmdPretty and '$' notin extname:
# note that '{.importc.}' is transformed into '{.importc: "$1".}'
s.loc.flags.incl(lfFullExternalName)
@@ -677,7 +677,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
incl(sym.loc.flags, lfHeader)
incl(sym.loc.flags, lfNoDecl)
# implies nodecl, because otherwise header would not make sense
if sym.loc.r == nil: sym.loc.r = toRope(sym.name.s)
if sym.loc.r == nil: sym.loc.r = rope(sym.name.s)
of wDestructor:
sym.flags.incl sfOverriden
if sym.name.s.normalize != "destroy":
@@ -879,7 +879,7 @@ proc implicitPragmas*(c: PContext, sym: PSym, n: PNode,
sfImportc in sym.flags and lib != nil:
incl(sym.loc.flags, lfDynamicLib)
addToLib(lib, sym)
if sym.loc.r == nil: sym.loc.r = toRope(sym.name.s)
if sym.loc.r == nil: sym.loc.r = rope(sym.name.s)
proc hasPragma*(n: PNode, pragma: TSpecialWord): bool =
if n == nil or n.sons == nil:

View File

@@ -277,7 +277,7 @@ proc decodeLoc(r: PRodReader, loc: var TLoc, info: TLineInfo) =
loc.t = nil
if r.s[r.pos] == '!':
inc(r.pos)
loc.r = toRope(decodeStr(r.s, r.pos))
loc.r = rope(decodeStr(r.s, r.pos))
else:
loc.r = nil
if r.s[r.pos] == '>': inc(r.pos)
@@ -344,7 +344,7 @@ proc decodeLib(r: PRodReader, info: TLineInfo): PLib =
result.kind = TLibKind(decodeVInt(r.s, r.pos))
if r.s[r.pos] != '|': internalError("decodeLib: 1")
inc(r.pos)
result.name = toRope(decodeStr(r.s, r.pos))
result.name = rope(decodeStr(r.s, r.pos))
if r.s[r.pos] != '|': internalError("decodeLib: 2")
inc(r.pos)
result.path = decodeNode(r, info)

View File

@@ -76,11 +76,6 @@ type
rCannotOpenFile
rInvalidFormatStr
{.deprecated: [TFormatStr: FormatStr].}
{.deprecated: [PRope: Rope].}
{.deprecated: [TRopeSeq: RopeSeq].}
{.deprecated: [TRopesError: RopesError].}
# implementation
var errorHandler*: proc(err: RopesError, msg: string, useWarning = false)
@@ -152,12 +147,6 @@ proc rope*(i: BiggestInt): Rope =
proc rope*(f: BiggestFloat): Rope =
result = rope($f)
# TODO Old names - change invokations to rope
proc toRope*(s: string): Rope {.deprecated.} =
result = rope(s)
proc toRope*(i: BiggestInt): Rope {.deprecated.} =
result = rope(i)
proc ropeSeqInsert(rs: var RopeSeq, r: Rope, at: Natural) =
var length = len(rs)
if at > length:
@@ -214,19 +203,9 @@ proc `$`*(p: Rope): string =
var resultLen = 0
newRecRopeToStr(result, resultLen, p)
# TODO Old names - change invokations to `&`
proc con*(a, b: Rope): Rope {.deprecated.} = a & b
proc con*(a: Rope, b: string): Rope {.deprecated.} = a & b
proc con*(a: string, b: Rope): Rope {.deprecated.} = a & b
proc con*(a: varargs[Rope]): Rope {.deprecated.} = `&`(a)
proc ropeConcat*(a: varargs[Rope]): Rope =
# not overloaded version of concat to speed-up `rfmt` a little bit
for i in countup(0, high(a)): result = con(result, a[i])
# TODO Old names - change invokations to add
proc app*(a: var Rope, b: Rope) {.deprecated.} = add(a, b)
proc app*(a: var Rope, b: string) {.deprecated.} = add(a, b)
for i in countup(0, high(a)): result = result & a[i]
proc prepend*(a: var Rope, b: Rope) = a = b & a
proc prepend*(a: var Rope, b: string) = a = b & a
@@ -254,7 +233,7 @@ var
rnl* = tnl.newRope
softRnl* = tnl.newRope
proc `%`*(frmt: TFormatStr, args: openArray[Rope]): Rope =
proc `%`*(frmt: FormatStr, args: openArray[Rope]): Rope =
var i = 0
var length = len(frmt)
result = nil
@@ -311,23 +290,17 @@ proc `%`*(frmt: TFormatStr, args: openArray[Rope]): Rope =
add(result, substr(frmt, start, i - 1))
assert(ropeInvariant(result))
proc addf*(c: var Rope, frmt: TFormatStr, args: openArray[Rope]) =
proc addf*(c: var Rope, frmt: FormatStr, args: openArray[Rope]) =
add(c, frmt % args)
# TODO Compatibility names
proc ropef*(frmt: TFormatStr, args: varargs[Rope]): Rope {.deprecated.} =
result = frmt % args
proc appf*(c: var Rope, frmt: TFormatStr, args: varargs[Rope]) {.deprecated.} =
addf(c, frmt, args)
when true:
template `~`*(r: string): Rope = r.ropef
template `~`*(r: string): Rope = r % []
else:
{.push stack_trace: off, line_trace: off.}
proc `~`*(r: static[string]): Rope =
# this is the new optimized "to rope" operator
# the mnemonic is that `~` looks a bit like a rope :)
var r {.global.} = r.ropef
var r {.global.} = r % []
return r
{.pop.}

View File

@@ -593,7 +593,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
f.position = pos
if (rec != nil) and ({sfImportc, sfExportc} * rec.flags != {}) and
(f.loc.r == nil):
f.loc.r = toRope(f.name.s)
f.loc.r = rope(f.name.s)
f.flags = f.flags + ({sfImportc, sfExportc} * rec.flags)
inc(pos)
if containsOrIncl(check, f.name.id):