Skip to content

Commit eb4b114

Browse files
committed
canonicalize anon function names through a per-module counter
1 parent 4aa7d31 commit eb4b114

File tree

1 file changed

+37
-21
lines changed

1 file changed

+37
-21
lines changed

src/ast.c

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ struct macroctx_stack {
149149
struct macroctx_stack *parent;
150150
};
151151

152-
// Map of scheme symbols to forwared julia symbols
152+
// Map of scheme symbols to forwarded julia symbols
153153
htable_t scm_to_jl_sym_map;
154154

155155
static jl_value_t *scm_to_julia(fl_context_t *fl_ctx, value_t e, jl_module_t *mod);
@@ -181,34 +181,50 @@ static jl_sym_t *scmsym_to_julia(fl_context_t *fl_ctx, value_t s)
181181
// Get the module name
182182
const char *mname = jl_symbol_name(m->name);
183183
size_t l = strlen(n) + 1 + strlen(mname) + 1;
184-
char *nn = (char*)malloc_s(l);
184+
char *nn = (char*)calloc_s(l);
185185
// Get the last `#` in the symbol
186186
char *p = strrchr(n, '#');
187187
assert(p != NULL);
188-
// Copy the prefix
189-
size_t pl = p - n;
190-
memcpy(nn, n, pl);
188+
size_t pl;
189+
// Now we check if the prefix itself is gensym'ed, i.e. #some_number
190+
if (n[0] == '#' && '0' < n[1] && n[1] <= '9') {
191+
// It is, so we forward the prefix as well
192+
uint32_t nxt = ++m->sym_counter;
193+
// Now convert it to module_name<counter>
194+
char str[strlen(mname) + 16];
195+
snprintf(str, sizeof(str), "#%s<%d>", mname, nxt);
196+
// Copy the prefix
197+
memcpy(nn, str, strlen(str) + 1);
198+
pl = strlen(str);
199+
// First get the flisp symbol corresponding to the prefix
200+
char pp[strlen(n) + 1];
201+
memcpy(pp, n, p - n);
202+
pp[p - n] = '\0';
203+
value_t ps = symbol(fl_ctx, pp);
204+
// Then forward it
205+
ptrhash_put(&scm_to_jl_sym_map, (void*)ps, (void*)jl_symbol(nn));
206+
// If there is exactly one occurence of `#` (instead of something like `#foo#42`), we are done
207+
if (p == n) {
208+
n = nn;
209+
goto done;
210+
}
211+
}
212+
else {
213+
pl = p - n;
214+
// Copy the prefix
215+
memcpy(nn, n, pl);
216+
}
191217
nn[pl] = '#';
192-
// Copy the module name
193-
memcpy(nn + pl + 1, mname, l - pl - 1);
194-
nn[l - 1] = '\0';
195-
n = nn;
196-
// Now add the numeric suffix of m->sym_counter++
218+
// Append the module_name<counter>
197219
uint32_t nxt = ++m->sym_counter;
198-
// Convert it to string adding a leading `<` and a trailing `>`
199-
char *q = uint2str((char*)alloca(16), 16, nxt, 10);
200-
// Add the leading `<` and the trailing `>`
201-
char *qq = alloca(strlen(q) + 2);
202-
memset(qq, 0, strlen(q) + 2);
203-
qq[0] = '<';
204-
memcpy(qq + 1, q, strlen(q) + 1);
205-
qq[strlen(q) + 1] = '>';
206-
q = qq;
207-
// Append it to the symbol, without a leading `#`
208-
memcpy(nn + pl + 1 + strlen(mname), q, strlen(q) + 1);
220+
char str[strlen(mname) + 16];
221+
snprintf(str, sizeof(str), "%s<%d>", mname, nxt);
222+
memcpy(nn + pl + 1, str, strlen(str) + 1);
209223
// Add it to the hash table of forwarded symbols
224+
n = nn;
210225
ptrhash_put(&scm_to_jl_sym_map, (void*)s, (void*)jl_symbol(n));
211226
}
227+
done:
212228
return jl_symbol(n);
213229
}
214230

0 commit comments

Comments
 (0)