X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=parser.c;h=7fba786c9cead285969038375c0e801cbc4f24b3;hb=bc4749d95adc747c5d73231aba5716dd870ed33f;hp=d95a44642beaa606c13b88d07effdf6a760e0bc8;hpb=ce73074d51fd60604bbe7e06058709d66ee370c8;p=xonotic%2Fgmqcc.git diff --git a/parser.c b/parser.c index d95a446..7fba786 100644 --- a/parser.c +++ b/parser.c @@ -5639,9 +5639,11 @@ skipvar: } if (parser->tok == '#') { - ast_function *func = NULL; - ast_value *number; - int builtin_num; + ast_function *func = NULL; + ast_value *number = NULL; + float fractional; + float integral; + int builtin_num; if (localblock) { parseerror(parser, "cannot declare builtins within functions"); @@ -5656,30 +5658,41 @@ skipvar: break; } - number = (ast_value*)parse_expression_leave(parser, true, false, false); - if (!number) { - parseerror(parser, "builtin number expected"); - break; - } - if (!ast_istype(number, ast_value) || !number->hasvalue || number->cvq != CV_CONST) - { - ast_unref(number); - parseerror(parser, "builtin number must be a compile time constant"); - break; - } - if (number->expression.vtype == TYPE_INTEGER) - builtin_num = number->constval.vint; - else if (number->expression.vtype == TYPE_FLOAT) - builtin_num = number->constval.vfloat; - else { + if (OPTS_FLAG(EXPRESSIONS_FOR_BUILTINS)) { + number = (ast_value*)parse_expression_leave(parser, true, false, false); + if (!number) { + parseerror(parser, "builtin number expected"); + break; + } + if (!ast_istype(number, ast_value) || !number->hasvalue || number->cvq != CV_CONST) + { + ast_unref(number); + parseerror(parser, "builtin number must be a compile time constant"); + break; + } + if (number->expression.vtype == TYPE_INTEGER) + builtin_num = number->constval.vint; + else if (number->expression.vtype == TYPE_FLOAT) + builtin_num = number->constval.vfloat; + else { + ast_unref(number); + parseerror(parser, "builtin number must be an integer constant"); + break; + } ast_unref(number); - parseerror(parser, "builtin number must be an integer constant"); - break; - } - ast_unref(number); - if (builtin_num < 0) { - parseerror(parser, "builtin number must be an integer greater than zero"); + fractional = modff(builtin_num, &integral); + if (builtin_num < 0 || fractional != 0) { + parseerror(parser, "builtin number must be an integer greater than zero"); + break; + } + + /* we only want the integral part anyways */ + builtin_num = integral; + } else if (parser->tok == TOKEN_INTCONST) { + builtin_num = parser_token(parser)->constval.i; + } else { + parseerror(parser, "builtin number must be a compile time constant"); break; } @@ -5701,7 +5714,10 @@ skipvar: func->builtin = -builtin_num-1; } - if (parser->tok != ',' && parser->tok != ';') { + if (OPTS_FLAG(EXPRESSIONS_FOR_BUILTINS) + ? (parser->tok != ',' && parser->tok != ';') + : (!parser_next(parser))) + { parseerror(parser, "expected comma or semicolon"); if (func) ast_function_delete(func);