ast2 nested struct support
This commit is contained in:
parent
08306b9802
commit
92fe90f834
4 changed files with 82 additions and 27 deletions
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue