diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2019-03-23 13:33:52 -0500 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2019-03-23 13:33:52 -0500 |
| commit | 454403b9fe96788534ade09631d3546edc418add (patch) | |
| tree | ace5ca6a855967036caea8997ab280aa8a4b7ffc | |
| parent | 28e2d7bb872c94ca0f25ba0e018b5d6132dc8fbc (diff) | |
| download | nimterop-454403b9fe96788534ade09631d3546edc418add.tar.gz nimterop-454403b9fe96788534ade09631d3546edc418add.zip | |
Double pointer support
| -rw-r--r-- | nimterop/ast.nim | 9 | ||||
| -rw-r--r-- | nimterop/getters.nim | 6 | ||||
| -rw-r--r-- | nimterop/globals.nim | 4 | ||||
| -rw-r--r-- | nimterop/grammar.nim | 89 | ||||
| -rw-r--r-- | tests/include/test.c | 4 | ||||
| -rw-r--r-- | tests/include/test.h | 15 | ||||
| -rw-r--r-- | tests/tnimterop_c.nim | 16 |
7 files changed, 111 insertions, 32 deletions
diff --git a/nimterop/ast.nim b/nimterop/ast.nim index aede004..dc0ac3c 100644 --- a/nimterop/ast.nim +++ b/nimterop/ast.nim @@ -23,6 +23,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = pname = node.getPxName(1) ppname = node.getPxName(2) pppname = node.getPxName(3) + ppppname = node.getPxName(4) if node.tsNodePrevNamedSibling().tsNodeIsNull(): if pname == "pointer_declarator": @@ -30,9 +31,15 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = nimState.data.add(("pointer_declarator", "")) elif ppname == "array_declarator": nimState.data.add(("array_pointer_declarator", "")) + + # Double pointer + if ppname == "pointer_declarator": + nimState.data.add(("pointer_declarator", "")) elif pname in ["function_declarator", "array_declarator"]: if ppname == "pointer_declarator": nimState.data.add(("pointer_declarator", "")) + if pppname == "pointer_declarator": + nimState.data.add(("pointer_declarator", "")) nimState.data.add((name, val)) @@ -41,6 +48,8 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool = ppname == "function_declarator": if pppname == "pointer_declarator": nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) + if ppppname == "pointer_declarator": + nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) nimState.data.add(("function_declarator", "")) elif name in gExpressions: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 2fe7447..052e532 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -24,7 +24,7 @@ using var when while xor -yield""".split(Whitespace).toSet() +yield""".split(Whitespace).toHashSet() const gTypeMap = { # char @@ -151,8 +151,12 @@ proc getPtrType*(str: string): string = result = case str: of "ptr cchar": "cstring" + of "ptr ptr cchar": + "ptr cstring" of "ptr object": "pointer" + of "ptr ptr object": + "ptr pointer" else: str diff --git a/nimterop/globals.nim b/nimterop/globals.nim index bdb29dc..2f1a451 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -16,14 +16,14 @@ const "primitive_type", "sized_type_specifier", "type_identifier" - ].toSet() + ].toHashSet() gExpressions {.used.} = @[ "parenthesized_expression", "bitwise_expression", "shift_expression", "math_expression" - ].toSet() + ].toHashSet() gEnumVals {.used.} = @[ "identifier", diff --git a/nimterop/grammar.nim b/nimterop/grammar.nim index 3895aa1..8cd3275 100644 --- a/nimterop/grammar.nim +++ b/nimterop/grammar.nim @@ -50,6 +50,9 @@ proc initGrammar(): Grammar = {typeGrammar} (identifier|type_identifier?) (pointer_declarator? + (pointer_declarator! + (identifier|type_identifier) + ) (identifier|type_identifier) ) (abstract_pointer_declarator?) @@ -61,6 +64,9 @@ proc initGrammar(): Grammar = (function_declarator* (identifier|type_identifier!) (pointer_declarator + (pointer_declarator! + (type_identifier) + ) (type_identifier) ) {paramListGrammar} @@ -70,6 +76,9 @@ proc initGrammar(): Grammar = arrGrammar = &""" (array_declarator! (pointer_declarator! + (pointer_declarator! + (type_identifier) + ) (type_identifier) ) (type_identifier) @@ -80,11 +89,10 @@ proc initGrammar(): Grammar = template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i: untyped): untyped = ptyp = nimState.data[i].val.getIdentifier(nskType, fname) - if i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator": - pptr = "ptr " + pptr = "" + while i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator": + pptr &= "ptr " i += 1 - else: - pptr = "" if i+1 < nimState.data.len and nimState.data[i+1].name == "identifier": pname = nimState.data[i+1].val.getIdentifier(nskParam, fname) @@ -94,8 +102,8 @@ proc initGrammar(): Grammar = count += 1 i += 1 - if pptr == "ptr " or ptyp != "object": - pout &= &"{pname}: {getPtrType(pptr&ptyp)}," + if pptr.len != 0 or ptyp != "object": + pout &= &"{pname}: {getPtrType(pptr&ptyp)}, " # typedef int X # typedef X Y @@ -107,6 +115,11 @@ proc initGrammar(): Grammar = (type_identifier!) {arrGrammar} (pointer_declarator! + (pointer_declarator! + (type_identifier!) + {arrGrammar} + {funcGrammar} + ) (type_identifier!) {arrGrammar} {funcGrammar} @@ -123,13 +136,13 @@ proc initGrammar(): Grammar = aptr = "" i += 1 - if i < nimState.data.len: + while i < nimState.data.len and "pointer" in nimState.data[i].name: case nimState.data[i].name: of "pointer_declarator": - tptr = "ptr " + tptr &= "ptr " i += 1 of "array_pointer_declarator": - aptr = "ptr " + aptr &= "ptr " i += 1 if i < nimState.data.len: @@ -149,10 +162,10 @@ proc initGrammar(): Grammar = funcParamCommon(fname, pname, ptyp, pptr, pout, count, i) - if pout.len != 0 and pout[^1] == ',': - pout = pout[0 .. ^2] + if pout.len != 0 and pout[^2 .. ^1] == ", ": + pout = pout[0 .. ^3] - if tptr == "ptr " or typ != "object": + if tptr.len != 0 or typ != "object": nimState.typeStr &= &"\n {name}* = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}" else: nimState.typeStr &= &"\n {name}* = proc({pout}) {{.nimcall.}}" @@ -242,13 +255,14 @@ proc initGrammar(): Grammar = ftyp = nimState.data[i].val.getType() i += 1 - case nimState.data[i].name: - of "pointer_declarator": - fptr = "ptr " - i += 1 - of "array_pointer_declarator": - aptr = "ptr " - i += 1 + while i < nimState.data.len-fend and "pointer" in nimState.data[i].name: + case nimState.data[i].name: + of "pointer_declarator": + fptr &= "ptr " + i += 1 + of "array_pointer_declarator": + aptr &= "ptr " + i += 1 fname = nimState.data[i].val.getIdentifier(nskField, nname) @@ -273,9 +287,9 @@ proc initGrammar(): Grammar = funcParamCommon(fname, pname, ptyp, pptr, pout, count, i) - if pout.len != 0 and pout[^1] == ',': - pout = pout[0 .. ^2] - if fptr == "ptr " or ftyp != "object": + if pout.len != 0 and pout[^2 .. ^1] == ", ": + pout = pout[0 .. ^3] + if fptr.len != 0 or ftyp != "object": nimState.typeStr &= &"\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}" else: nimState.typeStr &= &"\n {fname}*: proc({pout}) {{.nimcall.}}" @@ -297,12 +311,18 @@ proc initGrammar(): Grammar = (array_declarator! (field_identifier!) (pointer_declarator + (pointer_declarator! + (field_identifier) + ) (field_identifier) ) (^$1+) ) (function_declarator+ (pointer_declarator + (pointer_declarator! + (field_identifier) + ) (field_identifier) ) {paramListGrammar} @@ -314,6 +334,9 @@ proc initGrammar(): Grammar = (field_declaration+ {typeGrammar} (pointer_declarator! + (pointer_declarator! + {fieldGrammar} + ) {fieldGrammar} ) {fieldGrammar} @@ -341,6 +364,9 @@ proc initGrammar(): Grammar = ) (type_identifier!) (pointer_declarator + (pointer_declarator! + (type_identifier) + ) (type_identifier) ) ) @@ -433,6 +459,9 @@ proc initGrammar(): Grammar = {result[^1].grammar} (type_identifier!) (pointer_declarator + (pointer_declarator! + (type_identifier) + ) (type_identifier) ) ) @@ -459,6 +488,9 @@ proc initGrammar(): Grammar = (storage_class_specifier?) {typeGrammar} (pointer_declarator! + (pointer_declarator! + {funcGrammar} + ) {funcGrammar} ) {funcGrammar} @@ -474,11 +506,10 @@ proc initGrammar(): Grammar = i += 1 continue - if nimState.data[i].name == "pointer_declarator": - fptr = "ptr " + fptr = "" + while i < nimState.data.len and nimState.data[i].name == "pointer_declarator": + fptr &= "ptr " i += 1 - else: - fptr = "" var fname = nimState.data[i].val @@ -493,12 +524,12 @@ proc initGrammar(): Grammar = funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i) - if pout.len != 0 and pout[^1] == ',': - pout = pout[0 .. ^2] + if pout.len != 0 and pout[^2 .. ^1] == ", ": + pout = pout[0 .. ^3] if fnname.nBl and nimState.identifiers.addNewIdentifer(fnname): let ftyp = nimState.data[0].val.getIdentifier(nskType, fnname) - if fptr == "ptr " or ftyp != "object": + if fptr.len != 0 or ftyp != "object": nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}" else: nimState.procStr &= &"\nproc {fnname}*({pout}) {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}" diff --git a/tests/include/test.c b/tests/include/test.c index 0312b4f..8990df9 100644 --- a/tests/include/test.c +++ b/tests/include/test.c @@ -60,6 +60,10 @@ void *test_call9() { return NULL; } +void **test_call10(int **param1) { + return NULL; +} + void multiline1(void) {} void *multiline2(void) { diff --git a/tests/include/test.h b/tests/include/test.h index e85acfd..9dba8ba 100644 --- a/tests/include/test.h +++ b/tests/include/test.h @@ -108,6 +108,7 @@ unsigned char test_call_param6(UNION2 param1); int test_call_param7(union UNION1 param1); float test_call_param8(int *param1); void *test_call9(); +void **test_call10(int **param1); // Issue #58 void @@ -131,6 +132,20 @@ UNION3 test_call_etype_ptr3(); typedef struct _Kernel { char name; } *Kernel; +// Double pointers +typedef void **DVOIDPTR; +typedef int **DINTPTR; + +struct dstruct { + int **field1; +}; + +typedef struct dstruct2 { + char **field1; + float **field2; + void **(*tcv)(int **param1); +} DSTRUCT2; + #ifdef __cplusplus } #endif
\ No newline at end of file diff --git a/tests/tnimterop_c.nim b/tests/tnimterop_c.nim index 86ac0fd..3fc33b9 100644 --- a/tests/tnimterop_c.nim +++ b/tests/tnimterop_c.nim @@ -145,3 +145,19 @@ when false: doAssert foobar1(3) == OSDEF * 3 when false: # Error: undeclared identifier: 'foobar2' doAssert foobar2(3) == 3 + 1 + +# Double pointer +var + dv: DVOIDPTR + di: DINTPTR + ds: dstruct + cstr = "Hello".cstring + ds2: DSTRUCT2 + +dv = addr vptr +di = addr iptr + +ds.field1 = di +ds2.field1 = addr cstr +ds2.tcv = test_call10 +check ds2.tcv(di) == nil
\ No newline at end of file |
