[前][次][番号順一覧][スレッド一覧]

ruby-changes:62027

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Mon, 29 Jun 2020 11:07:55 +0900 (JST)
Subject: [ruby-changes:62027] a523eca1c2 (master): rb_enc_symname_type: refactor split

https://git.ruby-lang.org/ruby.git/commit/?id=a523eca1c2

From a523eca1c2581be92cab4b1461e3dd65102d99bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Thu, 25 Jun 2020 14:03:23 +0900
Subject: rb_enc_symname_type: refactor split

Reduce goto by splitting the function.

diff --git a/symbol.c b/symbol.c
index e9f0942..6e868d3 100644
--- a/symbol.c
+++ b/symbol.c
@@ -238,89 +238,138 @@ rb_sym_constant_char_p(const char *name, long nlen, rb_encoding *enc) https://github.com/ruby/ruby/blob/trunk/symbol.c#L238
 #define IDSET_ATTRSET_FOR_SYNTAX ((1U<<ID_LOCAL)|(1U<<ID_CONST))
 #define IDSET_ATTRSET_FOR_INTERN (~(~0U<<(1<<ID_SCOPE_SHIFT)) & ~(1U<<ID_ATTRSET))
 
-int
-rb_enc_symname_type(const char *name, long len, rb_encoding *enc, unsigned int allowed_attrset)
+struct enc_synmane_type_leading_chars_tag {
+    const enum { invalid, stophere, needmore, } kind;
+    const enum ruby_id_types type;
+    const long nread;
+};
+
+#define t struct enc_synmane_type_leading_chars_tag
+
+static struct enc_synmane_type_leading_chars_tag
+enc_synmane_type_leading_chars(const char *name, long len, const rb_encoding *enc, int allowed_attrset)
 {
     const char *m = name;
     const char *e = m + len;
-    int type = ID_JUNK;
 
-    if (!rb_enc_asciicompat(enc)) return -1;
-    if (!m || len <= 0) return -1;
+    if (! rb_enc_asciicompat(enc)) {
+        return (t) { invalid, 0, 0, };
+    }
+    else if (! m) {
+        return (t) { invalid, 0, 0, };
+    }
+    else if ( len <= 0 ) {
+        return (t) { invalid, 0, 0, };
+    }
     switch (*m) {
       case '\0':
-	return -1;
+        return (t) { invalid, 0, 0, };
 
       case '$':
-	type = ID_GLOBAL;
-	if (is_special_global_name(++m, e, enc)) return type;
-	goto id;
+        if (is_special_global_name(++m, e, enc)) {
+            return (t) { stophere, ID_GLOBAL, len, };
+        }
+        else {
+            return (t) { needmore, ID_GLOBAL, 1, };
+        }
 
       case '@':
-	type = ID_INSTANCE;
-	if (*++m == '@') {
-	    ++m;
-	    type = ID_CLASS;
-	}
-	goto id;
+        switch (*++m) {
+          default:  return (t) { needmore, ID_INSTANCE, 1, };
+          case '@': return (t) { needmore, ID_CLASS,    2, };
+        }
 
       case '<':
 	switch (*++m) {
-	  case '<': ++m; break;
-	  case '=': if (*++m == '>') ++m; break;
-	  default: break;
+          default:  return (t) { stophere, ID_JUNK, 1, };
+          case '<': return (t) { stophere, ID_JUNK, 2, };
+          case '=':
+            switch (*++m) {
+              default:  return (t) { stophere, ID_JUNK, 2, };
+              case '>': return (t) { stophere, ID_JUNK, 3, };
+            }
 	}
-	break;
 
       case '>':
 	switch (*++m) {
-	  case '>': case '=': ++m; break;
+          default:            return (t) { stophere, ID_JUNK, 1, };
+          case '>': case '=': return (t) { stophere, ID_JUNK, 2, };
 	}
-	break;
 
       case '=':
 	switch (*++m) {
-	  case '~': ++m; break;
-	  case '=': if (*++m == '=') ++m; break;
-	  default: return -1;
+          default:  return (t) { invalid,  0,       1, };
+          case '~': return (t) { stophere, ID_JUNK, 2, };
+          case '=':
+            switch (*++m) {
+              default:  return (t) { stophere, ID_JUNK, 2, };
+              case '=': return (t) { stophere, ID_JUNK, 3, };
+            }
 	}
-	break;
 
       case '*':
-	if (*++m == '*') ++m;
-	break;
+        switch (*++m) {
+          default:  return (t) { stophere, ID_JUNK, 1, };
+          case '*': return (t) { stophere, ID_JUNK, 2, };
+        }
 
       case '+': case '-':
-	if (*++m == '@') ++m;
-	break;
+        switch (*++m) {
+          default:  return (t) { stophere, ID_JUNK, 1, };
+          case '@': return (t) { stophere, ID_JUNK, 2, };
+        }
 
       case '|': case '^': case '&': case '/': case '%': case '~': case '`':
-	++m;
-	break;
+        return (t) { stophere, ID_JUNK, 1, };
 
       case '[':
-	if (m[1] != ']') goto id;
-	++m;
-	if (*++m == '=') ++m;
-	break;
+        switch (*++m) {
+          default: return (t) { needmore, ID_JUNK, 0, };
+          case ']':
+            switch (*++m) {
+              default:  return (t) { stophere, ID_JUNK, 2, };
+              case '=': return (t) { stophere, ID_JUNK, 3, };
+            }
+        }
 
       case '!':
-	if (len == 1) return ID_JUNK;
 	switch (*++m) {
-	  case '=': case '~': ++m; break;
+          case '=': case '~': return (t) { stophere, ID_JUNK, 2, };
 	  default:
-	    if (allowed_attrset & (1U << ID_JUNK)) goto id;
-	    return -1;
+            if (allowed_attrset & (1U << ID_JUNK)) {
+                return (t) { needmore, ID_JUNK, 1, };
+            }
+            else {
+                return (t) { stophere, ID_JUNK, 1, };
+            }
 	}
-	break;
 
       default:
-	type = rb_sym_constant_char_p(m, e-m, enc) ? ID_CONST : ID_LOCAL;
-        goto id;
+        if (rb_sym_constant_char_p(name, len, enc)) {
+            return (t) { needmore, ID_CONST, 0, };
+        }
+        else {
+            return (t) { needmore, ID_LOCAL, 0, };
+        }
+    }
+}
+#undef t
+
+int
+rb_enc_symname_type(const char *name, long len, rb_encoding *enc, unsigned int allowed_attrset)
+{
+    const struct enc_synmane_type_leading_chars_tag f =
+        enc_synmane_type_leading_chars(name, len, enc, allowed_attrset);
+    const char *m = name + f.nread;
+    const char *e = name + len;
+    int type = (int)f.type;
+
+    switch (f.kind) {
+      case invalid:  return -1;
+      case stophere: goto stophere;
+      case needmore: break;
     }
-    goto stophere;
 
-  id:
     if (m >= e || (*m != '_' && !ISALPHA(*m) && ISASCII(*m))) {
         if (len > 1 && *(e-1) == '=') {
             type = rb_enc_symname_type(name, len-1, enc, allowed_attrset);
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]