diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 6f8f543..dc1a4b1 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -60,24 +60,51 @@ proc newTypeIdent(nimState: NimState, node: TSNode): PNode = result.add ident result.add newNode(nkEmpty) -proc newPtrTree(count: int): tuple[parent, child: PNode] = +proc newPtrTree(count: int, typ: PNode): PNode = # Create nkPtrTy tree depending on count # + # Reduce by 1 if Nim type available for ptr X - e.g. ptr cchar = cstring + # # nkPtrTy( # nkPtrTy( - # .. + # typ # ) # ) + var + count = count + if typ.kind == nkIdent: + let + tname = typ.ident.s + ptname = getPtrType(tname) + if tname != ptname: + typ.ident.s = ptname + count -= 1 if count > 0: - result.parent = newNode(nkPtrTy) - result.child = result.parent + result = newNode(nkPtrTy) + var + parent = result + child: PNode for i in 1 ..< count: - let - child = newNode(nkPtrTy) - result.child.add child - result.child = child + child = newNode(nkPtrTy) + parent.add child + parent = child + parent.add typ + else: + result = typ -proc addType0(nimState: NimState, node: TSNode) = +proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode = + result = newNode(nkBracketExpr) + + let + (_, info) = nimState.getNameInfo(node, nskType) + ident = nimState.getIdent("array", info, exported = false) + + result.add ident + result.add size + result.add typ + +proc addTypeObject(nimState: NimState, node: TSNode) = + # Add a type of object let typeDef = nimState.newTypeIdent(node) @@ -110,7 +137,8 @@ proc addType0(nimState: NimState, node: TSNode) = nimState.printDebug(typeDef) -proc addType1(nimState: NimState, node: TSNode) = +proc addTypeTyped(nimState: NimState, node: TSNode) = + # Add a type of a specific type let # node[1] = identifer = name typeDef = nimState.newTypeIdent(node[1]) @@ -118,10 +146,9 @@ proc addType1(nimState: NimState, node: TSNode) = # 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 + # node[1] could have nested pointers count = node[1].getPtrCount() # type X* = [ptr ..] Y @@ -137,13 +164,62 @@ proc addType1(nimState: NimState, node: TSNode) = # ) # ) - if count > 0: + # Skip typedef X X; + if $typeDef[0][1] != name: + if count > 0: + # If pointers + typeDef.add newPtrTree(count, ident) + else: + typeDef.add ident + + # nkTypeSection.add + nimState.typeSection.add typeDef + + nimState.printDebug(typeDef) + +proc addTypeArray(nimState: NimState, node: TSNode) = + # Add a type of a array type + 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 + ident = nimState.getIdent(name, info, exported = false) + + # Top-most array declarator + adecl = node[1].firstChildInTree("array_declarator") + + # node[1] could have nested arrays + acount = adecl.getArrayCount() + innermost = adecl.mostNestedChildInTree() + + # node[1] could have nested pointers - type + tcount = node[1].getPtrCount() + + # Name could have nested pointers + ncount = innermost[0].getPtrCount() + + var + cnode = adecl + typ = ident + + if tcount > 0: + # If pointers + typ = newPtrTree(tcount, typ) + + for i in 0 ..< acount: let - (parent, child) = newPtrTree(count) - child.add ident - typeDef.add parent - else: - typeDef.add ident + size = nimState.getNodeVal(cnode[1]).getLit() + if size.kind != nkNilLit: + typ = nimState.newArrayTree(cnode, typ, size) + cnode = cnode[0] + + if ncount > 0: + typ = newPtrTree(ncount, typ) + + typeDef.add typ # nkTypeSection.add nimState.typeSection.add typeDef @@ -151,22 +227,6 @@ proc addType1(nimState: NimState, node: TSNode) = nimState.printDebug(typeDef) proc addType(nimState: NimState, node: TSNode) = - # CASE1: - # - # - # CASE 2 - # - # typedef struct X *Y; - # - # (type_definition - # (struct_specifier - # (type_identifier) - # ) - # (pointer_declarator - # (type_identifier) - # ) - # ) - # nimState.printDebug(node) if node.getName() == "struct_specifier": @@ -176,7 +236,7 @@ proc addType(nimState: NimState, node: TSNode) = # (struct_specifier # (type_identifier) # ) - nimState.addType0(node) + nimState.addTypeObject(node) elif node.len == 2: if node[1].getName() == "field_declaration_list" and node[1].len == 0: # struct X {}; @@ -185,7 +245,7 @@ proc addType(nimState: NimState, node: TSNode) = # (type_identifier) # (field_declaration_list = "{}") # ) - nimState.addType0(node) + nimState.addTypeObject(node) elif node.getName() == "type_definition": if node.len == 2: let @@ -200,7 +260,7 @@ proc addType(nimState: NimState, node: TSNode) = # ) # (type_definition = "") # ) - nimState.addType0(node) + nimState.addTypeObject(node) elif fdlist.len == 0: # typedef struct X {}; # @@ -211,16 +271,17 @@ proc addType(nimState: NimState, node: TSNode) = # ) # (type_definition = "") # ) - nimState.addType0(node) + nimState.addTypeObject(node) else: let sspec = node[0].firstChildInTree("struct_specifier") - adecl = node[1].anyChildInTree("array_declarator") fdecl = node[1].anyChildInTree("function_declarator") + adecl = node[1].anyChildInTree("array_declarator") if fdlist.isNil(): if adecl.isNil and fdecl.isNil: if not sspec.isNil: - # typedef struct X [*]Y; + # typedef struct X Y; + # typedef struct X *Y; # # (type_definition # (struct_specifier @@ -230,9 +291,10 @@ proc addType(nimState: NimState, node: TSNode) = # (type_identifier) # ) # ) - nimState.addType1(node) + nimState.addTypeTyped(node) else: - # typedef struct int Y; + # typedef X Y; + # typedef X *Y; # # (type_definition # (type_identifier|primitive_type) @@ -240,22 +302,46 @@ proc addType(nimState: NimState, node: TSNode) = # (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) - # ) - # ) - # ) + nimState.addTypeTyped(node) + elif not fdecl.isNil: discard + elif not adecl.isNil: + if not sspec.isNil: + # typedef struct X Y[a][..]; + # typedef struct X *Y[a][..]; + # typedef struct X *(*Y)[a][..]; + # + # (type_definition + # (struct_specifier + # (type_identifier) + # ) + # (pointer_declarator - optional, nested + # (array_declarator - nested + # (pointer_declarator - optional, nested + # (type_identifier) + # ) + # (number_literal) + # ) + # ) + # ) + nimState.addTypeArray(node) + else: + # typedef X Y[a][..]; + # typedef X *Y[a][..]; + # typedef X *(*Y)[a][..]; + # + # (type_definition + # (type_identifier|primitive_type) + # (pointer_declarator - optional, nested + # (array_declarator - nested + # (pointer_declarator - optional, nested + # (type_identifier) + # ) + # (number_literal) + # ) + # ) + # ) + nimState.addTypeArray(node) proc addEnum(nimState: NimState, node: TSNode) = nimState.printDebug(node) diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 2269268..46c333a 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -97,14 +97,10 @@ proc getType*(str: string): string = proc getPtrType*(str: string): string = result = case str: - of "ptr cchar": + of "cchar": "cstring" - of "ptr ptr cchar": - "ptr cstring" - of "ptr object": + of "object": "pointer" - of "ptr ptr object": - "ptr pointer" else: str @@ -267,18 +263,24 @@ proc getAtom*(node: TSNode): TSNode = elif node.len() != 0: return node[0].getAtom() -proc getPtrCount*(node: TSNode): int = +proc getXCount*(node: TSNode, ntype: string): int = if not node.isNil: - # Get number of ptr nodes in tree + # Get number of ntype nodes nested in tree var cnode = node - while "pointer_declarator" in cnode.getName(): + while ntype in cnode.getName(): result += 1 if cnode.len() != 0: cnode = cnode[0] else: break +proc getPtrCount*(node: TSNode): int = + node.getXCount("pointer_declarator") + +proc getArrayCount*(node: TSNode): int = + node.getXCount("array_declarator") + proc getDeclarator*(node: TSNode): TSNode = if not node.isNil: # Return if child is a function or array declarator @@ -310,6 +312,15 @@ proc anyChildInTree*(node: TSNode, ntype: string): TSNode = return ccnode cnode = cnode.tsNodeNextNamedSibling() +proc mostNestedChildInTree*(node: TSNode): TSNode = + # Search for the most nested child of node's type in tree + var + cnode = node + ntype = cnode.getName() + while not cnode.isNil and cnode.len != 0 and cnode[0].getName() == ntype: + cnode = cnode[0] + result = cnode + proc inChildren*(node: TSNode, ntype: string): bool = # Search for node type in immediate children result = false