From 2a21b457d71e8cace0db0e3b4913234d25f38aec Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Tue, 2 Dec 2025 14:26:48 -0500 Subject: Advent --- fig-utils/csrc/fig.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 6 deletions(-) (limited to 'fig-utils/csrc/fig.c') diff --git a/fig-utils/csrc/fig.c b/fig-utils/csrc/fig.c index 2ad1005..0df8bae 100644 --- a/fig-utils/csrc/fig.c +++ b/fig-utils/csrc/fig.c @@ -1,9 +1,61 @@ #include #include +SCM default_bindings() { + SCM bindings = scm_c_public_ref("ice-9 sandbox", "all-pure-and-impure-bindings"); + bindings = scm_cons( + scm_list_2( + scm_list_2(scm_from_utf8_symbol("srfi"), scm_from_utf8_symbol("srfi-9")), + scm_from_utf8_symbol("define-record-type")), + bindings + ); + bindings = scm_cons( + scm_list_2( + scm_list_2(scm_from_utf8_symbol("srfi"), scm_from_utf8_symbol("srfi-1")), + scm_from_utf8_symbol("drop")), + bindings + ); + bindings = scm_cons( + scm_list_2( + scm_list_1(scm_from_utf8_symbol("guile")), + scm_from_utf8_symbol("seed->random-state")), + bindings + ); + bindings = scm_cons( + scm_list_2( + scm_list_1(scm_from_utf8_symbol("guile")), + scm_from_utf8_symbol("random")), + bindings + ); + bindings = scm_cons( + scm_list_2( + scm_list_1(scm_from_utf8_symbol("guile")), + scm_from_utf8_symbol("eval")), + bindings + ); + bindings = scm_cons( + scm_list_2( + scm_list_1(scm_from_utf8_symbol("guile")), + scm_from_utf8_symbol("interaction-environment")), + bindings + ); + return bindings; +} + +SCM eval_sandbox(SCM call) { + SCM eval = scm_c_public_ref("ice-9 sandbox", "eval-in-sandbox"); + return scm_call_7(eval, call, + scm_from_utf8_keyword("time-limit"), scm_from_int64(3), + scm_from_utf8_keyword("allocation-limit"), scm_from_int64(1024 * 1024 * 1024), + scm_from_utf8_keyword("bindings"), + default_bindings() + ); +} + typedef struct check_answer_args { char *code; - char *data; + char *actual; + char *expected; } check_answer_args; SCM check_answer_catch_body(void *data) { check_answer_args *args = (check_answer_args *) data; @@ -11,9 +63,8 @@ SCM check_answer_catch_body(void *data) { // SCM res = scm_call_1(handler, scm_from_utf8_string(args->data)); SCM readport = scm_open_input_string(scm_from_utf8_string(args->code)); SCM func = scm_read(readport); - SCM call = scm_list_2(func, scm_from_utf8_string(args->data)); - SCM eval = scm_c_public_ref("ice-9 sandbox", "eval-in-sandbox"); - return scm_call_1(eval, call); + SCM call = scm_list_3(func, scm_from_utf8_string(args->actual), scm_from_utf8_string(args->expected)); + return eval_sandbox(call); } SCM check_answer_catch_handler(void *data, SCM key, SCM args) { SCM format = scm_c_public_ref("ice-9 format", "format"); @@ -25,9 +76,9 @@ SCM check_answer_catch_handler(void *data, SCM key, SCM args) { return scm_call_5(format, SCM_BOOL_F, fmt, key, func, msg); } -int check_answer(char **failure, char *code, char *data) { +int check_answer(char **failure, char *code, char *actual, char *expected) { scm_init_guile(); - check_answer_args args = { .code = code, .data = data }; + check_answer_args args = { .code = code, .actual = actual, .expected = expected }; SCM res = scm_c_catch( SCM_BOOL_T, check_answer_catch_body, &args, @@ -41,3 +92,41 @@ int check_answer(char **failure, char *code, char *data) { return 0; } } + +typedef struct gen_input_answer_args { + char *code; + char *twitchid; +} gen_input_answer_args; +SCM gen_input_answer_catch_body(void *data) { + gen_input_answer_args *args = (gen_input_answer_args *) data; + SCM readport = scm_open_input_string(scm_from_utf8_string(args->code)); + SCM func = scm_read(readport); + SCM call = scm_list_2(func, scm_from_utf8_string(args->twitchid)); + return eval_sandbox(call); +} +SCM gen_input_answer_catch_handler(void *data, SCM key, SCM args) { + SCM format = scm_c_public_ref("ice-9 format", "format"); + SCM fmt = scm_from_utf8_string("~a: ~a: ~a"); + SCM func = scm_car(args); + SCM afmt = scm_cadr(args); + SCM aargs = scm_caddr(args); + SCM msg = scm_apply_2(format, SCM_BOOL_F, afmt, aargs); + return scm_call_5(format, SCM_BOOL_F, fmt, key, func, msg); +} + +void gen_input_answer(char **failure, char **input, char **answer, char *code, char *twitchid) { + scm_init_guile(); + gen_input_answer_args args = { .code = code, .twitchid = twitchid }; + SCM res = scm_c_catch( + SCM_BOOL_T, + gen_input_answer_catch_body, &args, + gen_input_answer_catch_handler, NULL, + gen_input_answer_catch_handler, NULL); + if (scm_is_pair(res)) { + *failure = NULL; + *input = scm_to_utf8_stringn(scm_car(res), NULL); + *answer = scm_to_utf8_stringn(scm_cdr(res), NULL); + } else { + *failure = scm_to_utf8_stringn(res, NULL); + } +} -- cgit v1.2.3