mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-20 06:09:18 +02:00
112 lines
3.3 KiB
C
112 lines
3.3 KiB
C
|
|
#include "eval.c"
|
|
|
|
void repl (sexp ctx) {
|
|
sexp obj, tmp, res, env, in, out, err;
|
|
env = sexp_context_env(ctx);
|
|
sexp_context_tracep(ctx) = 1;
|
|
in = env_global_ref(env, the_cur_in_symbol, SEXP_FALSE);
|
|
out = env_global_ref(env, the_cur_out_symbol, SEXP_FALSE);
|
|
err = env_global_ref(env, the_cur_err_symbol, SEXP_FALSE);
|
|
while (1) {
|
|
sexp_write_string("> ", out);
|
|
sexp_flush(out);
|
|
obj = sexp_read(ctx, in);
|
|
if (obj == SEXP_EOF)
|
|
break;
|
|
if (sexp_exceptionp(obj)) {
|
|
sexp_print_exception(ctx, obj, err);
|
|
} else {
|
|
tmp = sexp_env_bindings(env);
|
|
res = eval_in_context(ctx, obj);
|
|
#if USE_WARN_UNDEFS
|
|
sexp_warn_undefs(sexp_env_bindings(env), tmp, err);
|
|
#endif
|
|
if (res != SEXP_VOID) {
|
|
sexp_write(res, out);
|
|
sexp_write_char('\n', out);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void run_main (int argc, char **argv) {
|
|
sexp env, out=NULL, res, ctx, perr_cell, err_cell, err_handler;
|
|
sexp_uint_t i, quit=0, init_loaded=0;
|
|
|
|
ctx = sexp_make_context(NULL, NULL, NULL);
|
|
env = sexp_make_standard_env(ctx, sexp_make_integer(5));
|
|
env_define(ctx, env, the_interaction_env_symbol, env);
|
|
out = env_global_ref(env, the_cur_out_symbol, SEXP_FALSE);
|
|
err_cell = env_cell(env, the_cur_err_symbol);
|
|
perr_cell = env_cell(env, sexp_intern(ctx, "print-exception"));
|
|
sexp_context_env(ctx) = env;
|
|
sexp_context_tailp(ctx) = 0;
|
|
if (err_cell && perr_cell && sexp_opcodep(sexp_cdr(perr_cell))) {
|
|
emit(ctx, OP_GLOBAL_KNOWN_REF);
|
|
emit_word(ctx, (sexp_uint_t)err_cell);
|
|
emit(ctx, OP_LOCAL_REF);
|
|
emit_word(ctx, 0);
|
|
emit(ctx, OP_FCALL2);
|
|
emit_word(ctx, (sexp_uint_t)sexp_opcode_data(sexp_cdr(perr_cell)));
|
|
}
|
|
emit_push(ctx, SEXP_VOID);
|
|
emit(ctx, OP_DONE);
|
|
err_handler = sexp_make_procedure(ctx,
|
|
sexp_make_integer(0),
|
|
sexp_make_integer(0),
|
|
finalize_bytecode(ctx),
|
|
sexp_make_vector(ctx, 0, SEXP_VOID));
|
|
env_define(ctx, env, the_err_handler_symbol, err_handler);
|
|
|
|
/* parse options */
|
|
for (i=1; i < argc && argv[i][0] == '-'; i++) {
|
|
switch (argv[i][1]) {
|
|
#if USE_STRING_STREAMS
|
|
case 'e':
|
|
case 'p':
|
|
if (! init_loaded++)
|
|
sexp_load(ctx, sexp_c_string(ctx, sexp_init_file, -1), env);
|
|
res = sexp_read_from_string(ctx, argv[i+1]);
|
|
if (! sexp_exceptionp(res))
|
|
res = eval_in_context(ctx, res);
|
|
if (sexp_exceptionp(res)) {
|
|
sexp_print_exception(ctx, res, out);
|
|
} else if (argv[i][1] == 'p') {
|
|
sexp_write(res, out);
|
|
sexp_write_char('\n', out);
|
|
}
|
|
quit=1;
|
|
i++;
|
|
break;
|
|
#endif
|
|
case 'l':
|
|
if (! init_loaded++)
|
|
sexp_load(ctx, sexp_c_string(ctx, sexp_init_file, -1), env);
|
|
sexp_load(ctx, sexp_c_string(ctx, argv[++i], -1), env);
|
|
break;
|
|
case 'q':
|
|
init_loaded = 1;
|
|
break;
|
|
default:
|
|
errx(1, "unknown option: %s", argv[i]);
|
|
}
|
|
}
|
|
|
|
if (! quit) {
|
|
if (! init_loaded)
|
|
sexp_load(ctx, sexp_c_string(ctx, sexp_init_file, -1), env);
|
|
if (i < argc)
|
|
for ( ; i < argc; i++)
|
|
sexp_load(ctx, sexp_c_string(ctx, argv[i], -1), env);
|
|
else
|
|
repl(ctx);
|
|
}
|
|
}
|
|
|
|
int main (int argc, char **argv) {
|
|
scheme_init();
|
|
run_main(argc, argv);
|
|
return 0;
|
|
}
|
|
|