shithub: scc

Download patch

ref: 98d60a06534921e0b79dd3b0a13910f2a8ec83a9
parent: 689b7bf05b8a3612c26fced0b6bf9dd3f944902b
author: Roberto E. Vargas Caballero <[email protected]>
date: Tue Sep 24 13:44:10 EDT 2013

Add enum types

A enum defines a integer type which can store a series of symbolic
values defined in the enum definition.

--- a/decl.c
+++ b/decl.c
@@ -82,9 +82,96 @@
 	}
 }
 
+static void
+new_struct(register struct ctype *tp)
+{
+	if (yytoken == IDEN) {
+		(namespace(NS_STRUCT, -1)->ctype = tp)->refcnt++;
+		next();
+	}
+	if (nr_structs == NR_MAXSTRUCTS)
+		error("too much structs/unions/enum defined");
+	if (structp == &structbuf[NR_STRUCT_LEVEL])
+		error("too much nested structs/unions");
+	tp->c_struct = *structp++ = nr_structs;
+}
 
-static struct ctype *struct_spec(register struct ctype *);
+static struct ctype * spec(void);
 
+static struct ctype *
+struct_dcl(unsigned char ns)
+{
+	register struct ctype *tp, *base;
+
+	if (!(base = spec())) {
+		base = newctype();
+		base->type = INT;
+		warning_error(options.implicit,
+		              "data definition has no type or storage class");
+	}
+	if (base->c_typedef  || base->c_static || base->c_auto ||
+	    base->c_register || base->c_extern) {
+		error("storage specifier in a struct/union field declaration");
+	}
+
+	do {                      /* TODO: detect unnamed structs */
+		declarator(base, ns);
+		tp = decl_type(base);
+		(cursym->ctype = tp)->refcnt++;
+	} while (accept(','));
+
+	expect(';');
+	return tp;
+}
+
+static struct ctype *
+struct_spec(register struct ctype *tp)
+{
+	new_struct(tp);
+	if (!accept('{'))
+		return tp;
+
+	if (!tp->forward)
+		error("struct/union already defined");
+
+	do
+		struct_dcl(tp->c_struct);
+	while (!accept('}'));
+	tp->forward = 0;
+
+	return tp;
+}
+
+static struct ctype *
+enum_dcl(struct ctype *base)
+{
+	short val = 0;
+
+	new_struct(base);
+	if (!accept('{'))
+		return base;
+
+	do {
+		register struct symbol *sym;
+		register struct ctype *tp = btype(NULL, INT);
+
+		if (yytoken == '}')
+			break;
+
+		expect(IDEN);
+		((sym = namespace(NS_IDEN, 1))->ctype = tp)->refcnt++;
+		if (accept('=')) {
+			expect(CONSTANT);
+			val = yyval.sym->val;
+		}
+		sym->val = val++;
+	} while (accept(','));
+
+	expect('}');
+
+	return base;
+}
+
 struct ctype *
 spec(void)
 {
@@ -100,10 +187,13 @@
 		case COMPLEX:  case IMAGINARY:
 		case FLOAT:    case DOUBLE: case BOOL:
 		case VOID:     case CHAR:   case SHORT:
-		case INT:      case ENUM:   case LONG:
+		case INT:      case LONG:
 			tp = btype(tp, yytoken);
 			break;
-			/* TODO: ENUM */
+		case ENUM:
+			tp = btype(tp, yytoken);
+			next();
+			return enum_dcl(tp);
 		case STRUCT:   case UNION:
 			tp = btype(tp, yytoken);
 			next();
@@ -147,60 +237,6 @@
 	}
 }
 
-static struct ctype *
-struct_dcl(unsigned char ns)
-{
-	register struct ctype *tp, *base;
-
-	if (!(base = spec())) {
-		base = newctype();
-		base->type = INT;
-		warning_error(options.implicit,
-		              "data definition has no type or storage class");
-	}
-	if (base->c_typedef  || base->c_static || base->c_auto ||
-	    base->c_register || base->c_extern) {
-		error("storage specifier in a struct/union field declaration");
-	}
-
-	do {                      /* TODO: detect unnamed structs */
-		declarator(base, ns);
-		tp = decl_type(base);
-		(cursym->ctype = tp)->refcnt++;
-	} while (accept(','));
-
-	expect(';');
-	return tp;
-}
-
-static struct ctype *
-struct_spec(register struct ctype *tp)
-{
-	if (yytoken == IDEN) {
-		(namespace(NS_STRUCT, -1)->ctype = tp)->refcnt++;
-		next();
-	}
-
-	if (nr_structs == NR_MAXSTRUCTS)
-		error("too much structs/unions defined");
-	if (structp == &structbuf[NR_STRUCT_LEVEL])
-		error("too much nested structs/unions");
-	tp->c_struct = *structp++ = nr_structs;
-
-	if (!accept('{'))
-		return tp;
-
-	if (!tp->forward)
-		error("struct/union already defined");
-
-	do
-		struct_dcl(tp->c_struct);
-	while (!accept('}'));
-	tp->forward = 0;
-
-	return tp;
-}
-
 static void
 declarator(struct ctype *tp, unsigned char ns)
 {
@@ -295,7 +331,7 @@
 	} else if (accept(';')) {
 		register unsigned char type = tp->type;
 
-		if (type == STRUCT || type == UNION) {
+		if (type == STRUCT || type == UNION || type == ENUM) {
 			if (tp->c_extern || tp->c_static || tp->c_auto ||
 			    tp->c_register || tp->c_const || tp->c_volatile) {
 				warning_error(options.useless,
--- a/symbol.h
+++ b/symbol.h
@@ -11,7 +11,7 @@
 #define CTX_FUNC  2
 #define CTX_ANY   0
 
-enum namespace {
+enum {
 	NS_IDEN,
 	NS_KEYWORD,
 	NS_STRUCT,