diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2020-03-25 15:17:20 -0500 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2020-03-25 15:17:20 -0500 |
| commit | 8b9c39f42eec79607392c81538e08da1b814809a (patch) | |
| tree | a6971f90c00d67bc0e28476727380f0033ba3fa1 | |
| parent | e98564528ee8a9fc934bb2de31114b66673b3eaa (diff) | |
| download | nimterop-8b9c39f42eec79607392c81538e08da1b814809a.tar.gz nimterop-8b9c39f42eec79607392c81538e08da1b814809a.zip | |
ast2 newTypeIdent cleanup, pragma tests, docs.nim docs
| -rw-r--r-- | nimterop.nimble | 1 | ||||
| -rw-r--r-- | nimterop/all.nim | 2 | ||||
| -rw-r--r-- | nimterop/ast2.nim | 91 | ||||
| -rw-r--r-- | nimterop/docs.nim | 4 | ||||
| -rw-r--r-- | tests/include/tast2.h | 12 | ||||
| -rw-r--r-- | tests/tast2.nim | 85 |
6 files changed, 154 insertions, 41 deletions
diff --git a/nimterop.nimble b/nimterop.nimble index c33e78b..86ee029 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -37,6 +37,7 @@ task test, "Test": buildToastTask() execTest "tests/tast2.nim" + #execCmd "nim c -f -d:HEADER -r tests/tast2.nim" execTest "tests/tnimterop_c.nim" execCmd "nim cpp -f -r tests/tnimterop_cpp.nim" diff --git a/nimterop/all.nim b/nimterop/all.nim index dc22967..fef1bdd 100644 --- a/nimterop/all.nim +++ b/nimterop/all.nim @@ -4,4 +4,4 @@ Module that should import everything so that `nim doc --project nimtero/all` run # TODO: make sure it does import everything. -import "."/[cimport, build, types, plugin] +import "."/[docs, cimport, build, types, plugin] diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 62fdcf2..93b26a1 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -248,12 +248,13 @@ proc newPragmaExpr(nimState: NimState, node: TSNode, ident: PNode, pragmas: seq[ result.add ident result.add nimState.newPragma(node, pragmas) -proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", pragmas: seq[string] = @[]): PNode = - # Create nkTypeDef PNode with first ident +proc newTypeIdent(nimState: NimState, node: TSNode, kind = nskType, fname = "", pragmas: seq[string] = @[]): PNode = + # Create nkTypeDef PNode with first ident if `nskType` else just create an nkPostfix node for `nskProc` # # If `fname`, use it instead of node.getAtom() for name + # If `pragmas`, add as nkPragmaExpr but only if `nskType` since procs add pragmas elsewhere let - (tname, origname, info) = nimState.getNameInfo(node.getAtom(), nskType) + (tname, origname, info) = nimState.getNameInfo(node.getAtom(), kind) name = if fname.nBl: @@ -262,32 +263,49 @@ proc newTypeIdent(nimState: NimState, node: TSNode, fname = "", pragmas: seq[str tname ident = nimState.getIdent(name, info) - prident = - if pragmas.nBl and not ident.isNil: - nimState.newPragmaExpr(node, ident, pragmas) - else: - ident - if name.Bl: # Name skipped or overridden since blank - result = nimState.getOverrideOrSkip(node, origname, nskType) + result = nimState.getOverrideOrSkip(node, origname, kind) elif nimState.addNewIdentifer(name): - # type name* = - # - # nkTypeDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent(name) - # ), - # nkEmpty() - # ) - result = newNode(nkTypeDef) - result.add prident - result.add newNode(nkEmpty) + if kind == nskType: + # type name* = + # + # nkTypeDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent(name) + # ), + # nkEmpty() + # ) + let + pragmas = + if nimState.includeHeader and tname == origname: + # Need to add impShort + pragmas & nimState.impShort + else: + pragmas + + prident = + if pragmas.nBl and not ident.isNil: + nimState.newPragmaExpr(node, ident, pragmas) + else: + ident + + result = newNode(nkTypeDef) + result.add prident + result.add newNode(nkEmpty) + elif kind == nskProc: + # name* + # + # nkPostfix( + # nkIdent("*"), + # nkIdent(name) + # ) + result = ident nimState.identifierNodes[name] = result else: - necho &"# type '{origname}' is duplicate, skipped" + necho &"# $1 '{origname}' is duplicate, skipped" % getKeyword(kind) proc newPtrTree(nimState: NimState, count: int, typ: PNode): PNode = # Create nkPtrTy tree depending on count @@ -520,9 +538,11 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname else: @["bycopy"] + typeDefExisting = not typeDef.isNil + typeDef = if typeDef.isNil: - nimState.newTypeIdent(node, fname, pragmas) + nimState.newTypeIdent(node, fname = fname, pragmas = pragmas) else: typeDef @@ -558,10 +578,14 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname typeDef.add obj # If typeDef was passed in, need to add pragmas if any - if pragmas.nBl and typeDef[0].kind != nkPragmaExpr: - let - npexpr = nimState.newPragmaExpr(node, typedef[0], pragmas) - typedef[0] = npexpr + if pragmas.nBl and typeDefExisting: + if typeDef[0].kind != nkPragmaExpr: + # includeHeader already added impShort + let + npexpr = nimState.newPragmaExpr(node, typedef[0], pragmas) + typedef[0] = npexpr + else: + nimState.addPragma(node, typeDef[0][1], pragmas) # nkTypeSection.add nimState.typeSection.add typeDef @@ -1112,13 +1136,12 @@ proc addProc(nimState: NimState, node: TSNode) = for i in start+1 ..< node.len: let # node[i] = identifier = name - tident = nimState.newTypeIdent(node[i]) + ident = nimState.newTypeIdent(node[i], kind = nskProc) - if not tident.isNil: + if not ident.isNil: let # Only need the ident tree, not nkTypeDef parent - ident = tident[0] - name = tident.getIdentName() + name = ident.getIdentName() # node[i] could have nested pointers tcount = node[i].getPtrCount() @@ -1258,7 +1281,7 @@ proc setupPragmas(nimState: NimState, root: TSNode, fullpath: string) = nimState.constSection.add nimState.newConstDef( root, fname = nimState.currentHeader, fval = '"' & fullpath & '"') - nimState.addPragma(root, impPragma, "header", newStrNode(nkStrLit, nimState.currentHeader)) + nimState.addPragma(root, impPragma, "header", nimState.getIdent(nimState.currentHeader)) nimState.addPragma(root, impCPragma, "pragma", nimState.getIdent(nimState.impShort & "C")) nimState.addPragma(root, impCPragma, nimState.impShort) @@ -1312,9 +1335,9 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = var tree = newNode(nkStmtList) - tree.add nimState.pragmaSection tree.add nimState.enumSection tree.add nimState.constSection + tree.add nimState.pragmaSection tree.add nimState.typeSection tree.add nimState.procSection diff --git a/nimterop/docs.nim b/nimterop/docs.nim index a194086..97fab96 100644 --- a/nimterop/docs.nim +++ b/nimterop/docs.nim @@ -1,6 +1,10 @@ import macros, strformat from os import parentDir, getCurrentCompilerExe, DirSep + +when defined(nimdoc): + from os import getCurrentDir, paramCount, paramStr + proc getNimRootDir(): string = #[ hack, but works diff --git a/tests/include/tast2.h b/tests/include/tast2.h index 84505db..8e84b01 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -11,7 +11,7 @@ typedef struct A3 {}; typedef struct A4 A4, *A4p; typedef const int A5; typedef int *A6; -typedef A0 **A7; +typedef struct A0 **A7; typedef void *A8; // Forward declaration @@ -104,6 +104,8 @@ typedef enum VSPresetFormat { // DUPLICATES +#ifndef HEADER + #define A 1 #define B 1.0 #define C 0x10 @@ -117,7 +119,7 @@ typedef struct A3 {}; typedef struct A4 A4, *A4p; typedef const int A5; typedef int *A6; -typedef A0 **A7; +typedef struct A0 **A7; typedef void *A8; // Forward declaration @@ -131,7 +133,7 @@ typedef char *(*A11)[3]; typedef struct A1 *A111[12]; typedef int **(*A12)(int, int b, int *c, int *, int *count[4], int (*func)(int, int)); -typedef int A13(int, int); +typedef int A13(int, int, void (*func)(void)); struct A14 { volatile char a1; }; struct A15 { char *a1; const int *a2[1]; }; @@ -200,4 +202,6 @@ typedef enum VSPresetFormat { // Anonymous //typedef struct { char a1; }; -//struct A2 test_proc1(struct A0 a);
\ No newline at end of file +//struct A2 test_proc1(struct A0 a); + +#endif
\ No newline at end of file diff --git a/tests/tast2.nim b/tests/tast2.nim index 56b1868..76e4561 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -1,4 +1,4 @@ -import tables +import macros, sets, tables import nimterop/[cimport] @@ -12,7 +12,36 @@ cOverride: type A1* = A0 -cImport("include/tast2.h", flags="-d -f:ast2 -ENK_") +when defined(HEADER): + cDefine("HEADER") + const + flags = " -H" + imp = @["importc", "header:headertast2"] +else: + const + flags = "" + imp = @[] + +cImport("include/tast2.h", flags="-d -f:ast2 -ENK_" & flags) + +proc getPragmas(n: NimNode): HashSet[string] = + for i in 0 ..< n.len: + if n[i].kind == nnkPragma: + for j in 0 ..< n[i].len: + if n[i][j].kind == nnkIdent: + result.incl $n[i][j] + elif n[i][j].kind == nnkExprColonExpr: + result.incl $n[i][j][0] & ":" & $n[i][j][1] + else: + result.incl n[i].getPragmas() + +macro checkPragmas(t: typed, pragmas: static[seq[string]]): untyped = + let + ast = t.getImpl() + prag = ast.getPragmas() + exprag = pragmas.toHashSet() + doAssert symmetricDifference(prag, exprag).len == 0, + "\nWrong number of pragmas in " & $t & "\n" & $prag & " vs " & $exprag proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) = var @@ -31,62 +60,114 @@ assert C == 0x10 assert D == "hello" assert E == 'c' +const + pragmas = @["bycopy"] & imp + assert A0 is object testFields(A0, {"f1": "cint"}.toTable()) +checkPragmas(A0, pragmas) + assert A1 is A0 testFields(A1, {"f1": "cint"}.toTable()) + assert A2 is object testFields(A2) +checkPragmas(A2, pragmas) + assert A3 is object testFields(A3) +checkPragmas(A3, pragmas) + assert A4 is object testFields(A4) +checkPragmas(A4, pragmas) + assert A4p is ptr A4 +checkPragmas(A4p, imp) + assert A5 is cint +checkPragmas(A5, imp) + assert A6 is ptr cint +checkPragmas(A6, imp) + assert A7 is ptr ptr A0 +checkPragmas(A7, imp) + assert A8 is pointer +checkPragmas(A8, imp) assert A9p is array[3, cstring] +checkPragmas(A9p, imp) + #assert A9 is array[4, cchar] +#checkPragmas(A9, imp) + assert A10 is array[3, array[6, cstring]] +checkPragmas(A10, imp) + assert A11 is ptr array[3, cstring] +checkPragmas(A11, imp) + assert A111 is array[12, ptr A1] +checkPragmas(A111, imp) 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 +checkPragmas(A12, imp) + assert A13 is proc(a1: cint, a2: cint, `func`: proc()): cint +checkPragmas(A13, imp) assert A14 is object testFields(A14, {"a1": "cchar"}.toTable()) +checkPragmas(A14, pragmas) assert A15 is object testFields(A15, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) +checkPragmas(A15, pragmas) assert A16 is object testFields(A16, {"f1": "cchar"}.toTable()) +checkPragmas(A16, pragmas) assert A17 is object testFields(A17, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) +checkPragmas(A17, pragmas) + assert A18 is A17 +checkPragmas(A18, imp) + assert A18p is ptr A17 +checkPragmas(A18p, imp) assert A19 is object testFields(A19, {"a1": "cstring", "a2": "array[0..0, ptr cint]"}.toTable()) +checkPragmas(A19, pragmas) + assert A19p is ptr A19 +checkPragmas(A19p, imp) assert A20 is object testFields(A20, {"a1": "cchar"}.toTable()) +checkPragmas(A20, pragmas) + assert A21 is A20 +checkPragmas(A21, imp) + assert A21p is ptr A20 +checkPragmas(A21p, imp) assert A22 is object testFields(A22, {"f1": "ptr ptr cint", "f2": "array[0..254, ptr cint]"}.toTable()) +checkPragmas(A22, pragmas) assert U1 is object assert sizeof(U1) == sizeof(cfloat) +checkPragmas(U1, pragmas & @["union"]) assert U2 is object assert sizeof(U2) == 256 * sizeof(cint) +checkPragmas(U2, pragmas & @["union"]) assert PANEL_WINDOW == 1 assert PANEL_GROUP == 2 |
