]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - parser.c
gitignore: add gmqcc, gmqpak, qmcvm, testsuite, pak.
[xonotic/gmqcc.git] / parser.c
index d95a44642beaa606c13b88d07effdf6a760e0bc8..c6819223cb279d4233ff8af9db6de883d31469ca 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -266,6 +266,7 @@ static ast_value* parser_const_string(parser_t *parser, const char *str, bool do
             char name[32];
             util_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++));
             ast_value_set_name(out, name);
+            out->expression.flags |= AST_FLAG_INCLUDE_DEF;
         }
         return out;
     }
@@ -279,6 +280,7 @@ static ast_value* parser_const_string(parser_t *parser, const char *str, bool do
         char name[32];
         util_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(parser->translated++));
         out = ast_value_new(parser_ctx(parser), name, TYPE_STRING);
+        out->expression.flags |= AST_FLAG_INCLUDE_DEF;
     } else
         out = ast_value_new(parser_ctx(parser), "#IMMEDIATE", TYPE_STRING);
     out->cvq      = CV_CONST;
@@ -5639,9 +5641,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 +5660,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 +5716,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);