Double pointer support

This commit is contained in:
Ganesh Viswanathan 2019-03-23 13:33:52 -05:00
commit 454403b9fe
7 changed files with 111 additions and 32 deletions

View file

@ -23,6 +23,7 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool =
pname = node.getPxName(1) pname = node.getPxName(1)
ppname = node.getPxName(2) ppname = node.getPxName(2)
pppname = node.getPxName(3) pppname = node.getPxName(3)
ppppname = node.getPxName(4)
if node.tsNodePrevNamedSibling().tsNodeIsNull(): if node.tsNodePrevNamedSibling().tsNodeIsNull():
if pname == "pointer_declarator": if pname == "pointer_declarator":
@ -30,9 +31,15 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool =
nimState.data.add(("pointer_declarator", "")) nimState.data.add(("pointer_declarator", ""))
elif ppname == "array_declarator": elif ppname == "array_declarator":
nimState.data.add(("array_pointer_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"]: elif pname in ["function_declarator", "array_declarator"]:
if ppname == "pointer_declarator": if ppname == "pointer_declarator":
nimState.data.add(("pointer_declarator", "")) nimState.data.add(("pointer_declarator", ""))
if pppname == "pointer_declarator":
nimState.data.add(("pointer_declarator", ""))
nimState.data.add((name, val)) nimState.data.add((name, val))
@ -41,6 +48,8 @@ proc saveNodeData(node: TSNode, nimState: NimState): bool =
ppname == "function_declarator": ppname == "function_declarator":
if pppname == "pointer_declarator": if pppname == "pointer_declarator":
nimState.data.insert(("pointer_declarator", ""), nimState.data.len-1) 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", "")) nimState.data.add(("function_declarator", ""))
elif name in gExpressions: elif name in gExpressions:

View file

@ -24,7 +24,7 @@ using
var var
when while when while
xor xor
yield""".split(Whitespace).toSet() yield""".split(Whitespace).toHashSet()
const gTypeMap = { const gTypeMap = {
# char # char
@ -151,8 +151,12 @@ proc getPtrType*(str: string): string =
result = case str: result = case str:
of "ptr cchar": of "ptr cchar":
"cstring" "cstring"
of "ptr ptr cchar":
"ptr cstring"
of "ptr object": of "ptr object":
"pointer" "pointer"
of "ptr ptr object":
"ptr pointer"
else: else:
str str

View file

@ -16,14 +16,14 @@ const
"primitive_type", "primitive_type",
"sized_type_specifier", "sized_type_specifier",
"type_identifier" "type_identifier"
].toSet() ].toHashSet()
gExpressions {.used.} = @[ gExpressions {.used.} = @[
"parenthesized_expression", "parenthesized_expression",
"bitwise_expression", "bitwise_expression",
"shift_expression", "shift_expression",
"math_expression" "math_expression"
].toSet() ].toHashSet()
gEnumVals {.used.} = @[ gEnumVals {.used.} = @[
"identifier", "identifier",

View file

@ -50,6 +50,9 @@ proc initGrammar(): Grammar =
{typeGrammar} {typeGrammar}
(identifier|type_identifier?) (identifier|type_identifier?)
(pointer_declarator? (pointer_declarator?
(pointer_declarator!
(identifier|type_identifier)
)
(identifier|type_identifier) (identifier|type_identifier)
) )
(abstract_pointer_declarator?) (abstract_pointer_declarator?)
@ -61,6 +64,9 @@ proc initGrammar(): Grammar =
(function_declarator* (function_declarator*
(identifier|type_identifier!) (identifier|type_identifier!)
(pointer_declarator (pointer_declarator
(pointer_declarator!
(type_identifier)
)
(type_identifier) (type_identifier)
) )
{paramListGrammar} {paramListGrammar}
@ -70,6 +76,9 @@ proc initGrammar(): Grammar =
arrGrammar = &""" arrGrammar = &"""
(array_declarator! (array_declarator!
(pointer_declarator! (pointer_declarator!
(pointer_declarator!
(type_identifier)
)
(type_identifier) (type_identifier)
) )
(type_identifier) (type_identifier)
@ -80,11 +89,10 @@ proc initGrammar(): Grammar =
template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i: untyped): untyped = template funcParamCommon(fname, pname, ptyp, pptr, pout, count, i: untyped): untyped =
ptyp = nimState.data[i].val.getIdentifier(nskType, fname) ptyp = nimState.data[i].val.getIdentifier(nskType, fname)
if i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator": pptr = ""
pptr = "ptr " while i+1 < nimState.data.len and nimState.data[i+1].name == "pointer_declarator":
pptr &= "ptr "
i += 1 i += 1
else:
pptr = ""
if i+1 < nimState.data.len and nimState.data[i+1].name == "identifier": if i+1 < nimState.data.len and nimState.data[i+1].name == "identifier":
pname = nimState.data[i+1].val.getIdentifier(nskParam, fname) pname = nimState.data[i+1].val.getIdentifier(nskParam, fname)
@ -94,8 +102,8 @@ proc initGrammar(): Grammar =
count += 1 count += 1
i += 1 i += 1
if pptr == "ptr " or ptyp != "object": if pptr.len != 0 or ptyp != "object":
pout &= &"{pname}: {getPtrType(pptr&ptyp)}," pout &= &"{pname}: {getPtrType(pptr&ptyp)}, "
# typedef int X # typedef int X
# typedef X Y # typedef X Y
@ -107,6 +115,11 @@ proc initGrammar(): Grammar =
(type_identifier!) (type_identifier!)
{arrGrammar} {arrGrammar}
(pointer_declarator! (pointer_declarator!
(pointer_declarator!
(type_identifier!)
{arrGrammar}
{funcGrammar}
)
(type_identifier!) (type_identifier!)
{arrGrammar} {arrGrammar}
{funcGrammar} {funcGrammar}
@ -123,13 +136,13 @@ proc initGrammar(): Grammar =
aptr = "" aptr = ""
i += 1 i += 1
if i < nimState.data.len: while i < nimState.data.len and "pointer" in nimState.data[i].name:
case nimState.data[i].name: case nimState.data[i].name:
of "pointer_declarator": of "pointer_declarator":
tptr = "ptr " tptr &= "ptr "
i += 1 i += 1
of "array_pointer_declarator": of "array_pointer_declarator":
aptr = "ptr " aptr &= "ptr "
i += 1 i += 1
if i < nimState.data.len: if i < nimState.data.len:
@ -149,10 +162,10 @@ proc initGrammar(): Grammar =
funcParamCommon(fname, pname, ptyp, pptr, pout, count, i) funcParamCommon(fname, pname, ptyp, pptr, pout, count, i)
if pout.len != 0 and pout[^1] == ',': if pout.len != 0 and pout[^2 .. ^1] == ", ":
pout = pout[0 .. ^2] 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.}}" nimState.typeStr &= &"\n {name}* = proc({pout}): {getPtrType(tptr&typ)} {{.nimcall.}}"
else: else:
nimState.typeStr &= &"\n {name}* = proc({pout}) {{.nimcall.}}" nimState.typeStr &= &"\n {name}* = proc({pout}) {{.nimcall.}}"
@ -242,13 +255,14 @@ proc initGrammar(): Grammar =
ftyp = nimState.data[i].val.getType() ftyp = nimState.data[i].val.getType()
i += 1 i += 1
case nimState.data[i].name: while i < nimState.data.len-fend and "pointer" in nimState.data[i].name:
of "pointer_declarator": case nimState.data[i].name:
fptr = "ptr " of "pointer_declarator":
i += 1 fptr &= "ptr "
of "array_pointer_declarator": i += 1
aptr = "ptr " of "array_pointer_declarator":
i += 1 aptr &= "ptr "
i += 1
fname = nimState.data[i].val.getIdentifier(nskField, nname) fname = nimState.data[i].val.getIdentifier(nskField, nname)
@ -273,9 +287,9 @@ proc initGrammar(): Grammar =
funcParamCommon(fname, pname, ptyp, pptr, pout, count, i) funcParamCommon(fname, pname, ptyp, pptr, pout, count, i)
if pout.len != 0 and pout[^1] == ',': if pout.len != 0 and pout[^2 .. ^1] == ", ":
pout = pout[0 .. ^2] pout = pout[0 .. ^3]
if fptr == "ptr " or ftyp != "object": if fptr.len != 0 or ftyp != "object":
nimState.typeStr &= &"\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}" nimState.typeStr &= &"\n {fname}*: proc({pout}): {getPtrType(fptr&ftyp)} {{.nimcall.}}"
else: else:
nimState.typeStr &= &"\n {fname}*: proc({pout}) {{.nimcall.}}" nimState.typeStr &= &"\n {fname}*: proc({pout}) {{.nimcall.}}"
@ -297,12 +311,18 @@ proc initGrammar(): Grammar =
(array_declarator! (array_declarator!
(field_identifier!) (field_identifier!)
(pointer_declarator (pointer_declarator
(pointer_declarator!
(field_identifier)
)
(field_identifier) (field_identifier)
) )
(^$1+) (^$1+)
) )
(function_declarator+ (function_declarator+
(pointer_declarator (pointer_declarator
(pointer_declarator!
(field_identifier)
)
(field_identifier) (field_identifier)
) )
{paramListGrammar} {paramListGrammar}
@ -314,6 +334,9 @@ proc initGrammar(): Grammar =
(field_declaration+ (field_declaration+
{typeGrammar} {typeGrammar}
(pointer_declarator! (pointer_declarator!
(pointer_declarator!
{fieldGrammar}
)
{fieldGrammar} {fieldGrammar}
) )
{fieldGrammar} {fieldGrammar}
@ -341,6 +364,9 @@ proc initGrammar(): Grammar =
) )
(type_identifier!) (type_identifier!)
(pointer_declarator (pointer_declarator
(pointer_declarator!
(type_identifier)
)
(type_identifier) (type_identifier)
) )
) )
@ -433,6 +459,9 @@ proc initGrammar(): Grammar =
{result[^1].grammar} {result[^1].grammar}
(type_identifier!) (type_identifier!)
(pointer_declarator (pointer_declarator
(pointer_declarator!
(type_identifier)
)
(type_identifier) (type_identifier)
) )
) )
@ -459,6 +488,9 @@ proc initGrammar(): Grammar =
(storage_class_specifier?) (storage_class_specifier?)
{typeGrammar} {typeGrammar}
(pointer_declarator! (pointer_declarator!
(pointer_declarator!
{funcGrammar}
)
{funcGrammar} {funcGrammar}
) )
{funcGrammar} {funcGrammar}
@ -474,11 +506,10 @@ proc initGrammar(): Grammar =
i += 1 i += 1
continue continue
if nimState.data[i].name == "pointer_declarator": fptr = ""
fptr = "ptr " while i < nimState.data.len and nimState.data[i].name == "pointer_declarator":
fptr &= "ptr "
i += 1 i += 1
else:
fptr = ""
var var
fname = nimState.data[i].val fname = nimState.data[i].val
@ -493,12 +524,12 @@ proc initGrammar(): Grammar =
funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i) funcParamCommon(fnname, pname, ptyp, pptr, pout, count, i)
if pout.len != 0 and pout[^1] == ',': if pout.len != 0 and pout[^2 .. ^1] == ", ":
pout = pout[0 .. ^2] pout = pout[0 .. ^3]
if fnname.nBl and nimState.identifiers.addNewIdentifer(fnname): if fnname.nBl and nimState.identifiers.addNewIdentifer(fnname):
let ftyp = nimState.data[0].val.getIdentifier(nskType, 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}.}}" nimState.procStr &= &"\nproc {fnname}*({pout}): {getPtrType(fptr&ftyp)} {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}"
else: else:
nimState.procStr &= &"\nproc {fnname}*({pout}) {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}" nimState.procStr &= &"\nproc {fnname}*({pout}) {{.{genImportC(fname, fnname)}, header: {nimState.currentHeader}.}}"

View file

@ -60,6 +60,10 @@ void *test_call9() {
return NULL; return NULL;
} }
void **test_call10(int **param1) {
return NULL;
}
void multiline1(void) {} void multiline1(void) {}
void *multiline2(void) { void *multiline2(void) {

View file

@ -108,6 +108,7 @@ unsigned char test_call_param6(UNION2 param1);
int test_call_param7(union UNION1 param1); int test_call_param7(union UNION1 param1);
float test_call_param8(int *param1); float test_call_param8(int *param1);
void *test_call9(); void *test_call9();
void **test_call10(int **param1);
// Issue #58 // Issue #58
void void
@ -131,6 +132,20 @@ UNION3 test_call_etype_ptr3();
typedef struct _Kernel { char name; } *Kernel; 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -145,3 +145,19 @@ when false:
doAssert foobar1(3) == OSDEF * 3 doAssert foobar1(3) == OSDEF * 3
when false: # Error: undeclared identifier: 'foobar2' when false: # Error: undeclared identifier: 'foobar2'
doAssert foobar2(3) == 3 + 1 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