diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2020-01-02 15:59:14 -0600 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2020-01-16 09:23:54 -0600 |
| commit | 68638c8bb6da233d8dd665c580a13c6a9e85b4b0 (patch) | |
| tree | be2e3705550f90938e514033391e18f9c93785b4 | |
| parent | 248761da11e03d4cf78739d7af9073e6179d0b8b (diff) | |
| download | nimterop-68638c8bb6da233d8dd665c580a13c6a9e85b4b0.tar.gz nimterop-68638c8bb6da233d8dd665c580a13c6a9e85b4b0.zip | |
More types, isNil, data in lisp
| -rw-r--r-- | nimterop/ast2.nim | 241 | ||||
| -rw-r--r-- | nimterop/getters.nim | 65 |
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 = |
