Ilya Zakharevich on Thu, 19 Jan 2006 03:31:31 +0100 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
[PATCH 2.2.11+] Support for :: in identifiers |
This is a beginning of "package" support in GP/PARI (installing functionality via loaded libraries written in GP). All this patch enables is double colon in identifiers (as in foo::bar). Remarks: a) I have no idea what this ':'-magic in filtre0() is doing. b) Likewise for skipdecl(). Both magics are undocumented, and not used in the test suite. The added support should not break them anyway, but should not they be removed completely? Enjoy, Ilya --- ./src/language/anal.c-pre Wed Jan 18 15:48:30 2006 +++ ./src/language/anal.c Wed Jan 18 17:59:22 2006 @@ -535,10 +535,8 @@ install(void *f, char *name, char *code) } else { - char *s = name; - if (isalpha((int)*s)) - while (is_keyword_char(*++s)) /* empty */; - if (*s) err(talker2,"not a valid identifier", s, name); + if (!isalpha((int)*name) || !is_identifier(name)) + err(talker,"not a valid identifier", name); ep = installep(f, name, strlen(name), EpINSTALL, 0, functions_hash + hash); } ep->code = pari_strdup(code); @@ -782,6 +780,7 @@ type0(GEN x) /* */ /*******************************************************************/ #define separator(c) ((c)==';' || (compatible && (c)==':')) +#define at_2colons(s) ((s)[0] == ':' && (s)[1] == ':' && compatible < 2) static void allocate_loop_err(void) { @@ -1083,7 +1082,7 @@ expand_string(char *bp, char **ptbuf, ch if (is_keyword_char(*analyseur)) { char *s = analyseur; - do s++; while (is_keyword_char(*s)); + do s++; while (is_keyword_char(*s) || (at_2colons(s) && ++s)); if ((*s == '"' || *s == ',' || *s == ')') && !is_entry(analyseur)) { /* Do not create new user variable. Consider as a literal */ @@ -2550,7 +2549,23 @@ hashvalue(char **str) { long n = 0; char *s = *str; - while (is_key(*s)) { n = (n<<1) ^ *s; s++; } + while (1) { /* alnum, "_" or "::" */ + switch (*s) { + case ':': + if (s[1] != ':') + goto end_while; + n = (n<<1) ^ *s; s++; + goto eat_char; + default: + if (!isalnum((int)*s)) + goto end_while; + /* Fall through */ + case '_': + eat_char: + n = (n<<1) ^ *s; s++; + } + } + end_while: *str = s; if (n < 0) n = -n; return n % functions_tblsz; } @@ -2587,7 +2602,7 @@ is_entry_intern(char *s, entree **table, int is_identifier(char *s) { - while (*s && is_keyword_char(*s)) s++; + while (*s && (is_keyword_char(*s) || (at_2colons(s) && s++))) s++; return *s? 0: 1; } @@ -2885,7 +2900,8 @@ L1: static void skipmember(void) { - while (is_key((int)*analyseur)) analyseur++; + while (is_key((int)*analyseur) || (at_2colons(analyseur) && ++analyseur)) + analyseur++; } static void --- ./src/language/default.c-pre Tue Nov 15 05:50:38 2005 +++ ./src/language/default.c Wed Jan 18 18:01:28 2006 @@ -417,10 +417,10 @@ GEN sd_compatible(const char *v, long flag) { char *msg[] = { - "(no backward compatibility)", - "(warn when using obsolete functions)", - "(use old functions, don't ignore case)", - "(use old functions, ignore case)", NULL + "(no backward compatibility, allow :: in identifiers)", + "(warn when using obsolete functions, allow :: in identifiers)", + "(use old functions, don't ignore case, no :: in identifiers)", + "(use old functions, ignore case, no :: in identifiers)", NULL }; ulong old = compatible; GEN r = sd_ulong(v,flag,"compatible",&compatible, 0,3,msg); --- ./src/language/es.c-pre Wed Nov 16 09:30:56 2005 +++ ./src/language/es.c Wed Jan 18 17:47:24 2006 @@ -122,6 +122,10 @@ filtre0(filtre_t *F) break; case ':': + if (*s == ':') { + *t++ = *s++; + break; + } if (!compatible && isalpha((int)*s)) { t--; s++; while (is_keyword_char(*s)) { s++; } } @@ -1558,7 +1562,7 @@ get_texvar(long v, char *buf, unsigned i if (!ep) err(talker, "this object uses debugging variables"); s = ep->name; if (strlen(s) >= len) err(talker, "TeX variable name too long"); - while(isalpha((int)*s)) *t++ = *s++; + while(isalpha((int)*s) || *s == ':') *t++ = *s++; *t = 0; if (isdigit((int)*s) || *s == '_') { int seen1 = 0, seen = 0;