diff options
| author | Ganesh Viswanathan <dev@genotrance.com> | 2020-03-23 14:02:40 -0500 |
|---|---|---|
| committer | Ganesh Viswanathan <dev@genotrance.com> | 2020-03-23 14:02:40 -0500 |
| commit | cadf16293d40bcd265d1bf8f366d351ba354a6f9 (patch) | |
| tree | 750ef0a722a2c08d2af14c4802af69a2999f724f | |
| parent | 6d1c428b6ebea47c7956c8580c26a810a9250db6 (diff) | |
| download | nimterop-cadf16293d40bcd265d1bf8f366d351ba354a6f9.tar.gz nimterop-cadf16293d40bcd265d1bf8f366d351ba354a6f9.zip | |
ast2 enum support
| -rw-r--r-- | nimterop/ast2.nim | 84 | ||||
| -rw-r--r-- | nimterop/getters.nim | 5 | ||||
| -rw-r--r-- | nimterop/globals.nim | 3 | ||||
| -rw-r--r-- | tests/include/tast2.h | 96 | ||||
| -rw-r--r-- | tests/tast2.nim | 21 |
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 |
