mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-23 20:33:05 +00:00
Pushing the -fexpressions-for-builtins stuff and the modff for catching fractional-part builtin numbers.
This commit is contained in:
parent
ce73074d51
commit
68ca2c4962
3 changed files with 45 additions and 27 deletions
1
main.c
1
main.c
|
@ -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;
|
||||
|
|
1
opts.def
1
opts.def
|
@ -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 */
|
||||
|
|
70
parser.c
70
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,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);
|
||||
|
|
Loading…
Reference in a new issue