Pushing the -fexpressions-for-builtins stuff and the modff for catching fractional-part builtin numbers.

This commit is contained in:
Dale Weiler 2013-04-25 17:08:02 +00:00
parent ce73074d51
commit 68ca2c4962
3 changed files with 45 additions and 27 deletions

1
main.c
View file

@ -173,6 +173,7 @@ static bool options_parse(int argc, char **argv) {
opts_set(opts.flags, INITIALIZED_NONCONSTANTS, true);
opts_set(opts.werror, WARN_INVALID_PARAMETER_COUNT, true);
opts_set(opts.werror, WARN_MISSING_RETURN_VALUES, true);
opts_set(opts.flags, EXPRESSIONS_FOR_BUILTINS, true);
OPTS_OPTION_U32(OPTION_STANDARD) = COMPILER_GMQCC;

View file

@ -50,6 +50,7 @@
GMQCC_DEFINE_FLAG(PERMISSIVE)
GMQCC_DEFINE_FLAG(VARIADIC_ARGS)
GMQCC_DEFINE_FLAG(LEGACY_VECTOR_MATHS)
GMQCC_DEFINE_FLAG(EXPRESSIONS_FOR_BUILTINS)
#endif
/* warning flags */

View file

@ -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,39 @@ 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)
{
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 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);
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) {
parseerror(parser, "builtin number must be a compile time constant");
break;
}
@ -5698,10 +5709,15 @@ skipvar:
}
vec_push(parser->functions, func);
func->builtin = -builtin_num-1;
func->builtin = -((OPTS_FLAG(EXPRESSIONS_FOR_BUILTINS))
? builtin_num
: parser_token(parser)->constval.i) - 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);