aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGanesh Viswanathan <dev@genotrance.com>2020-03-23 14:02:40 -0500
committerGanesh Viswanathan <dev@genotrance.com>2020-03-23 14:02:40 -0500
commitcadf16293d40bcd265d1bf8f366d351ba354a6f9 (patch)
tree750ef0a722a2c08d2af14c4802af69a2999f724f
parent6d1c428b6ebea47c7956c8580c26a810a9250db6 (diff)
downloadnimterop-cadf16293d40bcd265d1bf8f366d351ba354a6f9.tar.gz
nimterop-cadf16293d40bcd265d1bf8f366d351ba354a6f9.zip
ast2 enum support
-rw-r--r--nimterop/ast2.nim84
-rw-r--r--nimterop/getters.nim5
-rw-r--r--nimterop/globals.nim3
-rw-r--r--tests/include/tast2.h96
-rw-r--r--tests/tast2.nim21
5 files changed, 200 insertions, 9 deletions
diff --git a/nimterop/ast2.nim b/nimterop/ast2.nim
index c883537..23cddcb 100644
--- a/nimterop/ast2.nim
+++ b/nimterop/ast2.nim
@@ -98,10 +98,7 @@ proc newConstDef(nimState: NimState, node: TSNode, fname = "", fval = ""): PNode
else:
nimState.getNodeVal(node[1])
valident =
- if fval.nBl:
- newStrNode(nkStrLit, fval)
- else:
- nimState.getLit(val)
+ nimState.getLit(val)
if name.Bl:
# Name skipped or overridden since blank
@@ -147,6 +144,7 @@ proc addConst(nimState: NimState, node: TSNode) =
if not constDef.isNil:
# nkConstSection.add
nimState.constSection.add constDef
+ nimState.constIdentifiers.incl $constDef[0][1]
nimState.printDebug(constDef)
@@ -977,6 +975,80 @@ proc addEnum(nimState: NimState, node: TSNode) =
decho("addEnum()")
nimState.printDebug(node)
+ let
+ enumlist = node.anyChildInTree("enumerator_list")
+ if not enumlist.isNil:
+ var
+ name, origname = ""
+ offset = 0
+ prev = ""
+
+ if node.getAtom().getName() == "type_identifier":
+ # [typedef] enum X {} Y;
+ # Use X as name
+ origname = nimState.getNodeVal(node.getAtom())
+ elif node.getName() == "type_definition" and node.len > 1:
+ # typedef enum {} Y;
+ # Use Y as name
+ origname = nimState.getNodeVal(node[1].getAtom())
+ offset = 1
+
+ if origname.nBl:
+ name = nimState.getIdentifier(origname, nskType)
+ else:
+ # enum {};
+ # Nameless so create a name
+ name = nimState.getUniqueIdentifier("Enum")
+
+ if name.Bl:
+ # Name skipped or overridden since blank
+ let
+ eoverride = nimState.getOverrideOrSkip(node, origname, nskType)
+ if not eoverride.isNil:
+ nimState.typeSection.add eoverride
+ elif nimState.addNewIdentifer(name):
+ # Add enum definition and helpers
+ nimState.enumSection.add nimState.parseString(&"defineEnum({name})")
+
+ # Create const for fields
+ var
+ fnames: HashSet[string]
+ for i in 0 .. enumlist.len - 1:
+ let
+ en = enumlist[i]
+ if en.getName() == "comment":
+ continue
+ let
+ fname = nimState.getIdentifier(nimState.getNodeVal(en.getAtom()), nskEnumField)
+ if fname.nBl:
+ var
+ fval = ""
+ if prev.Bl:
+ # Starting default value
+ fval = &"(0).{name}"
+ else:
+ # One greater than previous
+ fval = &"({prev} + 1).{name}"
+
+ if en.len > 1 and en[1].getName() in gEnumVals:
+ # Explicit value
+ fval = "(" & nimState.getNimExpression(nimState.getNodeVal(en[1]), name) & ")." & name
+
+ # Cannot use newConstDef() since parseString(fval) adds backticks to and/or
+ nimState.constSection.add nimState.parseString(&"const {fname}* = {fval}")[0][0]
+
+ fnames.incl fname
+
+ prev = fname
+
+ # Add fields to list of consts after processing enum so that we don't cast
+ # enum field to itself
+ nimState.constIdentifiers.incl fnames
+
+ # Add other names
+ if node.getName() == "type_definition" and node.len > 1:
+ nimState.addTypeTyped(node, ftname = name, offset = offset)
+
proc addProc(nimState: NimState, node: TSNode) =
# Add a proc
decho("addProc()")
@@ -1060,9 +1132,9 @@ proc processNode(nimState: NimState, node: TSNode): bool =
of "preproc_def":
nimState.addConst(node)
of "type_definition":
- if not node.firstChildInTree("enum_specifier").isNil():
+ if node.len > 0 and node[0].getName() == "enum_specifier":
nimState.addEnum(node)
- elif not node.firstChildInTree("union_specifier").isNil():
+ elif node.len > 0 and node[0].getName() == "union_specifier":
nimState.addType(node, union = true)
else:
nimState.addType(node)
diff --git a/nimterop/getters.nim b/nimterop/getters.nim
index e1aa53e..091174b 100644
--- a/nimterop/getters.nim
+++ b/nimterop/getters.nim
@@ -596,7 +596,8 @@ proc getAstChildByName*(ast: ref Ast, name: string): ref Ast =
if ast.children.len == 1 and ast.children[0].name == ".":
return ast.children[0]
-proc getNimExpression*(nimState: NimState, expr: string): string =
+proc getNimExpression*(nimState: NimState, expr: string, name = ""): string =
+ # Convert C/C++ expression into Nim - cast identifiers to `name` if specified
var
clean = expr.multiReplace([("\n", " "), ("\r", "")])
ident = ""
@@ -641,6 +642,8 @@ proc getNimExpression*(nimState: NimState, expr: string): string =
# Process identifier
if ident.nBl:
ident = nimState.getIdentifier(ident, nskConst)
+ if name.nBl and ident in nimState.constIdentifiers:
+ ident = ident & "." & name
result &= ident
ident = ""
result &= gen
diff --git a/nimterop/globals.nim b/nimterop/globals.nim
index e7ea4c0..68f18b0 100644
--- a/nimterop/globals.nim
+++ b/nimterop/globals.nim
@@ -72,6 +72,9 @@ type
# All symbols that have been declared so far indexed by nimName
identifiers*: TableRef[string, string]
+ # All const names for enum casting
+ constIdentifiers*: HashSet[string]
+
# Legacy ast fields, remove when ast2 becomes default
constStr*, enumStr*, procStr*, typeStr*: string
diff --git a/tests/include/tast2.h b/tests/include/tast2.h
index e9339ae..b867020 100644
--- a/tests/include/tast2.h
+++ b/tests/include/tast2.h
@@ -43,6 +43,54 @@ typedef struct A22 { int **f1; int *f2[123+132]; } A22;
union U1 {int f1; float f2; };
typedef union U2 { int **f1; int abc[123+132]; } U2;
+// Enums
+
+// Issue #159
+#define NK_FLAG(x) (1 << (x))
+enum nk_panel_type {
+ NK_PANEL_NONE = 0,
+ NK_PANEL_WINDOW = NK_FLAG(0),
+ NK_PANEL_GROUP = NK_FLAG(1),
+ NK_PANEL_POPUP = NK_FLAG(2),
+ NK_PANEL_CONTEXTUAL = NK_FLAG(4),
+ NK_PANEL_COMBO = NK_FLAG(5),
+ NK_PANEL_MENU = NK_FLAG(6),
+ NK_PANEL_TOOLTIP = NK_FLAG(7)
+};
+enum nk_panel_set {
+ NK_PANEL_SET_NONBLOCK = NK_PANEL_CONTEXTUAL|NK_PANEL_COMBO|NK_PANEL_MENU|NK_PANEL_TOOLTIP,
+ NK_PANEL_SET_POPUP = NK_PANEL_SET_NONBLOCK|NK_PANEL_POPUP,
+ NK_PANEL_SET_SUB = NK_PANEL_SET_POPUP|NK_PANEL_GROUP
+};
+
+// Issue #171
+typedef enum VSColorFamily {
+ /* all planar formats */
+ cmGray = 1000000,
+ cmRGB = 2000000,
+ cmYUV = 3000000,
+ cmYCoCg = 4000000,
+ /* special for compatibility */
+ cmCompat = 9000000
+} VSColorFamily;
+
+typedef enum VSPresetFormat {
+ pfNone = 0,
+
+ pfGray8 = cmGray + 10,
+ pfGray16,
+
+ pfYUV420P8 = cmYUV + 10,
+ pfYUV422P8,
+
+ pfRGB24 = cmRGB + 10,
+ pfRGB27,
+ /* test */
+
+ pfCompatBGR32 = cmCompat + 10,
+ pfCompatYUY2
+} VSPresetFormat;
+
// Anonymous
//typedef struct { char a1; };
@@ -101,6 +149,54 @@ typedef struct A22 { int **f1; int *f2[123+132]; } A22;
union U1 {int f1; float f2; };
typedef union U2 { int **f1; int abc[123+132]; } U2;
+// Enums
+
+// Issue #159
+#define NK_FLAG(x) (1 << (x))
+enum nk_panel_type {
+ NK_PANEL_NONE = 0,
+ NK_PANEL_WINDOW = NK_FLAG(0),
+ NK_PANEL_GROUP = NK_FLAG(1),
+ NK_PANEL_POPUP = NK_FLAG(2),
+ NK_PANEL_CONTEXTUAL = NK_FLAG(4),
+ NK_PANEL_COMBO = NK_FLAG(5),
+ NK_PANEL_MENU = NK_FLAG(6),
+ NK_PANEL_TOOLTIP = NK_FLAG(7)
+};
+enum nk_panel_set {
+ NK_PANEL_SET_NONBLOCK = NK_PANEL_CONTEXTUAL|NK_PANEL_COMBO|NK_PANEL_MENU|NK_PANEL_TOOLTIP,
+ NK_PANEL_SET_POPUP = NK_PANEL_SET_NONBLOCK|NK_PANEL_POPUP,
+ NK_PANEL_SET_SUB = NK_PANEL_SET_POPUP|NK_PANEL_GROUP
+};
+
+// Issue #171
+typedef enum VSColorFamily {
+ /* all planar formats */
+ cmGray = 1000000,
+ cmRGB = 2000000,
+ cmYUV = 3000000,
+ cmYCoCg = 4000000,
+ /* special for compatibility */
+ cmCompat = 9000000
+} VSColorFamily;
+
+typedef enum VSPresetFormat {
+ pfNone = 0,
+
+ pfGray8 = cmGray + 10,
+ pfGray16,
+
+ pfYUV420P8 = cmYUV + 10,
+ pfYUV422P8,
+
+ pfRGB24 = cmRGB + 10,
+ pfRGB27,
+ /* test */
+
+ pfCompatBGR32 = cmCompat + 10,
+ pfCompatYUY2
+} VSPresetFormat;
+
// Anonymous
//typedef struct { char a1; };
diff --git a/tests/tast2.nim b/tests/tast2.nim
index 6465acc..914d40f 100644
--- a/tests/tast2.nim
+++ b/tests/tast2.nim
@@ -12,7 +12,7 @@ cOverride:
type
A1* = A0
-cImport("include/tast2.h", flags="-d -f:ast2")
+cImport("include/tast2.h", flags="-d -f:ast2 -ENK_")
proc testFields(t: typedesc, fields: Table[string, string] = initTable[string, string]()) =
var
@@ -86,4 +86,21 @@ assert U1 is object
assert sizeof(U1) == sizeof(cfloat)
assert U2 is object
-assert sizeof(U2) == 256 * sizeof(cint) \ No newline at end of file
+assert sizeof(U2) == 256 * sizeof(cint)
+
+assert PANEL_WINDOW == 1
+assert PANEL_GROUP == 2
+assert PANEL_POPUP == 4
+assert PANEL_CONTEXTUAL == 16
+assert PANEL_COMBO == 32
+assert PANEL_MENU == 64
+assert PANEL_TOOLTIP == 128
+assert PANEL_SET_NONBLOCK == 240
+assert PANEL_SET_POPUP == 244
+assert PANEL_SET_SUB == 246
+
+assert cmGray == 1000000
+assert pfGray16 == 1000011
+assert pfYUV422P8 == pfYUV420P8 + 1
+assert pfRGB27 == cmRGB.VSPresetFormat + 11
+assert pfCompatYUY2 == pfCompatBGR32 + 1 \ No newline at end of file