ptr cchar to cstring, array support, named type procs

This commit is contained in:
Ganesh Viswanathan 2020-01-03 18:24:21 -06:00
commit 0965eea3e9
2 changed files with 163 additions and 66 deletions

View file

@ -60,24 +60,51 @@ proc newTypeIdent(nimState: NimState, node: TSNode): PNode =
result.add ident result.add ident
result.add newNode(nkEmpty) result.add newNode(nkEmpty)
proc newPtrTree(count: int): tuple[parent, child: PNode] = proc newPtrTree(count: int, typ: PNode): PNode =
# Create nkPtrTy tree depending on count # Create nkPtrTy tree depending on count
# #
# Reduce by 1 if Nim type available for ptr X - e.g. ptr cchar = cstring
#
# nkPtrTy( # nkPtrTy(
# nkPtrTy( # nkPtrTy(
# .. # typ
# ) # )
# ) # )
var
count = count
if typ.kind == nkIdent:
let
tname = typ.ident.s
ptname = getPtrType(tname)
if tname != ptname:
typ.ident.s = ptname
count -= 1
if count > 0: if count > 0:
result.parent = newNode(nkPtrTy) result = newNode(nkPtrTy)
result.child = result.parent var
parent = result
child: PNode
for i in 1 ..< count: for i in 1 ..< count:
let child = newNode(nkPtrTy)
child = newNode(nkPtrTy) parent.add child
result.child.add child parent = child
result.child = child parent.add typ
else:
result = typ
proc addType0(nimState: NimState, node: TSNode) = proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode =
result = newNode(nkBracketExpr)
let
(_, info) = nimState.getNameInfo(node, nskType)
ident = nimState.getIdent("array", info, exported = false)
result.add ident
result.add size
result.add typ
proc addTypeObject(nimState: NimState, node: TSNode) =
# Add a type of object
let let
typeDef = nimState.newTypeIdent(node) typeDef = nimState.newTypeIdent(node)
@ -110,7 +137,8 @@ proc addType0(nimState: NimState, node: TSNode) =
nimState.printDebug(typeDef) nimState.printDebug(typeDef)
proc addType1(nimState: NimState, node: TSNode) = proc addTypeTyped(nimState: NimState, node: TSNode) =
# Add a type of a specific type
let let
# node[1] = identifer = name # node[1] = identifer = name
typeDef = nimState.newTypeIdent(node[1]) typeDef = nimState.newTypeIdent(node[1])
@ -118,10 +146,9 @@ proc addType1(nimState: NimState, node: TSNode) =
# node[0] = identifier = type name # node[0] = identifier = type name
(name, info) = nimState.getNameInfo(node[0].getAtom(), nskType) (name, info) = nimState.getNameInfo(node[0].getAtom(), nskType)
# TODO - check blank and override # TODO - check blank and override
# TODO - use getPtrType() - ptr cchar to cstring
ident = nimState.getIdent(name, info, exported = false) ident = nimState.getIdent(name, info, exported = false)
# node[1] could have pointers # node[1] could have nested pointers
count = node[1].getPtrCount() count = node[1].getPtrCount()
# type X* = [ptr ..] Y # type X* = [ptr ..] Y
@ -137,13 +164,62 @@ proc addType1(nimState: NimState, node: TSNode) =
# ) # )
# ) # )
if count > 0: # Skip typedef X X;
if $typeDef[0][1] != name:
if count > 0:
# If pointers
typeDef.add newPtrTree(count, ident)
else:
typeDef.add ident
# nkTypeSection.add
nimState.typeSection.add typeDef
nimState.printDebug(typeDef)
proc addTypeArray(nimState: NimState, node: TSNode) =
# Add a type of a array type
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
ident = nimState.getIdent(name, info, exported = false)
# Top-most array declarator
adecl = node[1].firstChildInTree("array_declarator")
# node[1] could have nested arrays
acount = adecl.getArrayCount()
innermost = adecl.mostNestedChildInTree()
# node[1] could have nested pointers - type
tcount = node[1].getPtrCount()
# Name could have nested pointers
ncount = innermost[0].getPtrCount()
var
cnode = adecl
typ = ident
if tcount > 0:
# If pointers
typ = newPtrTree(tcount, typ)
for i in 0 ..< acount:
let let
(parent, child) = newPtrTree(count) size = nimState.getNodeVal(cnode[1]).getLit()
child.add ident if size.kind != nkNilLit:
typeDef.add parent typ = nimState.newArrayTree(cnode, typ, size)
else: cnode = cnode[0]
typeDef.add ident
if ncount > 0:
typ = newPtrTree(ncount, typ)
typeDef.add typ
# nkTypeSection.add # nkTypeSection.add
nimState.typeSection.add typeDef nimState.typeSection.add typeDef
@ -151,22 +227,6 @@ proc addType1(nimState: NimState, node: TSNode) =
nimState.printDebug(typeDef) nimState.printDebug(typeDef)
proc addType(nimState: NimState, node: TSNode) = proc addType(nimState: NimState, node: TSNode) =
# CASE1:
#
#
# CASE 2
#
# typedef struct X *Y;
#
# (type_definition
# (struct_specifier
# (type_identifier)
# )
# (pointer_declarator
# (type_identifier)
# )
# )
#
nimState.printDebug(node) nimState.printDebug(node)
if node.getName() == "struct_specifier": if node.getName() == "struct_specifier":
@ -176,7 +236,7 @@ proc addType(nimState: NimState, node: TSNode) =
# (struct_specifier # (struct_specifier
# (type_identifier) # (type_identifier)
# ) # )
nimState.addType0(node) nimState.addTypeObject(node)
elif node.len == 2: elif node.len == 2:
if node[1].getName() == "field_declaration_list" and node[1].len == 0: if node[1].getName() == "field_declaration_list" and node[1].len == 0:
# struct X {}; # struct X {};
@ -185,7 +245,7 @@ proc addType(nimState: NimState, node: TSNode) =
# (type_identifier) # (type_identifier)
# (field_declaration_list = "{}") # (field_declaration_list = "{}")
# ) # )
nimState.addType0(node) nimState.addTypeObject(node)
elif node.getName() == "type_definition": elif node.getName() == "type_definition":
if node.len == 2: if node.len == 2:
let let
@ -200,7 +260,7 @@ proc addType(nimState: NimState, node: TSNode) =
# ) # )
# (type_definition = "") # (type_definition = "")
# ) # )
nimState.addType0(node) nimState.addTypeObject(node)
elif fdlist.len == 0: elif fdlist.len == 0:
# typedef struct X {}; # typedef struct X {};
# #
@ -211,16 +271,17 @@ proc addType(nimState: NimState, node: TSNode) =
# ) # )
# (type_definition = "") # (type_definition = "")
# ) # )
nimState.addType0(node) nimState.addTypeObject(node)
else: else:
let let
sspec = node[0].firstChildInTree("struct_specifier") sspec = node[0].firstChildInTree("struct_specifier")
adecl = node[1].anyChildInTree("array_declarator")
fdecl = node[1].anyChildInTree("function_declarator") fdecl = node[1].anyChildInTree("function_declarator")
adecl = node[1].anyChildInTree("array_declarator")
if fdlist.isNil(): if fdlist.isNil():
if adecl.isNil and fdecl.isNil: if adecl.isNil and fdecl.isNil:
if not sspec.isNil: if not sspec.isNil:
# typedef struct X [*]Y; # typedef struct X Y;
# typedef struct X *Y;
# #
# (type_definition # (type_definition
# (struct_specifier # (struct_specifier
@ -230,9 +291,10 @@ proc addType(nimState: NimState, node: TSNode) =
# (type_identifier) # (type_identifier)
# ) # )
# ) # )
nimState.addType1(node) nimState.addTypeTyped(node)
else: else:
# typedef struct int Y; # typedef X Y;
# typedef X *Y;
# #
# (type_definition # (type_definition
# (type_identifier|primitive_type) # (type_identifier|primitive_type)
@ -240,22 +302,46 @@ proc addType(nimState: NimState, node: TSNode) =
# (type_identifier) # (type_identifier)
# ) # )
# ) # )
nimState.addType1(node) nimState.addTypeTyped(node)
elif not adecl.isNil: elif not fdecl.isNil:
# typedef X Y[a][..];
#
# (type_definition
# (struct_specifier
# (type_identifier)
# )
# (pointer_declarator
# (array_declarator
# (type_identifier)
# (number_literal)
# )
# )
# )
discard discard
elif not adecl.isNil:
if not sspec.isNil:
# typedef struct X Y[a][..];
# typedef struct X *Y[a][..];
# typedef struct X *(*Y)[a][..];
#
# (type_definition
# (struct_specifier
# (type_identifier)
# )
# (pointer_declarator - optional, nested
# (array_declarator - nested
# (pointer_declarator - optional, nested
# (type_identifier)
# )
# (number_literal)
# )
# )
# )
nimState.addTypeArray(node)
else:
# typedef X Y[a][..];
# typedef X *Y[a][..];
# typedef X *(*Y)[a][..];
#
# (type_definition
# (type_identifier|primitive_type)
# (pointer_declarator - optional, nested
# (array_declarator - nested
# (pointer_declarator - optional, nested
# (type_identifier)
# )
# (number_literal)
# )
# )
# )
nimState.addTypeArray(node)
proc addEnum(nimState: NimState, node: TSNode) = proc addEnum(nimState: NimState, node: TSNode) =
nimState.printDebug(node) nimState.printDebug(node)

