@@ -208,11 +208,54 @@ static value_t fl_nothrow_julia_global(fl_context_t *fl_ctx, value_t *args, uint
208
208
return b != NULL && jl_atomic_load_relaxed (& b -> value ) != NULL ? fl_ctx -> T : fl_ctx -> F ;
209
209
}
210
210
211
+ arraylist_t parsed_method_stack ; // for keeping track of which methods are being parsed
212
+ uv_mutex_t counter_table_lock ;
213
+ htable_t counter_table ; // map from module_name -> inner htable; inner htable maps from char * -> uint32_t
214
+
211
215
static value_t fl_current_module_counter (fl_context_t * fl_ctx , value_t * args , uint32_t nargs ) JL_NOTSAFEPOINT
212
216
{
213
217
jl_ast_context_t * ctx = jl_ast_ctx (fl_ctx );
214
218
assert (ctx -> module );
215
- return fixnum (jl_module_next_counter (ctx -> module ));
219
+ // Create a string of the form <$outermost_func_name>$counter
220
+ // where counter is the next counter for the module obtained by calling `jl_module_next_counter`
221
+ // Get the module name
222
+ char * modname = jl_symbol_name (ctx -> module -> name );
223
+ // Get the outermost function name from the `parsed_method_stack` top
224
+ char * funcname = NULL ;
225
+ value_t funcname_v = parsed_method_stack .len > 0 ? (value_t )parsed_method_stack .items [0 ] : fl_ctx -> NIL ;
226
+ if (funcname_v != fl_ctx -> NIL ) {
227
+ funcname = symbol_name (fl_ctx , funcname_v );
228
+ }
229
+ // Create the string
230
+ char buf [(funcname != NULL ? strlen (funcname ) : 0 ) + 20 ];
231
+ if (funcname != NULL && funcname [0 ] != '#' ) {
232
+ uint32_t nxt ;
233
+ uv_mutex_lock (& counter_table_lock );
234
+ // try to find the module name in the counter table, if it's not create a symbol table for it
235
+ if (ptrhash_get (& counter_table , modname ) == HT_NOTFOUND ) {
236
+ // if not found, add it to the counter table
237
+ htable_t * new_table = (htable_t * )malloc_s (sizeof (htable_t ));
238
+ htable_new (new_table , 0 );
239
+ ptrhash_put (& counter_table , modname , new_table );
240
+ }
241
+ htable_t * mod_table = (htable_t * )ptrhash_get (& counter_table , modname );
242
+ // try to find the function name in the module's counter table, if it's not found, add it
243
+ if (ptrhash_get (mod_table , funcname ) == HT_NOTFOUND ) {
244
+ // Don't forget to shift the counter by 2 and or it with 3
245
+ // to avoid the counter being 0 or 1, which are reserved
246
+ ptrhash_put (mod_table , funcname , (void * )(uintptr_t )3 );
247
+ }
248
+ nxt = ((uint32_t )(uintptr_t )ptrhash_get (mod_table , funcname ) >> 2 );
249
+ // Increment the counter and don't forget to shift it by 2 and or it with 3
250
+ // to avoid the counter being 0 or 1, which are reserved
251
+ ptrhash_put (mod_table , funcname , (void * )(uintptr_t )((nxt + 1 ) << 2 | 3 ));
252
+ uv_mutex_unlock (& counter_table_lock );
253
+ snprintf (buf , sizeof (buf ), "%s%d" , funcname , nxt );
254
+ }
255
+ else {
256
+ snprintf (buf , sizeof (buf ), "%d" , jl_module_next_counter (ctx -> module ));
257
+ }
258
+ return symbol (fl_ctx , buf );
216
259
}
217
260
218
261
static value_t fl_julia_current_file (fl_context_t * fl_ctx , value_t * args , uint32_t nargs ) JL_NOTSAFEPOINT
@@ -250,6 +293,42 @@ static value_t fl_julia_scalar(fl_context_t *fl_ctx, value_t *args, uint32_t nar
250
293
return fl_ctx -> F ;
251
294
}
252
295
296
+ static value_t fl_julia_push_closure_expr (fl_context_t * fl_ctx , value_t * args , uint32_t nargs )
297
+ {
298
+ argcount (fl_ctx , "julia-push-closure-expr" , nargs , 1 );
299
+ // Check if the head of the symbol at `args[0]` is (method <name>) or (method (outerref <name>))
300
+ // and if so, push the name onto the `parsed_method_stack`
301
+ value_t arg = args [0 ];
302
+ if (iscons (arg )) {
303
+ value_t head = car_ (arg );
304
+ if (head == symbol (fl_ctx , "method" )) {
305
+ value_t name = car_ (cdr_ (arg ));
306
+ if (issymbol (name )) {
307
+ arraylist_push (& parsed_method_stack , (void * )name );
308
+ return fl_ctx -> T ;
309
+ }
310
+ if (iscons (name )) {
311
+ value_t head = car_ (name );
312
+ if (head == symbol (fl_ctx , "outerref" )) {
313
+ value_t name_inner = car_ (cdr_ (name ));
314
+ assert (issymbol (name_inner ));
315
+ arraylist_push (& parsed_method_stack , (void * )name_inner );
316
+ return fl_ctx -> T ;
317
+ }
318
+ }
319
+ }
320
+ }
321
+ return fl_ctx -> F ;
322
+ }
323
+
324
+ static value_t fl_julia_pop_closure_expr (fl_context_t * fl_ctx , value_t * args , uint32_t nargs )
325
+ {
326
+ argcount (fl_ctx , "julia-pop-closure-expr" , nargs , 0 );
327
+ // Pop the top of the `parsed_method_stack`
328
+ arraylist_pop (& parsed_method_stack );
329
+ return fl_ctx -> NIL ;
330
+ }
331
+
253
332
static jl_value_t * scm_to_julia_ (fl_context_t * fl_ctx , value_t e , jl_module_t * mod );
254
333
255
334
static const builtinspec_t julia_flisp_ast_ext [] = {
@@ -259,6 +338,8 @@ static const builtinspec_t julia_flisp_ast_ext[] = {
259
338
{ "julia-scalar?" , fl_julia_scalar },
260
339
{ "julia-current-file" , fl_julia_current_file },
261
340
{ "julia-current-line" , fl_julia_current_line },
341
+ { "julia-push-closure-expr" , fl_julia_push_closure_expr },
342
+ { "julia-pop-closure-expr" , fl_julia_pop_closure_expr },
262
343
{ NULL , NULL }
263
344
};
264
345
0 commit comments