Struct field function pointers, cstring, show toast error in cimport

This commit is contained in:
Ganesh Viswanathan 2018-12-27 22:42:55 -06:00
commit 21bd2d4112
7 changed files with 121 additions and 28 deletions

View file

@ -32,23 +32,28 @@ proc saveNodeData(node: TSNode): bool =
if name in ["math_expression", "primitive_type", "sized_type_specifier"]: if name in ["math_expression", "primitive_type", "sized_type_specifier"]:
val = val.getType() val = val.getType()
let if node.tsNodePrevNamedSibling().tsNodeIsNull() and
nparent = node.tsNodeParent() ((node.isPName("pointer_declarator") and not node.isPPName("function_declarator")) or
if not nparent.tsNodeIsNull() and node.tsNodePrevNamedSibling().tsNodeIsNull(): (node.getPName() in ["function_declarator", "array_declarator"] and node.isPPName("pointer_declarator"))):
let if gStateRT.data[^1].val != "object":
npname = nparent.tsNodeType() gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier()
npparent = nparent.tsNodeParent() if gStateRT.data[^1].val == "ptr char":
if npname == "pointer_declarator" or gStateRT.data[^1].val = "cstring"
($npname in ["function_declarator", "array_declarator"] and else:
not npparent.tsNodeIsNull() and npparent.tsNodeType() == "pointer_declarator"): gStateRT.data[^1].val = "pointer"
if gStateRT.data[^1].val != "object":
gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier()
else:
gStateRT.data[^1].val = "pointer"
gStateRT.data.add((name, val)) gStateRT.data.add((name, val))
if node.isPName("pointer_declarator") and node.isPPName("function_declarator"):
gStateRT.data.add(("function_declarator", ""))
elif name in ["abstract_pointer_declarator"]:
gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier()
if gStateRT.data[^1].val == "ptr char":
gStateRT.data[^1].val = "cstring"
elif name == "field_declaration":
gStateRT.data.add(("field_declaration", ""))
return true return true
proc searchAstForNode(ast: ref Ast, node: TSNode): bool = proc searchAstForNode(ast: ref Ast, node: TSNode): bool =

View file

@ -164,7 +164,15 @@ macro cImport*(filename: static string): untyped =
echo "Importing " & fullpath echo "Importing " & fullpath
result.add parseStmt(getToast(fullpath)) let
output = getToast(fullpath)
try:
result.add parseStmt(output)
except:
echo output
echo "Failed to import generated nim"
result.add parseStmt(output)
if gStateCT.debug: if gStateCT.debug:
echo result.repr echo result.repr

View file

@ -191,3 +191,17 @@ proc getAstChildByName*(ast: ref Ast, name: string): ref Ast =
for i in 0 .. ast.children.len-1: for i in 0 .. ast.children.len-1:
if name in ast.children[i].name.split("|"): if name in ast.children[i].name.split("|"):
return ast.children[i] return ast.children[i]
proc getPName*(node: TSNode): string =
if not node.tsNodeIsNull():
let
nparent = node.tsNodeParent()
if not nparent.tsNodeIsNull():
return $nparent.tsNodeType()
proc isPName*(node: TSNode, name: string): bool =
return node.getPName() == name
proc isPPName*(node: TSNode, name: string): bool =
if node.getPName().len != 0:
return node.tsNodeParent().isPName(name)

View file

