Skip to content

Commit d7b70b1

Browse files
do scope pushing in a separate enter handler
1 parent 5b475dc commit d7b70b1

File tree

2 files changed

+30
-21
lines changed

2 files changed

+30
-21
lines changed

cogni.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,15 +1281,10 @@ cog_object* cog_make_closure(cog_object* block, cog_object* scopes) {
12811281
}
12821282

12831283
cog_object* m_closure_exec() {
1284-
// trace();
1285-
// debug_dump_stuff();
1286-
// abort();
12871284
cog_object* self = cog_pop();
12881285
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;
12931288
// push scope teardown command
12941289
if (should_push_scope) cog_run_next(cog_make_identifier_c("[[Closure::RestoreCallerScope]]"), cog_on_exit(), COG_GLOBALS.scopes);
12951290
// push all current commands
@@ -1298,10 +1293,8 @@ cog_object* m_closure_exec() {
12981293
COG_ITER_LIST(self->data->next, cmd) cog_run_next(cmd, NULL, NULL);
12991294
cog_reverse_list_inplace(&COG_GLOBALS.command_queue);
13001295
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);
13051298
return NULL;
13061299
}
13071300
cog_object_method ome_closure_exec = {&ot_closure, COG_M_EXEC, m_closure_exec};
@@ -1319,6 +1312,21 @@ cog_modfunc fne_closure_restore_scope = {
13191312
NULL,
13201313
};
13211314

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+
13221330
cog_object* m_block_exec() {
13231331
cog_object* self = cog_pop();
13241332
cog_pop(); // ignore cookie
@@ -2815,9 +2823,8 @@ cog_object* m_continuation_exec() {
28152823
cog_object* old_command_queue = self->next->data;
28162824
cog_object* old_scopes = self->next->next;
28172825
// 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
28212828
COG_GLOBALS.stack = old_stack;
28222829
COG_GLOBALS.command_queue = old_command_queue;
28232830
COG_GLOBALS.scopes = old_scopes;
@@ -2862,6 +2869,7 @@ static cog_modfunc* builtin_modfunc_table[] = {
28622869
&fne_parser_handle_token,
28632870
&fne_parser_transform_def_or_let,
28642871
&fne_closure_restore_scope,
2872+
&fne_closure_insert_new_scope,
28652873
// math functions
28662874
&fne_empty,
28672875
&fne_plus,

run_tests.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import glob
2-
import subprocess
3-
import re
42
import os
3+
import re
4+
import signal
5+
import subprocess
56

67
os.chdir("cognac/")
78

@@ -20,11 +21,11 @@ def test(file: str, process: subprocess.Popen, pad_length: int):
2021
try:
2122
exit_code = process.wait()
2223
except KeyboardInterrupt:
23-
exit_code = "^C"
24-
out: bytes = process.stdout.read()
25-
if exit_code == "^C":
24+
exit_code = signal.SIGINT
25+
out: bytes = process.stdout.read() + process.stderr.read() + \
26+
f"\nProgram exited with code {exit_code}\n".encode()
27+
if exit_code == signal.SIGINT:
2628
print("\x1b[35mINTERRUPT\x1b[0m", end=" ")
27-
out += b"^C"
2829
elif exit_code != 0:
2930
crashes += 1
3031
print("\x1b[31mCRASH\x1b[0m", end=" ")
@@ -49,7 +50,7 @@ def test(file: str, process: subprocess.Popen, pad_length: int):
4950
test_files = sorted(glob.glob("tests/*.cog"))
5051
test_commands = [["../cogni", file] for file in test_files]
5152
test_processes = [subprocess.Popen(
52-
command, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
53+
command, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
5354
for command in test_commands]
5455
for f, p in zip(test_files, test_processes):
5556
test(f, p, max(map(len, test_files)))

0 commit comments

Comments
 (0)