]> git.draconx.ca Git - cdecl99.git/commitdiff
libcdecl: Simplify reduce_parentheses implementation.
authorNick Bowler <nbowler@draconx.ca>
Fri, 30 Jun 2023 05:24:12 +0000 (01:24 -0400)
committerNick Bowler <nbowler@draconx.ca>
Sun, 2 Jul 2023 00:16:06 +0000 (20:16 -0400)
Simplify the reduce_parentheses implementation so it operates in a
much more straightforward way.  We can also just call simplify_functions
directly during the same tree traversal, instead of trying to predict
what simplify_functions will do to a node on a later traversal.

src/parse-decl.c

index f156ba9f0052c23146cc2147f4b91b4f29b871a2..6ab624e4f30d0a15acd29dd9f05e7fd616c46258 100644 (file)
@@ -254,58 +254,52 @@ simplify_functions(struct cdecl_declarator **p, struct cdecl_declarator *d)
  * simplify_functions pass.
  */
 
-static int
-reduce_parentheses(struct cdecl_declarator **p, struct cdecl_declarator *d)
+static struct cdecl *fake_function_param(struct cdecl_declarator *d)
 {
        struct cdecl *param;
 
        if (d->type != CDECL_DECL_FUNCTION)
-               return 0;
+               return NULL;
 
        param = d->u.function.parameters;
-       if (param && param->specifiers == NULL) {
-               struct cdecl_declarator *decl;
+       if (!param || param->specifiers)
+               return NULL;
 
-               assert(!param->next);
+       assert(!param->next);
+       return param;
+}
 
-               decl = param->declarators;
-               if (decl->type == CDECL_DECL_NULL) {
-                       free(decl);
-                       free(param);
-                       d->u.function.parameters = NULL;
-                       return 0;
-               }
+static int
+reduce_parentheses(struct cdecl_declarator **p, struct cdecl_declarator *d)
+{
+       struct cdecl *param;
+       int fake = 0;
+
+       while ((param = fake_function_param(d))) {
+               struct cdecl_declarator *decl = param->declarators;
+               d->u.function.parameters = NULL;
+
+               if (decl->type != CDECL_DECL_NULL) {
+                       if (d->child->type != CDECL_DECL_NULL) {
+                               /* Found fake parameter on real function. */
+                               d->u.function.parameters = param;
+                               cdecl__errmsg(CDECL__EBADPARAM);
+                               return -1;
+                       }
 
-               if (d->child->type != CDECL_DECL_NULL) {
-                       cdecl__errmsg(CDECL__EBADPARAM);
-                       return -1;
+                       param->declarators = d;
+                       *p = d = decl;
+                       fake = 1;
                }
 
-               free(d->child);
-               free(param);
-               free(d);
-               *p = decl;
-
-               /*
-                * We may have replaced d with another fake function which
-                * also needs to be eliminated.
-                */
-               if (reduce_parentheses(p, decl) < 0)
-                       return -1;
-
-               /*
-                * If the remaining declarator is a function, make sure it's
-                * valid by checking its reducibility.
-                */
-               decl = *p;
-               if (decl->type == CDECL_DECL_FUNCTION
-                   && decl->child->type == CDECL_DECL_NULL
-                   && !function_is_reducible(decl)) {
-                       cdecl__errmsg(CDECL__EMANYPAREN);
-                       return -1;
-               }
+               cdecl__free(param);
+       }
 
-               return 0;
+       simplify_functions(p, d);
+       if (fake && (*p)->type == CDECL_DECL_FUNCTION) {
+               /* Started with a fake function but ended with a real one. */
+               cdecl__errmsg(CDECL__EMANYPAREN);
+               return -1;
        }
 
        return 0;
@@ -512,8 +506,6 @@ static int do_postprocess(struct cdecl *decl, int english_mode)
                if (!english_mode) {
                        if (forall_declarators(i, reduce_parentheses) < 0)
                                return 0;
-                       if (forall_declarators(i, simplify_functions) < 0)
-                               return 0;
                }
 
                if (forall_declarators(i, postproc_common) < 0)