summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xrod/c2nim/cparse.nim124
-rwxr-xr-xrod/c2nim/cpp.nim4
-rw-r--r--rod/c2nim/manual.txt2
-rw-r--r--rod/c2nim/tests/systest.c4
4 files changed, 44 insertions, 90 deletions
diff --git a/rod/c2nim/cparse.nim b/rod/c2nim/cparse.nim
index 3ec1594f1..668b68c0b 100755
--- a/rod/c2nim/cparse.nim
+++ b/rod/c2nim/cparse.nim
@@ -13,7 +13,7 @@
 
 # XXX standalone structs and unions!
 # XXX header pragma for struct and union fields!
-# XXX rewrite symbol export handling!
+# XXX "cast" bug!
 
 import 
   os, llstream, rnimsyn, clex, idents, strutils, pegs, ast, astalgo, msgs,
@@ -74,8 +74,6 @@ proc ParseUnit*(p: var TParser): PNode
 proc openParser*(p: var TParser, filename: string, inputStream: PLLStream,
                  options = newParserOptions())
 proc closeParser*(p: var TParser)
-proc exSymbol*(n: var PNode)
-proc fixRecordDef*(n: var PNode)
 
 # implementation
 
@@ -134,8 +132,8 @@ proc parseMacroArguments(p: var TParser): seq[seq[ref TToken]] =
       result[L].add(p.tok)
     of pxParRi:
       # end of arguments?
-      if i[pxParLe] == 0: break
-      dec(i[pxParLe])
+      if i[pxParLe] == 0 and i[pxBracketLe] == 0 and i[pxCurlyLe] == 0: break
+      if i[pxParLe] > 0: dec(i[pxParLe])
       result[L].add(p.tok)
     of pxBracketRi, pxCurlyRi:
       kind = pred(kind, 3)
@@ -144,7 +142,6 @@ proc parseMacroArguments(p: var TParser): seq[seq[ref TToken]] =
     of pxComma: 
       if i[pxParLe] == 0 and i[pxBracketLe] == 0 and i[pxCurlyLe] == 0:
         # next argument: comma is not part of the argument
-        rawGetTok(p)
         result.add(@[])
         inc(L)
       else: 
@@ -298,8 +295,16 @@ proc addImportToPragma(pragmas: PNode, ident: string, p: TParser) =
   else:
     addSon(pragmas, newIdentStrLitPair("header", p.options.header, p))
 
-proc mangledIdentAndImport(ident: string, p: TParser): PNode = 
-  result = mangledIdent(ident, p)
+proc exportSym(p: TParser, i: PNode): PNode = 
+  assert i.kind == nkIdent
+  if p.scopeCounter == 0:
+    result = newNodeI(nkPostfix, i.info)
+    addSon(result, newIdentNode(getIdent("*"), i.info), i)
+  else:
+    result = i
+
+proc varIdent(ident: string, p: TParser): PNode = 
+  result = exportSym(p, mangledIdent(ident, p))
   if p.scopeCounter > 0: return
   if p.options.dynlibSym.len > 0 or p.options.header.len > 0: 
     var a = result
@@ -318,45 +323,17 @@ proc newBinary(opr: string, a, b: PNode, p: TParser): PNode =
   addSon(result, newIdentNodeP(getIdent(opr), p))
   addSon(result, a)
   addSon(result, b)
-  
-# --------------- symbol exporter --------------------------------------------
 
-proc identVis(p: var TParser): PNode = 
-  # identifier with visability
-  var a = mangledIdent(p.tok.s, p)
-  result = newNodeP(nkPostfix, p)
-  addSon(result, newIdentNodeP("*", p))
-  addSon(result, a)
-  getTok(p)
+proc skipIdent(p: var TParser): PNode = 
+  expectIdent(p)
+  result = mangledIdent(p.tok.s, p)
+  getTok(p, result)
+
+proc skipIdentExport(p: var TParser): PNode = 
+  expectIdent(p)
+  result = exportSym(p, mangledIdent(p.tok.s, p))
+  getTok(p, result)
 
