diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2020-03-23 22:07:39 -0500 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2020-03-23 22:07:39 -0500 |
| commit | c5e978c2efe8557862944a7471eb9a3356b0f3f4 (patch) | |
| tree | 83c405ea37dddefae681670866525e8dfbb17feb | |
| parent | c113ecec986e4790a98c5c73f61864fe18c49bfe (diff) | |
| download | nimterop-c5e978c2efe8557862944a7471eb9a3356b0f3f4.tar.gz nimterop-c5e978c2efe8557862944a7471eb9a3356b0f3f4.zip | |
ast2 override final, void return and param fixes, multi proc support
| -rw-r--r-- | nimterop/ast2.nim | 192 | ||||
| -rw-r--r-- | nimterop/getters.nim | 7 | ||||
| -rw-r--r-- | tests/include/tast2.h | 2 | ||||
| -rw-r--r-- | tests/tast2.nim | 2 |
4 files changed, 128 insertions, 75 deletions
diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 6c2589c..d3d32c3 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -1,4 +1,4 @@ -import macros, os, sets, strformat, strutils, tables, times +import macros, os, sequtils, sets, strformat, strutils, tables, times import regex @@ -59,23 +59,51 @@ proc getOverrideOrSkip(nimState: NimState, node: TSNode, origname: string, kind: name = nimState.getIdentifier(origname, kind, parent = "override") override = nimState.getOverride(origname, kind) - skind = - if kind == nskConst: - "const " - elif kind == nskType: - "type " - elif kind == nskProc: - "proc " - else: - "" + var + skind = getKeyword(kind) & " " if override.nBl: + if kind == nskProc: + skind = "" result = nimState.parseString(skind & override.replace(origname, name))[0][0] else: necho &"\n# $1'{origname}' skipped" % skind if nimState.gState.debug: nimState.skipStr &= &"\n{nimState.getNodeVal(node)}" +proc addOverrideFinal(nimState: NimState, kind: NimSymKind) = + # Add all unused cOverride symbols for `kind` to AST + var + syms = nimState.getOverrideFinal(kind) + skind = getKeyword(kind) & "\n" + if kind == nskProc: + skind = "" + + if syms.nBl: + var + nsyms = nimState.parseString(skind & syms) + if not nsyms.isNil: + let + list = + if kind == nskProc: + nsyms.sons + else: + nsyms[0].sons + case kind + of nskConst: + nimState.constSection.sons.insert(list, 0) + of nskType: + nimState.typeSection.sons.insert(list, 0) + of nskProc: + nimState.procSection.sons.insert(list, 0) + else: + discard + +proc addAllOverrideFinal(nimState: NimState) = + # Add all unused cOverride symbols to AST + for kind in [nskConst, nskType, nskProc]: + nimState.addOverrideFinal(kind) + proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode = # Create an nkConstDef PNode # @@ -352,12 +380,16 @@ proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeIn # Only for proc with no named param - create a param name based on offset # # int func(char, int); - let - pname = "a" & $(offset+1) - pident = nimState.getIdent(pname, tinfo, exported) - result.add pident - result.add tident - result.add newNode(nkEmpty) + if tname != "object": + let + pname = "a" & $(offset+1) + pident = nimState.getIdent(pname, tinfo, exported) + result.add pident + result.add tident + result.add newNode(nkEmpty) + else: + # int func(void) + result = nil else: let fdecl = node[start+1].anyChildInTree("function_declarator") @@ -717,7 +749,12 @@ proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode = # Return type var - retType = nimState.getIdent(rname, rinfo, exported = false) + retType = + if rname == "object" and tcount == 0: + # void (*func)(..) + newNode(nkEmpty) + else: + nimState.getIdent(rname, rinfo, exported = false) if tcount > 0: retType = nimState.newPtrTree(tcount, retType) @@ -1055,73 +1092,80 @@ proc addProc(nimState: NimState, node: TSNode) = let start = getStartAtom(node) - # node[start+1] = identifier = name - tident = nimState.newTypeIdent(node[start+1]) - - if not tident.isNil: + for i in start+1 ..< node.len: let - # Only need the ident tree, not nkTypeDef parent - ident = tident[0] - name = tident.getIdentName() + # node[i] = identifier = name + tident = nimState.newTypeIdent(node[i]) + + if not tident.isNil: + let + # Only need the ident tree, not nkTypeDef parent + ident = tident[0] + name = tident.getIdentName() - # node[start+1] could have nested pointers - tcount = node[start+1].getPtrCount() + # node[i] could have nested pointers + tcount = node[i].getPtrCount() - # node[start] = identifier = return type name - (rname, _, rinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + # node[start] = identifier = return type name + (rname, _, rinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) - # Parameter list - plist = node[start+1].anyChildInTree("parameter_list") + # Parameter list + plist = node[i].anyChildInTree("parameter_list") - procDef = newNode(nkProcDef) + procDef = newNode(nkProcDef) - # proc X(a1: Y, a2: Z): P {.pragma.} - # - # nkProcDef( - # nkPostfix( - # nkIdent("*"), - # nkIdent("X") - # ), - # nkEmpty(), - # nkEmpty(), - # nkFormalParams( - # nkPtrTy( # optional, nested - # nkIdent(retType) - # ), - # nkIdentDefs( - # nkIdent(param), - # nkPtrTy( - # nkIdent(ptype) - # ), - # nkEmpty() - # ), - # ... - # ), - # nkPragma(...), - # nkEmpty(), - # nkEmpty() - # ) + # proc X(a1: Y, a2: Z): P {.pragma.} + # + # nkProcDef( + # nkPostfix( + # nkIdent("*"), + # nkIdent("X") + # ), + # nkEmpty(), + # nkEmpty(), + # nkFormalParams( + # nkPtrTy( # optional, nested + # nkIdent(retType) + # ), + # nkIdentDefs( + # nkIdent(param), + # nkPtrTy( + # nkIdent(ptype) + # ), + # nkEmpty() + # ), + # ... + # ), + # nkPragma(...), + # nkEmpty(), + # nkEmpty() + # ) - procDef.add ident - procDef.add newNode(nkEmpty) - procDef.add newNode(nkEmpty) + procDef.add ident + procDef.add newNode(nkEmpty) + procDef.add newNode(nkEmpty) - # Return type - var - retType = nimState.getIdent(rname, rinfo, exported = false) - if tcount > 0: - retType = nimState.newPtrTree(tcount, retType) + # Return type + var + retType = + if rname == "object" and tcount == 0: + # void func(..) + newNode(nkEmpty) + else: + nimState.getIdent(rname, rinfo, exported = false) + if tcount > 0: + retType = nimState.newPtrTree(tcount, retType) - # Proc with return type and params - procDef.add nimState.newFormalParams(name, plist, retType) - procDef.add newNode(nkEmpty) # Pragmas - procDef.add newNode(nkEmpty) - procDef.add newNode(nkEmpty) + # Proc with return type and params + procDef.add nimState.newFormalParams(name, plist, retType) + procDef.add newNode(nkEmpty) # Pragmas + procDef.add newNode(nkEmpty) + procDef.add newNode(nkEmpty) - # nkProcSection.add - nimState.procSection.add procDef + # nkProcSection.add + nimState.procSection.add procDef - nimState.printDebug(procDef) + nimState.printDebug(procDef) proc processNode(nimState: NimState, node: TSNode): bool = result = true @@ -1247,6 +1291,8 @@ proc printNim*(gState: State, fullpath: string, root: TSNode) = nimState.searchTree(root) + nimState.addAllOverrideFinal() + var tree = newNode(nkStmtList) tree.add nimState.pragmaSection diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 251955d..044cde7 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -174,6 +174,7 @@ proc addNewIdentifer*(nimState: NimState, name: string, override = false): bool # Overrides related proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = + # Get cOverride for identifier `name` of `kind` if defined doAssert name.nBl, "Blank identifier error" if nimState.gState.onSymbolOverride != nil: @@ -190,6 +191,7 @@ proc getOverride*(nimState: NimState, name: string, kind: NimSymKind): string = result = result.replace(re"(?m)^(.*?)$", " $1") proc getOverrideFinal*(nimState: NimState, kind: NimSymKind): string = + # Get all unused cOverride symbols of `kind` let typ = $kind @@ -197,6 +199,11 @@ proc getOverrideFinal*(nimState: NimState, kind: NimSymKind): string = for i in nimState.gState.onSymbolOverrideFinal(typ): result &= "\n" & nimState.getOverride(i, kind) +proc getKeyword*(kind: NimSymKind): string = + # Convert `kind` into a Nim keyword + # cOverride procs already include `proc` keyword + result = ($kind).replace("nsk", "").toLowerAscii() + # TSNode shortcuts proc isNil*(node: TSNode): bool = diff --git a/tests/include/tast2.h b/tests/include/tast2.h index b867020..84505db 100644 --- a/tests/include/tast2.h +++ b/tests/include/tast2.h @@ -25,7 +25,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]; }; diff --git a/tests/tast2.nim b/tests/tast2.nim index 914d40f..56b1868 100644 --- a/tests/tast2.nim +++ b/tests/tast2.nim @@ -54,7 +54,7 @@ assert A11 is ptr array[3, cstring] assert A111 is array[12, ptr A1] 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 A13 is proc(a1: cint, a2: cint, `func`: proc()): cint assert A14 is object testFields(A14, {"a1": "cchar"}.toTable()) |
