diff options
author | Vincent Burns <discoloda@gmail.com> | 2014-01-14 11:22:59 -0500 |
---|---|---|
committer | Vincent Burns <discoloda@gmail.com> | 2014-01-14 11:22:59 -0500 |
commit | d35dedf041d1ded5843a064c855e8e36dc194221 (patch) | |
tree | b5885c6f67df1d5809ed3dc1334a19aba389baa9 /compiler | |
parent | d9a61c13dd4a355a3898b4b852d078a2e1b5f0fd (diff) | |
download | Nim-d35dedf041d1ded5843a064c855e8e36dc194221.tar.gz |
Slightly better type parsing for parameters and cast expressions
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/c2nim/cparse.nim | 48 | ||||
-rw-r--r-- | compiler/c2nim/tests/vincent.c | 5 |
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., |