-proc exSymbol(n: var PNode) = 
-  case n.kind
-  of nkPostfix: 
-    nil
-  of nkPragmaExpr: 
-    exSymbol(n.sons[0])
-  of nkIdent, nkAccQuoted: 
-    var a = newNodeI(nkPostFix, n.info)
-    addSon(a, newIdentNode(getIdent("*"), n.info))
-    addSon(a, n)
-    n = a
-  else: internalError(n.info, "exSymbol(): " & $n.kind)
-  
-proc fixRecordDef(n: var PNode) = 
-  if n == nil: return 
-  case n.kind
-  of nkRecCase: 
-    fixRecordDef(n.sons[0])
-    for i in countup(1, sonsLen(n) - 1): 
-      var length = sonsLen(n.sons[i])
-      fixRecordDef(n.sons[i].sons[length - 1])
-  of nkRecList, nkRecWhen, nkElse, nkOfBranch, nkElifBranch, nkObjectTy: 
-    for i in countup(0, sonsLen(n) - 1): fixRecordDef(n.sons[i])
-  of nkIdentDefs: 
-    for i in countup(0, sonsLen(n) - 3): exSymbol(n.sons[i])
-  of nkNilLit: nil
-  else: internalError(n.info, "fixRecordDef(): " & $n.kind)
-  
 proc addPragmaToIdent(ident: var PNode, pragma: PNode) = 
   var pragmasNode: PNode
   if ident.kind != nkPragmaExpr: 
@@ -371,25 +348,6 @@ proc addPragmaToIdent(ident: var PNode, pragma: PNode) =
       InternalError(ident.info, "addPragmaToIdent")
   addSon(pragmasNode, pragma)
   
-proc exSymbols(n: PNode) = 
-  if n == nil: return 
-  case n.kind
-  of nkEmpty..nkNilLit: nil
-  of nkProcDef..nkIteratorDef: exSymbol(n.sons[namePos])
-  of nkWhenStmt:
-    for i in countup(0, sonsLen(n) - 1): exSymbols(lastSon(n.sons[i]))
-  of nkStmtList: 
-    for i in countup(0, sonsLen(n) - 1): exSymbols(n.sons[i])
-  of nkVarSection, nkConstSection: 
-    for i in countup(0, sonsLen(n) - 1): exSymbol(n.sons[i].sons[0])
-  of nkTypeSection: 
-    for i in countup(0, sonsLen(n) - 1): 
-      exSymbol(n.sons[i].sons[0])
-      if (n.sons[i].sons[2] != nil) and
-          (n.sons[i].sons[2].kind == nkObjectTy): 
-        fixRecordDef(n.sons[i].sons[2])
-  else: nil
-  
 # --------------- parser -----------------------------------------------------
 # We use this parsing rule: If it looks like a declaration, it is one. This
 # avoids to build a symbol table, which can't be done reliably anyway for our
@@ -418,11 +376,6 @@ proc stmtKeyword(s: string): bool =
 
 # ------------------- type desc -----------------------------------------------
 
-proc skipIdent(p: var TParser): PNode = 
-  expectIdent(p)
-  result = mangledIdent(p.tok.s, p)
-  getTok(p, result)
-
 proc isIntType(s: string): bool =
   case s
   of "short", "int", "long", "float", "double", "signed", "unsigned":
@@ -519,7 +472,7 @@ proc parseStructBody(p: var TParser): PNode =
     while true:
       var def = newNodeP(nkIdentDefs, p)
       var t = pointer(p, baseTyp)
-      var i = skipIdent(p)
+      var i = skipIdentExport(p)
       t = parseTypeSuffix(p, t)
       addSon(def, i, t, nil)
       addSon(result, def)
@@ -615,7 +568,7 @@ proc parseFunctionPointerDecl(p: var TParser, rettyp: PNode): PNode =
   parseCallConv(p, pragmas)
   if p.tok.xkind == pxStar: getTok(p, params)
   else: parMessage(p, errTokenExpected, "*")
-  var name = skipIdent(p)
+  var name = skipIdentExport(p)
   eat(p, pxParRi, name)
   parseFormalParams(p, params, pragmas)
   addSon(procType, params)
