More types, isNil, data in lisp

This commit is contained in:
Ganesh Viswanathan 2020-01-02 15:59:14 -06:00
commit 68638c8bb6
2 changed files with 251 additions and 59 deletions

View file

@ -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:

View file

@ -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 =