diff options
author | Araq <rumpf_a@web.de> | 2011-08-07 21:02:09 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-08-07 21:02:09 +0200 |
commit | 5131b3cea4ba50970ef5d3313cbd8a75acadc2d7 (patch) | |
tree | 28391aa51f7011e381da3c23cd3aee483a78e4a6 /compiler | |
parent | 7748dbc0b24756459e25e2f9f55a219f7d3faf50 (diff) | |
download | Nim-5131b3cea4ba50970ef5d3313cbd8a75acadc2d7.tar.gz |
support for C++ code generation; importcpp and importobjc pragmas
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 12 | ||||
-rwxr-xr-x | compiler/ccgexprs.nim | 167 | ||||
-rwxr-xr-x | compiler/ccgstmts.nim | 89 | ||||
-rwxr-xr-x | compiler/cgen.nim | 7 | ||||
-rwxr-xr-x | compiler/commands.nim | 3 | ||||
-rwxr-xr-x | compiler/docgen.nim | 2 | ||||
-rwxr-xr-x | compiler/ecmasgen.nim | 14 | ||||
-rwxr-xr-x | compiler/lexer.nim | 4 | ||||
-rwxr-xr-x | compiler/lookups.nim | 4 | ||||
-rwxr-xr-x | compiler/main.nim | 4 | ||||
-rwxr-xr-x | compiler/nimrod.ini | 11 | ||||
-rwxr-xr-x | compiler/pragmas.nim | 20 | ||||
-rwxr-xr-x | compiler/rodwrite.nim | 4 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 2 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 6 | ||||
-rwxr-xr-x | compiler/semtempl.nim | 10 | ||||
-rwxr-xr-x | compiler/semtypes.nim | 22 | ||||
-rwxr-xr-x | compiler/semtypinst.nim | 2 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 24 | ||||
-rwxr-xr-x | compiler/wordrecg.nim | 11 |
20 files changed, 247 insertions, 171 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 817b37d60..909c7c3bf 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -187,11 +187,9 @@ type TNodeKinds* = set[TNodeKind] type - TSymFlag* = enum # already 29 flags! + TSymFlag* = enum # already 29 flags! sfUsed, # read access of sym (for warnings) or simply used - sfStar, # symbol has * visibility - sfMinus, # symbol has - visibility - sfInInterface, # symbol is in interface section declared + sfExported, # symbol is exported from module sfFromGeneric, # symbol is instantiation of a generic; this is needed # for symbol file generation; such symbols should always # be written into the ROD file @@ -221,7 +219,11 @@ type sfThreadVar, # variable is a thread variable sfMerge, # proc can be merged with itself 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] diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 7534fc4e5..7c9b346e6 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -7,6 +7,9 @@ # distribution, for details about the copyright. # +proc lenField: PRope {.inline.} = + result = toRope(if gCmd != cmdCompileToCpp: "Sup.len" else: "len") + # -------------------------- constant expressions ------------------------ proc intLiteral(i: biggestInt): PRope = @@ -682,12 +685,12 @@ proc genSeqElem(p: BPRoc, e: PNode, d: var TLoc) = if (optBoundsCheck in p.options): if ty.kind == tyString: appcg(p, cpsStmts, - "if ((NU)($1) > (NU)($2->Sup.len)) #raiseIndexError();$n", - [rdLoc(b), rdLoc(a)]) + "if ((NU)($1) > (NU)($2->$3)) #raiseIndexError();$n", + [rdLoc(b), rdLoc(a), lenField()]) else: appcg(p, cpsStmts, - "if ((NU)($1) >= (NU)($2->Sup.len)) #raiseIndexError();$n", - [rdLoc(b), rdLoc(a)]) + "if ((NU)($1) >= (NU)($2->$3)) #raiseIndexError();$n", + [rdLoc(b), rdLoc(a), lenField()]) if d.k == locNone: d.s = OnHeap if skipTypes(a.t, abstractVar).kind in {tyRef, tyPtr}: a.r = ropef("(*$1)", [a.r]) @@ -781,6 +784,41 @@ proc genEcho(p: BProc, n: PNode) = appcg(p, cpsStmts, "printf($1$2);$n", [ makeCString(repeatStr(n.len-1, "%s") & tnl), args]) +proc fixupCall(p: BProc, t: PNode, d: var TLoc, pl: PRope) = + var pl = pl + var typ = t.sons[0].typ # getUniqueType() is too expensive here! + 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, 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 genCall(p: BProc, t: PNode, d: var TLoc) = var op, a: TLoc # this is a hotspot in the compiler @@ -788,12 +826,42 @@ proc genCall(p: BProc, t: PNode, d: var TLoc) = var pl = con(op.r, "(") 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)): + 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)) @@ -801,27 +869,65 @@ proc genCall(p: BProc, t: PNode, d: var TLoc) = 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 invalidRetType: - if length > 1: app(pl, ", ") + 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(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(pl, "]") app(p.s[cpsStmts], pl) app(p.s[cpsStmts], ';' & tnl) genAssignment(p, d, tmp, {}) # no need for deep copying else: - app(pl, ")") + app(pl, "]") if d.k == locNone: getTemp(p, typ.sons[0], d) assert(d.t != nil) # generate an assignment to d: var list: TLoc @@ -829,10 +935,10 @@ proc genCall(p: BProc, t: PNode, d: var TLoc) = list.r = pl genAssignment(p, d, list, {}) # no need for deep copying else: - app(pl, ")") + app(pl, "]") app(p.s[cpsStmts], pl) app(p.s[cpsStmts], ';' & tnl) - + proc genStrConcat(p: BProc, e: PNode, d: var TLoc) = # <Nimrod code> # 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}: Inc(L, len(e.sons[i + 1].strVal)) 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, cpsStmts, "$1 = #rawNewString($2$3);$n", [tmp.r, lens, toRope(L)]) 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}: Inc(L, len(e.sons[i + 2].strVal)) else: - appf(lens, "$1->Sup.len + ", [rdLoc(a)]) + appf(lens, "$1->$2 + ", [rdLoc(a), lenField()]) appcg(p.module, appends, "#appendString($1, $2);$n", [rdLoc(dest), rdLoc(a)]) 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[2].Typ, abstractVar))]) 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}) 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))", [nilCheck, r, genTypeInfo(p.module, dest)]) 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) 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 of tyOpenArray: putIntoDest(p, b, e.typ, rdLoc(a)) 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: putIntoDest(p, b, e.typ, 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)") else: unaryExpr(p, e, d, "strlen($1)") of tyString, tySequence: - if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)") - else: unaryExpr(p, e, d, "$1->Sup.len") + if gCmd != cmdCompileToCpp: + if op == mHigh: unaryExpr(p, e, d, "($1->Sup.len-1)") + 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: # YYY: length(sideeffect) is optimized away incorrectly? 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)])) of tyString, tySequence: 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: initLocExpr(p, n.sons[0], a) 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)") elif (a.kind in {nkStrLit..nkTripleStrLit}) and (a.strVal == ""): 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 == ""): 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: 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)) of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkPostfix, nkCommand, 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) + 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: genCall(p, e, d) of nkCurly: genSetConstr(p, e, d) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 8a05c68a4..9713dff0e 100755 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -218,10 +218,10 @@ proc genBreakStmt(p: BProc, t: PNode) = appf(p.s[cpsStmts], "goto LA$1;$n", [toRope(p.blocks[idx].id)]) proc getRaiseFrmt(p: BProc): string = - if gCmd == cmdCompileToCpp: - result = "throw #nimException($1, $2);$n" - else: - result = "#raiseException((#E_Base*)$1, $2);$n" + #if gCmd == cmdCompileToCpp: + # result = "throw #nimException($1, $2);$n" + #else: + result = "#raiseException((#E_Base*)$1, $2);$n" proc genRaiseStmt(p: BProc, t: PNode) = if t.sons[0].kind != nkEmpty: @@ -234,10 +234,10 @@ proc genRaiseStmt(p: BProc, t: PNode) = else: genLineDir(p, t) # reraise the last exception: - if gCmd == cmdCompileToCpp: - appcg(p, cpsStmts, "throw;" & tnl) - else: - appcg(p, cpsStmts, "#reraiseException();" & tnl) + #if gCmd == cmdCompileToCpp: + # appcg(p, cpsStmts, "throw;" & tnl) + #else: + appcg(p, cpsStmts, "#reraiseException();" & tnl) proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc, rangeFormat, eqFormat: TFormatStr, labl: TLabel) = @@ -491,72 +491,6 @@ proc genTryStmtCpp(p: BProc, t: PNode) = if rethrowFlag != nil: 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) = # code to generate: # @@ -655,7 +589,7 @@ proc genEmit(p: BProc, t: PNode) = var s = genAsmOrEmitStmt(p, t.sons[1]) if p.prc == nil: # top level emit pragma? - app(p.module.s[cfsProcs], s) + app(p.module.s[cfsProcHeaders], s) else: app(p.s[cpsStmts], s) @@ -768,8 +702,9 @@ proc genStmts(p: BProc, t: PNode) = initLocExpr(p, t.sons[0], a) of nkAsmStmt: genAsmStmt(p, t) of nkTryStmt: - if gCmd == cmdCompileToCpp: genTryStmtCpp(p, t) - else: genTryStmt(p, t) + #if gCmd == cmdCompileToCpp: genTryStmtCpp(p, t) + #else: + genTryStmt(p, t) of nkRaiseStmt: genRaiseStmt(p, t) of nkTypeSection: # we have to emit the type information for object types here to support diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 431aade09..7b17e9958 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -271,9 +271,10 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc, var r = rdLoc(a) if not takeAddr: r = ropef("(*$1)", [r]) var s = skipTypes(t, abstractInst) - while (s.kind == tyObject) and (s.sons[0] != nil): - app(r, ".Sup") - s = skipTypes(s.sons[0], abstractInst) + if gCmd != cmdCompileToCpp: + while (s.kind == tyObject) and (s.sons[0] != nil): + app(r, ".Sup") + s = skipTypes(s.sons[0], abstractInst) appcg(p, section, "$1.m_type = $2;$n", [r, genTypeInfo(p.module, t)]) of frEmbedded: # worst case for performance: diff --git a/compiler/commands.nim b/compiler/commands.nim index c5a689dfc..a4fe80702 100755 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -68,7 +68,8 @@ Options: AdvancedUsage = """ Advanced commands: 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 rst2tex convert a reStructuredText file to TeX run run the project (with Tiny C backend; buggy!) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 0c5d41b47..c05c35b90 100755 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -287,7 +287,7 @@ proc isVisible(n: PNode): bool = var v = n.sons[0].ident result = (v.id == ord(wStar)) or (v.id == ord(wMinus)) elif n.kind == nkSym: - result = sfInInterface in n.sym.flags + result = sfExported in n.sym.flags elif n.kind == nkPragmaExpr: result = isVisible(n.sons[0]) diff --git a/compiler/ecmasgen.nim b/compiler/ecmasgen.nim index 2e66f61c9..8fc525a28 100755 --- a/compiler/ecmasgen.nim +++ b/compiler/ecmasgen.nim @@ -1349,10 +1349,10 @@ proc gen(p: var TProc, n: PNode, r: var TCompRes) = of nkNilLit: if mapType(n.typ) == etyBaseIndex: r.kind = etyBaseIndex - r.com = toRope("null") - r.res = toRope("0") + r.com = toRope"null" + r.res = toRope"0" else: - r.res = toRope("null") + r.res = toRope"null" of nkStrLit..nkTripleStrLit: if skipTypes(n.typ, abstractVarRange).kind == tyString: useMagic(p, "cstrToNimstr") @@ -1361,11 +1361,11 @@ proc gen(p: var TProc, n: PNode, r: var TCompRes) = r.res = makeCString(n.strVal) of nkFloatLit..nkFloat64Lit: f = n.floatVal - if f != f: r.res = toRope("NaN") - elif f == 0.0: r.res = toRope("0.0") + if f != f: r.res = toRope"NaN" + elif f == 0.0: r.res = toRope"0.0" elif f == 0.5 * f: - if f > 0.0: r.res = toRope("Infinity") - else: r.res = toRope("-Infinity") + if f > 0.0: r.res = toRope"Infinity" + else: r.res = toRope"-Infinity" else: r.res = toRope(f.ToStrMaxPrecision) of nkBlockExpr: genBlock(p, n, r) of nkIfExpr: genIfExpr(p, n, r) diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 7d6503929..496712237 100755 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -35,7 +35,7 @@ type tkBind, tkBlock, tkBreak, tkCase, tkCast, tkConst, tkContinue, tkConverter, tkDiscard, tkDistinct, tkDiv, tkElif, tkElse, tkEnd, tkEnum, tkExcept, tkFinally, tkFor, tkFrom, tkGeneric, tkIf, - tkImplies, tkImport, tkIn, tkInclude, tkIs, tkIsnot, tkIterator, + tkImport, tkIn, tkInclude, tkIs, tkIsnot, tkIterator, tkLambda, tkLet, tkMacro, tkMethod, tkMod, tkNil, tkNot, tkNotin, tkObject, tkOf, tkOr, tkOut, tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShl, tkShr, tkTemplate, @@ -63,7 +63,7 @@ const "bind", "block", "break", "case", "cast", "const", "continue", "converter", "discard", "distinct", "div", "elif", "else", "end", "enum", "except", "finally", "for", "from", "generic", "if", - "implies", "import", "in", "include", "is", "isnot", "iterator", + "import", "in", "include", "is", "isnot", "iterator", "lambda", "let", "macro", "method", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template", diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 324618447..61b8ead4c 100755 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -55,7 +55,7 @@ proc CloseScope*(tab: var TSymTab) = while s != nil: if sfForward in s.flags: 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! if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}: 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) proc AddInterfaceDeclAux(c: PContext, sym: PSym) = - if (sfInInterface in sym.flags): + if sfExported in sym.flags: # add to interface: if c.module == nil: InternalError(sym.info, "AddInterfaceDeclAux") StrTableAdd(c.module.tab, sym) diff --git a/compiler/main.nim b/compiler/main.nim index 1ba13c649..b7670f5aa 100755 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -199,12 +199,12 @@ proc MainCommand(cmd, filename: string) = gCmd = cmdCompileToC wantFile(filename) CommandCompileToC(filename) - of "compiletocpp": + of "cpp", "compiletocpp": extccomp.cExt = ".cpp" gCmd = cmdCompileToCpp wantFile(filename) CommandCompileToC(filename) - of "oc", "compiletooc": + of "objc", "compiletooc": extccomp.cExt = ".m" gCmd = cmdCompileToOC wantFile(filename) diff --git a/compiler/nimrod.ini b/compiler/nimrod.ini index 471790111..cb3a80a04 100755 --- a/compiler/nimrod.ini +++ b/compiler/nimrod.ini @@ -80,6 +80,17 @@ Files: "lib/ecmas/*.nim" [Other] 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/*.txt" Files: "examples/*.cfg" diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 49505be49..014f431c4 100755 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -22,7 +22,7 @@ const procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, wMagic, wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, wCompilerProc, wPure, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, - wBorrow, wExtern, wImportCompilerProc, wThread} + wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC} converterPragmas* = procPragmas methodPragmas* = procPragmas macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, @@ -87,6 +87,18 @@ proc processImportCompilerProc(s: PSym, extname: string) = excl(s.flags, sfForward) 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 = if n.kind != nkExprColonExpr: GlobalError(n.info, errStringLiteralExpected) @@ -410,7 +422,11 @@ proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = of wImportCompilerProc: processImportCompilerProc(sym, getOptionalStr(c, it, sym.name.s)) of wExtern: setExternName(sym, expectStrLit(c, it)) - of wAlign: + of wImportCpp: + processImportCpp(sym, getOptionalStr(c, it, sym.name.s)) + of wImportObjC: + processImportObjC(sym, getOptionalStr(c, it, sym.name.s)) + of wAlign: if sym.typ == nil: invalidPragma(it) var align = expectIntLit(c, it) if not IsPowerOfTwo(align) and align != 0: diff --git a/compiler/rodwrite.nim b/compiler/rodwrite.nim index 327083ff1..0bc73d6f1 100755 --- a/compiler/rodwrite.nim +++ b/compiler/rodwrite.nim @@ -265,7 +265,7 @@ proc symStack(w: PRodWriter) = addToIndex(w.index, s.id, L) #intSetIncl(debugWritten, s.id); app(w.data, encodeSym(w, s)) 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)]) if sfCompilerProc in s.flags: appf(w.compilerProcs, "$1 $2" & rodNL, @@ -305,7 +305,7 @@ proc rawAddInterfaceSym(w: PRodWriter, s: PSym) = proc addInterfaceSym(w: PRodWriter, s: PSym) = if w == nil: return - if {sfInInterface, sfCompilerProc} * s.flags != {}: + if {sfExported, sfCompilerProc} * s.flags != {}: rawAddInterfaceSym(w, s) proc addStmt(w: PRodWriter, n: PNode) = diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 3bbc0c71f..58fbf3a25 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -658,7 +658,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = if ty.sons[0] == nil: break ty = skipTypes(ty.sons[0], {tyGenericInst}) 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? n.sons[0] = makeDeref(n.sons[0]) n.sons[1] = newSymNode(f) # we now have the correct field diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 38ecffdf8..e88fed51a 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -212,7 +212,7 @@ proc fitRemoveHiddenConv(c: PContext, typ: Ptype, n: PNode): PNode = proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym = if isTopLevel(c): - result = semIdentWithPragma(c, kind, n, {sfStar, sfMinus}) + result = semIdentWithPragma(c, kind, n, {sfExported}) incl(result.flags, sfGlobal) else: result = semIdentWithPragma(c, kind, n, {}) @@ -257,7 +257,6 @@ proc semVar(c: PContext, n: PNode): PNode = addSon(result, b) for j in countup(0, length-3): var v = semIdentDef(c, a.sons[j], skVar) - if v.flags * {sfStar, sfMinus} != {}: incl(v.flags, sfInInterface) addInterfaceDecl(c, v) if a.kind != nkVarTuple: v.typ = typ @@ -300,7 +299,6 @@ proc semConst(c: PContext, n: PNode): PNode = GlobalError(a.info, errXisNoType, typeToString(typ)) v.typ = typ v.ast = def # no need to copy - if v.flags * {sfStar, sfMinus} != {}: incl(v.flags, sfInInterface) addInterfaceDecl(c, v) var b = newNodeI(nkConstDef, a.info) addSon(b, newSymNode(v)) @@ -463,7 +461,6 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = if a.kind != nkTypeDef: IllFormedAst(a) checkSonsLen(a, 3) var s = semIdentDef(c, a.sons[0], skType) - if s.flags * {sfStar, sfMinus} != {}: incl(s.flags, sfInInterface) s.typ = newTypeS(tyForward, c) s.typ.sym = s # process pragmas: if a.sons[0].kind == nkPragmaExpr: @@ -619,7 +616,6 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, checkSonsLen(n, codePos + 1) var s = semIdentDef(c, n.sons[0], kind) n.sons[namePos] = newSymNode(s) - if sfStar in s.flags: incl(s.flags, sfInInterface) s.ast = n pushOwner(s) openScope(c.tab) diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index dee703d30..e2b2a03d1 100755 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -158,15 +158,13 @@ proc transformToExpr(n: PNode): PNode = nil proc semTemplateDef(c: PContext, n: PNode): PNode = - var - s: PSym + var s: PSym 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) - else: + else: s = semIdentVis(c, skTemplate, n.sons[0], {}) - if sfStar in s.flags: - incl(s.flags, sfInInterface) # check parameter list: + # check parameter list: pushOwner(s) openScope(c.tab) n.sons[namePos] = newSymNode(s) # check that no pragmas exist: diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 894dec1cb..728dffc8d 100755 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -50,8 +50,8 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = x = counter else: x = getOrdValue(v) - if i != 1: - if (x != counter): incl(result.flags, tfEnumHasHoles) + if i != 1: + if x != counter: incl(result.flags, tfEnumHasHoles) if x < counter: GlobalError(n.sons[i].info, errInvalidOrderInEnumX, e.name.s) e.ast = strVal # might be nil @@ -63,9 +63,9 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = else: illFormedAst(n) e.typ = result 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, sfInInterface) # BUGFIX + incl(e.flags, sfExported) # BUGFIX StrTableAdd(c.module.tab, e) # BUGFIX addSon(result.n, newSymNode(e)) addDeclAt(c, e, c.tab.tos - 1) @@ -240,15 +240,13 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, if sonsLen(n) == 2 and n.sons[0].kind == nkIdent: result = newSymS(kind, n.sons[1], c) var v = n.sons[0].ident - if (sfStar in allowed) and (v.id == ord(wStar)): - incl(result.flags, sfStar) - elif (sfMinus in allowed) and (v.id == ord(wMinus)): - incl(result.flags, sfMinus) - else: + if sfExported in allowed and v.id == ord(wStar): + incl(result.flags, sfExported) + else: LocalError(n.sons[0].info, errInvalidVisibilityX, v.s) - else: + else: illFormedAst(n) - else: + else: result = newSymS(kind, n, c) proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, @@ -422,7 +420,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, GlobalError(n.info, errTypeExpected) typ = semTypeNode(c, n.sons[length-2], nil) 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.position = pos if (rectype != nil) and ({sfImportc, sfExportc} * rectype.flags != {}) and diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 7cdc81b94..420c84193 100755 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -131,8 +131,6 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = case t.kind of tyGenericParam: result = lookupTypeVar(cl, t) - if result.kind == tyGenericInvokation: - result = handleGenericInvokation(cl, result) of tyGenericInvokation: result = handleGenericInvokation(cl, t) of tyGenericBody: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index ec689d315..ea40dd0c9 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -76,15 +76,15 @@ proc copyCandidate(a: var TCandidate, b: TCandidate) = a.baseTypeMatch = b.baseTypeMatch copyIdTable(a.bindings, b.bindings) -proc cmpCandidates*(a, b: TCandidate): int = +proc cmpCandidates*(a, b: TCandidate): int = result = a.exactMatches - b.exactMatches - if result != 0: return + if result != 0: return result = a.genericMatches - b.genericMatches - if result != 0: return + if result != 0: return result = a.subtypeMatches - b.subtypeMatches - if result != 0: return + if result != 0: return result = a.intConvMatches - b.intConvMatches - if result != 0: return + if result != 0: return result = a.convMatches - b.convMatches proc writeMatches(c: TCandidate) = @@ -397,13 +397,13 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation = InternalError("wrong instantiated type!") if typeRel(mapping, f.sons[i], a.sons[i]) < isGeneric: return result = isGeneric - else: + else: result = typeRel(mapping, f.sons[0], a) - if result != isNone: + if result != isNone: # 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])) - if (x == nil) or (x.kind == tyGenericParam): + if x == nil or x.kind == tyGenericParam: InternalError("wrong instantiated type!") idTablePut(mapping, f.sons[i], x) 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, arg: PNode): PNode = - if (arg == nil) or (arg.kind != nkSymChoice): + if arg == nil or arg.kind != nkSymChoice: result = ParamTypesMatchAux(c, m, f, a, arg) else: # 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 elif cmp == 0: y = z # z is as good as x - else: - nil if x.state == csEmpty: result = nil 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 var arg = ParamTypesMatch(c, m, formal.typ, n.sons[a].typ, n.sons[a].sons[1]) - if (arg == nil): + if arg == nil: m.state = csNoMatch return if m.baseTypeMatch: diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 47d0fa3fc..1361475e4 100755 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -25,7 +25,7 @@ type wAddr, wAnd, wAs, wAsm, wAtomic, wBind, wBlock, wBreak, wCase, wCast, wConst, 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, wMacro, wMethod, wMod, wNil, wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn, @@ -34,6 +34,7 @@ type wColon, wColonColon, wEquals, wDot, wDotDot, wStar, wMinus, wMagic, wThread, wFinal, wProfiler, wObjChecks, + wImportCpp, wImportObjC, wImportCompilerProc, wImportc, wExportc, wExtern, wAlign, wNodecl, wPure, wVolatile, wRegister, wSideeffect, wHeader, @@ -51,7 +52,7 @@ type wPragma, wCompileTime, wGc, wRefc, wBoehm, wA, wOpt, wO, wApp, wConsole, wGui, 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, wCc, wGenscript, wCheckPoint, wThreadAnalysis, wNoMain, wSubsChar, wAcyclic, wShallow, wUnroll, wLinearScanEnd, @@ -72,7 +73,7 @@ const "bind", "block", "break", "case", "cast", "const", "continue", "converter", "discard", "distinct", "div", "elif", "else", "end", "enum", "except", "finally", "for", "from", "generic", "if", - "implies", "import", "in", "include", "is", "isnot", "iterator", + "import", "in", "include", "is", "isnot", "iterator", "lambda", "let", "macro", "method", "mod", "nil", "not", "notin", "object", "of", "or", "out", "proc", "ptr", "raise", "ref", "return", "shl", "shr", "template", @@ -81,6 +82,8 @@ const ":", "::", "=", ".", "..", "*", "-", "magic", "thread", "final", "profiler", "objchecks", + + "importcpp", "importobjc", "importcompilerproc", "importc", "exportc", "extern", "align", "nodecl", "pure", "volatile", "register", "sideeffect", "header", "nosideeffect", "noreturn", "merge", "lib", "dynlib", @@ -99,7 +102,7 @@ const "pragma", "compiletime", "gc", "refc", "boehm", "a", "opt", "o", "app", "console", "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", "skipcfg", "skipprojcfg", "cc", "genscript", "checkpoint", "threadanalysis", "nomain", "subschar", "acyclic", "shallow", "unroll", "linearscanend", |