summaryrefslogtreecommitdiff
path: root/fig-utils/csrc/fig.c
diff options
context:
space:
mode:
Diffstat (limited to 'fig-utils/csrc/fig.c')
-rw-r--r--fig-utils/csrc/fig.c101
1 files changed, 95 insertions, 6 deletions
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 <stdio.h>
#include <libguile.h>
+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);
+ }
+}