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]
|
import "."/[compat, globals, getters]
|
||||||
|
|
||||||
proc addConst(nimState: NimState, node: TSNode) =
|
proc addConst(nimState: NimState, node: TSNode) =
|
||||||
|
# #define X Y
|
||||||
|
#
|
||||||
# (preproc_def
|
# (preproc_def
|
||||||
# (identifier)
|
# (identifier)
|
||||||
# (preproc_arg)
|
# (preproc_arg)
|
||||||
|
|
@ -28,35 +30,130 @@ proc addConst(nimState: NimState, node: TSNode) =
|
||||||
|
|
||||||
# If supported literal
|
# If supported literal
|
||||||
if val.kind != nkNilLit:
|
if val.kind != nkNilLit:
|
||||||
# nnkConstDef(
|
# const X* = Y
|
||||||
# nnkPostfix(
|
#
|
||||||
# nnkIdent("*"),
|
# nkConstDef(
|
||||||
# nnkIdent(name)
|
# nkPostfix(
|
||||||
# ),
|
# nkIdent("*"),
|
||||||
# nnkEmpty(),
|
# nkIdent("X")
|
||||||
# nnkXLit(val)
|
# ),
|
||||||
|
# nkEmpty(),
|
||||||
|
# nkXLit(Y)
|
||||||
# )
|
# )
|
||||||
constDef.add ident
|
constDef.add ident
|
||||||
constDef.add newNode(nkEmpty)
|
constDef.add newNode(nkEmpty)
|
||||||
constDef.add val
|
constDef.add val
|
||||||
|
|
||||||
# nnkConstSection.add
|
# nkConstSection.add
|
||||||
nimState.constSection.add constDef
|
nimState.constSection.add constDef
|
||||||
|
|
||||||
nimState.printDebug(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) =
|
proc addType(nimState: NimState, node: TSNode) =
|
||||||
# CASE1:
|
# CASE1:
|
||||||
#
|
#
|
||||||
# typedef struct X Y;
|
#
|
||||||
#
|
|
||||||
# (type_definition
|
|
||||||
# (struct_specifier
|
|
||||||
# (type_identifier)
|
|
||||||
# )
|
|
||||||
# (type_identifier)
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# CASE 2
|
# CASE 2
|
||||||
#
|
#
|
||||||
# typedef struct X *Y;
|
# typedef struct X *Y;
|
||||||
|
|
@ -72,20 +169,93 @@ proc addType(nimState: NimState, node: TSNode) =
|
||||||
#
|
#
|
||||||
nimState.printDebug(node)
|
nimState.printDebug(node)
|
||||||
|
|
||||||
let
|
if node.getName() == "struct_specifier":
|
||||||
typeDef = newNode(nkTypeDef)
|
if node.len == 1:
|
||||||
|
# struct X;
|
||||||
fdlist = node.inTree("field_declaration_list")
|
#
|
||||||
|
# (struct_specifier
|
||||||
identNode = if fdlist: node[1] else: node
|
# (type_identifier)
|
||||||
|
# )
|
||||||
(name, info) = nimState.getNameInfo(identNode.getAtom(), nskType)
|
nimState.addType0(node)
|
||||||
# TODO - check blank and override
|
elif node.len == 2:
|
||||||
ident = nimState.getIdent(name, info)
|
if node[1].getName() == "field_declaration_list" and node[1].len == 0:
|
||||||
|
# struct X {};
|
||||||
typeNode =
|
#
|
||||||
if fdlist: node[0] else: node[1]
|
# (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) =
|
proc addEnum(nimState: NimState, node: TSNode) =
|
||||||
nimState.printDebug(node)
|
nimState.printDebug(node)
|
||||||
|
|
@ -100,13 +270,10 @@ proc processNode(nimState: NimState, node: TSNode): bool =
|
||||||
of "preproc_def":
|
of "preproc_def":
|
||||||
nimState.addConst(node)
|
nimState.addConst(node)
|
||||||
of "type_definition":
|
of "type_definition":
|
||||||
if node.inTree("struct_specifier"):
|
if not node.firstChildInTree("enum_specifier").isNil():
|
||||||
nimState.addType(node)
|
|
||||||
elif node.inTree("enum_specifier"):
|
|
||||||
nimState.addEnum(node)
|
nimState.addEnum(node)
|
||||||
else:
|
else:
|
||||||
# Unknown type
|
nimState.addType(node)
|
||||||
result = false
|
|
||||||
of "struct_specifier":
|
of "struct_specifier":
|
||||||
nimState.addType(node)
|
nimState.addType(node)
|
||||||
of "enum_specifier":
|
of "enum_specifier":
|
||||||
|
|
@ -126,7 +293,7 @@ proc searchTree(nimState: NimState, root: TSNode) =
|
||||||
processed = false
|
processed = false
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
if not node.tsNodeIsNull() and depth > -1:
|
if not node.isNil() and depth > -1:
|
||||||
processed = nimState.processNode(node)
|
processed = nimState.processNode(node)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
@ -137,7 +304,7 @@ proc searchTree(nimState: NimState, root: TSNode) =
|
||||||
else:
|
else:
|
||||||
nextnode = node.tsNodeNextNamedSibling()
|
nextnode = node.tsNodeNextNamedSibling()
|
||||||
|
|
||||||
if nextnode.tsNodeIsNull():
|
if nextnode.isNil():
|
||||||
while true:
|
while true:
|
||||||
node = node.tsNodeParent()
|
node = node.tsNodeParent()
|
||||||
depth -= 1
|
depth -= 1
|
||||||
|
|
@ -145,7 +312,7 @@ proc searchTree(nimState: NimState, root: TSNode) =
|
||||||
break
|
break
|
||||||
if node == root:
|
if node == root:
|
||||||
break
|
break
|
||||||
if not node.tsNodeNextNamedSibling().tsNodeIsNull():
|
if not node.tsNodeNextNamedSibling().isNil():
|
||||||
node = node.tsNodeNextNamedSibling()
|
node = node.tsNodeNextNamedSibling()
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -237,8 +237,11 @@ proc getLit*(str: string): PNode =
|
||||||
|
|
||||||
# TSNode shortcuts
|
# TSNode shortcuts
|
||||||
|
|
||||||
|
proc isNil*(node: TSNode): bool =
|
||||||
|
node.tsNodeIsNull()
|
||||||
|
|
||||||
proc len*(node: TSNode): uint =
|
proc len*(node: TSNode): uint =
|
||||||
if not node.tsNodeIsNull:
|
if not node.isNil:
|
||||||
result = node.tsNodeNamedChildCount().uint
|
result = node.tsNodeNamedChildCount().uint
|
||||||
|
|
||||||
proc `[]`*(node: TSNode, i: BiggestUInt): TSNode =
|
proc `[]`*(node: TSNode, i: BiggestUInt): TSNode =
|
||||||
|
|
@ -246,51 +249,67 @@ proc `[]`*(node: TSNode, i: BiggestUInt): TSNode =
|
||||||
result = node.tsNodeNamedChild(i.uint32)
|
result = node.tsNodeNamedChild(i.uint32)
|
||||||
|
|
||||||
proc getName*(node: TSNode): string {.inline.} =
|
proc getName*(node: TSNode): string {.inline.} =
|
||||||
if not node.tsNodeIsNull:
|
if not node.isNil:
|
||||||
return $node.tsNodeType()
|
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 =
|
proc getNodeVal*(nimState: NimState, node: TSNode): string =
|
||||||
if not node.tsNodeIsNull:
|
nimState.gState.getNodeVal(node)
|
||||||
return nimState.gState.code[node.tsNodeStartByte() .. node.tsNodeEndByte()-1].strip()
|
|
||||||
|
|
||||||
proc getAtom*(node: TSNode): TSNode =
|
proc getAtom*(node: TSNode): TSNode =
|
||||||
if not node.tsNodeIsNull:
|
if not node.isNil:
|
||||||
# Get child node which is topmost atom
|
# Get child node which is topmost atom
|
||||||
if node.getName() in gAtoms:
|
if node.getName() in gAtoms:
|
||||||
return node
|
return node
|
||||||
elif node.len() != 0:
|
elif node.len() != 0:
|
||||||
return node[0].getAtom()
|
return node[0].getAtom()
|
||||||
|
|
||||||
proc getPtrCount*(node: TSNode): string =
|
proc getPtrCount*(node: TSNode): int =
|
||||||
if not node.tsNodeIsNull:
|
if not node.isNil:
|
||||||
# Get number of ptr nodes in tree
|
# Get number of ptr nodes in tree
|
||||||
var
|
var
|
||||||
cnode = node
|
cnode = node
|
||||||
while "pointer_declarator" in cnode.getName():
|
while "pointer_declarator" in cnode.getName():
|
||||||
result &= "ptr "
|
result += 1
|
||||||
if cnode.len() != 0:
|
if cnode.len() != 0:
|
||||||
cnode = cnode[0]
|
cnode = cnode[0]
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
proc getDeclarator*(node: TSNode): TSNode =
|
proc getDeclarator*(node: TSNode): TSNode =
|
||||||
if not node.tsNodeIsNull:
|
if not node.isNil:
|
||||||
# Return if child is a function or array declarator
|
# Return if child is a function or array declarator
|
||||||
if node.getName() in ["function_declarator", "array_declarator"]:
|
if node.getName() in ["function_declarator", "array_declarator"]:
|
||||||
return node
|
return node
|
||||||
elif node.len() != 0:
|
elif node.len() != 0:
|
||||||
return node[0].getDeclarator()
|
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
|
# Search for node type in tree - first children
|
||||||
result = false
|
|
||||||
var
|
var
|
||||||
cnode = node
|
cnode = node
|
||||||
while not cnode.tsNodeIsNull:
|
while not cnode.isNil:
|
||||||
if cnode.getName() == ntype:
|
if cnode.getName() == ntype:
|
||||||
return true
|
return cnode
|
||||||
cnode = cnode[0]
|
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 =
|
proc inChildren*(node: TSNode, ntype: string): bool =
|
||||||
# Search for node type in immediate children
|
# Search for node type in immediate children
|
||||||
result = false
|
result = false
|
||||||
|
|
@ -320,11 +339,11 @@ proc getPxName*(node: TSNode, offset: int): string =
|
||||||
np = node
|
np = node
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
while not np.tsNodeIsNull() and count < offset:
|
while not np.isNil() and count < offset:
|
||||||
np = np.tsNodeParent()
|
np = np.tsNodeParent()
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
if count == offset and not np.tsNodeIsNull():
|
if count == offset and not np.isNil():
|
||||||
return np.getName()
|
return np.getName()
|
||||||
|
|
||||||
proc printLisp*(gState: State, root: TSNode): string =
|
proc printLisp*(gState: State, root: TSNode): string =
|
||||||
|
|
@ -334,12 +353,16 @@ proc printLisp*(gState: State, root: TSNode): string =
|
||||||
depth = 0
|
depth = 0
|
||||||
|
|
||||||
while true:
|
while true:
|
||||||
if not node.tsNodeIsNull() and depth > -1:
|
if not node.isNil() and depth > -1:
|
||||||
if gState.pretty:
|
if gState.pretty:
|
||||||
result &= spaces(depth)
|
result &= spaces(depth)
|
||||||
let
|
let
|
||||||
(line, col) = gState.getLineCol(node)
|
(line, col) = gState.getLineCol(node)
|
||||||
result &= &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}"
|
result &= &"({$node.tsNodeType()} {line} {col} {node.tsNodeEndByte() - node.tsNodeStartByte()}"
|
||||||
|
let
|
||||||
|
val = gState.getNodeVal(node)
|
||||||
|
if "\n" notin val and " " notin val:
|
||||||
|
result &= &" \"{val}\""
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
@ -355,7 +378,7 @@ proc printLisp*(gState: State, root: TSNode): string =
|
||||||
result &= ")"
|
result &= ")"
|
||||||
nextnode = node.tsNodeNextNamedSibling()
|
nextnode = node.tsNodeNextNamedSibling()
|
||||||
|
|
||||||
if nextnode.tsNodeIsNull():
|
if nextnode.isNil():
|
||||||
while true:
|
while true:
|
||||||
node = node.tsNodeParent()
|
node = node.tsNodeParent()
|
||||||
depth -= 1
|
depth -= 1
|
||||||
|
|
@ -367,7 +390,7 @@ proc printLisp*(gState: State, root: TSNode): string =
|
||||||
result &= ")"
|
result &= ")"
|
||||||
if node == root:
|
if node == root:
|
||||||
break
|
break
|
||||||
if not node.tsNodeNextNamedSibling().tsNodeIsNull():
|
if not node.tsNodeNextNamedSibling().isNil():
|
||||||
node = node.tsNodeNextNamedSibling()
|
node = node.tsNodeNextNamedSibling()
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|
@ -409,12 +432,12 @@ proc printTree*(nimState: NimState, pnode: PNode, offset = "") =
|
||||||
|
|
||||||
proc printDebug*(nimState: NimState, node: TSNode) =
|
proc printDebug*(nimState: NimState, node: TSNode) =
|
||||||
if nimState.gState.debug:
|
if nimState.gState.debug:
|
||||||
echo nimState.getNodeVal(node).getCommented()
|
echo ("Input => " & nimState.getNodeVal(node)).getCommented()
|
||||||
echo nimState.gState.printLisp(node).getCommented()
|
echo nimState.gState.printLisp(node).getCommented()
|
||||||
|
|
||||||
proc printDebug*(nimState: NimState, pnode: PNode) =
|
proc printDebug*(nimState: NimState, pnode: PNode) =
|
||||||
if nimState.gState.debug:
|
if nimState.gState.debug:
|
||||||
echo ($pnode).getCommented()
|
echo ("Output => " & $pnode).getCommented()
|
||||||
nimState.printTree(pnode)
|
nimState.printTree(pnode)
|
||||||
|
|
||||||
# Compiler shortcuts
|
# Compiler shortcuts
|
||||||
|
|
@ -445,6 +468,8 @@ proc getNameInfo*(nimState: NimState, node: TSNode, kind: NimSymKind, parent = "
|
||||||
let
|
let
|
||||||
name = nimState.getNodeVal(node)
|
name = nimState.getNodeVal(node)
|
||||||
result.name = nimState.getIdentifier(name, kind, parent)
|
result.name = nimState.getIdentifier(name, kind, parent)
|
||||||
|
if kind == nskType:
|
||||||
|
result.name = result.name.getType()
|
||||||
result.info = nimState.getLineInfo(node)
|
result.info = nimState.getLineInfo(node)
|
||||||
|
|
||||||
proc getCurrentHeader*(fullpath: string): string =
|
proc getCurrentHeader*(fullpath: string): string =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue