mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-02-25 20:51:38 +00:00
Implemented concept of enumeration attributes (can be further extended, but currently only "flag" is implemented as an attribute). An enumeration with a flag attribute will act as a "flagged enumeration", one that automatically handles exponentiation of the constants defined inside it, i.e enum : flag { A, B, C }, A,B,C will equal 2, 4, 8.
This commit is contained in:
parent
479f3b9343
commit
b971ddec3a
3 changed files with 36 additions and 3 deletions
26
parser.c
26
parser.c
|
@ -3861,6 +3861,7 @@ static bool parse_statement(parser_t *parser, ast_block *block, ast_expression *
|
||||||
|
|
||||||
static bool parse_enum(parser_t *parser)
|
static bool parse_enum(parser_t *parser)
|
||||||
{
|
{
|
||||||
|
bool flag = false;
|
||||||
qcfloat num = 0;
|
qcfloat num = 0;
|
||||||
ast_value **values = NULL;
|
ast_value **values = NULL;
|
||||||
ast_value *var = NULL;
|
ast_value *var = NULL;
|
||||||
|
@ -3868,11 +3869,28 @@ static bool parse_enum(parser_t *parser)
|
||||||
|
|
||||||
ast_expression *old;
|
ast_expression *old;
|
||||||
|
|
||||||
if (!parser_next(parser) || parser->tok != '{') {
|
if (!parser_next(parser) || (parser->tok != '{' && parser->tok != ':')) {
|
||||||
parseerror(parser, "expected `{` after `enum` keyword");
|
parseerror(parser, "expected `{` or `:` after `enum` keyword");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 ':'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parser_next(parser) || parser->tok != '{') {
|
||||||
|
parseerror(parser, "expected `{` after enum attribute `flag`");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* flagged enumeration start from 1 */
|
||||||
|
num = 1;
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
|
if (!parser_next(parser) || parser->tok != TOKEN_IDENT) {
|
||||||
if (parser->tok == '}') {
|
if (parser->tok == '}') {
|
||||||
|
@ -3896,7 +3914,9 @@ static bool parse_enum(parser_t *parser)
|
||||||
vec_push(values, var);
|
vec_push(values, var);
|
||||||
var->cvq = CV_CONST;
|
var->cvq = CV_CONST;
|
||||||
var->hasvalue = true;
|
var->hasvalue = true;
|
||||||
var->constval.vfloat = num++;
|
|
||||||
|
/* for flagged enumerations increment in POTs of TWO */
|
||||||
|
var->constval.vfloat = (flag) ? (num *= 2) : (num ++);
|
||||||
|
|
||||||
parser_addglobal(parser, var->name, (ast_expression*)var);
|
parser_addglobal(parser, var->name, (ast_expression*)var);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,12 @@ enum {
|
||||||
N
|
N
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum : flag {
|
||||||
|
F1, /* = 1 << 1 */
|
||||||
|
F2, /* = 1 << 2 */
|
||||||
|
F3 /* = 1 << 3 */
|
||||||
|
};
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
print(ftos(A), "\n");
|
print(ftos(A), "\n");
|
||||||
print(ftos(B), "\n");
|
print(ftos(B), "\n");
|
||||||
|
@ -42,4 +48,8 @@ void main() {
|
||||||
print(ftos(L), "\n");
|
print(ftos(L), "\n");
|
||||||
print(ftos(M), "\n");
|
print(ftos(M), "\n");
|
||||||
print(ftos(N), "\n");
|
print(ftos(N), "\n");
|
||||||
|
|
||||||
|
print(ftos(F1), "\n");
|
||||||
|
print(ftos(F2), "\n");
|
||||||
|
print(ftos(F3), "\n");
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,3 +16,6 @@ M: 10
|
||||||
M: 11
|
M: 11
|
||||||
M: 12
|
M: 12
|
||||||
M: 13
|
M: 13
|
||||||
|
M: 2
|
||||||
|
M: 4
|
||||||
|
M: 8
|
||||||
|
|
Loading…
Reference in a new issue