diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2020-04-14 19:40:46 -0500 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2020-04-14 19:40:46 -0500 |
| commit | 92fe90f834b1afc1098d4ed63760ca811ab48484 (patch) | |
| tree | 850f3d83d9f49df27f41600399b39e2076904a57 | |
| parent | 08306b98020d5dcfd513b515f7955d44cfef1d6b (diff) | |
| download | nimterop-92fe90f834b1afc1098d4ed63760ca811ab48484.tar.gz nimterop-92fe90f834b1afc1098d4ed63760ca811ab48484.zip | |
ast2 nested struct support
| -rw-r--r-- | nimterop.nimble | 2 | ||||
| -rw-r--r-- | nimterop/ast2.nim | 77 | ||||
| -rw-r--r-- | nimterop/getters.nim | 28 | ||||
| -rw-r--r-- | nimterop/lisp.nim | 2 |
4 files changed, 82 insertions, 27 deletions
diff --git a/nimterop.nimble b/nimterop.nimble index 9600faa..37c395d 100644 --- a/nimterop.nimble +++ b/nimterop.nimble @@ -29,7 +29,7 @@ task bt, "build toast": execCmd("nim c --hints:off -d:danger nimterop/toast.nim") task btd, "build toast": - execCmd("nim c -g --hints:off nimterop/toast.nim") + execCmd("nim c -g nimterop/toast.nim") task docs, "Generate docs": buildDocs(@["nimterop/all.nim"], "build/htmldocs") diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim index 708b473..8dba84a 100644 --- a/nimterop/ast2.nim +++ b/nimterop/ast2.nim @@ -495,10 +495,12 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode = nil): PNo proc getTypeArray(nimState: NimState, node, tnode: TSNode, name: string): PNode proc getTypeProc(nimState: NimState, name: string, node, rnode: TSNode): PNode -iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, exported = false): PNode = +iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: SomeInteger, ftname = "", exported = false): PNode = # Create nkIdentDefs tree for specified proc parameter or object field # - # For proc, param should not be exported + # For proc, param should not be `exported` + # + # If `ftname` is set, use it as the type name # # pname: [ptr ..] typ # @@ -531,7 +533,15 @@ iterator newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: So start = getStartAtom(node) # node[start] - param type - (tname, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + (tname0, _, tinfo) = nimState.getNameInfo(node[start].getAtom(), nskType, parent = name) + + # Override type name + tname = + if ftname.nBl: + ftname + else: + tname0 + tident = nimState.getIdent(tname, tinfo, exported = false) if start == node.len - 1: @@ -676,6 +686,7 @@ proc newProcTy(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNo result.add nimState.newFormalParams(name, node, rtyp) result.add nimState.newPragma(node, nimState.gState.convention) +proc processNode(nimState: NimState, node: TSNode): bool proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = # Create nkRecList tree for specified object if not node.isNil: @@ -691,8 +702,34 @@ proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode = for i in 0 ..< node.len: if node[i].getName() == "field_declaration": + # Check for nested structs / unions / enums + let + fdecl = node[i].anyChildInTree("field_declaration_list") + edecl = node[i].anyChildInTree("enumerator_list") + + # `tname` is name of nested struct / union / enum just + # added, passed on as type name for field in `newIdentDefs()` + (processed, tname) = + if not fdecl.isNil: + # Nested struct / union + ( + nimState.processNode(fdecl.tsNodeParent()), + nimState.typeSection[^1].getIdentName() + ) + elif not edecl.isNil: + # Nested enum + ( + nimState.processNode(edecl.tsNodeParent()), + $nimState.enumSection[^1][0][1] + ) + else: + (true, "") + + if not processed: + return nil + # Add nkIdentDefs for each field - for field in nimState.newIdentDefs(name, node[i], i, exported = true): + for field in nimState.newIdentDefs(name, node[i], i, ftname = tname, exported = true): if not field.isNil: result.add field @@ -722,6 +759,16 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname pragmas + fname = + if not node.firstChildInTree("field_declaration_list").isNil and + node.tsNodeParent().getName() == "field_declaration": + # If nested struct / union without a name + nimState.getUniqueIdentifier( + if union: "Union" else: "Type" + ) + else: + fname + typeDefExisting = not typeDef.isNil typeDef = @@ -784,7 +831,11 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname if not fdlist.isNil and fdlist.len > 0: # Add fields to object if present - obj.add nimState.newRecListTree(name, fdlist) + let + fields = nimState.newRecListTree(name, fdlist) + if fields.isNil: + return + obj.add fields else: obj.add newNode(nkEmpty) @@ -828,7 +879,11 @@ proc addTypeObject(nimState: NimState, node: TSNode, typeDef: PNode = nil, fname def[2].kind == nkObjectTy and def[2].len == 3 and def[2][2].kind == nkEmpty: # Add fields to existing object - def[2][2] = nimState.newRecListTree(name, fdlist) + let + fields = nimState.newRecListTree(name, fdlist) + if fields.isNil: + return + def[2][2] = fields # Change incompleteStruct to bycopy pragma if def[0].kind == nkPragmaExpr and def[0].len == 2 and @@ -1180,7 +1235,7 @@ proc addType(nimState: NimState, node: TSNode, union = false) = let fdecl = node[1].anyChildInTree("function_declarator") adecl = node[1].anyChildInTree("array_declarator") - if fdlist.isNil(): + if fdlist.isNil: if adecl.isNil and fdecl.isNil: # typedef X Y; # typedef X *Y; @@ -1605,18 +1660,18 @@ proc searchTree(nimState: NimState, root: TSNode) = processed = false while true: - if not node.isNil() and depth > -1: + if not node.isNil and depth > -1: processed = nimState.processNode(node) else: break - if not processed and node.len() != 0: + if not processed and node.len != 0: nextnode = node[0] depth += 1 else: nextnode = node.tsNodeNextNamedSibling() - if nextnode.isNil(): + if nextnode.isNil: while true: node = node.tsNodeParent() depth -= 1 @@ -1624,7 +1679,7 @@ proc searchTree(nimState: NimState, root: TSNode) = break if node == root: break - if not node.tsNodeNextNamedSibling().isNil(): + if not node.tsNodeNextNamedSibling().isNil: node = node.tsNodeNextNamedSibling() break else: diff --git a/nimterop/getters.nim b/nimterop/getters.nim index 76b528d..aeefbd8 100644 --- a/nimterop/getters.nim +++ b/nimterop/getters.nim @@ -214,7 +214,7 @@ proc len*(node: TSNode): int = result = node.tsNodeNamedChildCount().int proc `[]`*(node: TSNode, i: SomeInteger): TSNode = - if i < node.len(): + if i < node.len: result = node.tsNodeNamedChild(i.uint32) proc getName*(node: TSNode): string {.inline.} = @@ -233,10 +233,10 @@ proc getAtom*(node: TSNode): TSNode = # Get child node which is topmost atom if node.getName() in gAtoms: return node - elif node.len() != 0: + elif node.len != 0: if node[0].getName() == "type_qualifier": # Skip const, volatile - if node.len() > 1: + if node.len > 1: return node[1].getAtom() else: return @@ -262,10 +262,10 @@ proc getXCount*(node: TSNode, ntype: string, reverse = false): int = if reverse: cnode = cnode.tsNodeParent() else: - if cnode.len() != 0: + if cnode.len != 0: if cnode[0].getName() == "type_qualifier": # Skip const, volatile - if cnode.len() > 1: + if cnode.len > 1: cnode = cnode[1] else: break @@ -285,7 +285,7 @@ proc getDeclarator*(node: TSNode): TSNode = # Return if child is a function or array declarator if node.getName() in ["function_declarator", "array_declarator"]: return node - elif node.len() != 0: + elif node.len != 0: return node[0].getDeclarator() proc firstChildInTree*(node: TSNode, ntype: string): TSNode = @@ -307,7 +307,7 @@ proc anyChildInTree*(node: TSNode, ntype: string): TSNode = for i in 0 ..< cnode.len: let ccnode = cnode[i].anyChildInTree(ntype) - if not ccnode.isNil(): + if not ccnode.isNil: return ccnode if cnode != node: cnode = cnode.tsNodeNextNamedSibling() @@ -326,7 +326,7 @@ proc mostNestedChildInTree*(node: TSNode): TSNode = proc inChildren*(node: TSNode, ntype: string): bool = # Search for node type in immediate children result = false - for i in 0 ..< node.len(): + for i in 0 ..< node.len: if (node[i]).getName() == ntype: result = true break @@ -342,7 +342,7 @@ proc getLineCol*(gState: State, node: TSNode): tuple[line, col: int] = result.col += 1 proc getTSNodeNamedChildCountSansComments*(node: TSNode): int = - for i in 0 ..< node.len(): + for i in 0 ..< node.len: if node.getName() != "comment": result += 1 @@ -352,11 +352,11 @@ proc getPxName*(node: TSNode, offset: int): string = np = node count = 0 - while not np.isNil() and count < offset: + while not np.isNil and count < offset: np = np.tsNodeParent() count += 1 - if count == offset and not np.isNil(): + if count == offset and not np.isNil: return np.getName() proc printLisp*(gState: State, root: TSNode): string = @@ -366,7 +366,7 @@ proc printLisp*(gState: State, root: TSNode): string = depth = 0 while true: - if not node.isNil() and depth > -1: + if not node.isNil and depth > -1: result &= spaces(depth) let (line, col) = gState.getLineCol(node) @@ -386,7 +386,7 @@ proc printLisp*(gState: State, root: TSNode): string = result &= ")\n" nextnode = node.tsNodeNextNamedSibling() - if nextnode.isNil(): + if nextnode.isNil: while true: node = node.tsNodeParent() depth -= 1 @@ -395,7 +395,7 @@ proc printLisp*(gState: State, root: TSNode): string = result &= spaces(depth) & ")\n" if node == root: break - if not node.tsNodeNextNamedSibling().isNil(): + if not node.tsNodeNextNamedSibling().isNil: node = node.tsNodeNextNamedSibling() break else: diff --git a/nimterop/lisp.nim b/nimterop/lisp.nim index fb488d8..8287cf5 100644 --- a/nimterop/lisp.nim +++ b/nimterop/lisp.nim @@ -35,7 +35,7 @@ proc readFromTokens(): ref Ast = idx += 2 while gTokens[idx] != ")": var res = readFromTokens() - if not res.isNil(): + if not res.isNil: result.children.add(res) elif gTokens[idx] == ")": doAssert false, "Poor AST " & $(idx: idx) |
