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

@ -5640,7 +5640,9 @@ skipvar:
if (parser->tok == '#') {
ast_function *func = NULL;
ast_value *number;
ast_value *number = NULL;
float fractional;
float integral;
int builtin_num;
if (localblock) {
@ -5656,6 +5658,7 @@ skipvar:
break;
}
if (OPTS_FLAG(EXPRESSIONS_FOR_BUILTINS)) {
number = (ast_value*)parse_expression_leave(parser, true, false, false);
if (!number) {
parseerror(parser, "builtin number expected");
@ -5678,11 +5681,19 @@ skipvar:
}
ast_unref(number);
if (builtin_num < 0) {
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;
}
if (var->hasvalue) {
(void)!parsewarning(parser, WARN_DOUBLE_DECLARATION,
"builtin `%s` has already been defined\n"
@ -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);