static bool parse_enum(parser_t *parser)
{
bool flag = false;
+ bool reverse = false;
qcfloat num = 0;
ast_value **values = NULL;
ast_value *var = NULL;
/* enumeration attributes (can add more later) */
if (parser->tok == ':') {
- if (!parser_next(parser) || parser->tok != TOKEN_IDENT || strcmp(parser_tokval(parser), "flag")) {
- parseerror(parser, "expected `flag` after enumeration attribute ':'");
+ if (!parser_next(parser) || parser->tok != TOKEN_IDENT){
+ parseerror(parser, "expected `flag` or `reverse` for enumeration attribute");
return false;
}
- if (!parser_next(parser) || parser->tok != '{') {
- parseerror(parser, "expected `{` after enum attribute `flag`");
+ /* attributes? */
+ if (!strcmp(parser_tokval(parser), "flag")) {
+ num = 1;
+ flag = true;
+ }
+ else if (!strcmp(parser_tokval(parser), "reverse")) {
+ reverse = true;
+ }
+ else {
+ parseerror(parser, "invalid attribute `%s` for enumeration", parser_tokval(parser));
return false;
}
- /* flagged enumeration start from 1 */
- num = 1;
- flag = true;
+ if (!parser_next(parser) || parser->tok != '{') {
+ parseerror(parser, "expected `{` after enum attribute ");
+ return false;
+ }
}
while (true) {
/* for flagged enumerations increment in POTs of TWO */
var->constval.vfloat = (flag) ? (num *= 2) : (num ++);
-
parser_addglobal(parser, var->name, (ast_expression*)var);
if (!parser_next(parser)) {
}
}
+ /* patch them all (for reversed attribute) */
+ if (reverse) {
+ size_t i;
+ for (i = 0; i < vec_size(values); i++)
+ values[i]->constval.vfloat = vec_size(values) - i - 1;
+ }
+
if (parser->tok != '}') {
parseerror(parser, "internal error: breaking without `}`");
goto onerror;