]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - parser.c
factoring out the closing-paren handling code since it'll be used recursively
[xonotic/gmqcc.git] / parser.c
index ddb81d1ef6adcd6ff36b40d752e3fbe4de783e75..f95e7e087bdfc3784f1a36a493b3cddc57fe9759 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -391,6 +391,27 @@ static bool parser_sy_pop(parser_t *parser, shunt *sy)
     return true;
 }
 
+static bool parser_close_paren(parser_t *parser, shunt *sy)
+{
+    if (!sy->ops_count) {
+        parseerror(parser, "unmatched closing paren");
+        return false;
+    }
+    if (sy->ops[sy->ops_count-1].paren == 1) {
+        parseerror(parser, "empty parenthesis expression");
+        return false;
+    }
+    while (sy->ops_count) {
+        if (sy->ops[sy->ops_count-1].paren == 1) {
+            sy->ops_count--;
+            break;
+        }
+        if (!parser_sy_pop(parser, sy))
+            return false;
+    }
+    return true;
+}
+
 static ast_expression* parser_expression(parser_t *parser)
 {
     ast_expression *expr = NULL;
@@ -451,25 +472,18 @@ static ast_expression* parser_expression(parser_t *parser)
             wantop = nextwant;
             parser->lex->flags.noops = !wantop;
         } else {
-            if (parser->tok == ')') {
-                /* we do expect an operator next */
-                /* closing an opening paren */
-                if (!sy.ops_count) {
-                    parseerror(parser, "unmatched closing paren");
+            if (parser->tok == '(') {
+                /* we expected an operator, this is the function-call operator */
+                if (!shunt_ops_add(&sy, syparen(parser_ctx(parser), 'f'))) {
+                    parseerror(parser, "out of memory");
                     goto onerr;
                 }
-                if (sy.ops[sy.ops_count-1].paren == 1) {
-                    parseerror(parser, "empty parenthesis expression");
+            }
+            else if (parser->tok == ')') {
+                /* we do expect an operator next */
+                /* closing an opening paren */
+                if (!parser_close_paren(parser, &sy))
                     goto onerr;
-                }
-                while (sy.ops_count) {
-                    if (sy.ops[sy.ops_count-1].paren == 1) {
-                        sy.ops_count--;
-                        break;
-                    }
-                    if (!parser_sy_pop(parser, &sy))
-                        goto onerr;
-                }
             }
             else if (parser->tok != TOKEN_OPERATOR) {
                 parseerror(parser, "expected operator or end of statement");