summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/c2nim/cparse.nim53
-rw-r--r--compiler/c2nim/cpp.nim2
-rw-r--r--compiler/c2nim/tests/matrix.h7
3 files changed, 44 insertions, 18 deletions
diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim
index 6bb4451e4..44be556db 100644
--- a/compiler/c2nim/cparse.nim
+++ b/compiler/c2nim/cparse.nim
@@ -1,7 +1,7 @@
 #
 #
 #      c2nim - C to Nimrod source converter
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2013 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -12,9 +12,9 @@
 ## used to convert the AST to its text representation.
 
 # TODO
-# - implement handling of '::'
+# - document 'cpp' mode
+# - implement handling of '::': function declarations
 # - C++'s "operator" still needs some love
-# - ignore 'using' statements
 # - support '#if' in classes
 
 import 
@@ -46,6 +46,7 @@ type
     dynlibSym, header: string
     macros: seq[TMacro]
     toMangle: PStringTable
+    classes: PStringTable
   PParserOptions* = ref TParserOptions
   
   TParser* = object
@@ -71,6 +72,7 @@ proc newParserOptions*(): PParserOptions =
   result.dynlibSym = ""
   result.header = ""
   result.toMangle = newStringTable(modeCaseSensitive)
+  result.classes = newStringTable(modeCaseSensitive)
 
 proc setOption*(parserOptions: PParserOptions, key: string, val=""): bool = 
   result = true
@@ -88,6 +90,7 @@ proc setOption*(parserOptions: PParserOptions, key: string, val=""): bool =
   of "cpp": incl(parserOptions.flags, pfCpp)
   of "keepbodies": incl(parserOptions.flags, pfKeepBodies)
   of "ignorervaluerefs": incl(parserOptions.flags, pfIgnoreRValueRefs)
+  of "class": parserOptions.classes[val] = "true"
   else: result = false
 
 proc ParseUnit*(p: var TParser): PNode
@@ -234,22 +237,22 @@ proc getTok(p: var TParser, n: PNode) =
   getTok(p)
   skipCom(p, n)
 
-proc ExpectIdent(p: TParser) = 
+proc expectIdent(p: TParser) = 
   if p.tok.xkind != pxSymbol: parMessage(p, errIdentifierExpected, $(p.tok[]))
   
-proc Eat(p: var TParser, xkind: TTokKind, n: PNode) = 
+proc eat(p: var TParser, xkind: TTokKind, n: PNode) = 
   if p.tok.xkind == xkind: getTok(p, n)
   else: parMessage(p, errTokenExpected, TokKindToStr(xkind))
   
-proc Eat(p: var TParser, xkind: TTokKind) = 
+proc eat(p: var TParser, xkind: TTokKind) = 
   if p.tok.xkind == xkind: getTok(p)
   else: parMessage(p, errTokenExpected, TokKindToStr(xkind))
   
-proc Eat(p: var TParser, tok: string, n: PNode) = 
+proc eat(p: var TParser, tok: string, n: PNode) = 
   if p.tok.s == tok: getTok(p, n)
   else: parMessage(p, errTokenExpected, tok)
   
-proc Opt(p: var TParser, xkind: TTokKind, n: PNode) = 
+proc opt(p: var TParser, xkind: TTokKind, n: PNode) = 
   if p.tok.xkind == xkind: getTok(p, n)
   
 proc addSon(father, a, b: PNode) = 
@@ -361,11 +364,11 @@ proc fieldIdent(ident: string, p: TParser): PNode =
     addSon(result, pragmas)
     addSon(pragmas, newIdentStrLitPair("importc", ident, p))
 
-proc DoImport(ident: string, pragmas: PNode, p: TParser) = 
+proc doImport(ident: string, pragmas: PNode, p: TParser) = 
   if p.options.dynlibSym.len > 0 or p.options.header.len > 0: 
     addImportToPragma(pragmas, ident, p)
 
-proc DoImportCpp(ident: string, pragmas: PNode, p: TParser) = 
+proc doImportCpp(ident: string, pragmas: PNode, p: TParser) = 
   if p.options.dynlibSym.len > 0 or p.options.header.len > 0:
     addSon(pragmas, newIdentStrLitPair("importcpp", ident, p))
     if p.options.dynlibSym.len > 0:
@@ -505,9 +508,21 @@ proc optAngle(p: var TParser, n: PNode): PNode =
   else:
     result = n
 
+proc optScope(p: var TParser, n: PNode): PNode =
+  result = n
+  if pfCpp in p.options.flags:
+    while p.tok.xkind == pxScope:
+      let a = result
+      result = newNodeP(nkDotExpr, p)
+      result.add(a)
+      getTok(p, result)
+      expectIdent(p)
+      result.add(mangledIdent(p.tok.s, p))
+      getTok(p, result)
+
 proc typeAtom(p: var TParser): PNode = 
   skipConst(p)