@ -25,6 +25,7 @@ proc initGrammar() =
)) ))
let typeGrammar = """ let typeGrammar = """
(type_qualifier?)
(primitive_type|type_identifier?) (primitive_type|type_identifier?)
(sized_type_specifier? (sized_type_specifier?
(primitive_type?) (primitive_type?)
@ -88,6 +89,10 @@ proc initGrammar() =
var var
i = fstart i = fstart
while i < gStateRT.data.len-fend: while i < gStateRT.data.len-fend:
if gStateRT.data[i].name == "field_declaration":
i += 1
continue
let let
ftyp = gStateRT.data[i].val.getIdentifier() ftyp = gStateRT.data[i].val.getIdentifier()
fname = gStateRT.data[i+1].val.getIdentifier() fname = gStateRT.data[i+1].val.getIdentifier()
@ -96,17 +101,64 @@ proc initGrammar() =
flen = gStateRT.data[i+2].val.getIdentifier() flen = gStateRT.data[i+2].val.getIdentifier()
gStateRT.typeStr &= &" {fname}*: array[{flen}, {ftyp}]\n" gStateRT.typeStr &= &" {fname}*: array[{flen}, {ftyp}]\n"
i += 3 i += 3
elif i+2 < gStateRT.data.len-fend and gStateRT.data[i+2].name == "function_declarator":
var
pout, pname, ptyp = ""
count = 1
i += 3
while i < gStateRT.data.len-fend:
if gStateRT.data[i].name == "field_declaration":
break
ptyp = gStateRT.data[i].val.getIdentifier()
if gStateRT.data[i+1].name == "identifier":
pname = gStateRT.data[i+1].val.getIdentifier()
i += 2
else:
pname = "a" & $count
count += 1
i += 1
if ptyp != "object":
pout &= &"{pname}: {ptyp},"
if pout.len != 0 and pout[^1] == ',':
pout = pout[0 .. ^2]
if ftyp != "object":
gStateRT.typeStr &= &" {fname}*: proc({pout}): {ftyp} {{.nimcall.}}\n"
else:
gStateRT.typeStr &= &" {fname}*: proc({pout}) {{.nimcall.}}\n"
i += 1
else: else:
gStateRT.typeStr &= &" {fname}*: {ftyp}\n" gStateRT.typeStr &= &" {fname}*: {ftyp}\n"
i += 2 i += 2
let let
fieldGrammar = """ paramListGrammar = &"""
(parameter_list
(parameter_declaration*
{typeGrammar}
(identifier?)
(pointer_declarator?
(identifier)
)
(abstract_pointer_declarator?)
)
)
"""
fieldGrammar = &"""
(field_identifier?) (field_identifier?)
(array_declarator? (array_declarator?
(field_identifier) (field_identifier)
(identifier|number_literal) (identifier|number_literal)
) )
(function_declarator?
(pointer_declarator
(field_identifier)
)
{paramListGrammar}
)
""" """
fieldListGrammar = &""" fieldListGrammar = &"""
@ -231,16 +283,7 @@ proc initGrammar() =
let funcGrammar = &""" let funcGrammar = &"""
(function_declarator? (function_declarator?
(identifier) (identifier)
(parameter_list {paramListGrammar}
(parameter_declaration*
(type_qualifier?)
{typeGrammar}
(identifier?)
(pointer_declarator?
(identifier)
)
)
)
) )
""" """
@ -248,7 +291,6 @@ proc initGrammar() =
gStateRT.grammar.add((&""" gStateRT.grammar.add((&"""
(declaration (declaration
(storage_class_specifier?) (storage_class_specifier?)
(type_qualifier?)
{typeGrammar} {typeGrammar}
{funcGrammar} {funcGrammar}
(pointer_declarator? (pointer_declarator?

View file

@ -48,4 +48,10 @@ unsigned char test_call_param6(UNION2 param1) {
int test_call_param7(union UNION1 param1) { int test_call_param7(union UNION1 param1) {
return param1.field1; return param1.field1;
}
float test_call_param8(int *param1) {
*param1 = 5 * *param1;
return 1.0 * *param1;
} }

View file

@ -52,6 +52,12 @@ typedef struct {
ENUM4 *field5[TEST_INT]; ENUM4 *field5[TEST_INT];
} STRUCT4; } STRUCT4;
typedef struct STRUCT5 {
int (*tci)();
struct STRUCT1 (*tcp)(int);
float (*tcp8)(int *i);
} STRUCT5;
union UNION1 { union UNION1 {
int field1; int field1;
float field2; float field2;
@ -69,4 +75,5 @@ STRUCT2 test_call_param3(int param1, struct STRUCT1 param2);
ENUM2 test_call_param4(enum ENUM param1); ENUM2 test_call_param4(enum ENUM param1);
union UNION1 test_call_param5(float param1); union UNION1 test_call_param5(float param1);
unsigned char test_call_param6(UNION2 param1); 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);

View file

@ -21,6 +21,7 @@ var
s2: STRUCT2 s2: STRUCT2
s3: STRUCT3 s3: STRUCT3
s4: STRUCT4 s4: STRUCT4
s5: STRUCT5
e: ENUM e: ENUM
e2: ENUM2 = enum5 e2: ENUM2 = enum5
@ -33,6 +34,8 @@ var
u: UNION1 u: UNION1
u2: UNION2 u2: UNION2
i: int
pt = 3 pt = 3
ct = 4 ct = 4
@ -41,12 +44,18 @@ s2.field1 = 6
s3.field1 = 7 s3.field1 = 7
s4.field2[2] = 5 s4.field2[2] = 5
s4.field3[3] = enum1 s4.field3[3] = enum1
s5.tci = test_call_int
s5.tcp = test_call_param
s5.tcp8 = test_call_param8
check s5.tci() == 5
e = enum1 e = enum1
e2 = enum4 e2 = enum4
u2.field2 = 'c' u2.field2 = 'c'
i = 5
check test_call_int() == 5 check test_call_int() == 5
check test_call_param(5).field1 == 5 check test_call_param(5).field1 == 5
check test_call_param2(5, s2).field1 == 11 check test_call_param2(5, s2).field1 == 11
@ -56,6 +65,8 @@ check test_call_param5(5.0).field2 == 5.0
check test_call_param6(u2) == 'c' check test_call_param6(u2) == 'c'
u.field1 = 4 u.field1 = 4
check test_call_param7(u) == 4 check test_call_param7(u) == 4
check test_call_param8(addr i) == 25.0
check i == 25
check e3 == enum7 check e3 == enum7
check e4 == enum11 check e4 == enum11