summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-08-07 21:02:09 +0200
committerAraq <rumpf_a@web.de>2011-08-07 21:02:09 +0200
commit5131b3cea4ba50970ef5d3313cbd8a75acadc2d7 (patch)
tree28391aa51f7011e381da3c23cd3aee483a78e4a6 /compiler
parent7748dbc0b24756459e25e2f9f55a219f7d3faf50 (diff)
downloadNim-5131b3cea4ba50970ef5d3313cbd8a75acadc2d7.tar.gz
support for C++ code generation; importcpp and importobjc pragmas
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/ast.nim12
-rwxr-xr-xcompiler/ccgexprs.nim167
-rwxr-xr-xcompiler/ccgstmts.nim89
-rwxr-xr-xcompiler/cgen.nim7
-rwxr-xr-xcompiler/commands.nim3
-rwxr-xr-xcompiler/docgen.nim2
-rwxr-xr-xcompiler/ecmasgen.nim14
-rwxr-xr-xcompiler/lexer.nim4
-rwxr-xr-xcompiler/lookups.nim4
-rwxr-xr-xcompiler/main.nim4
-rwxr-xr-xcompiler/nimrod.ini11
-rwxr-xr-xcompiler/pragmas.nim20
-rwxr-xr-xcompiler/rodwrite.nim4
-rwxr-xr-xcompiler/semexprs.nim2
-rwxr-xr-xcompiler/semstmts.nim6
-rwxr-xr-xcompiler/semtempl.nim10
-rwxr-xr-xcompiler/semtypes.nim22
-rwxr-xr-xcompiler/semtypinst.nim2
-rwxr-xr-xcompiler/sigmatch.nim24
-rwxr-xr-xcompiler/wordrecg.nim11
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",