support for C++ code generation; importcpp and importobjc pragmas
This commit is contained in:
parent
7748dbc0b2
commit
5131b3cea4
29 changed files with 512 additions and 189 deletions
|
|
@ -189,9 +189,7 @@ type
|
||||||
type
|
type
|
||||||
TSymFlag* = enum # already 29 flags!
|
TSymFlag* = enum # already 29 flags!
|
||||||
sfUsed, # read access of sym (for warnings) or simply used
|
sfUsed, # read access of sym (for warnings) or simply used
|
||||||
sfStar, # symbol has * visibility
|
sfExported, # symbol is exported from module
|
||||||
sfMinus, # symbol has - visibility
|
|
||||||
sfInInterface, # symbol is in interface section declared
|
|
||||||
sfFromGeneric, # symbol is instantiation of a generic; this is needed
|
sfFromGeneric, # symbol is instantiation of a generic; this is needed
|
||||||
# for symbol file generation; such symbols should always
|
# for symbol file generation; such symbols should always
|
||||||
# be written into the ROD file
|
# be written into the ROD file
|
||||||
|
|
@ -221,7 +219,11 @@ type
|
||||||
sfThreadVar, # variable is a thread variable
|
sfThreadVar, # variable is a thread variable
|
||||||
sfMerge, # proc can be merged with itself
|
sfMerge, # proc can be merged with itself
|
||||||
sfDeadCodeElim, # dead code elimination for the module is turned on
|
sfDeadCodeElim, # dead code elimination for the module is turned on
|
||||||
sfBorrow # proc is borrowed
|
sfBorrow, # proc is borrowed
|
||||||
|
sfInfixCall, # symbol needs infix call syntax in target language;
|
||||||
|
# for interfacing with C++, JS
|
||||||
|
sfNamedParamCall # symbol needs named parameter call syntax in target
|
||||||
|
# language; for interfacing with Objective C
|
||||||
|
|
||||||
TSymFlags* = set[TSymFlag]
|
TSymFlags* = set[TSymFlag]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
proc lenField: PRope {.inline.} =
|
||||||
|
result = toRope(if gCmd != cmdCompileToCpp: "Sup.len" else: "len")
|
||||||
|
|
||||||
# -------------------------- constant expressions ------------------------
|
# -------------------------- constant expressions ------------------------
|
||||||
|
|
||||||
proc intLiteral(i: biggestInt): PRope =
|
proc intLiteral(i: biggestInt): PRope =
|
||||||
|
|
@ -682,12 +685,12 @@ proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) =
|
||||||
if (optBoundsCheck in p.options):
|
if (optBoundsCheck in p.options):
|
||||||
if ty.kind == tyString:
|
if ty.kind == tyString:
|
||||||
appcg(p, cpsStmts,
|
appcg(p, cpsStmts,
|
||||||
"if ((NU)($1) > (NU)($2->Sup.len)) #raiseIndexError();$n",
|
"if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n",
|
||||||
[rdLoc(b), rdLoc(a)])
|
[rdLoc(b), rdLoc(a), lenField()])
|
||||||
else:
|
else:
|
||||||
appcg(p, cpsStmts,
|
appcg(p, cpsStmts,
|
||||||
"if ((NU)($1) >= (NU)($2->Sup.len)) #raiseIndexError();$n",
|
"if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n",
|
||||||
[rdLoc(b), rdLoc(a)])
|
[rdLoc(b), rdLoc(a), lenField()])
|
||||||
if d.k == locNone: d.s = OnHeap
|
if d.k == locNone: d.s = OnHeap
|
||||||
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}:
|
||||||
a.r = ropef("(*$1)", [a.r])
|
a.r = ropef("(*$1)", [a.r])
|
||||||
|
|
@ -781,29 +784,12 @@ proc genEcho(p: BProc, n: PNode) =
|
||||||
appcg(p, cpsStmts, "printf($1$2);$n", [
|
appcg(p, cpsStmts, "printf($1$2);$n", [
|
||||||
makeCString(repeatStr(n.len-1, "%s") & tnl), args])
|
makeCString(repeatStr(n.len-1, "%s") & tnl), args])
|
||||||
|
|
||||||
proc genCall(p: BProc, t: PNode, d: var TLoc) =
|
proc fixupCall(p: BProc, t: PNode, d: var TLoc, pl: PRope) =
|
||||||
var op, a: TLoc
|
var pl = pl
|
||||||
# this is a hotspot in the compiler
|
|
||||||
initLocExpr(p, t.sons[0], op)
|
|
||||||
var pl = con(op.r, "(")
|
|
||||||
var typ = t.sons[0].typ # getUniqueType() is too expensive here!
|
var typ = t.sons[0].typ # getUniqueType() is too expensive here!
|
||||||
assert(typ.kind == tyProc)
|
|
||||||
var invalidRetType = isInvalidReturnType(typ.sons[0])
|
|
||||||
var length = sonsLen(t)
|
|
||||||
for i in countup(1, length - 1):
|
|
||||||
initLocExpr(p, t.sons[i], a) # generate expression for param
|
|
||||||
assert(sonsLen(typ) == sonsLen(typ.n))
|
|
||||||
if (i < sonsLen(typ)):
|
|
||||||
assert(typ.n.sons[i].kind == nkSym)
|
|
||||||
var param = typ.n.sons[i].sym
|
|
||||||
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
|
|
||||||
else: app(pl, rdLoc(a))
|
|
||||||
else:
|
|
||||||
app(pl, rdLoc(a))
|
|
||||||
if i < length - 1: app(pl, ", ")
|
|
||||||
if typ.sons[0] != nil:
|
if typ.sons[0] != nil:
|
||||||
if invalidRetType:
|
if isInvalidReturnType(typ.sons[0]):
|
||||||
if length > 1: app(pl, ", ")
|
if sonsLen(t) > 1: app(pl, ", ")
|
||||||
# beware of 'result = p(result)'. We always allocate a temporary:
|
# beware of 'result = p(result)'. We always allocate a temporary:
|
||||||
if d.k in {locTemp, locNone}:
|
if d.k in {locTemp, locNone}:
|
||||||
# We already got a temp. Great, special case it:
|
# We already got a temp. Great, special case it:
|
||||||
|
|
@ -833,6 +819,126 @@ proc genCall(p: BProc, t: PNode, d: var TLoc) =
|
||||||
app(p.s[cpsStmts], pl)
|
app(p.s[cpsStmts], pl)
|
||||||
app(p.s[cpsStmts], ';' & tnl)
|
app(p.s[cpsStmts], ';' & tnl)
|
||||||
|
|
||||||
|
proc genCall(p: BProc, t: PNode, d: var TLoc) =
|
||||||
|
var op, a: TLoc
|
||||||
|
# this is a hotspot in the compiler
|
||||||
|
initLocExpr(p, t.sons[0], op)
|
||||||
|
var pl = con(op.r, "(")
|
||||||
|
var typ = t.sons[0].typ # getUniqueType() is too expensive here!
|
||||||
|
assert(typ.kind == tyProc)
|
||||||
|
var length = sonsLen(t)
|
||||||
|
for i in countup(1, length - 1):
|
||||||
|
initLocExpr(p, t.sons[i], a) # generate expression for param
|
||||||
|
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||||
|
if i < sonsLen(typ):
|
||||||
|
assert(typ.n.sons[i].kind == nkSym)
|
||||||
|
var param = typ.n.sons[i].sym
|
||||||
|
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
|
||||||
|
else: app(pl, rdLoc(a))
|
||||||
|
else:
|
||||||
|
app(pl, rdLoc(a))
|
||||||
|
if i < length - 1: app(pl, ", ")
|
||||||
|
fixupCall(p, t, d, pl)
|
||||||
|
|
||||||
|
proc genInfixCall(p: BProc, t: PNode, d: var TLoc) =
|
||||||
|
var op, a: TLoc
|
||||||
|
initLocExpr(p, t.sons[0], op)
|
||||||
|
var pl: PRope = nil
|
||||||
|
var typ = t.sons[0].typ # getUniqueType() is too expensive here!
|
||||||
|
assert(typ.kind == tyProc)
|
||||||
|
var length = sonsLen(t)
|
||||||
|
initLocExpr(p, t.sons[1], a) # generate expression for first param
|
||||||
|
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||||
|
|
||||||
|
var param = typ.n.sons[1].sym
|
||||||
|
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
|
||||||
|
else: app(pl, rdLoc(a))
|
||||||
|
|
||||||
|
if skipTypes(param.typ, {tyGenericInst}).kind == tyPtr: app(pl, "->")
|
||||||
|
else: app(pl, ".")
|
||||||
|
app(pl, op.r)
|
||||||
|
app(pl, "(")
|
||||||
|
for i in countup(2, length - 1):
|
||||||
|
initLocExpr(p, t.sons[i], a) # generate expression for param
|
||||||
|
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||||
|
if i < sonsLen(typ):
|
||||||
|
assert(typ.n.sons[i].kind == nkSym)
|
||||||
|
var param = typ.n.sons[i].sym
|
||||||
|
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
|
||||||
|
else: app(pl, rdLoc(a))
|
||||||
|
else:
|
||||||
|
app(pl, rdLoc(a))
|
||||||
|
if i < length - 1: app(pl, ", ")
|
||||||
|
fixupCall(p, t, d, pl)
|
||||||
|
|
||||||
|
proc genNamedParamCall(p: BProc, t: PNode, d: var TLoc) =
|
||||||
|
# generates a crappy ObjC call
|
||||||
|
var op, a: TLoc
|
||||||
|
initLocExpr(p, t.sons[0], op)
|
||||||
|
var pl = toRope"["
|
||||||
|
var typ = t.sons[0].typ # getUniqueType() is too expensive here!
|
||||||
|
assert(typ.kind == tyProc)
|
||||||
|
var length = sonsLen(t)
|
||||||
|
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||||
|
|
||||||
|
if length > 1:
|
||||||
|
initLocExpr(p, t.sons[1], a)
|
||||||
|
var param = typ.n.sons[1].sym
|
||||||
|
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
|
||||||
|
else: app(pl, rdLoc(a))
|
||||||
|
app(pl, " ")
|
||||||
|
app(pl, op.r)
|
||||||
|
if length > 2:
|
||||||
|
initLocExpr(p, t.sons[2], a)
|
||||||
|
app(pl, ": ")
|
||||||
|
var param = typ.n.sons[2].sym
|
||||||
|
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
|
||||||
|
else: app(pl, rdLoc(a))
|
||||||
|
for i in countup(3, length-1):
|
||||||
|
initLocExpr(p, t.sons[i], a) # generate expression for param
|
||||||
|
assert(sonsLen(typ) == sonsLen(typ.n))
|
||||||
|
if i >= sonsLen(typ):
|
||||||
|
InternalError(t.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, ": ")
|
||||||
|
if ccgIntroducedPtr(param): app(pl, addrLoc(a))
|
||||||
|
else: app(pl, rdLoc(a))
|
||||||
|
if typ.sons[0] != nil:
|
||||||
|
if isInvalidReturnType(typ.sons[0]):
|
||||||
|
if sonsLen(t) > 1: app(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)
|
||||||
|
app(pl, "Result: ")
|
||||||
|
app(pl, addrLoc(d))
|
||||||
|
app(pl, "]")
|
||||||
|
app(p.s[cpsStmts], pl)
|
||||||
|
app(p.s[cpsStmts], ';' & tnl)
|
||||||
|
else:
|
||||||
|
var tmp: TLoc
|
||||||
|
getTemp(p, typ.sons[0], tmp)
|
||||||
|
app(pl, addrLoc(tmp))
|
||||||
|
app(pl, "]")
|
||||||
|
app(p.s[cpsStmts], pl)
|
||||||
|
app(p.s[cpsStmts], ';' & tnl)
|
||||||
|
genAssignment(p, d, tmp, {}) # no need for deep copying
|
||||||
|
else:
|
||||||
|
app(pl, "]")
|
||||||
|
if d.k == locNone: getTemp(p, typ.sons[0], d)
|
||||||
|
assert(d.t != nil) # generate an assignment to d:
|
||||||
|
var list: TLoc
|
||||||
|
initLoc(list, locCall, nil, OnUnknown)
|
||||||
|
list.r = pl
|
||||||
|
genAssignment(p, d, list, {}) # no need for deep copying
|
||||||
|
else:
|
||||||
|
app(pl, "]")
|
||||||
|
app(p.s[cpsStmts], pl)
|
||||||
|
app(p.s[cpsStmts], ';' & tnl)
|
||||||
|
|
||||||
proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
|
proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
|
||||||
# <Nimrod code>
|
# <Nimrod code>
|
||||||
# s = 'Hello ' & name & ', how do you feel?' & 'z'
|
# s = 'Hello ' & name & ', how do you feel?' & 'z'
|
||||||
|
|
@ -865,7 +971,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->Sup.len + ", [rdLoc(a)])
|
appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
|
||||||
appcg(p.module, appends, "#appendString($1, $2);$n", [tmp.r, rdLoc(a)])
|
appcg(p.module, appends, "#appendString($1, $2);$n", [tmp.r, rdLoc(a)])
|
||||||
appcg(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, toRope(L)])
|
appcg(p, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, toRope(L)])
|
||||||
app(p.s[cpsStmts], appends)
|
app(p.s[cpsStmts], appends)
|
||||||
|
|
@ -906,7 +1012,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->Sup.len + ", [rdLoc(a)])
|
appf(lens, "$1->$2 + ", [rdLoc(a), lenField()])
|
||||||
appcg(p.module, appends, "#appendString($1, $2);$n",
|
appcg(p.module, appends, "#appendString($1, $2);$n",
|
||||||
[rdLoc(dest), rdLoc(a)])
|
[rdLoc(dest), rdLoc(a)])
|
||||||
appcg(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
|
appcg(p, cpsStmts, "$1 = #resizeString($1, $2$3);$n",
|
||||||
|
|
@ -925,7 +1031,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
|
||||||
getTypeDesc(p.module, skipTypes(e.sons[1].typ, abstractVar)),
|
getTypeDesc(p.module, skipTypes(e.sons[1].typ, abstractVar)),
|
||||||
getTypeDesc(p.module, skipTypes(e.sons[2].Typ, abstractVar))])
|
getTypeDesc(p.module, skipTypes(e.sons[2].Typ, abstractVar))])
|
||||||
initLoc(dest, locExpr, b.t, OnHeap)
|
initLoc(dest, locExpr, b.t, OnHeap)
|
||||||
dest.r = ropef("$1->data[$1->Sup.len-1]", [rdLoc(a)])
|
dest.r = ropef("$1->data[$1->$2-1]", [rdLoc(a), lenField()])
|
||||||
genAssignment(p, dest, b, {needToCopy, afDestIsNil})
|
genAssignment(p, dest, b, {needToCopy, afDestIsNil})
|
||||||
|
|
||||||
proc genReset(p: BProc, n: PNode) =
|
proc genReset(p: BProc, n: PNode) =
|
||||||
|
|
@ -984,7 +1090,8 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||||
r = ropecg(p.module, "(($1) && #isObj($2.m_type, $3))",
|
r = ropecg(p.module, "(($1) && #isObj($2.m_type, $3))",
|
||||||
[nilCheck, r, genTypeInfo(p.module, dest)])
|
[nilCheck, r, genTypeInfo(p.module, dest)])
|
||||||
else:
|
else:
|
||||||
r = ropecg(p.module, "#isObj($1.m_type, $2)", [r, genTypeInfo(p.module, dest)])
|
r = ropecg(p.module, "#isObj($1.m_type, $2)",
|
||||||
|
[r, genTypeInfo(p.module, dest)])
|
||||||
putIntoDest(p, d, getSysType(tyBool), r)
|
putIntoDest(p, d, getSysType(tyBool), r)
|
||||||
|
|
||||||
proc genOf(p: BProc, n: PNode, d: var TLoc) =
|
proc genOf(p: BProc, n: PNode, d: var TLoc) =
|
||||||
|
|
@ -1041,7 +1148,8 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
case a.t.kind
|
case a.t.kind
|
||||||
of tyOpenArray: putIntoDest(p, b, e.typ, rdLoc(a))
|
of tyOpenArray: putIntoDest(p, b, e.typ, rdLoc(a))
|
||||||
of tyString, tySequence:
|
of tyString, tySequence:
|
||||||
putIntoDest(p, b, e.typ, ropef("$1->data, $1->Sup.len", [rdLoc(a)]))
|
putIntoDest(p, b, e.typ,
|
||||||
|
ropef("$1->data, $1->$2", [rdLoc(a), lenField()]))
|
||||||
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))]))
|
||||||
|
|
@ -1080,8 +1188,12 @@ 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 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:
|
||||||
|
if op == mHigh: unaryExpr(p, e, d, "($1->len-1)")
|
||||||
|
else: unaryExpr(p, e, d, "$1->len")
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
# YYY: length(sideeffect) is optimized away incorrectly?
|
# YYY: length(sideeffect) is optimized away incorrectly?
|
||||||
if op == mHigh: putIntoDest(p, d, e.typ, toRope(lastOrd(Typ)))
|
if op == mHigh: putIntoDest(p, d, e.typ, toRope(lastOrd(Typ)))
|
||||||
|
|
@ -1289,7 +1401,7 @@ proc passToOpenArray(p: BProc, n: PNode, d: var TLoc) =
|
||||||
putIntoDest(p, d, dest, ropef("$1, $1Len0", [rdLoc(a)]))
|
putIntoDest(p, d, dest, ropef("$1, $1Len0", [rdLoc(a)]))
|
||||||
of tyString, tySequence:
|
of tyString, tySequence:
|
||||||
initLocExpr(p, n.sons[0], a)
|
initLocExpr(p, n.sons[0], a)
|
||||||
putIntoDest(p, d, dest, ropef("$1->data, $1->Sup.len", [rdLoc(a)]))
|
putIntoDest(p, d, dest, ropef("$1->data, $1->$2", [rdLoc(a), lenField()]))
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
initLocExpr(p, n.sons[0], a)
|
initLocExpr(p, n.sons[0], a)
|
||||||
putIntoDest(p, d, dest, ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
|
putIntoDest(p, d, dest, ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
|
||||||
|
|
@ -1314,10 +1426,12 @@ proc genStrEquals(p: BProc, e: PNode, d: var TLoc) =
|
||||||
binaryExpr(p, e, d, "($1 == $2)")
|
binaryExpr(p, e, d, "($1 == $2)")
|
||||||
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, ropef("(($1) && ($1)->Sup.len == 0)", [rdLoc(x)]))
|
putIntoDest(p, d, e.typ,
|
||||||
|
ropef("(($1) && ($1)->$2 == 0)", [rdLoc(x), lenField()]))
|
||||||
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, ropef("(($1) && ($1)->Sup.len == 0)", [rdLoc(x)]))
|
putIntoDest(p, d, e.typ,
|
||||||
|
ropef("(($1) && ($1)->$2 == 0)", [rdLoc(x), lenField()]))
|
||||||
else:
|
else:
|
||||||
binaryExpr(p, e, d, "#eqStrings($1, $2)")
|
binaryExpr(p, e, d, "#eqStrings($1, $2)")
|
||||||
|
|
||||||
|
|
@ -1678,8 +1792,13 @@ proc expr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
putIntoDest(p, d, e.typ, genLiteral(p, e))
|
putIntoDest(p, d, e.typ, genLiteral(p, e))
|
||||||
of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkPostfix, nkCommand,
|
of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkPostfix, nkCommand,
|
||||||
nkCallStrLit:
|
nkCallStrLit:
|
||||||
if (e.sons[0].kind == nkSym) and (e.sons[0].sym.magic != mNone):
|
if e.sons[0].kind == nkSym and e.sons[0].sym.magic != mNone:
|
||||||
genMagicExpr(p, e, d, e.sons[0].sym.magic)
|
genMagicExpr(p, e, d, e.sons[0].sym.magic)
|
||||||
|
elif e.sons[0].kind == nkSym and sfInfixCall in e.sons[0].sym.flags and
|
||||||
|
e.len >= 2:
|
||||||
|
genInfixCall(p, e, d)
|
||||||
|
elif e.sons[0].kind == nkSym and sfNamedParamCall in e.sons[0].sym.flags:
|
||||||
|
genNamedParamCall(p, e, d)
|
||||||
else:
|
else:
|
||||||
genCall(p, e, d)
|
genCall(p, e, d)
|
||||||
of nkCurly: genSetConstr(p, e, d)
|
of nkCurly: genSetConstr(p, e, d)
|
||||||
|
|
|
||||||
|
|
@ -218,9 +218,9 @@ proc genBreakStmt(p: BProc, t: PNode) =
|
||||||
appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.blocks[idx].id)])
|
appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.blocks[idx].id)])
|
||||||
|
|
||||||
proc getRaiseFrmt(p: BProc): string =
|
proc getRaiseFrmt(p: BProc): string =
|
||||||
if gCmd == cmdCompileToCpp:
|
#if gCmd == cmdCompileToCpp:
|
||||||
result = "throw #nimException($1, $2);$n"
|
# result = "throw #nimException($1, $2);$n"
|
||||||
else:
|
#else:
|
||||||
result = "#raiseException((#E_Base*)$1, $2);$n"
|
result = "#raiseException((#E_Base*)$1, $2);$n"
|
||||||
|
|
||||||
proc genRaiseStmt(p: BProc, t: PNode) =
|
proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
|
|
@ -234,9 +234,9 @@ proc genRaiseStmt(p: BProc, t: PNode) =
|
||||||
else:
|
else:
|
||||||
genLineDir(p, t)
|
genLineDir(p, t)
|
||||||
# reraise the last exception:
|
# reraise the last exception:
|
||||||
if gCmd == cmdCompileToCpp:
|
#if gCmd == cmdCompileToCpp:
|
||||||
appcg(p, cpsStmts, "throw;" & tnl)
|
# appcg(p, cpsStmts, "throw;" & tnl)
|
||||||
else:
|
#else:
|
||||||
appcg(p, cpsStmts, "#reraiseException();" & tnl)
|
appcg(p, cpsStmts, "#reraiseException();" & tnl)
|
||||||
|
|
||||||
proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
|
proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
|
||||||
|
|
@ -491,72 +491,6 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
|
||||||
if rethrowFlag != nil:
|
if rethrowFlag != nil:
|
||||||
appf(p.s[cpsStmts], "if ($1) { throw; }$n", [rethrowFlag])
|
appf(p.s[cpsStmts], "if ($1) { throw; }$n", [rethrowFlag])
|
||||||
|
|
||||||
proc genTryStmtCpp2(p: BProc, t: PNode) =
|
|
||||||
# code to generate:
|
|
||||||
#
|
|
||||||
# TSafePoint sp;
|
|
||||||
# pushSafePoint(&sp);
|
|
||||||
# sp.status = setjmp(sp.context);
|
|
||||||
# if (sp.status == 0) {
|
|
||||||
# myDiv(4, 9);
|
|
||||||
# popSafePoint();
|
|
||||||
# } else {
|
|
||||||
# popSafePoint();
|
|
||||||
# /* except DivisionByZero: */
|
|
||||||
# if (sp.status == DivisionByZero) {
|
|
||||||
# printf('Division by Zero\n');
|
|
||||||
# clearException();
|
|
||||||
# } else {
|
|
||||||
# clearException();
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
# /* finally: */
|
|
||||||
# printf('fin!\n');
|
|
||||||
# if (exception not cleared)
|
|
||||||
# propagateCurrentException();
|
|
||||||
genLineDir(p, t)
|
|
||||||
var safePoint = getTempName()
|
|
||||||
discard cgsym(p.module, "E_Base")
|
|
||||||
appcg(p, cpsLocals, "#TSafePoint $1;$n", [safePoint])
|
|
||||||
appcg(p, cpsStmts, "#pushSafePoint(&$1);$n" &
|
|
||||||
"$1.status = setjmp($1.context);$n", [safePoint])
|
|
||||||
if optStackTrace in p.Options:
|
|
||||||
appcg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
|
|
||||||
appf(p.s[cpsStmts], "if ($1.status == 0) {$n", [safePoint])
|
|
||||||
var length = sonsLen(t)
|
|
||||||
add(p.nestedTryStmts, t)
|
|
||||||
genStmts(p, t.sons[0])
|
|
||||||
appcg(p, cpsStmts, "#popSafePoint();$n} else {$n#popSafePoint();$n")
|
|
||||||
var i = 1
|
|
||||||
while (i < length) and (t.sons[i].kind == nkExceptBranch):
|
|
||||||
var blen = sonsLen(t.sons[i])
|
|
||||||
if blen == 1:
|
|
||||||
# general except section:
|
|
||||||
if i > 1: app(p.s[cpsStmts], "else {" & tnl)
|
|
||||||
genStmts(p, t.sons[i].sons[0])
|
|
||||||
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();$n", [safePoint])
|
|
||||||
if i > 1: app(p.s[cpsStmts], '}' & tnl)
|
|
||||||
else:
|
|
||||||
var orExpr: PRope = nil
|
|
||||||
for j in countup(0, blen - 2):
|
|
||||||
assert(t.sons[i].sons[j].kind == nkType)
|
|
||||||
if orExpr != nil: app(orExpr, "||")
|
|
||||||
appcg(p.module, orExpr,
|
|
||||||
"#isObj(#getCurrentException()->Sup.m_type, $1)",
|
|
||||||
[genTypeInfo(p.module, t.sons[i].sons[j].typ)])
|
|
||||||
if i > 1: app(p.s[cpsStmts], "else ")
|
|
||||||
appf(p.s[cpsStmts], "if ($1) {$n", [orExpr])
|
|
||||||
genStmts(p, t.sons[i].sons[blen-1])
|
|
||||||
# code to clear the exception:
|
|
||||||
appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();}$n",
|
|
||||||
[safePoint])
|
|
||||||
inc(i)
|
|
||||||
app(p.s[cpsStmts], '}' & tnl) # end of if statement
|
|
||||||
discard pop(p.nestedTryStmts)
|
|
||||||
if i < length and t.sons[i].kind == nkFinally:
|
|
||||||
genStmts(p, t.sons[i].sons[0])
|
|
||||||
appcg(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
|
|
||||||
|
|
||||||
proc genTryStmt(p: BProc, t: PNode) =
|
proc genTryStmt(p: BProc, t: PNode) =
|
||||||
# code to generate:
|
# code to generate:
|
||||||
#
|
#
|
||||||
|
|
@ -655,7 +589,7 @@ proc genEmit(p: BProc, t: PNode) =
|
||||||
var s = genAsmOrEmitStmt(p, t.sons[1])
|
var s = genAsmOrEmitStmt(p, t.sons[1])
|
||||||
if p.prc == nil:
|
if p.prc == nil:
|
||||||
# top level emit pragma?
|
# top level emit pragma?
|
||||||
app(p.module.s[cfsProcs], s)
|
app(p.module.s[cfsProcHeaders], s)
|
||||||
else:
|
else:
|
||||||
app(p.s[cpsStmts], s)
|
app(p.s[cpsStmts], s)
|
||||||
|
|
||||||
|
|
@ -768,8 +702,9 @@ proc genStmts(p: BProc, t: PNode) =
|
||||||
initLocExpr(p, t.sons[0], a)
|
initLocExpr(p, t.sons[0], a)
|
||||||
of nkAsmStmt: genAsmStmt(p, t)
|
of nkAsmStmt: genAsmStmt(p, t)
|
||||||
of nkTryStmt:
|
of nkTryStmt:
|
||||||
if gCmd == cmdCompileToCpp: genTryStmtCpp(p, t)
|
#if gCmd == cmdCompileToCpp: genTryStmtCpp(p, t)
|
||||||
else: genTryStmt(p, t)
|
#else:
|
||||||
|
genTryStmt(p, t)
|
||||||
of nkRaiseStmt: genRaiseStmt(p, t)
|
of nkRaiseStmt: genRaiseStmt(p, t)
|
||||||
of nkTypeSection:
|
of nkTypeSection:
|
||||||
# we have to emit the type information for object types here to support
|
# we have to emit the type information for object types here to support
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,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:
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,8 @@ Options:
|
||||||
AdvancedUsage = """
|
AdvancedUsage = """
|
||||||
Advanced commands:
|
Advanced commands:
|
||||||
compileToC, cc compile project with C code generator
|
compileToC, cc compile project with C code generator
|
||||||
compileToOC, oc compile project to Objective C code
|
compileToCpp, cpp compile project to C++ code
|
||||||
|
compileToOC, objc compile project to Objective C code
|
||||||
rst2html convert a reStructuredText file to HTML
|
rst2html convert a reStructuredText file to HTML
|
||||||
rst2tex convert a reStructuredText file to TeX
|
rst2tex convert a reStructuredText file to TeX
|
||||||
run run the project (with Tiny C backend; buggy!)
|
run run the project (with Tiny C backend; buggy!)
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@ proc isVisible(n: PNode): bool =
|
||||||
var v = n.sons[0].ident
|
var v = n.sons[0].ident
|
||||||
result = (v.id == ord(wStar)) or (v.id == ord(wMinus))
|
result = (v.id == ord(wStar)) or (v.id == ord(wMinus))
|
||||||
elif n.kind == nkSym:
|
elif n.kind == nkSym:
|
||||||
result = sfInInterface in n.sym.flags
|
result = sfExported in n.sym.flags
|
||||||
elif n.kind == nkPragmaExpr:
|
elif n.kind == nkPragmaExpr:
|
||||||
result = isVisible(n.sons[0])
|
result = isVisible(n.sons[0])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1349,10 +1349,10 @@ proc gen(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
of nkNilLit:
|
of nkNilLit:
|
||||||
if mapType(n.typ) == etyBaseIndex:
|
if mapType(n.typ) == etyBaseIndex:
|
||||||
r.kind = etyBaseIndex
|
r.kind = etyBaseIndex
|
||||||
r.com = toRope("null")
|
r.com = toRope"null"
|
||||||
r.res = toRope("0")
|
r.res = toRope"0"
|
||||||
else:
|
else:
|
||||||
r.res = toRope("null")
|
r.res = toRope"null"
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if skipTypes(n.typ, abstractVarRange).kind == tyString:
|
if skipTypes(n.typ, abstractVarRange).kind == tyString:
|
||||||
useMagic(p, "cstrToNimstr")
|
useMagic(p, "cstrToNimstr")
|
||||||
|
|
@ -1361,11 +1361,11 @@ proc gen(p: var TProc, n: PNode, r: var TCompRes) =
|
||||||
r.res = makeCString(n.strVal)
|
r.res = makeCString(n.strVal)
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkFloatLit..nkFloat64Lit:
|
||||||
f = n.floatVal
|
f = n.floatVal
|
||||||
if f != f: r.res = toRope("NaN")
|
if f != f: r.res = toRope"NaN"
|
||||||
elif f == 0.0: r.res = toRope("0.0")
|
elif f == 0.0: r.res = toRope"0.0"
|
||||||
elif f == 0.5 * f:
|
elif f == 0.5 * f:
|
||||||
if f > 0.0: r.res = toRope("Infinity")
|
if f > 0.0: r.res = toRope"Infinity"
|
||||||
else: r.res = toRope("-Infinity")
|
else: r.res = toRope"-Infinity"
|
||||||
else: r.res = toRope(f.ToStrMaxPrecision)
|
else: r.res = toRope(f.ToStrMaxPrecision)
|
||||||
of nkBlockExpr: genBlock(p, n, r)
|
of nkBlockExpr: genBlock(p, n, r)
|
||||||
of nkIfExpr: genIfExpr(p, n, r)
|
of nkIfExpr: genIfExpr(p, n, r)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ type
|
||||||
tkBind, tkBlock, tkBreak, tkCase, tkCast,
|
tkBind, tkBlock, tkBreak, tkCase, tkCast,
|
||||||
tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkElif,
|
tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkElif,
|
||||||
tkElse, tkEnd, tkEnum, tkExcept, tkFinally, tkFor, tkFrom, tkGeneric, tkIf,
|
tkElse, tkEnd, tkEnum, tkExcept, tkFinally, tkFor, tkFrom, tkGeneric, tkIf,
|
||||||
tkImplies, tkImport, tkIn, tkInclude, tkIs, tkIsnot, tkIterator,
|
tkImport, tkIn, tkInclude, tkIs, tkIsnot, tkIterator,
|
||||||
tkLambda, tkLet,
|
tkLambda, tkLet,
|
||||||
tkMacro, tkMethod, tkMod, tkNil, tkNot, tkNotin, tkObject, tkOf, tkOr,
|
tkMacro, tkMethod, tkMod, tkNil, tkNot, tkNotin, tkObject, tkOf, tkOr,
|
||||||
tkOut, tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShl, tkShr, tkTemplate,
|
tkOut, tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShl, tkShr, tkTemplate,
|
||||||
|
|
@ -63,7 +63,7 @@ const
|
||||||
"bind", "block", "break", "case", "cast",
|
"bind", "block", "break", "case", "cast",
|
||||||
"const", "continue", "converter", "discard", "distinct", "div", "elif",
|
"const", "continue", "converter", "discard", "distinct", "div", "elif",
|
||||||
"else", "end", "enum", "except", "finally", "for", "from", "generic", "if",
|
"else", "end", "enum", "except", "finally", "for", "from", "generic", "if",
|
||||||
"implies", "import", "in", "include", "is", "isnot", "iterator",
|
"import", "in", "include", "is", "isnot", "iterator",
|
||||||
"lambda", "let",
|
"lambda", "let",
|
||||||
"macro", "method", "mod", "nil", "not", "notin", "object", "of", "or",
|
"macro", "method", "mod", "nil", "not", "notin", "object", "of", "or",
|
||||||
"out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template",
|
"out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template",
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ proc CloseScope*(tab: var TSymTab) =
|
||||||
while s != nil:
|
while s != nil:
|
||||||
if sfForward in s.flags:
|
if sfForward in s.flags:
|
||||||
LocalError(s.info, errImplOfXexpected, getSymRepr(s))
|
LocalError(s.info, errImplOfXexpected, getSymRepr(s))
|
||||||
elif {sfUsed, sfInInterface} * s.flags == {} and optHints in s.options:
|
elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options:
|
||||||
# BUGFIX: check options in s!
|
# BUGFIX: check options in s!
|
||||||
if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}:
|
if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}:
|
||||||
Message(s.info, hintXDeclaredButNotUsed, getSymRepr(s))
|
Message(s.info, hintXDeclaredButNotUsed, getSymRepr(s))
|
||||||
|
|
@ -74,7 +74,7 @@ proc addDeclAt*(c: PContext, sym: PSym, at: Natural) =
|
||||||
LocalError(sym.info, errAttemptToRedefine, sym.Name.s)
|
LocalError(sym.info, errAttemptToRedefine, sym.Name.s)
|
||||||
|
|
||||||
proc AddInterfaceDeclAux(c: PContext, sym: PSym) =
|
proc AddInterfaceDeclAux(c: PContext, sym: PSym) =
|
||||||
if (sfInInterface in sym.flags):
|
if sfExported in sym.flags:
|
||||||
# add to interface:
|
# add to interface:
|
||||||
if c.module == nil: InternalError(sym.info, "AddInterfaceDeclAux")
|
if c.module == nil: InternalError(sym.info, "AddInterfaceDeclAux")
|
||||||
StrTableAdd(c.module.tab, sym)
|
StrTableAdd(c.module.tab, sym)
|
||||||
|
|
|
||||||
|
|
@ -199,12 +199,12 @@ proc MainCommand(cmd, filename: string) =
|
||||||
gCmd = cmdCompileToC
|
gCmd = cmdCompileToC
|
||||||
wantFile(filename)
|
wantFile(filename)
|
||||||
CommandCompileToC(filename)
|
CommandCompileToC(filename)
|
||||||
of "compiletocpp":
|
of "cpp", "compiletocpp":
|
||||||
extccomp.cExt = ".cpp"
|
extccomp.cExt = ".cpp"
|
||||||
gCmd = cmdCompileToCpp
|
gCmd = cmdCompileToCpp
|
||||||
wantFile(filename)
|
wantFile(filename)
|
||||||
CommandCompileToC(filename)
|
CommandCompileToC(filename)
|
||||||
of "oc", "compiletooc":
|
of "objc", "compiletooc":
|
||||||
extccomp.cExt = ".m"
|
extccomp.cExt = ".m"
|
||||||
gCmd = cmdCompileToOC
|
gCmd = cmdCompileToOC
|
||||||
wantFile(filename)
|
wantFile(filename)
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,17 @@ Files: "lib/ecmas/*.nim"
|
||||||
|
|
||||||
[Other]
|
[Other]
|
||||||
Files: "examples/*.nim"
|
Files: "examples/*.nim"
|
||||||
|
Files: "examples/gtk/*.nim"
|
||||||
|
Files: "examples/0mq/*.nim"
|
||||||
|
Files: "examples/c++iface/*.nim"
|
||||||
|
Files: "examples/objciface/*.nim"
|
||||||
|
Files: "examples/lazarus/*.nim"
|
||||||
|
Files: "examples/lazarus/*.lpi"
|
||||||
|
Files: "examples/lazarus/*.lpr"
|
||||||
|
Files: "examples/lazarus/*.txt"
|
||||||
|
Files: "examples/lazarus/*.lfm"
|
||||||
|
Files: "examples/lazarus/*.pas"
|
||||||
|
|
||||||
Files: "examples/*.html"
|
Files: "examples/*.html"
|
||||||
Files: "examples/*.txt"
|
Files: "examples/*.txt"
|
||||||
Files: "examples/*.cfg"
|
Files: "examples/*.cfg"
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const
|
||||||
procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||||
wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
|
wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader,
|
||||||
wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge,
|
||||||
wBorrow, wExtern, wImportCompilerProc, wThread}
|
wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC}
|
||||||
converterPragmas* = procPragmas
|
converterPragmas* = procPragmas
|
||||||
methodPragmas* = procPragmas
|
methodPragmas* = procPragmas
|
||||||
macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl,
|
||||||
|
|
@ -87,6 +87,18 @@ proc processImportCompilerProc(s: PSym, extname: string) =
|
||||||
excl(s.flags, sfForward)
|
excl(s.flags, sfForward)
|
||||||
incl(s.loc.flags, lfImportCompilerProc)
|
incl(s.loc.flags, lfImportCompilerProc)
|
||||||
|
|
||||||
|
proc processImportCpp(s: PSym, extname: string) =
|
||||||
|
setExternName(s, extname)
|
||||||
|
incl(s.flags, sfImportc)
|
||||||
|
incl(s.flags, sfInfixCall)
|
||||||
|
excl(s.flags, sfForward)
|
||||||
|
|
||||||
|
proc processImportObjC(s: PSym, extname: string) =
|
||||||
|
setExternName(s, extname)
|
||||||
|
incl(s.flags, sfImportc)
|
||||||
|
incl(s.flags, sfNamedParamCall)
|
||||||
|
excl(s.flags, sfForward)
|
||||||
|
|
||||||
proc getStrLitNode(c: PContext, n: PNode): PNode =
|
proc getStrLitNode(c: PContext, n: PNode): PNode =
|
||||||
if n.kind != nkExprColonExpr:
|
if n.kind != nkExprColonExpr:
|
||||||
GlobalError(n.info, errStringLiteralExpected)
|
GlobalError(n.info, errStringLiteralExpected)
|
||||||
|
|
@ -410,6 +422,10 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
||||||
of wImportCompilerProc:
|
of wImportCompilerProc:
|
||||||
processImportCompilerProc(sym, getOptionalStr(c, it, sym.name.s))
|
processImportCompilerProc(sym, getOptionalStr(c, it, sym.name.s))
|
||||||
of wExtern: setExternName(sym, expectStrLit(c, it))
|
of wExtern: setExternName(sym, expectStrLit(c, it))
|
||||||
|
of wImportCpp:
|
||||||
|
processImportCpp(sym, getOptionalStr(c, it, sym.name.s))
|
||||||
|
of wImportObjC:
|
||||||
|
processImportObjC(sym, getOptionalStr(c, it, sym.name.s))
|
||||||
of wAlign:
|
of wAlign:
|
||||||
if sym.typ == nil: invalidPragma(it)
|
if sym.typ == nil: invalidPragma(it)
|
||||||
var align = expectIntLit(c, it)
|
var align = expectIntLit(c, it)
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,7 @@ proc symStack(w: PRodWriter) =
|
||||||
addToIndex(w.index, s.id, L) #intSetIncl(debugWritten, s.id);
|
addToIndex(w.index, s.id, L) #intSetIncl(debugWritten, s.id);
|
||||||
app(w.data, encodeSym(w, s))
|
app(w.data, encodeSym(w, s))
|
||||||
app(w.data, rodNL)
|
app(w.data, rodNL)
|
||||||
if sfInInterface in s.flags:
|
if sfExported in s.flags:
|
||||||
appf(w.interf, "$1 $2" & rodNL, [encode(s.name.s), encodeInt(s.id)])
|
appf(w.interf, "$1 $2" & rodNL, [encode(s.name.s), encodeInt(s.id)])
|
||||||
if sfCompilerProc in s.flags:
|
if sfCompilerProc in s.flags:
|
||||||
appf(w.compilerProcs, "$1 $2" & rodNL,
|
appf(w.compilerProcs, "$1 $2" & rodNL,
|
||||||
|
|
@ -305,7 +305,7 @@ proc rawAddInterfaceSym(w: PRodWriter, s: PSym) =
|
||||||
|
|
||||||
proc addInterfaceSym(w: PRodWriter, s: PSym) =
|
proc addInterfaceSym(w: PRodWriter, s: PSym) =
|
||||||
if w == nil: return
|
if w == nil: return
|
||||||
if {sfInInterface, sfCompilerProc} * s.flags != {}:
|
if {sfExported, sfCompilerProc} * s.flags != {}:
|
||||||
rawAddInterfaceSym(w, s)
|
rawAddInterfaceSym(w, s)
|
||||||
|
|
||||||
proc addStmt(w: PRodWriter, n: PNode) =
|
proc addStmt(w: PRodWriter, n: PNode) =
|
||||||
|
|
|
||||||
|
|
@ -658,7 +658,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
if ty.sons[0] == nil: break
|
if ty.sons[0] == nil: break
|
||||||
ty = skipTypes(ty.sons[0], {tyGenericInst})
|
ty = skipTypes(ty.sons[0], {tyGenericInst})
|
||||||
if f != nil:
|
if f != nil:
|
||||||
if {sfStar, sfMinus} * f.flags != {} or getModule(f).id == c.module.id:
|
if sfExported in f.flags or getModule(f).id == c.module.id:
|
||||||
# is the access to a public field or in the same module?
|
# is the access to a public field or in the same module?
|
||||||
n.sons[0] = makeDeref(n.sons[0])
|
n.sons[0] = makeDeref(n.sons[0])
|
||||||
n.sons[1] = newSymNode(f) # we now have the correct field
|
n.sons[1] = newSymNode(f) # we now have the correct field
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ proc fitRemoveHiddenConv(c: PContext, typ: Ptype, n: PNode): PNode =
|
||||||
|
|
||||||
proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
|
proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym =
|
||||||
if isTopLevel(c):
|
if isTopLevel(c):
|
||||||
result = semIdentWithPragma(c, kind, n, {sfStar, sfMinus})
|
result = semIdentWithPragma(c, kind, n, {sfExported})
|
||||||
incl(result.flags, sfGlobal)
|
incl(result.flags, sfGlobal)
|
||||||
else:
|
else:
|
||||||
result = semIdentWithPragma(c, kind, n, {})
|
result = semIdentWithPragma(c, kind, n, {})
|
||||||
|
|
@ -257,7 +257,6 @@ proc semVar(c: PContext, n: PNode): PNode =
|
||||||
addSon(result, b)
|
addSon(result, b)
|
||||||
for j in countup(0, length-3):
|
for j in countup(0, length-3):
|
||||||
var v = semIdentDef(c, a.sons[j], skVar)
|
var v = semIdentDef(c, a.sons[j], skVar)
|
||||||
if v.flags * {sfStar, sfMinus} != {}: incl(v.flags, sfInInterface)
|
|
||||||
addInterfaceDecl(c, v)
|
addInterfaceDecl(c, v)
|
||||||
if a.kind != nkVarTuple:
|
if a.kind != nkVarTuple:
|
||||||
v.typ = typ
|
v.typ = typ
|
||||||
|
|
@ -300,7 +299,6 @@ proc semConst(c: PContext, n: PNode): PNode =
|
||||||
GlobalError(a.info, errXisNoType, typeToString(typ))
|
GlobalError(a.info, errXisNoType, typeToString(typ))
|
||||||
v.typ = typ
|
v.typ = typ
|
||||||
v.ast = def # no need to copy
|
v.ast = def # no need to copy
|
||||||
if v.flags * {sfStar, sfMinus} != {}: incl(v.flags, sfInInterface)
|
|
||||||
addInterfaceDecl(c, v)
|
addInterfaceDecl(c, v)
|
||||||
var b = newNodeI(nkConstDef, a.info)
|
var b = newNodeI(nkConstDef, a.info)
|
||||||
addSon(b, newSymNode(v))
|
addSon(b, newSymNode(v))
|
||||||
|
|
@ -463,7 +461,6 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) =
|
||||||
if a.kind != nkTypeDef: IllFormedAst(a)
|
if a.kind != nkTypeDef: IllFormedAst(a)
|
||||||
checkSonsLen(a, 3)
|
checkSonsLen(a, 3)
|
||||||
var s = semIdentDef(c, a.sons[0], skType)
|
var s = semIdentDef(c, a.sons[0], skType)
|
||||||
if s.flags * {sfStar, sfMinus} != {}: incl(s.flags, sfInInterface)
|
|
||||||
s.typ = newTypeS(tyForward, c)
|
s.typ = newTypeS(tyForward, c)
|
||||||
s.typ.sym = s # process pragmas:
|
s.typ.sym = s # process pragmas:
|
||||||
if a.sons[0].kind == nkPragmaExpr:
|
if a.sons[0].kind == nkPragmaExpr:
|
||||||
|
|
@ -619,7 +616,6 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||||
checkSonsLen(n, codePos + 1)
|
checkSonsLen(n, codePos + 1)
|
||||||
var s = semIdentDef(c, n.sons[0], kind)
|
var s = semIdentDef(c, n.sons[0], kind)
|
||||||
n.sons[namePos] = newSymNode(s)
|
n.sons[namePos] = newSymNode(s)
|
||||||
if sfStar in s.flags: incl(s.flags, sfInInterface)
|
|
||||||
s.ast = n
|
s.ast = n
|
||||||
pushOwner(s)
|
pushOwner(s)
|
||||||
openScope(c.tab)
|
openScope(c.tab)
|
||||||
|
|
|
||||||
|
|
@ -158,15 +158,13 @@ proc transformToExpr(n: PNode): PNode =
|
||||||
nil
|
nil
|
||||||
|
|
||||||
proc semTemplateDef(c: PContext, n: PNode): PNode =
|
proc semTemplateDef(c: PContext, n: PNode): PNode =
|
||||||
var
|
var s: PSym
|
||||||
s: PSym
|
|
||||||
if c.p.owner.kind == skModule:
|
if c.p.owner.kind == skModule:
|
||||||
s = semIdentVis(c, skTemplate, n.sons[0], {sfStar})
|
s = semIdentVis(c, skTemplate, n.sons[0], {sfExported})
|
||||||
incl(s.flags, sfGlobal)
|
incl(s.flags, sfGlobal)
|
||||||
else:
|
else:
|
||||||
s = semIdentVis(c, skTemplate, n.sons[0], {})
|
s = semIdentVis(c, skTemplate, n.sons[0], {})
|
||||||
if sfStar in s.flags:
|
# check parameter list:
|
||||||
incl(s.flags, sfInInterface) # check parameter list:
|
|
||||||
pushOwner(s)
|
pushOwner(s)
|
||||||
openScope(c.tab)
|
openScope(c.tab)
|
||||||
n.sons[namePos] = newSymNode(s) # check that no pragmas exist:
|
n.sons[namePos] = newSymNode(s) # check that no pragmas exist:
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||||
else:
|
else:
|
||||||
x = getOrdValue(v)
|
x = getOrdValue(v)
|
||||||
if i != 1:
|
if i != 1:
|
||||||
if (x != counter): incl(result.flags, tfEnumHasHoles)
|
if x != counter: incl(result.flags, tfEnumHasHoles)
|
||||||
if x < counter:
|
if x < counter:
|
||||||
GlobalError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s)
|
GlobalError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s)
|
||||||
e.ast = strVal # might be nil
|
e.ast = strVal # might be nil
|
||||||
|
|
@ -63,9 +63,9 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||||
else: illFormedAst(n)
|
else: illFormedAst(n)
|
||||||
e.typ = result
|
e.typ = result
|
||||||
e.position = int(counter)
|
e.position = int(counter)
|
||||||
if (result.sym != nil) and (sfInInterface in result.sym.flags):
|
if result.sym != nil and sfExported in result.sym.flags:
|
||||||
incl(e.flags, sfUsed) # BUGFIX
|
incl(e.flags, sfUsed) # BUGFIX
|
||||||
incl(e.flags, sfInInterface) # BUGFIX
|
incl(e.flags, sfExported) # BUGFIX
|
||||||
StrTableAdd(c.module.tab, e) # BUGFIX
|
StrTableAdd(c.module.tab, e) # BUGFIX
|
||||||
addSon(result.n, newSymNode(e))
|
addSon(result.n, newSymNode(e))
|
||||||
addDeclAt(c, e, c.tab.tos - 1)
|
addDeclAt(c, e, c.tab.tos - 1)
|
||||||
|
|
@ -240,10 +240,8 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
||||||
if sonsLen(n) == 2 and n.sons[0].kind == nkIdent:
|
if sonsLen(n) == 2 and n.sons[0].kind == nkIdent:
|
||||||
result = newSymS(kind, n.sons[1], c)
|
result = newSymS(kind, n.sons[1], c)
|
||||||
var v = n.sons[0].ident
|
var v = n.sons[0].ident
|
||||||
if (sfStar in allowed) and (v.id == ord(wStar)):
|
if sfExported in allowed and v.id == ord(wStar):
|
||||||
incl(result.flags, sfStar)
|
incl(result.flags, sfExported)
|
||||||
elif (sfMinus in allowed) and (v.id == ord(wMinus)):
|
|
||||||
incl(result.flags, sfMinus)
|
|
||||||
else:
|
else:
|
||||||
LocalError(n.sons[0].info, errInvalidVisibilityX, v.s)
|
LocalError(n.sons[0].info, errInvalidVisibilityX, v.s)
|
||||||
else:
|
else:
|
||||||
|
|
@ -422,7 +420,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int,
|
||||||
GlobalError(n.info, errTypeExpected)
|
GlobalError(n.info, errTypeExpected)
|
||||||
typ = semTypeNode(c, n.sons[length-2], nil)
|
typ = semTypeNode(c, n.sons[length-2], nil)
|
||||||
for i in countup(0, sonsLen(n) - 3):
|
for i in countup(0, sonsLen(n) - 3):
|
||||||
f = semIdentWithPragma(c, skField, n.sons[i], {sfStar, sfMinus})
|
f = semIdentWithPragma(c, skField, n.sons[i], {sfExported})
|
||||||
f.typ = typ
|
f.typ = typ
|
||||||
f.position = pos
|
f.position = pos
|
||||||
if (rectype != nil) and ({sfImportc, sfExportc} * rectype.flags != {}) and
|
if (rectype != nil) and ({sfImportc, sfExportc} * rectype.flags != {}) and
|
||||||
|
|
|
||||||
|
|
@ -131,8 +131,6 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyGenericParam:
|
of tyGenericParam:
|
||||||
result = lookupTypeVar(cl, t)
|
result = lookupTypeVar(cl, t)
|
||||||
if result.kind == tyGenericInvokation:
|
|
||||||
result = handleGenericInvokation(cl, result)
|
|
||||||
of tyGenericInvokation:
|
of tyGenericInvokation:
|
||||||
result = handleGenericInvokation(cl, t)
|
result = handleGenericInvokation(cl, t)
|
||||||
of tyGenericBody:
|
of tyGenericBody:
|
||||||
|
|
|
||||||
|
|
@ -403,7 +403,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
||||||
# we steal the generic parameters from the tyGenericBody:
|
# we steal the generic parameters from the tyGenericBody:
|
||||||
for i in countup(1, sonsLen(f) - 1):
|
for i in countup(1, sonsLen(f) - 1):
|
||||||
var x = PType(idTableGet(mapping, f.sons[0].sons[i - 1]))
|
var x = PType(idTableGet(mapping, f.sons[0].sons[i - 1]))
|
||||||
if (x == nil) or (x.kind == tyGenericParam):
|
if x == nil or x.kind == tyGenericParam:
|
||||||
InternalError("wrong instantiated type!")
|
InternalError("wrong instantiated type!")
|
||||||
idTablePut(mapping, f.sons[i], x)
|
idTablePut(mapping, f.sons[i], x)
|
||||||
of tyGenericParam:
|
of tyGenericParam:
|
||||||
|
|
@ -522,7 +522,7 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
|
|
||||||
proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
|
proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
arg: PNode): PNode =
|
arg: PNode): PNode =
|
||||||
if (arg == nil) or (arg.kind != nkSymChoice):
|
if arg == nil or arg.kind != nkSymChoice:
|
||||||
result = ParamTypesMatchAux(c, m, f, a, arg)
|
result = ParamTypesMatchAux(c, m, f, a, arg)
|
||||||
else:
|
else:
|
||||||
# CAUTION: The order depends on the used hashing scheme. Thus it is
|
# CAUTION: The order depends on the used hashing scheme. Thus it is
|
||||||
|
|
@ -555,8 +555,6 @@ proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
x = z
|
x = z
|
||||||
elif cmp == 0:
|
elif cmp == 0:
|
||||||
y = z # z is as good as x
|
y = z # z is as good as x
|
||||||
else:
|
|
||||||
nil
|
|
||||||
if x.state == csEmpty:
|
if x.state == csEmpty:
|
||||||
result = nil
|
result = nil
|
||||||
elif (y.state == csMatch) and (cmpCandidates(x, y) == 0):
|
elif (y.state == csMatch) and (cmpCandidates(x, y) == 0):
|
||||||
|
|
@ -620,7 +618,7 @@ proc matchesAux*(c: PContext, n: PNode, m: var TCandidate,
|
||||||
m.baseTypeMatch = false
|
m.baseTypeMatch = false
|
||||||
var arg = ParamTypesMatch(c, m, formal.typ,
|
var arg = ParamTypesMatch(c, m, formal.typ,
|
||||||
n.sons[a].typ, n.sons[a].sons[1])
|
n.sons[a].typ, n.sons[a].sons[1])
|
||||||
if (arg == nil):
|
if arg == nil:
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
return
|
return
|
||||||
if m.baseTypeMatch:
|
if m.baseTypeMatch:
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ type
|
||||||
wAddr, wAnd, wAs, wAsm, wAtomic,
|
wAddr, wAnd, wAs, wAsm, wAtomic,
|
||||||
wBind, wBlock, wBreak, wCase, wCast, wConst,
|
wBind, wBlock, wBreak, wCase, wCast, wConst,
|
||||||
wContinue, wConverter, wDiscard, wDistinct, wDiv, wElif, wElse, wEnd, wEnum,
|
wContinue, wConverter, wDiscard, wDistinct, wDiv, wElif, wElse, wEnd, wEnum,
|
||||||
wExcept, wFinally, wFor, wFrom, wGeneric, wIf, wImplies, wImport, wIn,
|
wExcept, wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn,
|
||||||
wInclude, wIs, wIsnot, wIterator, wLambda, wLet,
|
wInclude, wIs, wIsnot, wIterator, wLambda, wLet,
|
||||||
wMacro, wMethod, wMod, wNil,
|
wMacro, wMethod, wMod, wNil,
|
||||||
wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn,
|
wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn,
|
||||||
|
|
@ -34,6 +34,7 @@ type
|
||||||
|
|
||||||
wColon, wColonColon, wEquals, wDot, wDotDot, wStar, wMinus,
|
wColon, wColonColon, wEquals, wDot, wDotDot, wStar, wMinus,
|
||||||
wMagic, wThread, wFinal, wProfiler, wObjChecks,
|
wMagic, wThread, wFinal, wProfiler, wObjChecks,
|
||||||
|
wImportCpp, wImportObjC,
|
||||||
wImportCompilerProc,
|
wImportCompilerProc,
|
||||||
wImportc, wExportc, wExtern,
|
wImportc, wExportc, wExtern,
|
||||||
wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader,
|
wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader,
|
||||||
|
|
@ -51,7 +52,7 @@ type
|
||||||
wPragma,
|
wPragma,
|
||||||
wCompileTime, wGc, wRefc, wBoehm, wA, wOpt, wO, wApp, wConsole, wGui,
|
wCompileTime, wGc, wRefc, wBoehm, wA, wOpt, wO, wApp, wConsole, wGui,
|
||||||
wPassc, wT, wPassl, wL, wListcmd, wGendoc, wGenmapping, wOs, wCpu,
|
wPassc, wT, wPassl, wL, wListcmd, wGendoc, wGenmapping, wOs, wCpu,
|
||||||
wGenerate, wG, wC, wCpp, wBorrow, wRun, wR, wVerbosity, wV, wHelp, wH,
|
wGenerate, wG, wC, wBorrow, wRun, wR, wVerbosity, wV, wHelp, wH,
|
||||||
wSymbolFiles, wFieldChecks, wX, wVersion, wAdvanced, wSkipcfg, wSkipProjCfg,
|
wSymbolFiles, wFieldChecks, wX, wVersion, wAdvanced, wSkipcfg, wSkipProjCfg,
|
||||||
wCc, wGenscript, wCheckPoint, wThreadAnalysis, wNoMain, wSubsChar,
|
wCc, wGenscript, wCheckPoint, wThreadAnalysis, wNoMain, wSubsChar,
|
||||||
wAcyclic, wShallow, wUnroll, wLinearScanEnd,
|
wAcyclic, wShallow, wUnroll, wLinearScanEnd,
|
||||||
|
|
@ -72,7 +73,7 @@ const
|
||||||
"bind", "block", "break", "case", "cast",
|
"bind", "block", "break", "case", "cast",
|
||||||
"const", "continue", "converter", "discard", "distinct", "div", "elif",
|
"const", "continue", "converter", "discard", "distinct", "div", "elif",
|
||||||
"else", "end", "enum", "except", "finally", "for", "from", "generic", "if",
|
"else", "end", "enum", "except", "finally", "for", "from", "generic", "if",
|
||||||
"implies", "import", "in", "include", "is", "isnot", "iterator",
|
"import", "in", "include", "is", "isnot", "iterator",
|
||||||
"lambda", "let",
|
"lambda", "let",
|
||||||
"macro", "method", "mod", "nil", "not", "notin", "object", "of", "or",
|
"macro", "method", "mod", "nil", "not", "notin", "object", "of", "or",
|
||||||
"out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template",
|
"out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template",
|
||||||
|
|
@ -81,6 +82,8 @@ const
|
||||||
|
|
||||||
":", "::", "=", ".", "..", "*", "-",
|
":", "::", "=", ".", "..", "*", "-",
|
||||||
"magic", "thread", "final", "profiler", "objchecks",
|
"magic", "thread", "final", "profiler", "objchecks",
|
||||||
|
|
||||||
|
"importcpp", "importobjc",
|
||||||
"importcompilerproc", "importc", "exportc", "extern",
|
"importcompilerproc", "importc", "exportc", "extern",
|
||||||
"align", "nodecl", "pure", "volatile", "register", "sideeffect",
|
"align", "nodecl", "pure", "volatile", "register", "sideeffect",
|
||||||
"header", "nosideeffect", "noreturn", "merge", "lib", "dynlib",
|
"header", "nosideeffect", "noreturn", "merge", "lib", "dynlib",
|
||||||
|
|
@ -99,7 +102,7 @@ const
|
||||||
"pragma",
|
"pragma",
|
||||||
"compiletime", "gc", "refc", "boehm", "a", "opt", "o", "app", "console",
|
"compiletime", "gc", "refc", "boehm", "a", "opt", "o", "app", "console",
|
||||||
"gui", "passc", "t", "passl", "l", "listcmd", "gendoc", "genmapping", "os",
|
"gui", "passc", "t", "passl", "l", "listcmd", "gendoc", "genmapping", "os",
|
||||||
"cpu", "generate", "g", "c", "cpp", "borrow", "run", "r", "verbosity", "v",
|
"cpu", "generate", "g", "c", "borrow", "run", "r", "verbosity", "v",
|
||||||
"help", "h", "symbolfiles", "fieldchecks", "x", "version", "advanced",
|
"help", "h", "symbolfiles", "fieldchecks", "x", "version", "advanced",
|
||||||
"skipcfg", "skipprojcfg", "cc", "genscript", "checkpoint", "threadanalysis",
|
"skipcfg", "skipprojcfg", "cc", "genscript", "checkpoint", "threadanalysis",
|
||||||
"nomain", "subschar", "acyclic", "shallow", "unroll", "linearscanend",
|
"nomain", "subschar", "acyclic", "shallow", "unroll", "linearscanend",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
Advanced commands:
|
Advanced commands:
|
||||||
//compileToC, cc compile project with C code generator
|
//compileToC, cc compile project with C code generator
|
||||||
//compileToOC, oc compile project to Objective C code
|
//compileToCpp, cpp compile project to C++ code
|
||||||
|
//compileToOC, objc compile project to Objective C code
|
||||||
//rst2html convert a reStructuredText file to HTML
|
//rst2html convert a reStructuredText file to HTML
|
||||||
//rst2tex convert a reStructuredText file to TeX
|
//rst2tex convert a reStructuredText file to TeX
|
||||||
//run run the project (with Tiny C backend; buggy!)
|
//run run the project (with Tiny C backend; buggy!)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ case cast const continue converter
|
||||||
discard distinct div
|
discard distinct div
|
||||||
elif else end enum except
|
elif else end enum except
|
||||||
finally for from generic
|
finally for from generic
|
||||||
if implies import in include is isnot iterator
|
if import in include is isnot iterator
|
||||||
lambda let
|
lambda let
|
||||||
macro method mod
|
macro method mod
|
||||||
nil not notin
|
nil not notin
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,85 @@ Example:
|
||||||
embedsC()
|
embedsC()
|
||||||
|
|
||||||
|
|
||||||
|
ImportCpp pragma
|
||||||
|
----------------
|
||||||
|
The `importcpp`:idx: pragma can be used to import `C++`:idx: methods. The
|
||||||
|
generated code then uses the C++ method calling syntax: ``obj->method(arg)``.
|
||||||
|
In addition with the ``header`` and ``emit`` pragmas this allows *sloppy*
|
||||||
|
interfacing with libraries written in C++:
|
||||||
|
|
||||||
|
.. code-block:: Nimrod
|
||||||
|
# Horrible example of how to interface with a C++ engine ... ;-)
|
||||||
|
|
||||||
|
{.link: "/usr/lib/libIrrlicht.so".}
|
||||||
|
|
||||||
|
{.emit: """
|
||||||
|
using namespace irr;
|
||||||
|
using namespace core;
|
||||||
|
using namespace scene;
|
||||||
|
using namespace video;
|
||||||
|
using namespace io;
|
||||||
|
using namespace gui;
|
||||||
|
""".}
|
||||||
|
|
||||||
|
const
|
||||||
|
irr = "<irrlicht/irrlicht.h>"
|
||||||
|
|
||||||
|
type
|
||||||
|
TIrrlichtDevice {.final, header: irr, importc: "IrrlichtDevice".} = object
|
||||||
|
PIrrlichtDevice = ptr TIrrlichtDevice
|
||||||
|
|
||||||
|
proc createDevice(): PIrrlichtDevice {.
|
||||||
|
header: irr, importc: "createDevice".}
|
||||||
|
proc run(device: PIrrlichtDevice): bool {.
|
||||||
|
header: irr, importcpp: "run".}
|
||||||
|
|
||||||
|
|
||||||
|
ImportObjC pragma
|
||||||
|
-----------------
|
||||||
|
The `importobjc`:idx: pragma can be used to import `Objective C`:idx: methods.
|
||||||
|
The generated code then uses the Objective C method calling
|
||||||
|
syntax: ``[obj method param1: arg]``.
|
||||||
|
In addition with the ``header`` and ``emit`` pragmas this allows *sloppy*
|
||||||
|
interfacing with libraries written in Objective C:
|
||||||
|
|
||||||
|
.. code-block:: Nimrod
|
||||||
|
# horrible example of how to interface with GNUStep ...
|
||||||
|
|
||||||
|
{.passL: "-lobjc".}
|
||||||
|
{.emit: """
|
||||||
|
#include <objc/Object.h>
|
||||||
|
@interface Greeter:Object
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)greet:(long)x y:(long)dummy;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
@implementation Greeter
|
||||||
|
|
||||||
|
- (void)greet:(long)x y:(long)dummy
|
||||||
|
{
|
||||||
|
printf("Hello, World!\n");
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
""".}
|
||||||
|
|
||||||
|
type
|
||||||
|
TId {.importc: "id", header: "<objc/Object.h>", final.} = distinct int
|
||||||
|
|
||||||
|
proc newGreeter: TId {.importobjc: "Greeter new", nodecl.}
|
||||||
|
proc greet(self: TId, x, y: int) {.importobjc: "greet", nodecl.}
|
||||||
|
proc free(self: TId) {.importobjc: "free", nodecl.}
|
||||||
|
|
||||||
|
var g = newGreeter()
|
||||||
|
g.greet(12, 34)
|
||||||
|
g.free()
|
||||||
|
|
||||||
|
|
||||||
LineDir option
|
LineDir option
|
||||||
--------------
|
--------------
|
||||||
The `lineDir`:idx: option can be turned on or off. If turned on the
|
The `lineDir`:idx: option can be turned on or off. If turned on the
|
||||||
|
|
|
||||||
114
examples/c++iface/irrlichtex.nim
Normal file
114
examples/c++iface/irrlichtex.nim
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
# Horrible example of how to interface with a C++ engine ... ;-)
|
||||||
|
|
||||||
|
{.link: "/usr/lib/libIrrlicht.so".}
|
||||||
|
|
||||||
|
{.emit: """
|
||||||
|
using namespace irr;
|
||||||
|
using namespace core;
|
||||||
|
using namespace scene;
|
||||||
|
using namespace video;
|
||||||
|
using namespace io;
|
||||||
|
using namespace gui;
|
||||||
|
""".}
|
||||||
|
|
||||||
|
const
|
||||||
|
irr = "<irrlicht/irrlicht.h>"
|
||||||
|
|
||||||
|
type
|
||||||
|
TDimension2d {.final, header: irr, importc: "dimension2d".} = object
|
||||||
|
Tvector3df {.final, header: irr, importc: "vector3df".} = object
|
||||||
|
TColor {.final, header: irr, importc: "SColor".} = object
|
||||||
|
|
||||||
|
TIrrlichtDevice {.final, header: irr, importc: "IrrlichtDevice".} = object
|
||||||
|
TIVideoDriver {.final, header: irr, importc: "IVideoDriver".} = object
|
||||||
|
TISceneManager {.final, header: irr, importc: "ISceneManager".} = object
|
||||||
|
TIGUIEnvironment {.final, header: irr, importc: "IGUIEnvironment".} = object
|
||||||
|
TIAnimatedMesh {.final, header: irr, importc: "IAnimatedMesh".} = object
|
||||||
|
TIAnimatedMeshSceneNode {.final, header: irr,
|
||||||
|
importc: "IAnimatedMeshSceneNode".} = object
|
||||||
|
TITexture {.final, header: irr, importc: "ITexture".} = object
|
||||||
|
|
||||||
|
PIrrlichtDevice = ptr TIrrlichtDevice
|
||||||
|
PIVideoDriver = ptr TIVideoDriver
|
||||||
|
PISceneManager = ptr TISceneManager
|
||||||
|
PIGUIEnvironment = ptr TIGUIEnvironment
|
||||||
|
PIAnimatedMesh = ptr TIAnimatedMesh
|
||||||
|
PIAnimatedMeshSceneNode = ptr TIAnimatedMeshSceneNode
|
||||||
|
PITexture = ptr TITexture
|
||||||
|
|
||||||
|
proc dimension2d(x, y: cint): TDimension2d {.
|
||||||
|
header: irr, importc: "dimension2d<u32>".}
|
||||||
|
proc vector3df(x,y,z: cint): Tvector3df {.
|
||||||
|
header: irr, importc: "vector3df".}
|
||||||
|
proc SColor(r,g,b,a: cint): TColor {.
|
||||||
|
header: irr, importc: "SColor".}
|
||||||
|
|
||||||
|
proc createDevice(): PIrrlichtDevice {.
|
||||||
|
header: irr, importc: "createDevice".}
|
||||||
|
proc run(device: PIrrlichtDevice): bool {.
|
||||||
|
header: irr, importcpp: "run".}
|
||||||
|
|
||||||
|
proc getVideoDriver(dev: PIrrlichtDevice): PIVideoDriver {.
|
||||||
|
header: irr, importcpp: "getVideoDriver".}
|
||||||
|
proc getSceneManager(dev: PIrrlichtDevice): PISceneManager {.
|
||||||
|
header: irr, importcpp: "getSceneManager".}
|
||||||
|
proc getGUIEnvironment(dev: PIrrlichtDevice): PIGUIEnvironment {.
|
||||||
|
header: irr, importcpp: "getGUIEnvironment".}
|
||||||
|
|
||||||
|
proc getMesh(smgr: PISceneManager, path: cstring): PIAnimatedMesh {.
|
||||||
|
header: irr, importcpp: "getMesh".}
|
||||||
|
|
||||||
|
proc drawAll(smgr: PISceneManager) {.
|
||||||
|
header: irr, importcpp: "drawAll".}
|
||||||
|
proc drawAll(guienv: PIGUIEnvironment) {.
|
||||||
|
header: irr, importcpp: "drawAll".}
|
||||||
|
|
||||||
|
proc drop(dev: PIrrlichtDevice) {.
|
||||||
|
header: irr, importcpp: "drop".}
|
||||||
|
|
||||||
|
proc getTexture(driver: PIVideoDriver, path: cstring): PITexture {.
|
||||||
|
header: irr, importcpp: "getTexture".}
|
||||||
|
proc endScene(driver: PIVideoDriver) {.
|
||||||
|
header: irr, importcpp: "endScene".}
|
||||||
|
proc beginScene(driver: PIVideoDriver, a, b: bool, c: TColor) {.
|
||||||
|
header: irr, importcpp: "beginScene".}
|
||||||
|
|
||||||
|
proc addAnimatedMeshSceneNode(
|
||||||
|
smgr: PISceneManager, mesh: PIAnimatedMesh): PIAnimatedMeshSceneNode {.
|
||||||
|
header: irr, importcpp: "addAnimatedMeshSceneNode".}
|
||||||
|
|
||||||
|
proc setMaterialTexture(n: PIAnimatedMeshSceneNode, x: cint, t: PITexture) {.
|
||||||
|
header: irr, importcpp: "setMaterialTexture".}
|
||||||
|
proc addCameraSceneNode(smgr: PISceneManager, x: cint, a, b: TVector3df) {.
|
||||||
|
header: irr, importcpp: "addCameraSceneNode".}
|
||||||
|
|
||||||
|
|
||||||
|
var device = createDevice()
|
||||||
|
if device == nil: quit "device is nil"
|
||||||
|
|
||||||
|
var driver = device.getVideoDriver()
|
||||||
|
var smgr = device.getSceneManager()
|
||||||
|
var guienv = device.getGUIEnvironment()
|
||||||
|
|
||||||
|
var mesh = smgr.getMesh("/home/andreas/download/irrlicht-1.7.2/media/sydney.md2")
|
||||||
|
if mesh == nil:
|
||||||
|
device.drop()
|
||||||
|
quit "no mesh!"
|
||||||
|
|
||||||
|
var node = smgr.addAnimatedMeshSceneNode(mesh)
|
||||||
|
|
||||||
|
if node != nil:
|
||||||
|
#node->setMaterialFlag(EMF_LIGHTING, false)
|
||||||
|
#node->setMD2Animation(scene::EMAT_STAND)
|
||||||
|
node.setMaterialTexture(0,
|
||||||
|
driver.getTexture(
|
||||||
|
"/home/andreas/download/irrlicht-1.7.2/media/media/sydney.bmp"))
|
||||||
|
|
||||||
|
smgr.addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0))
|
||||||
|
while device.run():
|
||||||
|
driver.beginScene(true, true, SColor(255,100,101,140))
|
||||||
|
smgr.drawAll()
|
||||||
|
guienv.drawAll()
|
||||||
|
driver.endScene()
|
||||||
|
device.drop()
|
||||||
|
|
||||||
40
examples/objciface/gnustepex.nim
Normal file
40
examples/objciface/gnustepex.nim
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
# horrible example of how to interface with GNUStep ...
|
||||||
|
|
||||||
|
{.passL: "-lobjc".}
|
||||||
|
{.emit: """
|
||||||
|
|
||||||
|
#include <objc/Object.h>
|
||||||
|
|
||||||
|
@interface Greeter:Object
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)greet:(long)x y:(long)dummy;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@implementation Greeter
|
||||||
|
|
||||||
|
- (void)greet:(long)x y:(long)dummy
|
||||||
|
{
|
||||||
|
printf("Hello, World!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
""".}
|
||||||
|
|
||||||
|
type
|
||||||
|
TId {.importc: "id", header: "<objc/Object.h>", final.} = distinct int
|
||||||
|
|
||||||
|
proc newGreeter: TId {.importobjc: "Greeter new", nodecl.}
|
||||||
|
proc greet(self: TId, x, y: int) {.importobjc: "greet", nodecl.}
|
||||||
|
proc free(self: TId) {.importobjc: "free", nodecl.}
|
||||||
|
|
||||||
|
var g = newGreeter()
|
||||||
|
g.greet(12, 34)
|
||||||
|
g.free()
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Nimrod's Runtime Library
|
Nimrod's Runtime Library
|
||||||
(c) Copyright 2010 Andreas Rumpf
|
(c) Copyright 2011 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.
|
||||||
|
|
@ -281,6 +281,7 @@ static unsigned long nimInf[2]={0xffffffff, 0x7fffffff};
|
||||||
# define NIM_FALSE false
|
# define NIM_FALSE false
|
||||||
# endif
|
# endif
|
||||||
# define NIM_BOOL bool
|
# define NIM_BOOL bool
|
||||||
|
# define NIM_NIL 0
|
||||||
#else
|
#else
|
||||||
# ifdef bool
|
# ifdef bool
|
||||||
# define NIM_BOOL bool
|
# define NIM_BOOL bool
|
||||||
|
|
@ -293,10 +294,9 @@ static unsigned long nimInf[2]={0xffffffff, 0x7fffffff};
|
||||||
# ifndef NIM_FALSE
|
# ifndef NIM_FALSE
|
||||||
# define NIM_FALSE ((NIM_BOOL) 0)
|
# define NIM_FALSE ((NIM_BOOL) 0)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
# define NIM_NIL ((void*)0) /* C's NULL is fucked up in some C compilers, so
|
||||||
|
|
||||||
#define NIM_NIL ((void*)0) /* C's NULL is fucked up in some C compilers, so
|
|
||||||
the generated code does not rely on it anymore */
|
the generated code does not rely on it anymore */
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__BORLANDC__) || defined(__DMC__) \
|
#if defined(__BORLANDC__) || defined(__DMC__) \
|
||||||
|| defined(__WATCOMC__) || defined(_MSC_VER)
|
|| defined(__WATCOMC__) || defined(_MSC_VER)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
discard """
|
||||||
|
cmd: "nimrod cc --hints:on --threads:on $# $#"
|
||||||
|
"""
|
||||||
|
|
||||||
type
|
type
|
||||||
TThreadFuncArgs[T] = object of TObject
|
TThreadFuncArgs[T] = object of TObject
|
||||||
a: proc(): T {.thread.}
|
a: proc(): T {.thread.}
|
||||||
|
|
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -19,6 +19,7 @@ version 0.9.0
|
||||||
- tests: run the GC tests
|
- tests: run the GC tests
|
||||||
- change overloading resolution
|
- change overloading resolution
|
||||||
- implement closures; implement proper coroutines
|
- implement closures; implement proper coroutines
|
||||||
|
- make exceptions compatible with C++ exceptions
|
||||||
|
|
||||||
Bugs
|
Bugs
|
||||||
----
|
----
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ Changes affecting backwards compatibility
|
||||||
- Moved ``strutils.validEmailAddress`` to ``matchers.validEmailAddress``.
|
- Moved ``strutils.validEmailAddress`` to ``matchers.validEmailAddress``.
|
||||||
- The pointer dereference operator ``^`` has been removed, so that ``^``
|
- The pointer dereference operator ``^`` has been removed, so that ``^``
|
||||||
can now be a user-defined operator.
|
can now be a user-defined operator.
|
||||||
|
- ``implies`` is no keyword anymore.
|
||||||
- The ``is`` operator is now the ``of`` operator.
|
- The ``is`` operator is now the ``of`` operator.
|
||||||
- The ``is`` operator is now used to check type equivalence in generic code.
|
- The ``is`` operator is now used to check type equivalence in generic code.
|
||||||
|
|
||||||
|
|
@ -47,6 +48,13 @@ Language Additions
|
||||||
Compiler Additions
|
Compiler Additions
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
- The compiler can generate C++ code for easier interfacing with C++.
|
||||||
|
- The compiler can generate Objective C code for easier interfacing with
|
||||||
|
Objective C.
|
||||||
|
- The new pragmas ``importcpp`` and ``importobjc`` make interfacing with C++
|
||||||
|
and Objective C somewhat easier.
|
||||||
|
|
||||||
|
|
||||||
Library Additions
|
Library Additions
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue