summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorVincent Burns <discoloda@gmail.com>2014-01-14 11:22:59 -0500
committerVincent Burns <discoloda@gmail.com>2014-01-14 11:22:59 -0500
commitd35dedf041d1ded5843a064c855e8e36dc194221 (patch)
treeb5885c6f67df1d5809ed3dc1334a19aba389baa9 /compiler
parentd9a61c13dd4a355a3898b4b852d078a2e1b5f0fd (diff)
downloadNim-d35dedf041d1ded5843a064c855e8e36dc194221.tar.gz
Slightly better type parsing for parameters and cast expressions
Diffstat (limited to 'compiler')
-rw-r--r--compiler/c2nim/cparse.nim48
-rw-r--r--compiler/c2nim/tests/vincent.c5
2 files changed, 46 insertions, 7 deletions
diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim
index df263ee4e..aa9929139 100644
--- a/compiler/c2nim/cparse.nim
+++ b/compiler/c2nim/cparse.nim
@@ -651,6 +651,22 @@ proc parseTypeSuffix(p: var TParser, typ: PNode): PNode =
 proc typeDesc(p: var TParser): PNode = 
   result = pointer(p, typeAtom(p))
 
+proc abstractDeclarator(p: var TParser, a: PNode): PNode
+
+proc directAbstractDeclarator(p: var TParser, a: PNode): PNode =
+  if p.tok.xkind == pxParLe:
+    getTok(p, a)
+    if p.tok.xkind in {pxStar, pxAmp, pxAmpAmp}:
+      result = abstractDeclarator(p, a)
+      eat(p, pxParRi, result)
+  return parseTypeSuffix(p, a)
+
+proc abstractDeclarator(p: var TParser, a: PNode): PNode =
+  return directAbstractDeclarator(p, pointer(p, a))
+
+proc typeName(p: var TParser): PNode =
+  return abstractDeclarator(p, typeAtom(p))
+
 proc parseField(p: var TParser, kind: TNodeKind): PNode =
   if p.tok.xkind == pxParLe: 
     getTok(p, nil)
@@ -716,18 +732,36 @@ proc parseStruct(p: var TParser, isUnion: bool): PNode =
   else: 
     addSon(result, newNodeP(nkRecList, p))
 
+proc declarator(p: var TParser, a: PNode, ident: ptr PNode): PNode
+
+proc directDeclarator(p: var TParser, a: PNode, ident: ptr PNode): PNode =
+  case p.tok.xkind
+  of pxSymbol:
+    ident[] = skipIdent(p)
+  of pxParLe:
+    getTok(p, a)
+    if p.tok.xkind in {pxStar, pxAmp, pxAmpAmp, pxSymbol}:
+      result = declarator(p, a, ident)
+      eat(p, pxParRi, result)
+  else:
+    nil
+  return parseTypeSuffix(p, a)
+
+proc declarator(p: var TParser, a: PNode, ident: ptr PNode): PNode =
+  return directDeclarator(p, pointer(p, a), ident)
+
+# parameter-declaration
+#   declaration-specifiers declarator
+#   declaration-specifiers asbtract-declarator(opt)
 proc parseParam(p: var TParser, params: PNode) = 
   var typ = typeDesc(p)
   # support for ``(void)`` parameter list: 
   if typ.kind == nkNilLit and p.tok.xkind == pxParRi: return
   var name: PNode
-  if p.tok.xkind == pxSymbol: 
-    name = skipIdent(p)
-  else:
-    # generate a name for the formal parameter:
+  typ = declarator(p, typ, addr name)
+  if name == nil:
     var idx = sonsLen(params)+1
     name = newIdentNodeP("a" & $idx, p)
-  typ = parseTypeSuffix(p, typ)
   var x = newNodeP(nkIdentDefs, p)
   addSon(x, name, typ)
   if p.tok.xkind == pxAsgn: 
@@ -1150,7 +1184,7 @@ proc startExpression(p : var TParser, tok : TToken) : PNode =
       except:
         backtrackContext(p)
         eat(p, pxParLe)
-        addSon(result, typeDesc(p))
+        addSon(result, typeName(p))
         eat(p, pxParRi)
     elif (tok.s == "new" or tok.s == "delete") and pfCpp in p.options.flags:
       var opr = tok.s
@@ -1200,7 +1234,7 @@ proc startExpression(p : var TParser, tok : TToken) : PNode =
     except:
       backtrackContext(p)
       result = newNodeP(nkCast, p)
-      addSon(result, typeDesc(p))
+      addSon(result, typeName(p))
       eat(p, pxParRi, result)
       addSon(result, expression(p, 139))
   of pxPlusPlus:
diff --git a/compiler/c2nim/tests/vincent.c b/compiler/c2nim/tests/vincent.c
index b9436c39b..a30077f77 100644
--- a/compiler/c2nim/tests/vincent.c
+++ b/compiler/c2nim/tests/vincent.c
@@ -3,6 +3,11 @@
 
 int rand(void);
 
+int id(void (*f)(void)) {
+    f();
+    ((void (*)(int))f)(10);
+}
+
 int main() {
     float f = .2,
           g = 2.,