@@ -651,11 +604,11 @@ proc otherTypeDef(p: var TParser, section, typ: PNode) =
   of pxStar:
     # typedef typ *b;
     t = pointer(p, typ)
-    name = skipIdent(p)
+    name = skipIdentExport(p)
   else: 
     # typedef typ name;
     t = typ
-    name = skipIdent(p)
+    name = skipIdentExport(p)
   t = parseTypeSuffix(p, t)
   addTypeDef(section, name, t)
 
@@ -663,7 +616,7 @@ proc parseTrailingDefinedTypes(p: var TParser, section, typ: PNode) =
   while p.tok.xkind == pxComma:
     getTok(p, nil)
     var newTyp = pointer(p, typ)
-    var newName = skipIdent(p)
+    var newName = skipIdentExport(p)
     newTyp = parseTypeSuffix(p, newTyp)
     addTypeDef(section, newName, newTyp)
 
@@ -697,7 +650,7 @@ proc parseTypeDef(p: var TParser): PNode =
       if p.tok.xkind == pxCurlyLe:
         var t = parseStruct(p)
         var name = skipIdent(p)
-        addTypeDef(result, structPragmas(p, name), t)
+        addTypeDef(result, structPragmas(p, exportSym(p, name)), t)
         parseTrailingDefinedTypes(p, result, name)
       elif p.tok.xkind == pxSymbol: 
         # name to be defined or type "struct a", we don't know yet:
@@ -709,10 +662,10 @@ proc parseTypeDef(p: var TParser): PNode =
             # typedef struct tagABC {} abc, *pabc;
             # --> abc is a better type name than tagABC!
             var name = skipIdent(p)
-            addTypeDef(result, structPragmas(p, name), t)
+            addTypeDef(result, structPragmas(p, exportSym(p, name)), t)
             parseTrailingDefinedTypes(p, result, name)
           else:
-            addTypeDef(result, structPragmas(p, nameOrType), t)
+            addTypeDef(result, structPragmas(p, exportSym(p, nameOrType)), t)
         of pxSymbol: 
           # typedef struct a a?
           if mangleName(p.tok.s, p) == nameOrType.ident.s:
@@ -732,7 +685,7 @@ proc parseTypeDef(p: var TParser): PNode =
         var t = enumFields(p)
         eat(p, pxCurlyRi, t)
         var name = skipIdent(p)
-        addTypeDef(result, enumPragmas(p, name), t)
+        addTypeDef(result, enumPragmas(p, exportSym(p, name)), t)
         parseTrailingDefinedTypes(p, result, name)
       elif p.tok.xkind == pxSymbol: 
         # name to be defined or type "enum a", we don't know yet:
@@ -746,10 +699,10 @@ proc parseTypeDef(p: var TParser): PNode =
             # typedef enum tagABC {} abc, *pabc;
             # --> abc is a better type name than tagABC!
             var name = skipIdent(p)
-            addTypeDef(result, enumPragmas(p, name), t)
+            addTypeDef(result, enumPragmas(p, exportSym(p, name)), t)
             parseTrailingDefinedTypes(p, result, name)
           else:
-            addTypeDef(result, enumPragmas(p, nameOrType), t)
+            addTypeDef(result, enumPragmas(p, exportSym(p, nameOrType)), t)
         of pxSymbol: 
           # typedef enum a a?
           if mangleName(p.tok.s, p) == nameOrType.ident.s:
@@ -798,7 +751,7 @@ proc parseVarDecl(p: var TParser, baseTyp, typ: PNode,
                   origName: string): PNode =  
   result = newNodeP(nkVarSection, p)
   var def = newNodeP(nkIdentDefs, p)
-  addSon(def, mangledIdentAndImport(origName, p))
+  addSon(def, varIdent(origName, p))
   addSon(def, parseTypeSuffix(p, typ))
   addInitializer(p, def)
   addSon(result, def)
