@@ -1281,15 +1281,10 @@ cog_object* cog_make_closure(cog_object* block, cog_object* scopes) {
1281
1281
}
1282
1282
1283
1283
cog_object * m_closure_exec () {
1284
- // trace();
1285
- // debug_dump_stuff();
1286
- // abort();
1287
1284
cog_object * self = cog_pop ();
1288
1285
cog_object * cookie = cog_pop ();
1289
- bool should_push_scope = true;
1290
- if (cookie ) {
1291
- should_push_scope = cog_expect_type_fatal (cookie , & cog_ot_bool )-> as_int ;
1292
- }
1286
+ if (!cookie ) cookie = cog_box_bool (true);
1287
+ bool should_push_scope = cog_expect_type_fatal (cookie , & cog_ot_bool )-> as_int ;
1293
1288
// push scope teardown command
1294
1289
if (should_push_scope ) cog_run_next (cog_make_identifier_c ("[[Closure::RestoreCallerScope]]" ), cog_on_exit (), COG_GLOBALS .scopes );
1295
1290
// push all current commands
@@ -1298,10 +1293,8 @@ cog_object* m_closure_exec() {
1298
1293
COG_ITER_LIST (self -> data -> next , cmd ) cog_run_next (cmd , NULL , NULL );
1299
1294
cog_reverse_list_inplace (& COG_GLOBALS .command_queue );
1300
1295
cog_list_splice (& COG_GLOBALS .command_queue , head_existing );
1301
- // push closed over scopes
1302
- COG_GLOBALS .scopes = self -> next ;
1303
- // push a new scope for local variables
1304
- if (should_push_scope ) cog_push_new_scope ();
1296
+ cog_push_to (& cookie , self -> next );
1297
+ cog_run_next (cog_make_identifier_c ("[[Closure::InsertCallScope]]" ), cog_on_enter (), cookie );
1305
1298
return NULL ;
1306
1299
}
1307
1300
cog_object_method ome_closure_exec = {& ot_closure , COG_M_EXEC , m_closure_exec };
@@ -1319,6 +1312,21 @@ cog_modfunc fne_closure_restore_scope = {
1319
1312
NULL ,
1320
1313
};
1321
1314
1315
+ cog_object * fn_closure_insert_new_scope () {
1316
+ cog_object * cookie2 = cog_pop ();
1317
+ cog_object * closed_scopes = cookie2 -> data ;
1318
+ bool should_push_new = cookie2 -> next ? cookie2 -> next -> as_int : false;
1319
+ COG_GLOBALS .scopes = closed_scopes ;
1320
+ if (should_push_new ) cog_push_new_scope ();
1321
+ return NULL ;
1322
+ }
1323
+ cog_modfunc fne_closure_insert_new_scope = {
1324
+ "[[Closure::InsertCallScope]]" ,
1325
+ COG_COOKIEFUNC ,
1326
+ fn_closure_insert_new_scope ,
1327
+ NULL ,
1328
+ };
1329
+
1322
1330
cog_object * m_block_exec () {
1323
1331
cog_object * self = cog_pop ();
1324
1332
cog_pop (); // ignore cookie
@@ -2815,9 +2823,8 @@ cog_object* m_continuation_exec() {
2815
2823
cog_object * old_command_queue = self -> next -> data ;
2816
2824
cog_object * old_scopes = self -> next -> next ;
2817
2825
// TODO: get displaced enter and exit handlers and queue them to be run
2818
- // TODO: this would allow the closure to put the scope pushing in an enter handler
2819
- // TODO: and that would mean continuations don't have to save it because it gets saved
2820
- // TODO: on the command queue cookie
2826
+ // TODO: this would mean continuations don't have to save the scopes because it gets saved
2827
+ // TODO: on the command queue cookie of closures' enter handlers
2821
2828
COG_GLOBALS .stack = old_stack ;
2822
2829
COG_GLOBALS .command_queue = old_command_queue ;
2823
2830
COG_GLOBALS .scopes = old_scopes ;
@@ -2862,6 +2869,7 @@ static cog_modfunc* builtin_modfunc_table[] = {
2862
2869
& fne_parser_handle_token ,
2863
2870
& fne_parser_transform_def_or_let ,
2864
2871
& fne_closure_restore_scope ,
2872
+ & fne_closure_insert_new_scope ,
2865
2873
// math functions
2866
2874
& fne_empty ,
2867
2875
& fne_plus ,
0 commit comments