diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2020-01-09 13:58:34 -0600 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2020-01-16 09:23:54 -0600 |
| commit | ee58be398ad47fe62a722d29bba9fc5344a513ad (patch) | |
| tree | a3ecea209c9db5003eff9d1f4d6aacc0c56f58b1 | |
| parent | 166eae7a5a7bdc697c2a8103e89302f5415b5bad (diff) | |
| download | nimterop-ee58be398ad47fe62a722d29bba9fc5344a513ad.tar.gz nimterop-ee58be398ad47fe62a722d29bba9fc5344a513ad.zip | |
Fix type bugs, enable basic tests
| -rw-r--r-- | nimterop.nimble | 23 | ||||
| -rw-r--r-- | nimterop/ast2.nim | 128 | ||||
| -rw-r--r-- | nimterop/getters.nim | 9 | ||||
| -rw-r--r-- | nimterop/globals.nim | 10 | ||||
| -rw-r--r-- | tests/include/test3.h | 42 | ||||
| -rw-r--r-- | tests/tnimterop2.nim | 71 |
6 files changed, 223 insertions, 60 deletions
diff --git a/nimterop.nimble b/nimterop.nimble index 3b6b7c1..39a2346 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -36,19 +36,22 @@ task docs, "Generate docs": task test, "Test": buildToastTask() - execTest "tests/tnimterop_c.nim" - execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" - execCmd "./nimterop/toast -pnk -E=_ tests/include/toast.h" - execTest "tests/tpcre.nim" + execTest "tests/tnimterop2.nim" + + # Commented out until newalgo is ready + # execTest "tests/tnimterop_c.nim" + # execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" + # execCmd "./nimterop/toast -pnk -E=_ tests/include/toast.h" + # execTest "tests/tpcre.nim" # Platform specific tests - when defined(Windows): - execTest "tests/tmath.nim" - if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): - execTest "tests/tsoloud.nim" + # when defined(Windows): + # execTest "tests/tmath.nim" + # if defined(OSX) or defined(Windows) or not existsEnv("TRAVIS"): + # execTest "tests/tsoloud.nim" # getHeader tests - withDir("tests"): - execCmd("nim e getheader.nims") + # withDir("tests"): + # execCmd("nim e getheader.nims") docsTask() diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index caa2a13..6c62b05 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -13,6 +13,7 @@ proc addConst(nimState: NimState, node: TSNode) = # (identifier) # (preproc_arg) # ) + decho("addConst()") nimState.printDebug(node) if node[0].getName() == "identifier" and @@ -51,6 +52,8 @@ proc addConst(nimState: NimState, node: TSNode) = proc newTypeIdent(nimState: NimState, node: TSNode, override = ""): PNode = # Create nkTypeDef PNode with first ident + # + # If `override`, use it instead of node.getAtom() for name let (name, info) = nimState.getNameInfo(node.getAtom(), nskType) # TODO - check blank and override @@ -60,30 +63,46 @@ proc newTypeIdent(nimState: NimState, node: TSNode, override = ""): PNode = else: nimState.getIdent(name, info) + # type name* = + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent(name) + # ), + # nkEmpty() + # ) result = newNode(nkTypeDef) result.add ident result.add newNode(nkEmpty) -proc newPtrTree(count: int, typ: PNode): PNode = +proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = # Create nkPtrTy tree depending on count # # Reduce by 1 if Nim type available for ptr X - e.g. ptr cchar = cstring - # - # nkPtrTy( - # nkPtrTy( - # typ - # ) - # ) var count = count + chng = false if typ.kind == nkIdent: let tname = typ.ident.s ptname = getPtrType(tname) if tname != ptname: - typ.ident.s = ptname + # If Nim type available, use that ident + result = nimState.getIdent(ptname, typ.info, exported = false) + chng = true + # One ptr reduced count -= 1 if count > 0: + # Nested nkPtrTy(typ) depending on count + # + # [ptr ...] typ + # + # nkPtrTy( + # nkPtrTy( + # typ + # ) + # ) result = newNode(nkPtrTy) var parent = result @@ -93,11 +112,17 @@ proc newPtrTree(count: int, typ: PNode): PNode = parent.add child parent = child parent.add typ - else: + elif not chng: + # Either no ptr, or none left after Nim type adjustment result = typ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = # Create nkBracketExpr tree depending on input + let + (_, info) = nimState.getNameInfo(node, nskType) + ident = nimState.getIdent("array", info, exported = false) + + # array[size, typ] # # nkBracketExpr( # nkIdent("array"), @@ -105,11 +130,6 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = # typ # ) result = newNode(nkBracketExpr) - - let - (_, info) = nimState.getNameInfo(node, nskType) - ident = nimState.getIdent("array", info, exported = false) - result.add ident result.add size result.add typ @@ -122,6 +142,8 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: uint64 # # For proc, param should not be exported # + # pname: [ptr ..] typ + # # nkIdentDefs( # nkIdent(pname), # typ, @@ -130,6 +152,8 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: uint64 # # For object, field should be exported # + # pname*: [ptr ..] typ + # # nkIdentDefs( # nkPostfix( # nkIdent("*"), @@ -171,7 +195,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: uint64 pident = nimState.getIdent(pname, tinfo, exported) acount = node[1].getXCount("abstract_pointer_declarator") result.add pident - result.add newPtrTree(acount, tident) + result.add nimState.newPtrTree(acount, tident) result.add newNode(nkEmpty) else: # Named param, simple type @@ -182,7 +206,7 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: uint64 count = node[1].getPtrCount() result.add pident if count > 0: - result.add newPtrTree(count, tident) + result.add nimState.newPtrTree(count, tident) else: result.add tident result.add newNode(nkEmpty) @@ -207,18 +231,6 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: uint64 proc newProcTree(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode = # Create nkProcTy tree for specified proc type - # - # nkProcTy( - # nkFormalParams( - # rtyp, - # nkIdentDefs( # multiple depending on params - # .. - # ) - # ), - # nkEmpty() - # ) - result = newNode(nkProcTy) - let fparam = newNode(nkFormalParams) @@ -233,18 +245,32 @@ proc newProcTree(nimState: NimState, name: string, node: TSNode, rtyp: PNode): P if not param.isNil: fparam.add param + # proc(pname: ptyp ..): rtyp + # + # nkProcTy( + # nkFormalParams( + # rtyp, + # nkIdentDefs( # multiple depending on params + # .. + # ) + # ), + # nkEmpty() + # ) + result = newNode(nkProcTy) result.add fparam result.add newNode(nkEmpty) proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = # Create nkRecList tree for specified object - # - # nkRecList( - # nkIdentDefs( # multiple depending on fields - # .. - # ) - # ) if not node.isNil: + # fname*: ftyp + # .. + # + # nkRecList( + # nkIdentDefs( # multiple depending on fields + # .. + # ) + # ) result = newNode(nkRecList) for i in 0 ..< node.len: @@ -259,6 +285,7 @@ proc addTypeObject(nimState: NimState, node: TSNode, override = "", duplicate = # # If `override` is set, use it as the name # If `duplicate` is set, don't add the same name + decho("addTypeObject()") let # TODO - check blank and override typeDef = nimState.newTypeIdent(node, override) @@ -304,6 +331,7 @@ proc addTypeTyped(nimState: NimState, node: TSNode, toverride = "", duplicate = # # If `toverride` is set, use it as the type name # If `duplicate` is set, don't add the same name + decho("addTypeTyped()") for i in 1 ..< node.len: # Add a type of a specific type let @@ -326,7 +354,7 @@ proc addTypeTyped(nimState: NimState, node: TSNode, toverride = "", duplicate = if $typeDef[0][1] != tname: if count > 0: # If pointers - typeDef.add newPtrTree(count, ident) + typeDef.add nimState.newPtrTree(count, ident) else: typeDef.add ident @@ -348,7 +376,7 @@ proc addTypeTyped(nimState: NimState, node: TSNode, toverride = "", duplicate = nimState.printDebug(typeDef) else: - nimState.addTypeObject(node, duplicate) + nimState.addTypeObject(node, duplicate = duplicate) proc getTypeArray(nimState: NimState, node: TSNode): PNode = # Create array type tree @@ -388,7 +416,7 @@ proc getTypeArray(nimState: NimState, node: TSNode): PNode = if tcount > 0: # If pointers - result = newPtrTree(tcount, result) + result = nimState.newPtrTree(tcount, result) for i in 0 ..< acount: let @@ -398,10 +426,11 @@ proc getTypeArray(nimState: NimState, node: TSNode): PNode = cnode = cnode[0] if ncount > 0: - result = newPtrTree(ncount, result) + result = nimState.newPtrTree(ncount, result) proc addTypeArray(nimState: NimState, node: TSNode) = # Add a type of array type + decho("addTypeArray()") let # node[1] = identifer = name # TODO - check blank and override @@ -466,15 +495,16 @@ proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode = var retType = nimState.getIdent(rname, rinfo, exported = false) if tcount > 0: - retType = newPtrTree(tcount, retType) + retType = nimState.newPtrTree(tcount, retType) # Proc with return type and params result = nimState.newProcTree(name, plist, retType) if ncount > 1: - result = newPtrTree(ncount-1, result) + result = nimState.newPtrTree(ncount-1, result) proc addTypeProc(nimState: NimState, node: TSNode) = # Add a type of proc type + decho("addTypeProc()") let # node[1] = identifier = name # TODO - check blank and override @@ -519,6 +549,7 @@ proc addTypeProc(nimState: NimState, node: TSNode) = nimState.printDebug(typeDef) proc addType(nimState: NimState, node: TSNode) = + decho("addType()") nimState.printDebug(node) if node.getName() == "struct_specifier": @@ -550,12 +581,14 @@ proc addType(nimState: NimState, node: TSNode) = # ) # (field_declaration ...) # ) + decho("addType(): case 1") nimState.addTypeObject(node) elif node.getName() == "type_definition": if node.len >= 2: let fdlist = node[0].anyChildInTree("field_declaration_list") - if nimState.getNodeVal(node[1]) == "": + if (fdlist.isNil or (not fdlist.isNil and fdlist.len == 0)) and + nimState.getNodeVal(node[1]) == "": # typedef struct X; # # (type_definition @@ -574,6 +607,7 @@ proc addType(nimState: NimState, node: TSNode) = # ) # (type_definition = "") # ) + decho("addType(): case 2") nimState.addTypeObject(node[0]) else: let @@ -596,6 +630,7 @@ proc addType(nimState: NimState, node: TSNode) = # (type_identifier) # ) # ) + decho("addType(): case 3") nimState.addTypeTyped(node) elif not fdecl.isNil: # typedef X (*Y)(a1, a2, a3); @@ -625,6 +660,7 @@ proc addType(nimState: NimState, node: TSNode) = # ) # ) # ) + decho("addType(): case 4") nimState.addTypeProc(node) elif not adecl.isNil: # typedef struct X Y[a][..]; @@ -646,6 +682,7 @@ proc addType(nimState: NimState, node: TSNode) = # ) # ) # ) + decho("addType(): case 5") nimState.addTypeArray(node) else: if node.firstChildInTree("field_declaration_list").isNil: @@ -673,6 +710,7 @@ proc addType(nimState: NimState, node: TSNode) = # ) # First add struct as object + decho("addType(): case 6") nimState.addTypeObject(node[0]) if node.len > 1 and nimState.getNodeVal(node[1]) != "": @@ -684,6 +722,7 @@ proc addType(nimState: NimState, node: TSNode) = # typedef struct { .. } Y, *Z; # Get any name that isn't a pointer + decho("addType(): case 7") let name = block: var @@ -692,22 +731,21 @@ proc addType(nimState: NimState, node: TSNode) = if node[i].getName() == "type_identifier": name = nimState.getNodeVal(node[i].getAtom()) - if name.len == 0: - name = nimState.getUniqueIdentifier("STRUCT") - name # Now add struct as object with specified name nimState.addTypeObject(node[0], override = name) - if node.len > 1 and nimState.getNodeVal(node[1]) != "": + if name.len != 0: # Add any additional names except duplicate nimState.addTypeTyped(node, toverride = name, duplicate = name) proc addEnum(nimState: NimState, node: TSNode) = + decho("addEnum()") nimState.printDebug(node) proc addProc(nimState: NimState, node: TSNode) = + decho("addProc()") nimState.printDebug(node) proc processNode(nimState: NimState, node: TSNode): bool = diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 081364a..13093f7 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -313,7 +313,10 @@ proc anyChildInTree*(node: TSNode, ntype: string): TSNode = ccnode = cnode[i].anyChildInTree(ntype) if not ccnode.isNil(): return ccnode - cnode = cnode.tsNodeNextNamedSibling() + if cnode != node: + cnode = cnode.tsNodeNextNamedSibling() + else: + break proc mostNestedChildInTree*(node: TSNode): TSNode = # Search for the most nested child of node's type in tree @@ -444,6 +447,10 @@ proc printTree*(nimState: NimState, pnode: PNode, offset = "") = if offset.len == 0: echo "" +template decho*(str: untyped): untyped = + if nimState.gState.debug: + echo str.getCommented() + proc printDebug*(nimState: NimState, node: TSNode) = if nimState.gState.debug: echo ("Input => " & nimState.getNodeVal(node)).getCommented() diff --git a/nimterop/globals.nim b/nimterop/globals.nim index 1921b1b..be24436 100644 --- a/nimterop/globals.nim +++ b/nimterop/globals.nim @@ -1,10 +1,11 @@ import sequtils, sets, tables -import compiler/[ast, idents, options] +import regex import "."/plugin when not declared(CIMPORT): + import compiler/[ast, idents, options] import "."/treesitter/api const @@ -52,9 +53,10 @@ type commentStr*, debugStr*, skipStr*: string # Nim compiler objects - constSection*, enumSection*, procSection*, typeSection*: PNode - identCache*: IdentCache - config*: ConfigRef + when not declared(CIMPORT): + constSection*, enumSection*, procSection*, typeSection*: PNode + identCache*: IdentCache + config*: ConfigRef gState*: State diff --git a/tests/include/test3.h b/tests/include/test3.h new file mode 100644 index 0000000..d1cf8aa --- /dev/null +++ b/tests/include/test3.h @@ -0,0 +1,42 @@ + +#define A 1 +#define B 1.0 +#define C 0x10 +#define D "hello" +#define E 'c' + +struct A0; +struct A1 {}; +typedef struct A2; +typedef struct A3 {}; +typedef struct A4 A4, *A4p; +typedef int A5; +typedef int *A6; +typedef A0 **A7; +typedef void *A8; + +typedef char *A9[3]; +typedef char *A10[3][6]; +typedef char *(*A11)[3]; + +typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); +typedef int A13(int, int); + +struct A14 { char a1; }; +struct A15 { char *a1; int *a2[1]; }; + +typedef struct A16 { char f1; }; +typedef struct A17 { char *a1; int *a2[1]; } A18, *A18p; +typedef struct { char *a1; int *a2[1]; } A19, *A19p; + +typedef struct A20 { char a1; } A20, A21, *A21p; + +//Expression +//typedef struct A21 { int **f1; int abc[123+132]; } A21; + +//Unions +//union UNION1 {int f1; }; +//typedef union UNION2 { int **f1; int abc[123+132]; } UNION2; + +// Anonymous +//typedef struct { char a1; }; diff --git a/tests/tnimterop2.nim b/tests/tnimterop2.nim new file mode 100644 index 0000000..1e9c21d --- /dev/null +++ b/tests/tnimterop2.nim @@ -0,0 +1,71 @@ +import tables + +import nimterop/[cimport] + +static: + cDebug() + +cImport("include/test3.h", flags="-d") + +proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) = + var + obj: t + count = 0 + for name, value in obj.fieldPairs(): + count += 1 + assert name in fields, $t & "." & name & " invalid" + assert $fields[name] == $typeof(value), + "typeof(" & $t & ":" & name & ") != " & fields[name] & ", is " & $typeof(value) + assert count == fields.len, "Failed for " & $t + +assert A == 1 +assert B == 1.0 +assert C == 0x10 +assert D == "hello" +assert E == 'c' + +assert A0 is object +testFields(A0) +assert A1 is object +testFields(A1) +assert A2 is object +testFields(A2) +assert A3 is object +testFields(A3) +assert A4 is object +testFields(A4) +assert A4p is ptr A4 +assert A5 is cint +assert A6 is ptr cint +assert A7 is ptr ptr A0 +assert A8 is pointer + +assert A9 is array[3, cstring] +assert A10 is array[3, array[6, cstring]] +assert A11 is ptr array[3, cstring] + +assert A12 is proc(a1: cint, b: cint, c: ptr cint, a4: ptr cint, count: array[4, ptr cint], `func`: proc(a1: cint, a2: cint): cint): ptr ptr cint +assert A13 is proc(a1: cint, a2: cint): cint + +assert A14 is object +testFields(A14, {"a1": "cchar"}.toTable()) + +assert A15 is object +testFields(A15, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) + +assert A16 is object +testFields(A16, {"f1": "cchar"}.toTable()) + +assert A17 is object +testFields(A17, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) +assert A18 is A17 +assert A18p is ptr A17 + +assert A19 is object +testFields(A19, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) +assert A19p is ptr A19 + +assert A20 is object +testFields(A20, {"a1": "cchar"}.toTable()) +assert A21 is A20 +assert A21p is ptr A20 |
