expressions: Simplify function name parsing.
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 6 Dec 2021 05:19:12 +0000 (21:19 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 6 Dec 2021 17:05:31 +0000 (09:05 -0800)
src/language/expressions/parse.c

index 0493ed878bfd98283451eed17b06a66ea88b3409..f0fdafd808001d299bce731fc2e4a22085d2dbfc 100644 (file)
@@ -1044,61 +1044,53 @@ word_matches (const char **test, const char **name)
   return true;
 }
 
+/* Returns 0 if TOKEN and FUNC do not match,
+   1 if TOKEN is an acceptable abbreviation for FUNC,
+   2 if TOKEN equals FUNC. */
 static int
-compare_names (const char *test, const char *name, bool abbrev_ok)
+compare_function_names (const char *token_, const char *func_)
 {
-  if (!abbrev_ok)
-    return true;
-
-  for (;;)
-    {
-      if (!word_matches (&test, &name))
-        return true;
-      if (*name == '\0' && *test == '\0')
-        return false;
-    }
-}
-
-static int
-compare_strings (const char *test, const char *name, bool abbrev_ok UNUSED)
-{
-  return c_strcasecmp (test, name);
+  const char *token = token_;
+  const char *func = func_;
+  while (*token || *func)
+    if (!word_matches (&token, &func))
+      return 0;
+  return !c_strcasecmp (token_, func_) ? 2 : 1;
 }
 
 static bool
-lookup_function_helper (const char *name,
-                        int (*compare) (const char *test, const char *name,
-                                        bool abbrev_ok),
-                        const struct operation **first,
-                        const struct operation **last)
+lookup_function (const char *token,
+                 const struct operation **first,
+                 const struct operation **last)
 {
-  const struct operation *f;
+  *first = *last = NULL;
+  const struct operation *best = NULL;
 
-  for (f = operations + OP_function_first;
+  for (const struct operation *f = operations + OP_function_first;
        f <= operations + OP_function_last; f++)
-    if (!compare (name, f->name, !(f->flags & OPF_NO_ABBREV)))
-      {
-        *first = f;
+    {
+      int score = compare_function_names (token, f->name);
+      if (score == 2)
+        {
+          best = f;
+          break;
+        }
+      else if (score == 1 && !(f->flags & OPF_NO_ABBREV) && !best)
+        best = f;
+    }
 
-        while (f <= operations + OP_function_last
-               && !compare (name, f->name, !(f->flags & OPF_NO_ABBREV)))
-          f++;
-        *last = f;
+  if (!best)
+    return false;
 
-        return true;
-      }
+  *first = best;
 
-  return false;
-}
+  const struct operation *f = best;
+  while (f <= operations + OP_function_last
+         && !c_strcasecmp (f->name, best->name))
+    f++;
+  *last = f;
 
-static bool
-lookup_function (const char *name,
-                 const struct operation **first,
-                 const struct operation **last)
-{
-  *first = *last = NULL;
-  return (lookup_function_helper (name, compare_strings, first, last)
-          || lookup_function_helper (name, compare_names, first, last));
+  return true;
 }
 
 static int