implemented mixed mode codegen
This commit is contained in:
parent
595cc93762
commit
e65c296bcc
15 changed files with 133 additions and 95 deletions
|
|
@ -291,6 +291,8 @@ const
|
||||||
|
|
||||||
sfNoRoot* = sfBorrow # a local variable is provably no root so it doesn't
|
sfNoRoot* = sfBorrow # a local variable is provably no root so it doesn't
|
||||||
# require RC ops
|
# require RC ops
|
||||||
|
sfCompileToCpp* = sfInfixCall # compile the module as C++ code
|
||||||
|
sfCompileToObjc* = sfNamedParamCall # compile the module as Objective-C code
|
||||||
|
|
||||||
const
|
const
|
||||||
# getting ready for the future expr/stmt merge
|
# getting ready for the future expr/stmt merge
|
||||||
|
|
|
||||||
|
|
@ -103,9 +103,9 @@ proc openArrayLoc(p: BProc, n: PNode): PRope =
|
||||||
result = ropef("$1, $1Len0", [rdLoc(a)])
|
result = ropef("$1, $1Len0", [rdLoc(a)])
|
||||||
of tyString, tySequence:
|
of tyString, tySequence:
|
||||||
if skipTypes(n.typ, abstractInst).kind == tyVar:
|
if skipTypes(n.typ, abstractInst).kind == tyVar:
|
||||||
result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField()])
|
result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField(p)])
|
||||||
else:
|
else:
|
||||||
result = ropef("$1->data, $1->$2", [a.rdLoc, lenField()])
|
result = ropef("$1->data, $1->$2", [a.rdLoc, lenField(p)])
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])
|
result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])
|
||||||
else: internalError("openArrayLoc: " & typeToString(a.t))
|
else: internalError("openArrayLoc: " & typeToString(a.t))
|
||||||
|
|
|
||||||
|
|
@ -721,7 +721,7 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
internalError(e.info, "genRecordField")
|
internalError(e.info, "genRecordField")
|
||||||
field = lookupInRecord(ty.n, f.name)
|
field = lookupInRecord(ty.n, f.name)
|
||||||
if field != nil: break
|
if field != nil: break
|
||||||
if gCmd != cmdCompileToCpp: app(r, ".Sup")
|
if not p.module.compileToCpp: app(r, ".Sup")
|
||||||
ty = getUniqueType(ty.sons[0])
|
ty = getUniqueType(ty.sons[0])
|
||||||
if field == nil: internalError(e.info, "genRecordField 2 ")
|
if field == nil: internalError(e.info, "genRecordField 2 ")
|
||||||
if field.loc.r == nil: internalError(e.info, "genRecordField 3")
|
if field.loc.r == nil: internalError(e.info, "genRecordField 3")
|
||||||
|
|
@ -773,7 +773,7 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) =
|
||||||
assert(ty.kind in {tyTuple, tyObject})
|
assert(ty.kind in {tyTuple, tyObject})
|
||||||
field = lookupInRecord(ty.n, f.name)
|
field = lookupInRecord(ty.n, f.name)
|
||||||
if field != nil: break
|
if field != nil: break
|
||||||
if gCmd != cmdCompileToCpp: app(r, ".Sup")
|
if not p.module.compileToCpp: app(r, ".Sup")
|
||||||
ty = getUniqueType(ty.sons[0])
|
ty = getUniqueType(ty.sons[0])
|
||||||
if field == nil: internalError(e.info, "genCheckedRecordField")
|
if field == nil: internalError(e.info, "genCheckedRecordField")
|
||||||
if field.loc.r == nil:
|
if field.loc.r == nil:
|
||||||
|
|
@ -840,11 +840,11 @@ proc genSeqElem(p: BProc, e: PNode, d: var TLoc) =
|
||||||
if ty.kind == tyString:
|
if ty.kind == tyString:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n",
|
"if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n",
|
||||||
rdLoc(b), rdLoc(a), lenField())
|
rdLoc(b), rdLoc(a), lenField(p))
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts,
|
linefmt(p, cpsStmts,
|
||||||
"if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n",
|
"if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n",
|
||||||
rdLoc(b), rdLoc(a), lenField())
|
rdLoc(b), rdLoc(a), lenField(p))
|
||||||
if d.k == locNone: d.s = OnHeap
|
if d.k == locNone: d.s = OnHeap
|
||||||
d.heapRoot = a.r
|
d.heapRoot = a.r
|
||||||
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
||||||
|
|
@ -937,7 +937,7 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
|
||||||
if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
|
if e.sons[i + 1].kind in {nkStrLit..nkTripleStrLit}:
|
||||||
inc(L, len(e.sons[i + 1].strVal))
|
inc(L, len(e.sons[i + 1].strVal))
|
||||||
else:
|
else:
|
||||||
appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
|
appf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
|
||||||
app(appends, rfmt(p.module, "#appendString($1, $2);$n", tmp.r, rdLoc(a)))
|
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))
|
linefmt(p, cpsStmts, "$1 = #rawNewString($2$3);$n", tmp.r, lens, toRope(L))
|
||||||
app(p.s(cpsStmts), appends)
|
app(p.s(cpsStmts), appends)
|
||||||
|
|
@ -977,7 +977,7 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||||
if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}:
|
if e.sons[i + 2].kind in {nkStrLit..nkTripleStrLit}:
|
||||||
inc(L, len(e.sons[i + 2].strVal))
|
inc(L, len(e.sons[i + 2].strVal))
|
||||||
else:
|
else:
|
||||||
appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
|
appf(lens, "$1->$2 + ", [rdLoc(a), lenField(p)])
|
||||||
app(appends, rfmt(p.module, "#appendString($1, $2);$n",
|
app(appends, rfmt(p.module, "#appendString($1, $2);$n",
|
||||||
rdLoc(dest), rdLoc(a)))
|
rdLoc(dest), rdLoc(a)))
|
||||||
linefmt(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
|
linefmt(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
|
||||||
|
|
@ -990,7 +990,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||||
# seq &= x -->
|
# seq &= x -->
|
||||||
# seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x));
|
# seq = (typeof seq) incrSeq(&seq->Sup, sizeof(x));
|
||||||
# seq->data[seq->len-1] = x;
|
# seq->data[seq->len-1] = x;
|
||||||
let seqAppendPattern = if gCmd != cmdCompileToCpp:
|
let seqAppendPattern = if not p.module.compileToCpp:
|
||||||
"$1 = ($2) #incrSeq(&($1)->Sup, sizeof($3));$n"
|
"$1 = ($2) #incrSeq(&($1)->Sup, sizeof($3));$n"
|
||||||
else:
|
else:
|
||||||
"$1 = ($2) #incrSeq($1, sizeof($3));$n"
|
"$1 = ($2) #incrSeq($1, sizeof($3));$n"
|
||||||
|
|
@ -1003,7 +1003,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||||
getTypeDesc(p.module, skipTypes(e.sons[2].typ, abstractVar))])
|
getTypeDesc(p.module, skipTypes(e.sons[2].typ, abstractVar))])
|
||||||
keepAlive(p, a)
|
keepAlive(p, a)
|
||||||
initLoc(dest, locExpr, b.t, OnHeap)
|
initLoc(dest, locExpr, b.t, OnHeap)
|
||||||
dest.r = rfmt(nil, "$1->data[$1->$2-1]", rdLoc(a), lenField())
|
dest.r = rfmt(nil, "$1->data[$1->$2-1]", rdLoc(a), lenField(p))
|
||||||
genAssignment(p, dest, b, {needToCopy, afDestIsNil})
|
genAssignment(p, dest, b, {needToCopy, afDestIsNil})
|
||||||
gcUsage(e)
|
gcUsage(e)
|
||||||
|
|
||||||
|
|
@ -1097,7 +1097,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
while ty != nil:
|
while ty != nil:
|
||||||
field = lookupInRecord(ty.n, it.sons[0].sym.name)
|
field = lookupInRecord(ty.n, it.sons[0].sym.name)
|
||||||
if field != nil: break
|
if field != nil: break
|
||||||
if gCmd != cmdCompileToCpp: app(tmp2.r, ".Sup")
|
if not p.module.compileToCpp: app(tmp2.r, ".Sup")
|
||||||
ty = getUniqueType(ty.sons[0])
|
ty = getUniqueType(ty.sons[0])
|
||||||
if field == nil or field.loc.r == nil: internalError(e.info, "genObjConstr")
|
if field == nil or field.loc.r == nil: internalError(e.info, "genObjConstr")
|
||||||
if it.len == 3 and optFieldCheck in p.options:
|
if it.len == 3 and optFieldCheck in p.options:
|
||||||
|
|
@ -1198,8 +1198,8 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||||
if t.kind != tyVar: nilCheck = r
|
if t.kind != tyVar: nilCheck = r
|
||||||
r = rfmt(nil, "(*$1)", r)
|
r = rfmt(nil, "(*$1)", r)
|
||||||
t = skipTypes(t.lastSon, typedescInst)
|
t = skipTypes(t.lastSon, typedescInst)
|
||||||
if gCmd != cmdCompileToCpp:
|
if not p.module.compileToCpp:
|
||||||
while (t.kind == tyObject) and (t.sons[0] != nil):
|
while t.kind == tyObject and t.sons[0] != nil:
|
||||||
app(r, ~".Sup")
|
app(r, ~".Sup")
|
||||||
t = skipTypes(t.sons[0], typedescInst)
|
t = skipTypes(t.sons[0], typedescInst)
|
||||||
if isObjLackingTypeField(t):
|
if isObjLackingTypeField(t):
|
||||||
|
|
@ -1244,7 +1244,7 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
|
putIntoDest(p, b, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
|
||||||
of tyString, tySequence:
|
of tyString, tySequence:
|
||||||
putIntoDest(p, b, e.typ,
|
putIntoDest(p, b, e.typ,
|
||||||
ropef("$1->data, $1->$2", [rdLoc(a), lenField()]))
|
ropef("$1->data, $1->$2", [rdLoc(a), lenField(p)]))
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
putIntoDest(p, b, e.typ,
|
putIntoDest(p, b, e.typ,
|
||||||
ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
|
ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
|
||||||
|
|
@ -1287,7 +1287,7 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||||
if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)")
|
if op == mHigh: unaryExpr(p, e, d, "(strlen($1)-1)")
|
||||||
else: unaryExpr(p, e, d, "strlen($1)")
|
else: unaryExpr(p, e, d, "strlen($1)")
|
||||||
of tyString, tySequence:
|
of tyString, tySequence:
|
||||||
if gCmd != cmdCompileToCpp:
|
if not p.module.compileToCpp:
|
||||||
if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)")
|
if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)")
|
||||||
else: unaryExpr(p, e, d, "$1->Sup.len")
|
else: unaryExpr(p, e, d, "$1->Sup.len")
|
||||||
else:
|
else:
|
||||||
|
|
@ -1305,7 +1305,7 @@ proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
|
||||||
initLocExpr(p, e.sons[1], a)
|
initLocExpr(p, e.sons[1], a)
|
||||||
initLocExpr(p, e.sons[2], b)
|
initLocExpr(p, e.sons[2], b)
|
||||||
var t = skipTypes(e.sons[1].typ, abstractVar)
|
var t = skipTypes(e.sons[1].typ, abstractVar)
|
||||||
let setLenPattern = if gCmd != cmdCompileToCpp:
|
let setLenPattern = if not p.module.compileToCpp:
|
||||||
"$1 = ($3) #setLengthSeq(&($1)->Sup, sizeof($4), $2);$n"
|
"$1 = ($3) #setLengthSeq(&($1)->Sup, sizeof($4), $2);$n"
|
||||||
else:
|
else:
|
||||||
"$1 = ($3) #setLengthSeq($1, sizeof($4), $2);$n"
|
"$1 = ($3) #setLengthSeq($1, sizeof($4), $2);$n"
|
||||||
|
|
@ -1561,11 +1561,11 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
|
||||||
elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""):
|
elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""):
|
||||||
initLocExpr(p, e.sons[2], x)
|
initLocExpr(p, e.sons[2], x)
|
||||||
putIntoDest(p, d, e.typ,
|
putIntoDest(p, d, e.typ,
|
||||||
rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField()))
|
rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField(p)))
|
||||||
elif (b.kind in {nkStrLit..nkTripleStrLit}) and (b.strVal == ""):
|
elif (b.kind in {nkStrLit..nkTripleStrLit}) and (b.strVal == ""):
|
||||||
initLocExpr(p, e.sons[1], x)
|
initLocExpr(p, e.sons[1], x)
|
||||||
putIntoDest(p, d, e.typ,
|
putIntoDest(p, d, e.typ,
|
||||||
rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField()))
|
rfmt(nil, "(($1) && ($1)->$2 == 0)", rdLoc(x), lenField(p)))
|
||||||
else:
|
else:
|
||||||
binaryExpr(p, e, d, "#eqStrings($1, $2)")
|
binaryExpr(p, e, d, "#eqStrings($1, $2)")
|
||||||
|
|
||||||
|
|
@ -1824,7 +1824,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
if t.kind != tyVar: nilCheck = r
|
if t.kind != tyVar: nilCheck = r
|
||||||
r = ropef("(*$1)", [r])
|
r = ropef("(*$1)", [r])
|
||||||
t = skipTypes(t.lastSon, abstractInst)
|
t = skipTypes(t.lastSon, abstractInst)
|
||||||
if gCmd != cmdCompileToCpp:
|
if not p.module.compileToCpp:
|
||||||
while t.kind == tyObject and t.sons[0] != nil:
|
while t.kind == tyObject and t.sons[0] != nil:
|
||||||
app(r, ".Sup")
|
app(r, ".Sup")
|
||||||
t = skipTypes(t.sons[0], abstractInst)
|
t = skipTypes(t.sons[0], abstractInst)
|
||||||
|
|
@ -1842,7 +1842,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
[getTypeDesc(p.module, dest), addrLoc(a)]))
|
[getTypeDesc(p.module, dest), addrLoc(a)]))
|
||||||
|
|
||||||
proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
proc downConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
if gCmd == cmdCompileToCpp:
|
if p.module.compileToCpp:
|
||||||
expr(p, n.sons[0], d) # downcast does C++ for us
|
expr(p, n.sons[0], d) # downcast does C++ for us
|
||||||
else:
|
else:
|
||||||
var dest = skipTypes(n.typ, abstractPtrs)
|
var dest = skipTypes(n.typ, abstractPtrs)
|
||||||
|
|
@ -2028,7 +2028,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||||
initLocExpr(p, n.sons[0], a)
|
initLocExpr(p, n.sons[0], a)
|
||||||
of nkAsmStmt: genAsmStmt(p, n)
|
of nkAsmStmt: genAsmStmt(p, n)
|
||||||
of nkTryStmt:
|
of nkTryStmt:
|
||||||
if gCmd == cmdCompileToCpp: genTryCpp(p, n, d)
|
if p.module.compileToCpp: genTryCpp(p, n, d)
|
||||||
else: genTry(p, n, d)
|
else: genTry(p, n, d)
|
||||||
of nkRaiseStmt: genRaiseStmt(p, n)
|
of nkRaiseStmt: genRaiseStmt(p, n)
|
||||||
of nkTypeSection:
|
of nkTypeSection:
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ proc readMergeInfo*(cfilename: string, m: BModule) =
|
||||||
break
|
break
|
||||||
|
|
||||||
type
|
type
|
||||||
TMergeSections = object {.pure.}
|
TMergeSections = object
|
||||||
f: TCFileSections
|
f: TCFileSections
|
||||||
p: TCProcSections
|
p: TCProcSections
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -289,8 +289,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
||||||
|
|
||||||
var alreadyPoppedCnt = p.inExceptBlock
|
var alreadyPoppedCnt = p.inExceptBlock
|
||||||
for i in countup(1, howManyTrys):
|
for i in countup(1, howManyTrys):
|
||||||
|
if not p.module.compileToCpp:
|
||||||
if gCmd != cmdCompileToCpp:
|
|
||||||
# Pop safe points generated by try
|
# Pop safe points generated by try
|
||||||
if alreadyPoppedCnt > 0:
|
if alreadyPoppedCnt > 0:
|
||||||
dec alreadyPoppedCnt
|
dec alreadyPoppedCnt
|
||||||
|
|
@ -312,7 +311,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
||||||
for i in countdown(howManyTrys-1, 0):
|
for i in countdown(howManyTrys-1, 0):
|
||||||
p.nestedTryStmts.add(stack[i])
|
p.nestedTryStmts.add(stack[i])
|
||||||
|
|
||||||
if gCmd != cmdCompileToCpp:
|
if not p.module.compileToCpp:
|
||||||
# Pop exceptions that was handled by the
|
# Pop exceptions that was handled by the
|
||||||
# except-blocks we are in
|
# except-blocks we are in
|
||||||
for i in countdown(howManyExcepts-1, 0):
|
for i in countdown(howManyExcepts-1, 0):
|
||||||
|
|
@ -496,7 +495,7 @@ proc genBreakStmt(p: BProc, t: PNode) =
|
||||||
lineF(p, cpsStmts, "goto $1;$n", [label])
|
lineF(p, cpsStmts, "goto $1;$n", [label])
|
||||||
|
|
||||||
proc getRaiseFrmt(p: BProc): string =
|
proc getRaiseFrmt(p: BProc): string =
|
||||||
if gCmd == cmdCompileToCpp:
|
if p.module.compileToCpp:
|
||||||
result = "throw NimException($1, $2);$n"
|
result = "throw NimException($1, $2);$n"
|
||||||
elif getCompilerProc("Exception") != nil:
|
elif getCompilerProc("Exception") != nil:
|
||||||
result = "#raiseException((#Exception*)$1, $2);$n"
|
result = "#raiseException((#Exception*)$1, $2);$n"
|
||||||
|
|
@ -517,10 +516,10 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
var typ = skipTypes(t.sons[0].typ, abstractPtrs)
|
var typ = skipTypes(t.sons[0].typ, abstractPtrs)
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
lineCg(p, cpsStmts, getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
|
lineCg(p, cpsStmts, getRaiseFrmt(p), [e, makeCString(typ.sym.name.s)])
|
||||||
else:
|
else:
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
# reraise the last exception:
|
# reraise the last exception:
|
||||||
if gCmd == cmdCompileToCpp:
|
if p.module.compileToCpp:
|
||||||
line(p, cpsStmts, ~"throw;$n")
|
line(p, cpsStmts, ~"throw;$n")
|
||||||
else:
|
else:
|
||||||
linefmt(p, cpsStmts, "#reraiseException();$n")
|
linefmt(p, cpsStmts, "#reraiseException();$n")
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, n: PNode) =
|
||||||
genTraverseProc(c, ropef("$1.$2", accessor, field.loc.r), field.loc.t)
|
genTraverseProc(c, ropef("$1.$2", accessor, field.loc.r), field.loc.t)
|
||||||
else: internalError(n.info, "genTraverseProc()")
|
else: internalError(n.info, "genTraverseProc()")
|
||||||
|
|
||||||
proc parentObj(accessor: PRope): PRope {.inline.} =
|
proc parentObj(accessor: PRope; m: BModule): PRope {.inline.} =
|
||||||
if gCmd != cmdCompileToCpp:
|
if not m.compileToCpp:
|
||||||
result = ropef("$1.Sup", accessor)
|
result = ropef("$1.Sup", accessor)
|
||||||
else:
|
else:
|
||||||
result = accessor
|
result = accessor
|
||||||
|
|
@ -71,7 +71,7 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: PRope, typ: PType) =
|
||||||
lineF(p, cpsStmts, "}$n")
|
lineF(p, cpsStmts, "}$n")
|
||||||
of tyObject:
|
of tyObject:
|
||||||
for i in countup(0, sonsLen(typ) - 1):
|
for i in countup(0, sonsLen(typ) - 1):
|
||||||
genTraverseProc(c, accessor.parentObj, typ.sons[i])
|
genTraverseProc(c, accessor.parentObj(c.p.module), typ.sons[i])
|
||||||
if typ.n != nil: genTraverseProc(c, accessor, typ.n)
|
if typ.n != nil: genTraverseProc(c, accessor, typ.n)
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
let typ = getUniqueType(typ)
|
let typ = getUniqueType(typ)
|
||||||
|
|
@ -91,7 +91,7 @@ proc genTraverseProcSeq(c: var TTraversalClosure, accessor: PRope, typ: PType) =
|
||||||
var i: TLoc
|
var i: TLoc
|
||||||
getTemp(p, getSysType(tyInt), i)
|
getTemp(p, getSysType(tyInt), i)
|
||||||
lineF(p, cpsStmts, "for ($1 = 0; $1 < $2->$3; $1++) {$n",
|
lineF(p, cpsStmts, "for ($1 = 0; $1 < $2->$3; $1++) {$n",
|
||||||
i.r, accessor, toRope(if gCmd != cmdCompileToCpp: "Sup.len" else: "len"))
|
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])
|
genTraverseProc(c, ropef("$1->data[$2]", accessor, i.r), typ.sons[0])
|
||||||
lineF(p, cpsStmts, "}$n")
|
lineF(p, cpsStmts, "}$n")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -342,8 +342,8 @@ proc getTypePre(m: BModule, typ: PType): PRope =
|
||||||
proc structOrUnion(t: PType): PRope =
|
proc structOrUnion(t: PType): PRope =
|
||||||
(if tfUnion in t.flags: toRope("union") else: toRope("struct"))
|
(if tfUnion in t.flags: toRope("union") else: toRope("struct"))
|
||||||
|
|
||||||
proc getForwardStructFormat(): string =
|
proc getForwardStructFormat(m: BModule): string =
|
||||||
if gCmd == cmdCompileToCpp: result = "$1 $2;$n"
|
if m.compileToCpp: result = "$1 $2;$n"
|
||||||
else: result = "typedef $1 $2 $2;$n"
|
else: result = "typedef $1 $2 $2;$n"
|
||||||
|
|
||||||
proc getTypeForward(m: BModule, typ: PType): PRope =
|
proc getTypeForward(m: BModule, typ: PType): PRope =
|
||||||
|
|
@ -355,7 +355,7 @@ proc getTypeForward(m: BModule, typ: PType): PRope =
|
||||||
of tySequence, tyTuple, tyObject:
|
of tySequence, tyTuple, tyObject:
|
||||||
result = getTypeName(typ)
|
result = getTypeName(typ)
|
||||||
if not isImportedType(typ):
|
if not isImportedType(typ):
|
||||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(),
|
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
|
||||||
[structOrUnion(typ), result])
|
[structOrUnion(typ), result])
|
||||||
idTablePut(m.forwTypeCache, typ, result)
|
idTablePut(m.forwTypeCache, typ, result)
|
||||||
else: internalError("getTypeForward(" & $typ.kind & ')')
|
else: internalError("getTypeForward(" & $typ.kind & ')')
|
||||||
|
|
@ -442,7 +442,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: PRope,
|
||||||
else:
|
else:
|
||||||
appcg(m, result, " {$n#TNimType* m_type;$n", [name, attribute])
|
appcg(m, result, " {$n#TNimType* m_type;$n", [name, attribute])
|
||||||
hasField = true
|
hasField = true
|
||||||
elif gCmd == cmdCompileToCpp:
|
elif m.compileToCpp:
|
||||||
appcg(m, result, " : public $1 {$n",
|
appcg(m, result, " : public $1 {$n",
|
||||||
[getTypeDescAux(m, typ.sons[0], check)])
|
[getTypeDescAux(m, typ.sons[0], check)])
|
||||||
hasField = true
|
hasField = true
|
||||||
|
|
@ -538,7 +538,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = getTypeName(t)
|
result = getTypeName(t)
|
||||||
if not isImportedType(t):
|
if not isImportedType(t):
|
||||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(),
|
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
|
||||||
[structOrUnion(t), result])
|
[structOrUnion(t), result])
|
||||||
idTablePut(m.forwTypeCache, t, result)
|
idTablePut(m.forwTypeCache, t, result)
|
||||||
assert(cacheGetType(m.typeCache, t) == nil)
|
assert(cacheGetType(m.typeCache, t) == nil)
|
||||||
|
|
@ -550,7 +550,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
cSeq = "struct $2 {$n" &
|
cSeq = "struct $2 {$n" &
|
||||||
" #TGenericSeq Sup;$n"
|
" #TGenericSeq Sup;$n"
|
||||||
appcg(m, m.s[cfsSeqTypes],
|
appcg(m, m.s[cfsSeqTypes],
|
||||||
(if gCmd == cmdCompileToCpp: cppSeq else: cSeq) &
|
(if m.compileToCpp: cppSeq else: cSeq) &
|
||||||
" $1 data[SEQ_DECL_SIZE];$n" &
|
" $1 data[SEQ_DECL_SIZE];$n" &
|
||||||
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
|
||||||
else:
|
else:
|
||||||
|
|
@ -570,7 +570,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): PRope =
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = getTypeName(t)
|
result = getTypeName(t)
|
||||||
if not isImportedType(t):
|
if not isImportedType(t):
|
||||||
appf(m.s[cfsForwardTypes], getForwardStructFormat(),
|
appf(m.s[cfsForwardTypes], getForwardStructFormat(m),
|
||||||
[structOrUnion(t), result])
|
[structOrUnion(t), result])
|
||||||
idTablePut(m.forwTypeCache, t, result)
|
idTablePut(m.forwTypeCache, t, result)
|
||||||
idTablePut(m.typeCache, t, result) # always call for sideeffects:
|
idTablePut(m.typeCache, t, result) # always call for sideeffects:
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@ proc mangle*(name: string): string =
|
||||||
## Lowercases the given name and manges any non-alphanumeric characters
|
## Lowercases the given name and manges any non-alphanumeric characters
|
||||||
## so they are represented as `HEX____`. If the name starts with a number,
|
## so they are represented as `HEX____`. If the name starts with a number,
|
||||||
## `N` is prepended
|
## `N` is prepended
|
||||||
result = ""
|
result = newStringOfCap(name.len)
|
||||||
case name[0]
|
case name[0]
|
||||||
of Letters:
|
of Letters:
|
||||||
result.add(name[0].toLower)
|
result.add(name[0].toLower)
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,9 @@ proc accessThreadLocalVar(p: BProc, s: PSym)
|
||||||
proc emulatedThreadVars(): bool {.inline.}
|
proc emulatedThreadVars(): bool {.inline.}
|
||||||
proc genProc(m: BModule, prc: PSym)
|
proc genProc(m: BModule, prc: PSym)
|
||||||
|
|
||||||
|
template compileToCpp(m: BModule): expr =
|
||||||
|
gCmd == cmdCompileToCpp or sfCompileToCpp in m.module.flags
|
||||||
|
|
||||||
include "ccgtypes.nim"
|
include "ccgtypes.nim"
|
||||||
|
|
||||||
# ------------------------------ Manager of temporaries ------------------
|
# ------------------------------ Manager of temporaries ------------------
|
||||||
|
|
@ -326,7 +329,7 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
|
||||||
var r = rdLoc(a)
|
var r = rdLoc(a)
|
||||||
if not takeAddr: r = ropef("(*$1)", [r])
|
if not takeAddr: r = ropef("(*$1)", [r])
|
||||||
var s = skipTypes(t, abstractInst)
|
var s = skipTypes(t, abstractInst)
|
||||||
if gCmd != cmdCompileToCpp:
|
if not p.module.compileToCpp:
|
||||||
while (s.kind == tyObject) and (s.sons[0] != nil):
|
while (s.kind == tyObject) and (s.sons[0] != nil):
|
||||||
app(r, ".Sup")
|
app(r, ".Sup")
|
||||||
s = skipTypes(s.sons[0], abstractInst)
|
s = skipTypes(s.sons[0], abstractInst)
|
||||||
|
|
@ -506,7 +509,7 @@ proc assignLocalVar(p: BProc, s: PSym) =
|
||||||
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
|
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
|
||||||
# app(decl, " GC_GUARD")
|
# app(decl, " GC_GUARD")
|
||||||
if sfVolatile in s.flags or (p.nestedTryStmts.len > 0 and
|
if sfVolatile in s.flags or (p.nestedTryStmts.len > 0 and
|
||||||
gCmd != cmdCompileToCpp):
|
not p.module.compileToCpp):
|
||||||
app(decl, " volatile")
|
app(decl, " volatile")
|
||||||
appf(decl, " $1;$n", [s.loc.r])
|
appf(decl, " $1;$n", [s.loc.r])
|
||||||
else:
|
else:
|
||||||
|
|
@ -587,8 +590,8 @@ proc initLocExpr(p: BProc, e: PNode, result: var TLoc) =
|
||||||
initLoc(result, locNone, e.typ, OnUnknown)
|
initLoc(result, locNone, e.typ, OnUnknown)
|
||||||
expr(p, e, result)
|
expr(p, e, result)
|
||||||
|
|
||||||
proc lenField: PRope {.inline.} =
|
proc lenField(p: BProc): PRope =
|
||||||
result = toRope(if gCmd != cmdCompileToCpp: "Sup.len" else: "len")
|
result = toRope(if p.module.compileToCpp: "len" else: "Sup.len")
|
||||||
|
|
||||||
include ccgcalls, "ccgstmts.nim", "ccgexprs.nim"
|
include ccgcalls, "ccgstmts.nim", "ccgexprs.nim"
|
||||||
|
|
||||||
|
|
@ -812,7 +815,12 @@ proc genProcAux(m: BModule, prc: PSym) =
|
||||||
app(generatedProc, returnStmt)
|
app(generatedProc, returnStmt)
|
||||||
app(generatedProc, ~"}$N")
|
app(generatedProc, ~"}$N")
|
||||||
app(m.s[cfsProcs], generatedProc)
|
app(m.s[cfsProcs], generatedProc)
|
||||||
|
|
||||||
|
proc crossesCppBoundary(m: BModule; sym: PSym): bool {.inline.} =
|
||||||
|
result = sfCompileToCpp in m.module.flags and
|
||||||
|
sfCompileToCpp notin sym.getModule().flags and
|
||||||
|
gCmd != cmdCompileToCpp
|
||||||
|
|
||||||
proc genProcPrototype(m: BModule, sym: PSym) =
|
proc genProcPrototype(m: BModule, sym: PSym) =
|
||||||
useHeader(m, sym)
|
useHeader(m, sym)
|
||||||
if lfNoDecl in sym.loc.flags: return
|
if lfNoDecl in sym.loc.flags: return
|
||||||
|
|
@ -824,6 +832,8 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
||||||
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
|
if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect)
|
||||||
elif not containsOrIncl(m.declaredProtos, sym.id):
|
elif not containsOrIncl(m.declaredProtos, sym.id):
|
||||||
var header = genProcHeader(m, sym)
|
var header = genProcHeader(m, sym)
|
||||||
|
if sym.typ.callConv != ccInline and crossesCppBoundary(m, sym):
|
||||||
|
header = con("extern \"C\" ", header)
|
||||||
if sfPure in sym.flags and hasNakedAttribute in CC[cCompiler].props:
|
if sfPure in sym.flags and hasNakedAttribute in CC[cCompiler].props:
|
||||||
header.app(" __attribute__((naked))")
|
header.app(" __attribute__((naked))")
|
||||||
app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header))
|
app(m.s[cfsProcHeaders], rfmt(nil, "$1;$n", header))
|
||||||
|
|
@ -915,7 +925,7 @@ proc addIntTypes(result: var PRope) {.inline.} =
|
||||||
appf(result, "#define NIM_INTBITS $1", [
|
appf(result, "#define NIM_INTBITS $1", [
|
||||||
platform.CPU[targetCPU].intSize.toRope])
|
platform.CPU[targetCPU].intSize.toRope])
|
||||||
|
|
||||||
proc getCopyright(cfilenoext: string): PRope =
|
proc getCopyright(cfile: string): PRope =
|
||||||
if optCompileOnly in gGlobalOptions:
|
if optCompileOnly in gGlobalOptions:
|
||||||
result = ropeff("/* Generated by Nim Compiler v$1 */$N" &
|
result = ropeff("/* Generated by Nim Compiler v$1 */$N" &
|
||||||
"/* (c) 2014 Andreas Rumpf */$N" &
|
"/* (c) 2014 Andreas Rumpf */$N" &
|
||||||
|
|
@ -935,10 +945,10 @@ proc getCopyright(cfilenoext: string): PRope =
|
||||||
toRope(platform.OS[targetOS].name),
|
toRope(platform.OS[targetOS].name),
|
||||||
toRope(platform.CPU[targetCPU].name),
|
toRope(platform.CPU[targetCPU].name),
|
||||||
toRope(extccomp.CC[extccomp.cCompiler].name),
|
toRope(extccomp.CC[extccomp.cCompiler].name),
|
||||||
toRope(getCompileCFileCmd(cfilenoext))])
|
toRope(getCompileCFileCmd(cfile))])
|
||||||
|
|
||||||
proc getFileHeader(cfilenoext: string): PRope =
|
proc getFileHeader(cfile: string): PRope =
|
||||||
result = getCopyright(cfilenoext)
|
result = getCopyright(cfile)
|
||||||
addIntTypes(result)
|
addIntTypes(result)
|
||||||
|
|
||||||
proc genFilenames(m: BModule): PRope =
|
proc genFilenames(m: BModule): PRope =
|
||||||
|
|
@ -1078,9 +1088,9 @@ proc registerModuleToMain(m: PSym) =
|
||||||
var
|
var
|
||||||
init = m.getInitName
|
init = m.getInitName
|
||||||
datInit = m.getDatInitName
|
datInit = m.getDatInitName
|
||||||
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
|
appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
|
||||||
"declare void $1() noinline$N", [init])
|
"declare void $1() noinline$N", [init])
|
||||||
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
|
appff(mainModProcs, "NIM_EXTERNC N_NOINLINE(void, $1)(void);$N",
|
||||||
"declare void $1() noinline$N", [datInit])
|
"declare void $1() noinline$N", [datInit])
|
||||||
if sfSystemModule notin m.flags:
|
if sfSystemModule notin m.flags:
|
||||||
appff(mainDatInit, "\t$1();$N", "call void ()* $1$n", [datInit])
|
appff(mainDatInit, "\t$1();$N", "call void ()* $1$n", [datInit])
|
||||||
|
|
@ -1092,7 +1102,7 @@ proc registerModuleToMain(m: PSym) =
|
||||||
|
|
||||||
proc genInitCode(m: BModule) =
|
proc genInitCode(m: BModule) =
|
||||||
var initname = getInitName(m.module)
|
var initname = getInitName(m.module)
|
||||||
var prc = ropeff("N_NOINLINE(void, $1)(void) {$N",
|
var prc = ropeff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
|
||||||
"define void $1() noinline {$n", [initname])
|
"define void $1() noinline {$n", [initname])
|
||||||
if m.typeNodes > 0:
|
if m.typeNodes > 0:
|
||||||
appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
|
appcg(m, m.s[cfsTypeInit1], "static #TNimNode $1[$2];$n",
|
||||||
|
|
@ -1135,7 +1145,7 @@ proc genInitCode(m: BModule) =
|
||||||
app(prc, deinitGCFrame(m.initProc))
|
app(prc, deinitGCFrame(m.initProc))
|
||||||
appf(prc, "}$N$N")
|
appf(prc, "}$N$N")
|
||||||
|
|
||||||
prc.appff("N_NOINLINE(void, $1)(void) {$N",
|
prc.appff("NIM_EXTERNC N_NOINLINE(void, $1)(void) {$N",
|
||||||
"define void $1() noinline {$n", [getDatInitName(m.module)])
|
"define void $1() noinline {$n", [getDatInitName(m.module)])
|
||||||
|
|
||||||
for i in cfsTypeInit1..cfsDynLibInit:
|
for i in cfsTypeInit1..cfsDynLibInit:
|
||||||
|
|
@ -1155,8 +1165,8 @@ proc genInitCode(m: BModule) =
|
||||||
(i.ord - '0'.ord).toRope, el)
|
(i.ord - '0'.ord).toRope, el)
|
||||||
app(m.s[cfsInitProc], ex)
|
app(m.s[cfsInitProc], ex)
|
||||||
|
|
||||||
proc genModule(m: BModule, cfilenoext: string): PRope =
|
proc genModule(m: BModule, cfile: string): PRope =
|
||||||
result = getFileHeader(cfilenoext)
|
result = getFileHeader(cfile)
|
||||||
result.app(genMergeInfo(m))
|
result.app(genMergeInfo(m))
|
||||||
|
|
||||||
generateHeaders(m)
|
generateHeaders(m)
|
||||||
|
|
@ -1297,7 +1307,11 @@ proc writeHeader(m: BModule) =
|
||||||
writeRope(result, m.filename)
|
writeRope(result, m.filename)
|
||||||
|
|
||||||
proc getCFile(m: BModule): string =
|
proc getCFile(m: BModule): string =
|
||||||
result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), cExt)
|
let ext =
|
||||||
|
if m.compileToCpp: ".cpp"
|
||||||
|
elif gCmd == cmdCompileToOC or sfCompileToObjC in m.module.flags: ".m"
|
||||||
|
else: ".c"
|
||||||
|
result = changeFileExt(completeCFilePath(m.cfilename.withPackageName), ext)
|
||||||
|
|
||||||
proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
|
proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
|
||||||
assert optSymbolFiles in gGlobalOptions
|
assert optSymbolFiles in gGlobalOptions
|
||||||
|
|
@ -1326,10 +1340,10 @@ proc finishModule(m: BModule) =
|
||||||
dec(gForwardedProcsCounter, i)
|
dec(gForwardedProcsCounter, i)
|
||||||
setLen(m.forwardedProcs, 0)
|
setLen(m.forwardedProcs, 0)
|
||||||
|
|
||||||
proc shouldRecompile(code: PRope, cfile, cfilenoext: string): bool =
|
proc shouldRecompile(code: PRope, cfile: string): bool =
|
||||||
result = true
|
result = true
|
||||||
if optForceFullMake notin gGlobalOptions:
|
if optForceFullMake notin gGlobalOptions:
|
||||||
var objFile = toObjFile(cfilenoext)
|
var objFile = toObjFile(cfile)
|
||||||
if writeRopeIfNotEqual(code, cfile): return
|
if writeRopeIfNotEqual(code, cfile): return
|
||||||
if existsFile(objFile) and os.fileNewer(objFile, cfile): result = false
|
if existsFile(objFile) and os.fileNewer(objFile, cfile): result = false
|
||||||
else:
|
else:
|
||||||
|
|
@ -1354,26 +1368,26 @@ proc writeModule(m: BModule, pending: bool) =
|
||||||
app(m.s[cfsProcHeaders], mainModProcs)
|
app(m.s[cfsProcHeaders], mainModProcs)
|
||||||
generateThreadVarsSize(m)
|
generateThreadVarsSize(m)
|
||||||
|
|
||||||
var code = genModule(m, cfilenoext)
|
var code = genModule(m, cfile)
|
||||||
when hasTinyCBackend:
|
when hasTinyCBackend:
|
||||||
if gCmd == cmdRun:
|
if gCmd == cmdRun:
|
||||||
tccgen.compileCCode(ropeToStr(code))
|
tccgen.compileCCode(ropeToStr(code))
|
||||||
return
|
return
|
||||||
|
|
||||||
if shouldRecompile(code, cfile, cfilenoext):
|
if shouldRecompile(code, cfile):
|
||||||
addFileToCompile(cfilenoext)
|
addFileToCompile(cfile)
|
||||||
elif pending and mergeRequired(m) and sfMainModule notin m.module.flags:
|
elif pending and mergeRequired(m) and sfMainModule notin m.module.flags:
|
||||||
mergeFiles(cfile, m)
|
mergeFiles(cfile, m)
|
||||||
genInitCode(m)
|
genInitCode(m)
|
||||||
finishTypeDescriptions(m)
|
finishTypeDescriptions(m)
|
||||||
var code = genModule(m, cfilenoext)
|
var code = genModule(m, cfile)
|
||||||
writeRope(code, cfile)
|
writeRope(code, cfile)
|
||||||
addFileToCompile(cfilenoext)
|
addFileToCompile(cfile)
|
||||||
elif not existsFile(toObjFile(cfilenoext)):
|
elif not existsFile(toObjFile(cfilenoext)):
|
||||||
# Consider: first compilation compiles ``system.nim`` and produces
|
# Consider: first compilation compiles ``system.nim`` and produces
|
||||||
# ``system.c`` but then compilation fails due to an error. This means
|
# ``system.c`` but then compilation fails due to an error. This means
|
||||||
# that ``system.o`` is missing, so we need to call the C compiler for it:
|
# that ``system.o`` is missing, so we need to call the C compiler for it:
|
||||||
addFileToCompile(cfilenoext)
|
addFileToCompile(cfile)
|
||||||
|
|
||||||
addFileToLink(cfilenoext)
|
addFileToLink(cfilenoext)
|
||||||
|
|
||||||
|
|
@ -1385,9 +1399,9 @@ proc updateCachedModule(m: BModule) =
|
||||||
mergeFiles(cfile, m)
|
mergeFiles(cfile, m)
|
||||||
genInitCode(m)
|
genInitCode(m)
|
||||||
finishTypeDescriptions(m)
|
finishTypeDescriptions(m)
|
||||||
var code = genModule(m, cfilenoext)
|
var code = genModule(m, cfile)
|
||||||
writeRope(code, cfile)
|
writeRope(code, cfile)
|
||||||
addFileToCompile(cfilenoext)
|
addFileToCompile(cfile)
|
||||||
|
|
||||||
addFileToLink(cfilenoext)
|
addFileToLink(cfilenoext)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -323,10 +323,7 @@ const
|
||||||
|
|
||||||
var
|
var
|
||||||
cCompiler* = ccGcc # the used compiler
|
cCompiler* = ccGcc # the used compiler
|
||||||
|
gMixedMode*: bool # true if some module triggered C++ codegen
|
||||||
cExt* = ".c" # extension of generated C/C++ files
|
|
||||||
# (can be changed to .cpp later)
|
|
||||||
|
|
||||||
cIncludes*: seq[string] = @[] # directories to search for included files
|
cIncludes*: seq[string] = @[] # directories to search for included files
|
||||||
cLibs*: seq[string] = @[] # directories to search for lib files
|
cLibs*: seq[string] = @[] # directories to search for lib files
|
||||||
cLinkedLibs*: seq[string] = @[] # libraries to link
|
cLinkedLibs*: seq[string] = @[] # libraries to link
|
||||||
|
|
@ -387,8 +384,6 @@ proc initVars*() =
|
||||||
# we need to define the symbol here, because ``CC`` may have never been set!
|
# we need to define the symbol here, because ``CC`` may have never been set!
|
||||||
for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name)
|
for i in countup(low(CC), high(CC)): undefSymbol(CC[i].name)
|
||||||
defineSymbol(CC[cCompiler].name)
|
defineSymbol(CC[cCompiler].name)
|
||||||
if gCmd == cmdCompileToCpp: cExt = ".cpp"
|
|
||||||
elif gCmd == cmdCompileToOC: cExt = ".m"
|
|
||||||
addCompileOption(getConfigVar(cCompiler, ".options.always"))
|
addCompileOption(getConfigVar(cCompiler, ".options.always"))
|
||||||
addLinkOption(getConfigVar(cCompiler, ".options.linker"))
|
addLinkOption(getConfigVar(cCompiler, ".options.linker"))
|
||||||
if len(ccompilerpath) == 0:
|
if len(ccompilerpath) == 0:
|
||||||
|
|
@ -397,9 +392,9 @@ proc initVars*() =
|
||||||
proc completeCFilePath*(cfile: string, createSubDir: bool = true): string =
|
proc completeCFilePath*(cfile: string, createSubDir: bool = true): string =
|
||||||
result = completeGeneratedFilePath(cfile, createSubDir)
|
result = completeGeneratedFilePath(cfile, createSubDir)
|
||||||
|
|
||||||
proc toObjFile*(filenameWithoutExt: string): string =
|
proc toObjFile*(filename: string): string =
|
||||||
# Object file for compilation
|
# Object file for compilation
|
||||||
result = changeFileExt(filenameWithoutExt, CC[cCompiler].objExt)
|
result = changeFileExt(filename, CC[cCompiler].objExt)
|
||||||
|
|
||||||
proc addFileToCompile*(filename: string) =
|
proc addFileToCompile*(filename: string) =
|
||||||
appendStr(toCompile, filename)
|
appendStr(toCompile, filename)
|
||||||
|
|
@ -497,6 +492,7 @@ proc getCompilerExe(compiler: TSystemCC): string =
|
||||||
|
|
||||||
proc getLinkerExe(compiler: TSystemCC): string =
|
proc getLinkerExe(compiler: TSystemCC): string =
|
||||||
result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe
|
result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe
|
||||||
|
elif gMixedMode and gCmd != cmdCompileToCpp: CC[compiler].cppCompiler
|
||||||
else: compiler.getCompilerExe
|
else: compiler.getCompilerExe
|
||||||
|
|
||||||
proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||||
|
|
@ -507,11 +503,11 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||||
|
|
||||||
if needsExeExt(): exe = addFileExt(exe, "exe")
|
if needsExeExt(): exe = addFileExt(exe, "exe")
|
||||||
if optGenDynLib in gGlobalOptions and
|
if optGenDynLib in gGlobalOptions and
|
||||||
ospNeedsPIC in platform.OS[targetOS].props:
|
ospNeedsPIC in platform.OS[targetOS].props:
|
||||||
add(options, ' ' & CC[c].pic)
|
add(options, ' ' & CC[c].pic)
|
||||||
|
|
||||||
var includeCmd, compilePattern: string
|
var includeCmd, compilePattern: string
|
||||||
if not noAbsolutePaths():
|
if not noAbsolutePaths():
|
||||||
# compute include paths:
|
# compute include paths:
|
||||||
includeCmd = CC[c].includeCmd & quoteShell(libpath)
|
includeCmd = CC[c].includeCmd & quoteShell(libpath)
|
||||||
|
|
||||||
|
|
@ -519,26 +515,27 @@ proc getCompileCFileCmd*(cfilename: string, isExternal = false): string =
|
||||||
includeCmd.add([CC[c].includeCmd, includeDir.quoteShell])
|
includeCmd.add([CC[c].includeCmd, includeDir.quoteShell])
|
||||||
|
|
||||||
compilePattern = joinPath(ccompilerpath, exe)
|
compilePattern = joinPath(ccompilerpath, exe)
|
||||||
else:
|
else:
|
||||||
includeCmd = ""
|
includeCmd = ""
|
||||||
compilePattern = c.getCompilerExe
|
compilePattern = c.getCompilerExe
|
||||||
|
|
||||||
var cfile = if noAbsolutePaths(): extractFilename(cfilename)
|
var cfile = if noAbsolutePaths(): extractFilename(cfilename)
|
||||||
else: cfilename
|
else: cfilename
|
||||||
var objfile = if not isExternal or noAbsolutePaths():
|
var objfile = if not isExternal or noAbsolutePaths():
|
||||||
toObjFile(cfile)
|
toObjFile(cfile)
|
||||||
else:
|
else:
|
||||||
completeCFilePath(toObjFile(cfile))
|
completeCFilePath(toObjFile(cfile))
|
||||||
cfile = quoteShell(addFileExt(cfile, cExt))
|
|
||||||
objfile = quoteShell(objfile)
|
objfile = quoteShell(objfile)
|
||||||
result = quoteShell(compilePattern % [
|
result = quoteShell(compilePattern % [
|
||||||
"file", cfile, "objfile", objfile, "options", options,
|
"file", cfile, "objfile", objfile, "options", options,
|
||||||
"include", includeCmd, "nimrod", getPrefixDir(), "lib", libpath])
|
"include", includeCmd, "nimrod", getPrefixDir(),
|
||||||
|
"nim", getPrefixDir(), "lib", libpath])
|
||||||
add(result, ' ')
|
add(result, ' ')
|
||||||
addf(result, CC[c].compileTmpl, [
|
addf(result, CC[c].compileTmpl, [
|
||||||
"file", cfile, "objfile", objfile,
|
"file", cfile, "objfile", objfile,
|
||||||
"options", options, "include", includeCmd,
|
"options", options, "include", includeCmd,
|
||||||
"nimrod", quoteShell(getPrefixDir()),
|
"nimrod", quoteShell(getPrefixDir()),
|
||||||
|
"nim", quoteShell(getPrefixDir()),
|
||||||
"lib", quoteShell(libpath)])
|
"lib", quoteShell(libpath)])
|
||||||
|
|
||||||
proc footprint(filename: string): TCrc32 =
|
proc footprint(filename: string): TCrc32 =
|
||||||
|
|
@ -668,7 +665,7 @@ proc callCCompiler*(projectfile: string) =
|
||||||
proc genMappingFiles(list: TLinkedList): PRope =
|
proc genMappingFiles(list: TLinkedList): PRope =
|
||||||
var it = PStrEntry(list.head)
|
var it = PStrEntry(list.head)
|
||||||
while it != nil:
|
while it != nil:
|
||||||
appf(result, "--file:r\"$1\"$N", [toRope(addFileExt(it.data, cExt))])
|
appf(result, "--file:r\"$1\"$N", [toRope(it.data)])
|
||||||
it = PStrEntry(it.next)
|
it = PStrEntry(it.next)
|
||||||
|
|
||||||
proc writeMapping*(gSymbolMapping: PRope) =
|
proc writeMapping*(gSymbolMapping: PRope) =
|
||||||
|
|
|
||||||
|
|
@ -272,13 +272,11 @@ proc mainCommand* =
|
||||||
gCmd = cmdCompileToC
|
gCmd = cmdCompileToC
|
||||||
commandCompileToC()
|
commandCompileToC()
|
||||||
of "cpp", "compiletocpp":
|
of "cpp", "compiletocpp":
|
||||||
extccomp.cExt = ".cpp"
|
|
||||||
gCmd = cmdCompileToCpp
|
gCmd = cmdCompileToCpp
|
||||||
if cCompiler == ccGcc: setCC("gcc")
|
if cCompiler == ccGcc: setCC("gcc")
|
||||||
defineSymbol("cpp")
|
defineSymbol("cpp")
|
||||||
commandCompileToC()
|
commandCompileToC()
|
||||||
of "objc", "compiletooc":
|
of "objc", "compiletooc":
|
||||||
extccomp.cExt = ".m"
|
|
||||||
gCmd = cmdCompileToOC
|
gCmd = cmdCompileToOC
|
||||||
defineSymbol("objc")
|
defineSymbol("objc")
|
||||||
commandCompileToC()
|
commandCompileToC()
|
||||||
|
|
|
||||||
|
|
@ -128,12 +128,17 @@ proc processImportCpp(s: PSym, extname: string) =
|
||||||
incl(s.flags, sfImportc)
|
incl(s.flags, sfImportc)
|
||||||
incl(s.flags, sfInfixCall)
|
incl(s.flags, sfInfixCall)
|
||||||
excl(s.flags, sfForward)
|
excl(s.flags, sfForward)
|
||||||
|
let m = s.getModule()
|
||||||
|
incl(m.flags, sfCompileToCpp)
|
||||||
|
extccomp.gMixedMode = true
|
||||||
|
|
||||||
proc processImportObjC(s: PSym, extname: string) =
|
proc processImportObjC(s: PSym, extname: string) =
|
||||||
setExternName(s, extname)
|
setExternName(s, extname)
|
||||||
incl(s.flags, sfImportc)
|
incl(s.flags, sfImportc)
|
||||||
incl(s.flags, sfNamedParamCall)
|
incl(s.flags, sfNamedParamCall)
|
||||||
excl(s.flags, sfForward)
|
excl(s.flags, sfForward)
|
||||||
|
let m = s.getModule()
|
||||||
|
incl(m.flags, sfCompileToObjC)
|
||||||
|
|
||||||
proc newEmptyStrNode(n: PNode): PNode {.noinline.} =
|
proc newEmptyStrNode(n: PNode): PNode {.noinline.} =
|
||||||
result = newNodeIT(nkStrLit, n.info, getSysType(tyString))
|
result = newNodeIT(nkStrLit, n.info, getSysType(tyString))
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Nimrod's Runtime Library
|
Nim's Runtime Library
|
||||||
(c) Copyright 2013 Andreas Rumpf
|
(c) Copyright 2014 Andreas Rumpf
|
||||||
|
|
||||||
See the file "copying.txt", included in this
|
See the file "copying.txt", included in this
|
||||||
distribution, for details about the copyright.
|
distribution, for details about the copyright.
|
||||||
|
|
@ -384,3 +384,9 @@ static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); }
|
||||||
"error: 'assert_numbits' declared as an array with a negative size" */
|
"error: 'assert_numbits' declared as an array with a negative size" */
|
||||||
typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
|
typedef int assert_numbits[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# define NIM_EXTERNC extern "C"
|
||||||
|
#else
|
||||||
|
# define NIM_EXTERNC
|
||||||
|
#endif
|
||||||
|
|
|
||||||
4
todo.txt
4
todo.txt
|
|
@ -3,8 +3,6 @@ version 0.10
|
||||||
|
|
||||||
- Test nimfix on various babel packages
|
- Test nimfix on various babel packages
|
||||||
|
|
||||||
- VM: Pegs do not work at compile-time
|
|
||||||
- VM: ptr/ref T cannot work in general
|
|
||||||
|
|
||||||
version 0.9.6
|
version 0.9.6
|
||||||
=============
|
=============
|
||||||
|
|
@ -41,6 +39,8 @@ Misc
|
||||||
Bugs
|
Bugs
|
||||||
====
|
====
|
||||||
|
|
||||||
|
- VM: Pegs do not work at compile-time
|
||||||
|
- VM: ptr/ref T cannot work in general
|
||||||
- scopes are still broken for generic instantiation!
|
- scopes are still broken for generic instantiation!
|
||||||
- bug: type conversions concerning proc types are weird
|
- bug: type conversions concerning proc types are weird
|
||||||
- compilation of niminst takes way too long. looks like a regression
|
- compilation of niminst takes way too long. looks like a regression
|
||||||
|
|
|
||||||
19
web/news.txt
19
web/news.txt
|
|
@ -52,13 +52,30 @@ News
|
||||||
- Recursive tuple types are not allowed anymore. Use ``object`` instead.
|
- Recursive tuple types are not allowed anymore. Use ``object`` instead.
|
||||||
|
|
||||||
|
|
||||||
|
Compiler Additions
|
||||||
|
------------------
|
||||||
|
|
||||||
|
- The compiler now supports *mixed* Objective C / C++ / C code generation:
|
||||||
|
The modules that use ``importCpp`` or ``importObjc`` are compiled to C++
|
||||||
|
or Objective C code, any other module is compiled to C code. This
|
||||||
|
improves interoperability.
|
||||||
|
|
||||||
|
|
||||||
Language Additions
|
Language Additions
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- There is a new ``parallel`` statement for safe fork&join parallel computing.
|
- There is a new ``parallel`` statement for safe fork&join parallel computing.
|
||||||
- ``guard`` and ``lock`` pragmas have been implemented to support safer
|
- ``guard`` and ``lock`` pragmas have been implemented to support safer
|
||||||
concurrent programming.
|
concurrent programming.
|
||||||
- ``system.writeFile`` can be used at compile-time.
|
- The following procs are now available at compile-time::
|
||||||
|
|
||||||
|
math.sqrt, math.ln, math.log10, math.log2, math.exp, math.round,
|
||||||
|
math.arccos, math.arcsin, math.arctan, math.arctan2, math.cos, math.cosh,
|
||||||
|
math.hypot, math.sinh, math.sin, math.tan, math.tanh, math.pow,
|
||||||
|
math.trunc, math.floor, math.ceil, math.fmod,
|
||||||
|
os.getEnv, os.existsEnv, os.dirExists, os.fileExists,
|
||||||
|
system.writeFile
|
||||||
|
|
||||||
|
|
||||||
Library Additions
|
Library Additions
|
||||||
-----------------
|
-----------------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue