More types, isNil, data in lisp
This commit is contained in:
parent
248761da11
commit
68638c8bb6
2 changed files with 251 additions and 59 deletions
|
|
@ -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 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
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# nkTypeDef(
|
||||
# nkPostfix(
|
||||
# nkIdent("*"),
|
||||
# nkIdent("X")
|
||||
# ),
|
||||
# nkEmpty(),
|
||||
# nkObjectTy(
|
||||
# nkEmpty(),
|
||||
# nkEmpty(),
|
||||
# nkEmpty()
|
||||
# )
|
||||
# )
|
||||
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:
|
||||
#
|
||||
# typedef struct X Y;
|
||||
#
|
||||
# (type_definition
|
||||
# (struct_specifier
|
||||
# (type_identifier)
|
||||
# )
|
||||
# (type_identifier)
|
||||
# )
|
||||
#
|
||||
#
|
||||
# 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:
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue