aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2020-01-07 01:12:42 -0600
committerGanesh Viswanathan <dev@genotrance.com>2020-01-16 09:23:54 -0600
commit166eae7a5a7bdc697c2a8103e89302f5415b5bad (patch)
tree0073d0230f3372bfaddf3aa27ec1ca4ecfab15f9
parent8d3d41f5d8b1ff3de6e0fdbb335c0a4667062ff2 (diff)
downloadnimterop-166eae7a5a7bdc697c2a8103e89302f5415b5bad.tar.gz
nimterop-166eae7a5a7bdc697c2a8103e89302f5415b5bad.zip
Struct fields support, multiple bugs
-rw-r--r--config.nims5
-rw-r--r--nimterop/ast2.nim366
2 files changed, 264 insertions, 107 deletions
diff --git a/config.nims b/config.nims
index d312c07..e3d4ce0 100644
--- a/config.nims
+++ b/config.nims
@@ -13,3 +13,8 @@ switch("stackTrace", "on")
# Path to compiler
switch("path", "$nim")
+
+# Case objects
+when not defined(danger):
+ switch("define", "nimOldCaseObjects")
+
diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim
index 68956ae..caa2a13 100644
--- a/nimterop/ast2.nim
+++ b/nimterop/ast2.nim
@@ -49,12 +49,16 @@ proc addConst(nimState: NimState, node: TSNode) =
nimState.printDebug(constDef)
-proc newTypeIdent(nimState: NimState, node: TSNode): PNode =
+proc newTypeIdent(nimState: NimState, node: TSNode, override = ""): 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)
+ ident =
+ if override.len != 0:
+ nimState.getIdent(override, info)
+ else:
+ nimState.getIdent(name, info)
result = newNode(nkTypeDef)
result.add ident
@@ -111,10 +115,29 @@ proc newArrayTree(nimState: NimState, node: TSNode, typ, size: PNode): PNode =
result.add typ
proc getTypeArray(nimState: NimState, node: TSNode): PNode
-proc getTypeProc(nimState: NimState, node: TSNode, name: string): PNode
+proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode
-proc newProcParam(nimState: NimState, name: string, node: TSNode, offset: uint64): PNode =
- # Create nkIdentDefs tree for specified parameter
+proc newIdentDefs(nimState: NimState, name: string, node: TSNode, offset: uint64, exported = false): PNode =
+ # Create nkIdentDefs tree for specified proc parameter or object field
+ #
+ # For proc, param should not be exported
+ #
+ # nkIdentDefs(
+ # nkIdent(pname),
+ # typ,
+ # nkEmpty()
+ # )
+ #
+ # For object, field should be exported
+ #
+ # nkIdentDefs(
+ # nkPostfix(
+ # nkIdent("*"),
+ # nkIdent(pname)
+ # ),
+ # typ,
+ # nkEmpty()
+ # )
result = newNode(nkIdentDefs)
let
@@ -123,9 +146,12 @@ proc newProcParam(nimState: NimState, name: string, node: TSNode, offset: uint64
tident = nimState.getIdent(tname, tinfo, exported = false)
if node.len == 1:
+ # Only for proc with no named param - create a param name based on offset
+ #
+ # int func(char, int);
let
pname = "a" & $(offset+1)
- pident = nimState.getIdent(pname, tinfo, exported = false)
+ pident = nimState.getIdent(pname, tinfo, exported)
result.add pident
result.add tident
result.add newNode(nkEmpty)
@@ -136,17 +162,22 @@ proc newProcParam(nimState: NimState, name: string, node: TSNode, offset: uint64
abst = node[1].getName() == "abstract_pointer_declarator"
if fdecl.isNil and adecl.isNil:
if abst:
+ # Only for proc with no named param with pointer type
+ # Create a param name based on offset
+ #
+ # int func(char *, int **);
let
pname = "a" & $(offset+1)
- pident = nimState.getIdent(pname, tinfo, exported = false)
+ pident = nimState.getIdent(pname, tinfo, exported)
acount = node[1].getXCount("abstract_pointer_declarator")
result.add pident
result.add newPtrTree(acount, tident)
result.add newNode(nkEmpty)
else:
+ # Named param, simple type
let
(pname, pinfo) = nimState.getNameInfo(node[1].getAtom(), nskField, parent = name)
- pident = nimState.getIdent(pname, pinfo, exported = false)
+ pident = nimState.getIdent(pname, pinfo, exported)
count = node[1].getPtrCount()
result.add pident
@@ -156,16 +187,18 @@ proc newProcParam(nimState: NimState, name: string, node: TSNode, offset: uint64
result.add tident
result.add newNode(nkEmpty)
elif not fdecl.isNil:
+ # Named param, function pointer
let
(pname, pinfo) = nimState.getNameInfo(node[1].getAtom(), nskField, parent = name)
- pident = nimState.getIdent(pname, pinfo, exported = false)
+ pident = nimState.getIdent(pname, pinfo, exported)
result.add pident
- result.add nimState.getTypeProc(node, name)
+ result.add nimState.getTypeProc(name, node)
result.add newNode(nkEmpty)
elif not adecl.isNil:
+ # Named param, array type
let
(pname, pinfo) = nimState.getNameInfo(node[1].getAtom(), nskField, parent = name)
- pident = nimState.getIdent(pname, pinfo, exported = false)
+ pident = nimState.getIdent(pname, pinfo, exported)
result.add pident
result.add nimState.getTypeArray(node)
result.add newNode(nkEmpty)
@@ -173,81 +206,66 @@ proc newProcParam(nimState: NimState, name: string, node: TSNode, offset: uint64
result = nil
proc newProcTree(nimState: NimState, name: string, node: TSNode, rtyp: PNode): PNode =
+ # Create nkProcTy tree for specified proc type
+ #
+ # nkProcTy(
+ # nkFormalParams(
+ # rtyp,
+ # nkIdentDefs( # multiple depending on params
+ # ..
+ # )
+ # ),
+ # nkEmpty()
+ # )
result = newNode(nkProcTy)
let
fparam = newNode(nkFormalParams)
- result.add fparam
- result.add newNode(nkEmpty)
# Add return type
fparam.add rtyp
if not node.isNil:
for i in 0 ..< node.len:
+ # Add nkIdentDefs for each param
let
- a = nimState.newProcParam(name, node[i], i)
- if not a.isNil:
- fparam.add a
+ param = nimState.newIdentDefs(name, node[i], i, exported = false)
+ if not param.isNil:
+ fparam.add param
-proc addTypeObject(nimState: NimState, node: TSNode) =
- # Add a type of object
- let
- # TODO - check blank and override
- typeDef = nimState.newTypeIdent(node)
+ result.add fparam
+ result.add newNode(nkEmpty)
- # type X* = object
+proc newRecListTree(nimState: NimState, name: string, node: TSNode): PNode =
+ # Create nkRecList tree for specified object
#
- # nkTypeDef(
- # nkPostfix(
- # nkIdent("*"),
- # nkIdent("X")
- # ),
- # nkEmpty(),
- # nkObjectTy(
- # nkEmpty(),
- # nkEmpty(),
- # nkEmpty()
+ # nkRecList(
+ # nkIdentDefs( # multiple depending on fields
+ # ..
# )
# )
- 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
+ if not node.isNil:
+ result = newNode(nkRecList)
- nimState.printDebug(typeDef)
+ for i in 0 ..< node.len:
+ # Add nkIdentDefs for each field
+ let
+ field = nimState.newIdentDefs(name, node[i], i, exported = true)
+ if not field.isNil:
+ result.add field
-proc addTypeTyped(nimState: NimState, node: TSNode) =
- # Add a type of a specific type
+proc addTypeObject(nimState: NimState, node: TSNode, override = "", duplicate = "") =
+ # Add a type of object
+ #
+ # If `override` is set, use it as the name
+ # If `duplicate` is set, don't add the same name
let
- # node[1] = identifer = name
# TODO - check blank and override
- typeDef = nimState.newTypeIdent(node[1])
-
- # node[0] = identifier = type name
- (name, info) = nimState.getNameInfo(node[0].getAtom(), nskType)
- ident = nimState.getIdent(name, info, exported = false)
-
- # node[1] could have nested pointers
- count = node[1].getPtrCount()
-
- # Skip typedef X X;
- if $typeDef[0][1] != name:
- if count > 0:
- # If pointers
- typeDef.add newPtrTree(count, ident)
- else:
- typeDef.add ident
+ typeDef = nimState.newTypeIdent(node, override)
+ name = $typeDef[0][1]
- # type X* = [ptr ..] Y
+ if name != duplicate:
+ # type X* = object
#
# nkTypeDef(
# nkPostfix(
@@ -255,16 +273,83 @@ proc addTypeTyped(nimState: NimState, node: TSNode) =
# nkIdent("X")
# ),
# nkEmpty(),
- # nkPtrTy( # optional, nested
- # nkIdent("Y")
+ # nkObjectTy(
+ # nkEmpty(),
+ # nkEmpty(),
+ # nkEmpty()
# )
# )
+ let
+ obj = newNode(nkObjectTy)
+ obj.add newNode(nkEmpty)
+ obj.add newNode(nkEmpty)
+
+ let
+ fdlist = node.anyChildInTree("field_declaration_list")
+ if not fdlist.isNil and fdlist.len > 0:
+ # Add fields to object if present
+ obj.add nimState.newRecListTree(name, fdlist)
+ else:
+ obj.add newNode(nkEmpty)
+
+ typeDef.add obj
# nkTypeSection.add
nimState.typeSection.add typeDef
nimState.printDebug(typeDef)
+proc addTypeTyped(nimState: NimState, node: TSNode, toverride = "", duplicate = "") =
+ # Add a type of a specified type
+ #
+ # If `toverride` is set, use it as the type name
+ # If `duplicate` is set, don't add the same name
+ for i in 1 ..< node.len:
+ # Add a type of a specific type
+ let
+ # node[i] = identifer = name
+ # TODO - check blank and override
+ typeDef = nimState.newTypeIdent(node[i])
+
+ # node[0] = identifier = type name
+ (tname0, tinfo) = nimState.getNameInfo(node[0].getAtom(), nskType)
+
+ # Override type name
+ tname = if toverride.len != 0: toverride else: tname0
+
+ ident = nimState.getIdent(tname, tinfo, exported = false)
+
+ # node[i] could have nested pointers
+ count = node[i].getPtrCount()
+
+ # Skip typedef X X;
+ if $typeDef[0][1] != tname:
+ if count > 0:
+ # If pointers
+ typeDef.add newPtrTree(count, ident)
+ else:
+ typeDef.add ident
+
+ # type X* = [ptr ..] Y
+ #
+ # nkTypeDef(
+ # nkPostfix(
+ # nkIdent("*"),
+ # nkIdent("X")
+ # ),
+ # nkEmpty(),
+ # nkPtrTy( # optional, nested
+ # nkIdent("Y")
+ # )
+ # )
+
+ # nkTypeSection.add
+ nimState.typeSection.add typeDef
+
+ nimState.printDebug(typeDef)
+ else:
+ nimState.addTypeObject(node, duplicate)
+
proc getTypeArray(nimState: NimState, node: TSNode): PNode =
# Create array type tree
let
@@ -350,7 +435,7 @@ proc addTypeArray(nimState: NimState, node: TSNode) =
nimState.printDebug(typeDef)
-proc getTypeProc(nimState: NimState, node: TSNode, name: string): PNode =
+proc getTypeProc(nimState: NimState, name: string, node: TSNode): PNode =
# Create proc type tree
let
# node[0] = identifier = return type name
@@ -396,7 +481,7 @@ proc addTypeProc(nimState: NimState, node: TSNode) =
typeDef = nimState.newTypeIdent(node[1])
name = $typeDef[0][1]
- procTy = nimState.getTypeProc(node, name)
+ procTy = nimState.getTypeProc(name, node)
typeDef.add procTy
@@ -437,48 +522,59 @@ proc addType(nimState: NimState, node: TSNode) =
nimState.printDebug(node)
if node.getName() == "struct_specifier":
- if node.len == 1:
- # struct X;
- #
- # (struct_specifier
- # (type_identifier)
- # )
- nimState.addTypeObject(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.addTypeObject(node)
+ # struct X;
+ #
+ # (struct_specifier
+ # (type_identifier)
+ # )
+ #
+ # struct X {};
+ #
+ # (struct_specifier
+ # (type_identifier)
+ # (field_declaration_list = "{}")
+ # )
+ #
+ # struct X { char *a1; };
+ #
+ # (struct_specifier
+ # (type_identifier)
+ # (field_declaration_list
+ # (field_declaration
+ # (type_identifier|primitive_type|)
+ # (struct_specifier
+ # (type_identifier)
+ # )
+ #
+ # (field_identifier)
+ # )
+ # (field_declaration ...)
+ # )
+ nimState.addTypeObject(node)
elif node.getName() == "type_definition":
- if node.len == 2:
+ 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.addTypeObject(node)
- elif fdlist.len == 0:
- # typedef struct X {};
- #
- # (type_definition
- # (struct_specifier
- # (type_identifier)
- # (field_declaration_list = "{}")
- # )
- # (type_definition = "")
- # )
- nimState.addTypeObject(node)
+ # typedef struct X;
+ #
+ # (type_definition
+ # (struct_specifier
+ # (type_identifier)
+ # )
+ # (type_definition = "")
+ # )
+ #
+ # typedef struct X {};
+ #
+ # (type_definition
+ # (struct_specifier
+ # (type_identifier)
+ # (field_declaration_list = "{}")
+ # )
+ # (type_definition = "")
+ # )
+ nimState.addTypeObject(node[0])
else:
let
fdecl = node[1].anyChildInTree("function_declarator")
@@ -551,6 +647,62 @@ proc addType(nimState: NimState, node: TSNode) =
# )
# )
nimState.addTypeArray(node)
+ else:
+ if node.firstChildInTree("field_declaration_list").isNil:
+ # typedef struct X { .. } Y, *Z;
+ #
+ # (type_definition
+ # (struct_specifier
+ # (type_identifier) - named struct <====
+ # (field_declaration_list
+ # (field_declaration - optional, multiple
+ # (type_identifier|primitive_type|)
+ # (function_declarator|array_declarator
+ # ..
+ # )
+ #
+ # (field_identifier)
+ # )
+ # )
+ # )
+ #
+ # (type_identifier)
+ # (pointer_declarator - optional, nested
+ # (type_identifier)
+ # )
+ # )
+
+ # First add struct as object
+ nimState.addTypeObject(node[0])
+
+ if node.len > 1 and nimState.getNodeVal(node[1]) != "":
+ # Add any additional names
+ nimState.addTypeTyped(node, duplicate = nimState.getNodeVal(node[0].getAtom()))
+ else:
+ # Same as above except unnamed struct
+ #
+ # typedef struct { .. } Y, *Z;
+
+ # Get any name that isn't a pointer
+ let
+ name = block:
+ var
+ name = ""
+ for i in 1 ..< node.len:
+ if node[i].getName() == "type_identifier":
+ name = nimState.getNodeVal(node[i].getAtom())
+
+ if name.len == 0:
+ name = nimState.getUniqueIdentifier("STRUCT")
+
+ name
+
+ # Now add struct as object with specified name
+ nimState.addTypeObject(node[0], override = name)
+
+ if node.len > 1 and nimState.getNodeVal(node[1]) != "":
+ # Add any additional names except duplicate
+ nimState.addTypeTyped(node, toverride = name, duplicate = name)
proc addEnum(nimState: NimState, node: TSNode) =
nimState.printDebug(node)