@@ -208,11 +208,54 @@ static value_t fl_nothrow_julia_global(fl_context_t *fl_ctx, value_t *args, uint
208208 return b != NULL && jl_atomic_load_relaxed (& b -> value ) != NULL ? fl_ctx -> T : fl_ctx -> F ;
209209}
210210
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+
211215static value_t fl_current_module_counter (fl_context_t * fl_ctx , value_t * args , uint32_t nargs ) JL_NOTSAFEPOINT
212216{
213217 jl_ast_context_t * ctx = jl_ast_ctx (fl_ctx );
214218 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 );
216259}
217260
218261static int jl_is_number (jl_value_t * v )
@@ -240,13 +283,51 @@ static value_t fl_julia_scalar(fl_context_t *fl_ctx, value_t *args, uint32_t nar
240283 return fl_ctx -> F ;
241284}
242285
286+ static value_t fl_julia_push_closure_expr (fl_context_t * fl_ctx , value_t * args , uint32_t nargs )
287+ {
288+ argcount (fl_ctx , "julia-push-closure-expr" , nargs , 1 );
289+ // Check if the head of the symbol at `args[0]` is (method <name>) or (method (outerref <name>))
290+ // and if so, push the name onto the `parsed_method_stack`
291+ value_t arg = args [0 ];
292+ if (iscons (arg )) {
293+ value_t head = car_ (arg );
294+ if (head == symbol (fl_ctx , "method" )) {
295+ value_t name = car_ (cdr_ (arg ));
296+ if (issymbol (name )) {
297+ arraylist_push (& parsed_method_stack , (void * )name );
298+ return fl_ctx -> T ;
299+ }
300+ if (iscons (name )) {
301+ value_t head = car_ (name );
302+ if (head == symbol (fl_ctx , "outerref" )) {
303+ value_t name_inner = car_ (cdr_ (name ));
304+ assert (issymbol (name_inner ));
305+ arraylist_push (& parsed_method_stack , (void * )name_inner );
306+ return fl_ctx -> T ;
307+ }
308+ }
309+ }
310+ }
311+ return fl_ctx -> F ;
312+ }
313+
314+ static value_t fl_julia_pop_closure_expr (fl_context_t * fl_ctx , value_t * args , uint32_t nargs )
315+ {
316+ argcount (fl_ctx , "julia-pop-closure-expr" , nargs , 0 );
317+ // Pop the top of the `parsed_method_stack`
318+ arraylist_pop (& parsed_method_stack );
319+ return fl_ctx -> NIL ;
320+ }
321+
243322static jl_value_t * scm_to_julia_ (fl_context_t * fl_ctx , value_t e , jl_module_t * mod );
244323
245324static const builtinspec_t julia_flisp_ast_ext [] = {
246325 { "defined-julia-global" , fl_defined_julia_global }, // TODO: can we kill this safepoint
247326 { "nothrow-julia-global" , fl_nothrow_julia_global },
248327 { "current-julia-module-counter" , fl_current_module_counter },
249328 { "julia-scalar?" , fl_julia_scalar },
329+ { "julia-push-closure-expr" , fl_julia_push_closure_expr },
330+ { "julia-pop-closure-expr" , fl_julia_pop_closure_expr },
250331 { NULL , NULL }
251332};
252333
0 commit comments