@@ -808,7 +761,7 @@ proc parseVarDecl(p: var TParser, baseTyp, typ: PNode,
     var t = pointer(p, baseTyp)
     expectIdent(p)
     def = newNodeP(nkIdentDefs, p)
-    addSon(def, mangledIdentAndImport(p.tok.s, p))
+    addSon(def, varIdent(p.tok.s, p))
     getTok(p, def)
     addSon(def, parseTypeSuffix(p, t))
     addInitializer(p, def)
@@ -851,7 +804,7 @@ proc declaration(p: var TParser): PNode =
       addSon(pragmas, newIdentNodeP("cdecl", p))
     elif pfStdcall in p.options.flags:
       addSon(pragmas, newIdentNodeP("stdcall", p))
-    addSon(result, name)
+    addSon(result, exportSym(p, name))
     addSon(result, nil) # no generics
     addSon(result, params)
     addSon(result, pragmas)
@@ -883,7 +836,7 @@ proc enumSpecifier(p: var TParser): PNode =
     getTok(p, result)
     var i = 0
     while true:
-      var name = skipIdent(p)
+      var name = skipIdentExport(p)
       var val: PNode
       if p.tok.xkind == pxAsgn: 
         getTok(p, name)
@@ -908,7 +861,7 @@ proc enumSpecifier(p: var TParser): PNode =
       var t = newNodeP(nkTypeDef, p)
       getTok(p, t)
       var e = enumFields(p)
-      addSon(t, name, nil, e) # nil for generic params
+      addSon(t, exportSym(p, name), nil, e) # nil for generic params
       addSon(result, t)
   else:
     parMessage(p, errTokenExpected, "{")
@@ -1537,5 +1490,4 @@ proc parseUnit(p: var TParser): PNode =
   while p.tok.xkind != pxEof: 
     var s = statement(p)
     if s != nil: embedStmts(result, s)
-  exSymbols(result)
 
diff --git a/rod/c2nim/cpp.nim b/rod/c2nim/cpp.nim
index 46f78602b..860b1c063 100755
--- a/rod/c2nim/cpp.nim
+++ b/rod/c2nim/cpp.nim
@@ -40,7 +40,7 @@ proc parseDefine(p: var TParser): PNode =
     # a macro with parameters:
     result = newNodeP(nkTemplateDef, p)
     getTok(p)
-    addSon(result, skipIdent(p))
+    addSon(result, skipIdentExport(p))
     eat(p, pxParLe)
     var params = newNodeP(nkFormalParams, p)
     # return type; not known yet:
@@ -68,7 +68,7 @@ proc parseDefine(p: var TParser): PNode =
     while p.tok.xkind == pxDirective and p.tok.s == "define":
       getTok(p) # skip #define
       var c = newNodeP(nkConstDef, p)
-      addSon(c, skipIdent(p))
+      addSon(c, skipIdentExport(p))
       addSon(c, nil)
       skipStarCom(p, c)
       if p.tok.xkind in {pxLineComment, pxNewLine, pxEof}:
diff --git a/rod/c2nim/manual.txt b/rod/c2nim/manual.txt
index 3aca188b4..72c9d44da 100644
--- a/rod/c2nim/manual.txt
+++ b/rod/c2nim/manual.txt
@@ -234,8 +234,6 @@ Limitations
 
 * C's ``,`` operator (comma operator) is not supported.
 * C's ``union`` has no equivalent in Nimrod.
-* Standalone ``struct x {}`` declarations are not implemented. Put them into
-  a ``typedef``.
 * The condition in a ``do while(condition)`` statement must be ``0``.
 * Lots of other small issues...
 
diff --git a/rod/c2nim/tests/systest.c b/rod/c2nim/tests/systest.c
index 0cd174dc8..f6ccaeb0f 100644
--- a/rod/c2nim/tests/systest.c
+++ b/rod/c2nim/tests/systest.c
@@ -130,6 +130,7 @@ int IupConvertXYToPos(PIhandle ih, int x, int y);
 
   #ifdef C2NIM
   #  def EXTERN(x) static x
+  #  def TWO_ARGS(x, y) x* y
   #endif
   // parses now!
   EXTERN(int) f(void);
@@ -141,6 +142,9 @@ int IupConvertXYToPos(PIhandle ih, int x, int y);
   EXPORT int f(void);
   EXPORT int g(void); 
 
+  static TWO_ARGS(int, x) = TWO_ARGS(56, 45);
+
+
 #  define abc 34
 #  define xyz 42