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)
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:

View file

@ -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

View file

@ -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",

View file

@ -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}.}}"

View file

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

View file

@ -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

View file

@ -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