-  ExpectIdent(p)
+  expectIdent(p)
   case p.tok.s
   of "void": 
     result = newNodeP(nkNilLit, p) # little hack
@@ -533,6 +548,7 @@ proc typeAtom(p: var TParser): PNode =
   else:
     result = mangledIdent(p.tok.s, p)
     getTok(p, result)
+    result = optScope(p, result)
     result = optAngle(p, result)
     
 proc newPointerTy(p: TParser, typ: PNode): PNode =
@@ -1017,6 +1033,7 @@ proc declaration(p: var TParser): PNode =
     if pfCpp in p.options.flags and p.tok.xkind == pxSymbol and
         p.tok.s == "const":
       addSon(pragmas, newIdentNodeP("noSideEffect", p))
+      getTok(p)
     if pfCDecl in p.options.flags:
       addSon(pragmas, newIdentNodeP("cdecl", p))
     elif pfStdcall in p.options.flags:
@@ -1169,6 +1186,7 @@ proc primaryExpression(p: var TParser): PNode =
     else: 
       result = mangledIdent(p.tok.s, p)
     getTok(p, result)
+    result = optScope(p, result)
   of pxIntLit: 
     result = newIntNodeP(nkIntLit, p.tok.iNumber, p)
     setBaseFlags(result, p.tok.base)
@@ -1925,7 +1943,7 @@ proc parseClass(p: var TParser; isStruct: bool; stmtList: PNode): PNode =
       getTok(p, result)
       eat(p, pxColon, result)
       private = false
-    if p.tok.xkind == pxSymbol and p.tok.s == "friend":
+    if p.tok.xkind == pxSymbol and (p.tok.s == "friend" or p.tok.s == "using"):
       # we skip friend declarations:
       while p.tok.xkind notin {pxEof, pxSemicolon}: getTok(p)
       eat(p, pxSemicolon)
@@ -2012,7 +2030,9 @@ proc parseStandaloneClass(p: var TParser, isStruct: bool): PNode =
   else:
     p.currentClass = nil
   if p.tok.xkind in {pxCurlyLe, pxSemiColon, pxColon}:
-    if origName.len > 0: 
+    if origName.len > 0:
+      p.options.classes[origName] = "true"
+
       var typeSection = newNodeP(nkTypeSection, p)
       addSon(result, typeSection)
       
@@ -2092,6 +2112,13 @@ proc statement(p: var TParser): PNode =
         result = compoundStatement(p)
       else:
         result = declarationOrStatement(p)
+    of "using":
+      if pfCpp in p.options.flags:
+        while p.tok.xkind notin {pxEof, pxSemicolon}: getTok(p)
+        eat(p, pxSemicolon)
+        result = newNodeP(nkNilLit, p)
+      else:
+        result = declarationOrStatement(p)
     else: result = declarationOrStatement(p)
   of pxCurlyLe:
     result = compoundStatement(p)
diff --git a/compiler/c2nim/cpp.nim b/compiler/c2nim/cpp.nim
index 6b2ee905c..2ce64e59b 100644
--- a/compiler/c2nim/cpp.nim
+++ b/compiler/c2nim/cpp.nim
@@ -323,7 +323,7 @@ proc parseDir(p: var TParser): PNode =
     discard setOption(p.options, p.tok.s)
     getTok(p)
     eatNewLine(p, nil)
-  of "dynlib", "header", "prefix", "suffix": 
+  of "dynlib", "header", "prefix", "suffix", "class": 
     var key = p.tok.s
     getTok(p)
     if p.tok.xkind != pxStrLit: ExpectIdent(p)
diff --git a/compiler/c2nim/tests/matrix.h b/compiler/c2nim/tests/matrix.h
index 248b3d5e8..715e9e43b 100644
--- a/compiler/c2nim/tests/matrix.h
+++ b/compiler/c2nim/tests/matrix.h
@@ -55,7 +55,7 @@ public:
 

     void operator = (const wxTransformMatrix& mat);

     bool operator == (const wxTransformMatrix& mat) const;

-    bool operator != (const wxTransformMatrix& mat) const;

+    bool operator != (const module::gah::wxTransformMatrix& mat) const;

 

     //multiply every element by t

     wxTransformMatrix&          operator*=(const double& t);

@@ -184,7 +184,7 @@ public:
 Chris Breeze reported, that

 some functions of wxTransformMatrix cannot work because it is not

 known if he matrix has been inverted. Be careful when using it.

-

+*/

 

 // Transform X value from logical to device

 // warning: this function can only be used for this purpose

@@ -235,7 +235,6 @@ inline bool wxTransformMatrix::IsIdentity1(void) const
 inline double wxCalculateDet(double a11, double a21, double a12, double a22)

 {

     return a11 * a22 - a12 * a21;

-}

-*/
+}
 

 #endif // _WX_MATRIXH__