Eigenstate: myrddin-dev mailing list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[mcbind] [PATCH 1/4] Allow enum values to be previous members of same enum.


For example, pthread.h contains something like

    enum
    {
      PTHREAD_MUTEX_TIMED_NP,
      PTHREAD_MUTEX_RECURSIVE_NP,
      PTHREAD_MUTEX_ERRORCHECK_NP,
      PTHREAD_MUTEX_ADAPTIVE_NP,
      PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
      PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
      PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
      PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
    };

Since the enum e hasn't been added to p when PTHREAD_MUTEX_NORMAL is
read, lookup() will fail on PTHREAD_MUTEX_TIMED_NP unless e is
specifically probed.
---
 parse.myr | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/parse.myr b/parse.myr
index f28e01a..f5afb31 100644
--- a/parse.myr
+++ b/parse.myr
@@ -639,7 +639,30 @@ const parseenumbody = {p, tagname, pbody
 			match p.tok.kind
 			| `Tasn:
 				next(p)
-				v = parseconstexpr(p)
+				l = p.tok.loc
+				var expr = parseexpr(p)
+				var folded
+				/*
+				   References to enum values in this enum (which hasn't yet been added to p)
+				   have to be handled specially. Otherwise, just try to evaluate.
+				 */
+				match expr
+				| &(`Eident &[.sc=`Sclassenum, .name=other]):
+					match std.htget(e.membs, other)
+					| `std.Some c:
+						folded = `std.Some `Constint c
+					| `std.None:
+						folded = foldexpr(expr)
+					;;
+				| _:
+					folded = foldexpr(expr)
+				;;
+				match folded
+				| `std.Some `Constint c:
+					v = c
+				| _:
+					err(l, "expected constant value for enum {}", name)
+				;;
 				/* TODO: turn this into a bitfield type */
 			| _:
 			;;
-- 
2.25.1


References:
[mcbind] [PATCH 0/4] Misc mcbind adjustments"S. Gilles" <sgilles@xxxxxxx>