aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2020-01-02 15:59:14 -0600
committerGanesh Viswanathan <dev@genotrance.com>2020-01-16 09:23:54 -0600
commit68638c8bb6da233d8dd665c580a13c6a9e85b4b0 (patch)
treebe2e3705550f90938e514033391e18f9c93785b4
parent248761da11e03d4cf78739d7af9073e6179d0b8b (diff)
downloadnimterop-68638c8bb6da233d8dd665c580a13c6a9e85b4b0.tar.gz
nimterop-68638c8bb6da233d8dd665c580a13c6a9e85b4b0.zip
More types, isNil, data in lisp
-rw-r--r--nimterop/ast2.nim241
-rw-r--r--nimterop/getters.nim65
2 files changed, 249 insertions, 57 deletions
diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim
index 8790e6f..6f8f543 100644
--- a/nimterop/ast2.nim
+++ b/nimterop/ast2.nim
@@ -7,6 +7,8 @@ import "."/treesitter/api
import "."/[compat, globals, getters]
proc addConst(nimState: NimState, node: TSNode) =
+ # #define X Y
+ #
# (preproc_def
# (identifier)
# (preproc_arg)
@@ -28,35 +30,130 @@ proc addConst(nimState: NimState, node: TSNode) =
# If supported literal
if val.kind != nkNilLit:
- # nnkConstDef(
- # nnkPostfix(
- # nnkIdent("*"),
- # nnkIdent(name)
- # ),
- # nnkEmpty(),
- # nnkXLit(val)
+ # const X* = Y
+ #
+ # nkConstDef(
+ # nkPostfix(
+ # nkIdent("*"),
+ # nkIdent("X")
+ # ),
+ # nkEmpty(),
+ # nkXLit(Y)
# )
constDef.add ident
constDef.add newNode(nkEmpty)
constDef.add val
- # nnkConstSection.add
+ # nkConstSection.add
nimState.constSection.add constDef
nimState.printDebug(constDef)
-proc addType(nimState: NimState, node: TSNode) =
- # CASE1:
+proc newTypeIdent(nimState: NimState, node: TSNode): PNode =
+ # Create nkTypeDef PNode with first ident
+ let
+ (name, info) = nimState.getNameInfo(node.getAtom(), nskType)
+ # TODO - check blank and override
+ ident = nimState.getIdent(name, info)
+
+ result = newNode(nkTypeDef)
+ result.add ident
+ result.add newNode(nkEmpty)
+
+proc newPtrTree(count: int): tuple[parent, child: PNode] =
+ # Create nkPtrTy tree depending on count
#
- # typedef struct X Y;
+ # nkPtrTy(
+ # nkPtrTy(
+ # ..
+ # )
+ # )
+ if count > 0:
+ result.parent = newNode(nkPtrTy)
+ result.child = result.parent
+ for i in 1 ..< count:
+ let
+ child = newNode(nkPtrTy)
+ result.child.add child
+ result.child = child
+
+proc addType0(nimState: NimState, node: TSNode) =
+ let
+ typeDef = nimState.newTypeIdent(node)
+
+ # type X* = object
#
- # (type_definition
- # (struct_specifier
- # (type_identifier)
+ # nkTypeDef(
+ # nkPostfix(
+ # nkIdent("*"),
+ # nkIdent("X")
+ # ),
+ # nkEmpty(),
+ # nkObjectTy(
+ # nkEmpty(),
+ # nkEmpty(),
+ # nkEmpty()
# )
- # (type_identifier)
# )
+ typeDef.add(block:
+ let
+ obj = newNode(nkObjectTy)
+ obj.add newNode(nkEmpty)
+ obj.add newNode(nkEmpty)
+ obj.add newNode(nkEmpty)
+
+ obj
+ )
+
+ # nkTypeSection.add
+ nimState.typeSection.add typeDef
+
+ nimState.printDebug(typeDef)
+
+proc addType1(nimState: NimState, node: TSNode) =
+ let
+ # node[1] = identifer = name
+ typeDef = nimState.newTypeIdent(node[1])
+
+ # node[0] = identifier = type name
+ (name, info) = nimState.getNameInfo(node[0].getAtom(), nskType)
+ # TODO - check blank and override
+ # TODO - use getPtrType() - ptr cchar to cstring
+ ident = nimState.getIdent(name, info, exported = false)
+
+ # node[1] could have pointers
+ count = node[1].getPtrCount()
+
+ # type X* = [ptr ..] Y
+ #
+ # nkTypeDef(
+ # nkPostfix(
+ # nkIdent("*"),
+ # nkIdent("X")
+ # ),
+ # nkEmpty(),
+ # nkPtrTy( # optional, nested
+ # nkIdent("Y")
+ # )
+ # )
+
+ if count > 0:
+ let
+ (parent, child) = newPtrTree(count)
+ child.add ident
+ typeDef.add parent
+ else:
+ typeDef.add ident
+
+ # nkTypeSection.add
+ nimState.typeSection.add typeDef
+
+ nimState.printDebug(typeDef)
+
+proc addType(nimState: NimState, node: TSNode) =
+ # CASE1:
#
+ #
# CASE 2
#
# typedef struct X *Y;
@@ -72,20 +169,93 @@ proc addType(nimState: NimState, node: TSNode) =
#
nimState.printDebug(node)
- let
- typeDef = newNode(nkTypeDef)
-
- fdlist = node.inTree("field_declaration_list")
-
- identNode = if fdlist: node[1] else: node
-
- (name, info) = nimState.getNameInfo(identNode.getAtom(), nskType)
- # TODO - check blank and override
- ident = nimState.getIdent(name, info)
-
- typeNode =
- if fdlist: node[0] else: node[1]
-
+ if node.getName() == "struct_specifier":
+ if node.len == 1:
+ # struct X;
+ #
+ # (struct_specifier
+ # (type_identifier)
+ # )
+ nimState.addType0(node)
+ elif node.len == 2:
+ if node[1].getName() == "field_declaration_list" and node[1].len == 0:
+ # struct X {};
+ #
+ # (struct_specifier
+ # (type_identifier)
+ # (field_declaration_list = "{}")
+ # )
+ nimState.addType0(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():
+ # typedef struct X;
+ #
+ # (type_definition
+ # (struct_specifier
+ # (type_identifier)
+ # )
+ # (type_definition = "")
+ # )
+ nimState.addType0(node)
+ elif fdlist.len == 0:
+ # typedef struct X {};
+ #
+ # (type_definition
+ # (struct_specifier
+ # (type_identifier)
+ # (field_declaration_list = "{}")
+ # )
+ # (type_definition = "")
+ # )
+ nimState.addType0(node)
+ else:
+ let
+ sspec = node[0].firstChildInTree("struct_specifier")
+ adecl = node[1].anyChildInTree("array_declarator")
+ fdecl = node[1].anyChildInTree("function_declarator")
+ if fdlist.isNil():
+ if adecl.isNil and fdecl.isNil:
+ if not sspec.isNil:
+ # typedef struct X [*]Y;
+ #
+ # (type_definition
+ # (struct_specifier
+ # (type_identifier)
+ # )
+ # (pointer_declarator - optional, nested
+ # (type_identifier)
+ # )
+ # )
+ nimState.addType1(node)
+ else:
+ # typedef struct int Y;
+ #
+ # (type_definition
+ # (type_identifier|primitive_type)
+ # (pointer_declarator - optional, nested
+ # (type_identifier)
+ # )
+ # )
+ nimState.addType1(node)
+ elif not adecl.isNil:
+ # typedef X Y[a][..];
+ #
+ # (type_definition
+ # (struct_specifier
+ # (type_identifier)
+ # )
+ # (pointer_declarator
+ # (array_declarator
+ # (type_identifier)
+ # (number_literal)
+ # )
+ # )
+ # )
+ discard
proc addEnum(nimState: NimState, node: TSNode) =
nimState.printDebug(node)
@@ -100,13 +270,10 @@ proc processNode(nimState: NimState, node: TSNode): bool =
of "preproc_def":
nimState.addConst(node)
of "type_definition":
- if node.inTree("struct_specifier"):
- nimState.addType(node)
- elif node.inTree("enum_specifier"):
+ if not node.firstChildInTree("enum_specifier").isNil():
nimState.addEnum(node)
else:
- # Unknown type
- result = false
+ nimState.addType(node)
of "struct_specifier":
nimState.addType(node)
of "enum_specifier":
@@ -126,7 +293,7 @@ proc searchTree(nimState: NimState, root: TSNode) =
processed = false
while true:
- if not node.tsNodeIsNull() and depth > -1:
+ if not node.isNil() and depth > -1:
processed = nimState.processNode(node)
else:
break
@@ -137,7 +304,7 @@ proc searchTree(nimState: NimState, root: TSNode) =
else:
nextnode = node.tsNodeNextNamedSibling()
- if nextnode.tsNodeIsNull():
+ if nextnode.isNil():
while true:
node = node.tsNodeParent()
depth -= 1
@@ -145,7 +312,7 @@ proc searchTree(nimState: NimState, root: TSNode) =
break
if node == root:
break
- if not node.tsNodeNextNamedSibling().tsNodeIsNull():
+ if not node.tsNodeNextNamedSibling().isNil():
node = node.tsNodeNextNamedSibling()
break
else:
diff --git a/nimterop/getters.nim b/nimterop/getters.nim
index 5e53f94..2269268 100644
--- a/nimterop/getters.nim
+++ b/nimterop/getters.nim
@@ -237,8 +237,11 @@ proc getLit*(str: string): PNode =
# TSNode shortcuts
+proc isNil*(node: TSNode): bool =
+ node.tsNodeIsNull()
+
proc len*(node: TSNode): uint =
- if not node.tsNodeIsNull:
+ if not node.isNil:
result = node.tsNodeNamedChildCount().uint
proc `[]`*(node: TSNode, i: BiggestUInt): TSNode =
@@ -246,51 +249,67 @@ proc `[]`*(node: TSNode, i: BiggestUInt): TSNode =
result = node.tsNodeNamedChild(i.uint32)
proc getName*(node: TSNode): string {.inline.} =
- if not node.tsNodeIsNull:
+ if not node.isNil:
return $node.tsNodeType()
+proc getNodeVal*(gState: State, node: TSNode): string =
+ if not node.isNil:
+ return gState.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip()
+
proc getNodeVal*(nimState: NimState, node: TSNode): string =
- if not node.tsNodeIsNull:
- return nimState.gState.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip()
+ nimState.gState.getNodeVal(node)
proc getAtom*(node: TSNode): TSNode =
- if not node.tsNodeIsNull:
+ if not node.isNil:
# Get child node which is topmost atom
if node.getName() in gAtoms:
return node
elif node.len() != 0:
return node[0].getAtom()
-proc getPtrCount*(node: TSNode): string =
- if not node.tsNodeIsNull:
+proc getPtrCount*(node: TSNode): int =
+ if not node.isNil:
# Get number of ptr nodes in tree
var
cnode = node
while "pointer_declarator" in cnode.getName():
- result &= "ptr "
+ result += 1
if cnode.len() != 0:
cnode = cnode[0]
else:
break
proc getDeclarator*(node: TSNode): TSNode =
- if not node.tsNodeIsNull:
+ if not node.isNil:
# Return if child is a function or array declarator
if node.getName() in ["function_declarator", "array_declarator"]:
return node
elif node.len() != 0:
return node[0].getDeclarator()
-proc inTree*(node: TSNode, ntype: string): bool =
+proc firstChildInTree*(node: TSNode, ntype: string): TSNode =
# Search for node type in tree - first children
- result = false
var
cnode = node
- while not cnode.tsNodeIsNull:
+ while not cnode.isNil:
if cnode.getName() == ntype:
- return true
+ return cnode
cnode = cnode[0]
+proc anyChildInTree*(node: TSNode, ntype: string): TSNode =
+ # Search for node type anywhere in tree - depth first
+ var
+ cnode = node
+ while not cnode.isNil:
+ if cnode.getName() == ntype:
+ return cnode
+ for i in 0 ..< cnode.len:
+ let
+ ccnode = cnode[i].anyChildInTree(ntype)
+ if not ccnode.isNil():
+ return ccnode
+ cnode = cnode.tsNodeNextNamedSibling()
+
proc inChildren*(node: TSNode, ntype: string): bool =
# Search for node type in immediate children
result = false
@@ -320,11 +339,11 @@ proc getPxName*(node: TSNode, offset: int): string =
np = node
count = 0
- while not np.tsNodeIsNull() and count < offset:
+ while not np.isNil() and count < offset:
np = np.tsNodeParent()
count += 1
- if count == offset and not np.tsNodeIsNull():
+ if count == offset and not np.isNil():
return np.getName()
proc printLisp*(gState: State, root: TSNode): string =
@@ -334,12 +353,16 @@ proc printLisp*(gState: State, root: TSNode): string =
depth = 0
while true:
- if not node.tsNodeIsNull() and depth > -1:
+ if not node.isNil() and depth > -1:
if gState.pretty:
result &= spaces(depth)
let
(line, col) = gState.getLineCol(node)
result &= &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}"
+ let
+ val = gState.getNodeVal(node)
+ if "\n" notin val and " " notin val:
+ result &= &" \"{val}\""
else:
break
@@ -355,7 +378,7 @@ proc printLisp*(gState: State, root: TSNode): string =
result &= ")"
nextnode = node.tsNodeNextNamedSibling()
- if nextnode.tsNodeIsNull():
+ if nextnode.isNil():
while true:
node = node.tsNodeParent()
depth -= 1
@@ -367,7 +390,7 @@ proc printLisp*(gState: State, root: TSNode): string =
result &= ")"
if node == root:
break
- if not node.tsNodeNextNamedSibling().tsNodeIsNull():
+ if not node.tsNodeNextNamedSibling().isNil():
node = node.tsNodeNextNamedSibling()
break
else:
@@ -409,12 +432,12 @@ proc printTree*(nimState: NimState, pnode: PNode, offset = "") =
proc printDebug*(nimState: NimState, node: TSNode) =
if nimState.gState.debug:
- echo nimState.getNodeVal(node).getCommented()
+ echo ("Input => " & nimState.getNodeVal(node)).getCommented()
echo nimState.gState.printLisp(node).getCommented()
proc printDebug*(nimState: NimState, pnode: PNode) =
if nimState.gState.debug:
- echo ($pnode).getCommented()
+ echo ("Output => " & $pnode).getCommented()
nimState.printTree(pnode)
# Compiler shortcuts
@@ -445,6 +468,8 @@ proc getNameInfo*(nimState: NimState, node: TSNode, kind: NimSymKind, parent = "
let
name = nimState.getNodeVal(node)
result.name = nimState.getIdentifier(name, kind, parent)
+ if kind == nskType:
+ result.name = result.name.getType()
result.info = nimState.getLineInfo(node)
proc getCurrentHeader*(fullpath: string): string =