ast2 enum support

This commit is contained in:
Ganesh Viswanathan 2020-03-23 14:02:40 -05:00
commit cadf16293d
5 changed files with 200 additions and 9 deletions

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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; };

View file

@ -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)
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