node UniqueStringN(char *s, unsigned int len){ int h = hashn(s,len) % numberof(hash_buckets); node p; for (p = hash_buckets[h]; p != NULL; p = CDR(p)) { node q = CAR(p); assertpos(q->tag == unique_string_tag,q); if (strequaln(q->body.unique_string.characters,s,len)) { return q; } } node q = newnode(UNIQUE_STRING,unique_string_tag); q->body.unique_string.characters = strnperm(s,len); q->body.unique_string.hash = h; push(hash_buckets[h],q); return q; }
node IntegerN(char *s, unsigned int len) { node q = newnode(INT_CONST,int_const_tag); q->body.int_const.contents = strnperm(s,len); return q; }
static node DoubleN(char *s, unsigned int len) { node q = newnode(DOUBLE_CONST,double_const_tag); q->body.double_const.contents = strnperm(s,len); return q; }
char *strperm(const char *s){ return strnperm(s,strlen(s)); }
node gettoken(){ char *p = cur.text; if (*p == '\'') { char c; node token; advance(); if (cur.text == cur.eot) { fatal("file ends in character constant"); } if (*cur.text == '\\') { advance(); if (cur.text == cur.eot) { fatal("file ends in character constant"); } c = escaped(*cur.text); } else c = *cur.text; advance(); if (cur.text == cur.eot) fatal("file ends in character constant"); if (*cur.text != '\'') { fatal("character constant not terminated"); } advance(); token = newnode (CHAR_CONST,char_const_tag); token->body.char_const.contents = c; return token; } if (*p == '"') { char *s; node token; advance(); s = cur.text; while (TRUE) { if (cur.text == cur.eot) fatal("file ends before string"); if (cur.text[0]=='"') break; if (*cur.text == '\\') { advance(); if (cur.text == cur.eot) fatal("file ends before string"); } advance(); } token = newnode(STRING_CONST,string_const_tag); token->body.unique_string.characters = strnperm(s,cur.text-s); /* observe that escaped character sequences such as \n are not simplified here */ advance(); return token; } if (*p == ',' || *p == '.') { advance(); } else { bool digitssofar = TRUE; while (TRUE) { if (!isdigit((int)*cur.text)) digitssofar = FALSE; advance(); if (cur.text == cur.eot) break; if (*cur.text == '.' && digitssofar) continue; if (istoken(*cur.text)) continue; break; } if (integerq(p,cur.text-p)) { return IntegerN(p,cur.text-p); } if (doubleq(p,cur.text-p)) { return DoubleN(p,cur.text-p); } } return UniqueStringN(p,cur.text-p); }