1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36: #define LIBGAUCHE_BODY
37: #include "gauche.h"
38: #include "gauche/builtin-syms.h"
39:
40:
41:
42:
43:
44: static void symbol_print(ScmObj obj, ScmPort *port, ScmWriteContext *);
45: SCM_DEFINE_BUILTIN_CLASS_SIMPLE(Scm_SymbolClass, symbol_print);
46:
47: #define INITSYM(sym, nam) \
48: sym = SCM_NEW(ScmSymbol); \
49: SCM_SET_CLASS(sym, SCM_CLASS_SYMBOL); \
50: sym->name = SCM_STRING(nam)
51:
52:
53: static ScmHashTable *obtable = NULL;
54: static int gensym_count = 0;
55:
56:
57:
58: ScmObj Scm_Intern(ScmString *name)
59: {
60: ScmHashEntry *e = Scm_HashTableGet(obtable, SCM_OBJ(name));
61: if (e) return e->value;
62: else {
63: ScmObj n = Scm_CopyStringWithFlags(name, SCM_STRING_IMMUTABLE,
64: SCM_STRING_IMMUTABLE);
65: ScmSymbol *sym;
66: INITSYM(sym, n);
67: Scm_HashTablePut(obtable, n, SCM_OBJ(sym));
68: return SCM_OBJ(sym);
69: }
70: }
71:
72:
73: static SCM_DEFINE_STRING_CONST(default_prefix, "G", 1, 1);
74:
75:
76:
77: ScmObj Scm_Gensym(ScmString *prefix)
78: {
79: ScmString *name;
80: ScmSymbol *sym;
81: char numbuf[50];
82: int nc;
83:
84: if (prefix == NULL) prefix = &default_prefix;
85: nc = snprintf(numbuf, 50, "%d", gensym_count++);
86: name = SCM_STRING(Scm_StringAppendC(prefix, numbuf, nc, nc));
87: INITSYM(sym, name);
88: return SCM_OBJ(sym);
89: }
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100: static char special[] = {
101:
102: 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
103:
104: 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
105:
106: 3, 0, 3, 3, 0, 0, 0, 3, 3, 3, 0, 1, 3, 1, 1, 0,
107:
108: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0,
109:
110: 1, 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
111:
112: 16,16,16,16,16,16,16,16,16,16,16,3, 11,3, 0, 0,
113:
114: 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115:
116: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 11,3, 0, 7
117: };
118:
119: static void symbol_print(ScmObj obj, ScmPort *port, ScmWriteContext *ctx)
120: {
121: if (SCM_WRITE_MODE(ctx) == SCM_WRITE_DISPLAY) {
122: SCM_PUTS(SCM_SYMBOL(obj)->name, port);
123: } else {
124:
125:
126:
127: ScmString *snam = SCM_SYMBOL(obj)->name;
128: const ScmStringBody *b = SCM_STRING_BODY(snam);
129: const char *p = SCM_STRING_BODY_START(b), *q;
130: int siz = SCM_STRING_BODY_SIZE(b), i;
131: int escape = FALSE;
132: int case_mask =
133: ((SCM_WRITE_CASE(ctx) == SCM_WRITE_CASE_FOLD)? 0x12 : 0x02);
134:
135: if (siz == 0) {
136: SCM_PUTZ("||", -1, port);
137: return;
138: }
139: if (siz == 1 && (*p == '+' || *p == '-')) {
140: SCM_PUTC((unsigned)*p, port);
141: return;
142: }
143: if ((unsigned int)*p < 128 && (special[(unsigned int)*p]&1)) {
144: escape = TRUE;
145: } else {
146: for (i=0, q=p; i<siz; i++, q++) {
147: if ((unsigned int)*q < 128
148: && (special[(unsigned int)*q]&case_mask)) {
149: escape = TRUE;
150: break;
151: }
152: }
153: }
154: if (escape) {
155: SCM_PUTC('|', port);
156: for (q=p; q<p+siz; ) {
157: unsigned int ch;
158: SCM_CHAR_GET(q, ch);
159: q += SCM_CHAR_NBYTES(ch);
160: if (ch < 128) {
161: if (special[ch] & 8) {
162: SCM_PUTC('\\', port);
163: SCM_PUTC(ch, port);
164: } else if (special[ch] & 4) {
165: Scm_Printf(port, "\\x%02x", ch);
166: } else {
167: SCM_PUTC(ch, port);
168: }
169: } else {
170: SCM_PUTC(ch, port);
171: }
172: }
173: SCM_PUTC('|', port);
174: return;
175: } else {
176: SCM_PUTS(snam, port);
177: }
178: }
179: }
180:
181:
182:
183:
184:
185: #include "builtin-syms.c"
186:
187: void Scm__InitSymbol(void)
188: {
189: obtable = SCM_HASH_TABLE(Scm_MakeHashTableSimple(SCM_HASH_STRING, 4096));
190: init_builtin_syms();
191: }