aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2020-03-23 22:07:39 -0500
committerGanesh Viswanathan <dev@genotrance.com>2020-03-23 22:07:39 -0500
commitc5e978c2efe8557862944a7471eb9a3356b0f3f4 (patch)
tree83c405ea37dddefae681670866525e8dfbb17feb
parentc113ecec986e4790a98c5c73f61864fe18c49bfe (diff)
downloadnimterop-c5e978c2efe8557862944a7471eb9a3356b0f3f4.tar.gz
nimterop-c5e978c2efe8557862944a7471eb9a3356b0f3f4.zip
ast2 override final, void return and param fixes, multi proc support
-rw-r--r--nimterop/ast2.nim192
-rw-r--r--nimterop/getters.nim7
-rw-r--r--tests/include/tast2.h2
-rw-r--r--tests/tast2.nim2
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())