View file

@ -97,14 +97,10 @@ proc getType*(str: string): string =
proc getPtrType*(str: string): string = proc getPtrType*(str: string): string =
result = case str: result = case str:
of "ptr cchar": of "cchar":
"cstring" "cstring"
of "ptr ptr cchar": of "object":
"ptr cstring"
of "ptr object":
"pointer" "pointer"
of "ptr ptr object":
"ptr pointer"
else: else:
str str
@ -267,18 +263,24 @@ proc getAtom*(node: TSNode): TSNode =
elif node.len() != 0: elif node.len() != 0:
return node[0].getAtom() return node[0].getAtom()
proc getPtrCount*(node: TSNode): int = proc getXCount*(node: TSNode, ntype: string): int =
if not node.isNil: if not node.isNil:
# Get number of ptr nodes in tree # Get number of ntype nodes nested in tree
var var
cnode = node cnode = node
while "pointer_declarator" in cnode.getName(): while ntype in cnode.getName():
result += 1 result += 1
if cnode.len() != 0: if cnode.len() != 0:
cnode = cnode[0] cnode = cnode[0]
else: else:
break break
proc getPtrCount*(node: TSNode): int =
node.getXCount("pointer_declarator")
proc getArrayCount*(node: TSNode): int =
node.getXCount("array_declarator")
proc getDeclarator*(node: TSNode): TSNode = proc getDeclarator*(node: TSNode): TSNode =
if not node.isNil: if not node.isNil:
# Return if child is a function or array declarator # Return if child is a function or array declarator
@ -310,6 +312,15 @@ proc anyChildInTree*(node: TSNode, ntype: string): TSNode =
return ccnode return ccnode
cnode = cnode.tsNodeNextNamedSibling() cnode = cnode.tsNodeNextNamedSibling()
proc mostNestedChildInTree*(node: TSNode): TSNode =
# Search for the most nested child of node's type in tree
var
cnode = node
ntype = cnode.getName()
while not cnode.isNil and cnode.len != 0 and cnode[0].getName() == ntype:
cnode = cnode[0]
result = cnode
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