Struct field function pointers, cstring, show toast error in cimport
This commit is contained in:
parent
c7a3c7b7d6
commit
21bd2d4112
7 changed files with 121 additions and 28 deletions
|
|
@ -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
|
|
||||||
npname = nparent.tsNodeType()
|
|
||||||
npparent = nparent.tsNodeParent()
|
|
||||||
if npname == "pointer_declarator" or
|
|
||||||
($npname in ["function_declarator", "array_declarator"] and
|
|
||||||
not npparent.tsNodeIsNull() and npparent.tsNodeType() == "pointer_declarator"):
|
|
||||||
|
|
||||||
if gStateRT.data[^1].val != "object":
|
if gStateRT.data[^1].val != "object":
|
||||||
gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier()
|
gStateRT.data[^1].val = "ptr " & gStateRT.data[^1].val.getIdentifier()
|
||||||
|
if gStateRT.data[^1].val == "ptr char":
|
||||||
|
gStateRT.data[^1].val = "cstring"
|
||||||
else:
|
else:
|
||||||
gStateRT.data[^1].val = "pointer"
|
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 =
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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?
|
||||||
|
|
|
||||||
|
|
@ -49,3 +49,9 @@ 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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -70,3 +76,4 @@ 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);
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue