mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 13:49:17 +02:00
Adding the -R<module> option to run "main" procedures directly from modules,
analogous to Python's -m. With no argument, runs chibi.repl.
This commit is contained in:
parent
e037027fcf
commit
f9d73ddc30
4 changed files with 65 additions and 39 deletions
|
@ -6,7 +6,7 @@ chibi-scheme \- a tiny Scheme interpreter
|
||||||
|
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B chibi-scheme
|
.B chibi-scheme
|
||||||
[-qQrfV]
|
[-qQrRfV]
|
||||||
[-I
|
[-I
|
||||||
.I path
|
.I path
|
||||||
]
|
]
|
||||||
|
@ -103,9 +103,15 @@ The resulting environment will only contain the core syntactic
|
||||||
forms and primitives coded in C. This is very fast and guaranteed
|
forms and primitives coded in C. This is very fast and guaranteed
|
||||||
not to load any external files, but is also very limited.
|
not to load any external files, but is also very limited.
|
||||||
.TP
|
.TP
|
||||||
.BI -r
|
.BI -r [main]
|
||||||
Run the "main" procedure when the script finishes loading as in SRFI-22.
|
Run the "main" procedure when the script finishes loading as in SRFI-22.
|
||||||
.TP
|
.TP
|
||||||
|
.BI -R [module]
|
||||||
|
Loads the given module and runs the "main" procedure it defines (which
|
||||||
|
need not be exported) with a single argument of the list of command-line
|
||||||
|
arguments as in SRFI-22. The name "main" can be overridden with the -r
|
||||||
|
option.
|
||||||
|
.TP
|
||||||
.BI -s
|
.BI -s
|
||||||
Strict mode, escalating warnings to fatal errors.
|
Strict mode, escalating warnings to fatal errors.
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -110,8 +110,8 @@ are listed below.
|
||||||
|
|
||||||
The command-line programs \ccode{chibi-scheme}, \ccode{chibi-doc} and
|
The command-line programs \ccode{chibi-scheme}, \ccode{chibi-doc} and
|
||||||
\ccode{chibi-ffi} are installed by default, along with manpages.
|
\ccode{chibi-ffi} are installed by default, along with manpages.
|
||||||
\ccode{chibi-scheme} provides a REPL and way to run scripts. In the
|
\ccode{chibi-scheme} provides a REPL and way to run scripts. Run -?
|
||||||
interest of size it has no --help option - see the man page for usage.
|
for a brief list of options, or see the man page for more details.
|
||||||
\ccode{chibi-doc} is the command-line interface to the literate
|
\ccode{chibi-doc} is the command-line interface to the literate
|
||||||
documentation system described in
|
documentation system described in
|
||||||
\hyperlink["lib/chibi/scribble.html"]{(chibi scribble)}, and used to
|
\hyperlink["lib/chibi/scribble.html"]{(chibi scribble)}, and used to
|
||||||
|
|
|
@ -2,15 +2,13 @@
|
||||||
;; Copyright (c) 2012-2013 Alex Shinn. All rights reserved.
|
;; Copyright (c) 2012-2013 Alex Shinn. All rights reserved.
|
||||||
;; BSD-style license: http://synthcode.com/license.txt
|
;; BSD-style license: http://synthcode.com/license.txt
|
||||||
|
|
||||||
;;> A user-friendly REPL with line editing and signal handling.
|
;;> A user-friendly REPL with line editing and signal handling. The
|
||||||
;;> The default REPL provided by chibi-scheme is very minimal,
|
;;> default REPL provided by chibi-scheme is very minimal, meant
|
||||||
;;> meant primarily to be small and work on any platform. This
|
;;> primarily to be small and work on any platform. This module
|
||||||
;;> module provides an advanced REPL that handles vt100 line
|
;;> provides an advanced REPL that handles vt100 line editing and
|
||||||
;;> editing and signal handling, so that C-c will interrupt a
|
;;> signal handling, so that C-c will interrupt a computation and
|
||||||
;;> computation and bring you back to the REPL prompt. To use
|
;;> bring you back to the REPL prompt. To use this repl, run
|
||||||
;;> this repl, run
|
;;> \command{chibi-scheme -R} from the command line or within Emacs.
|
||||||
;;> \command{chibi-scheme -mchibi.repl -e'(repl)'}
|
|
||||||
;;> from the command line or within Emacs.
|
|
||||||
|
|
||||||
(define (with-signal-handler sig handler thunk)
|
(define (with-signal-handler sig handler thunk)
|
||||||
(let ((old-handler #f))
|
(let ((old-handler #f))
|
||||||
|
@ -448,3 +446,6 @@
|
||||||
(newline (current-error-port)))))
|
(newline (current-error-port)))))
|
||||||
(call-with-output-file (repl-history-file rp)
|
(call-with-output-file (repl-history-file rp)
|
||||||
(lambda (out) (write (history->list (repl-history rp)) out)))))))
|
(lambda (out) (write (history->list (repl-history rp)) out)))))))
|
||||||
|
|
||||||
|
(define (main args)
|
||||||
|
(repl))
|
||||||
|
|
43
main.c
43
main.c
|
@ -44,6 +44,7 @@ void sexp_usage(int err) {
|
||||||
" -e <expr> - evaluate an expression\n"
|
" -e <expr> - evaluate an expression\n"
|
||||||
" -p <expr> - evaluate and print an expression\n"
|
" -p <expr> - evaluate and print an expression\n"
|
||||||
" -r[<main>] - run a SRFI-22 main\n"
|
" -r[<main>] - run a SRFI-22 main\n"
|
||||||
|
" -R[<module>] - run main from a module\n"
|
||||||
#if SEXP_USE_IMAGE_LOADING
|
#if SEXP_USE_IMAGE_LOADING
|
||||||
" -d <file> - dump an image file and exit\n"
|
" -d <file> - dump an image file and exit\n"
|
||||||
" -i <file> - load an image file\n"
|
" -i <file> - load an image file\n"
|
||||||
|
@ -261,6 +262,18 @@ static sexp_uint_t multiplier (char c) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static char* make_import(const char* prefix, const char* mod, const char* suffix) {
|
||||||
|
int len = strlen(mod) + strlen(prefix) + strlen(suffix);
|
||||||
|
char *p, *impmod = (char*) malloc(len+1);
|
||||||
|
strcpy(impmod, prefix);
|
||||||
|
strcpy(impmod+strlen(prefix), mod);
|
||||||
|
strcpy(impmod+len-+strlen(suffix), suffix);
|
||||||
|
impmod[len] = '\0';
|
||||||
|
for (p=impmod; *p; p++)
|
||||||
|
if (*p == '.') *p=' ';
|
||||||
|
return impmod;
|
||||||
|
}
|
||||||
|
|
||||||
static void check_nonull_arg (int c, char *arg) {
|
static void check_nonull_arg (int c, char *arg) {
|
||||||
if (! arg) {
|
if (! arg) {
|
||||||
fprintf(stderr, "chibi-scheme: option '%c' requires an argument\n", c);
|
fprintf(stderr, "chibi-scheme: option '%c' requires an argument\n", c);
|
||||||
|
@ -341,10 +354,9 @@ static void do_init_context (sexp* ctx, sexp* env, sexp_uint_t heap_size,
|
||||||
|
|
||||||
void run_main (int argc, char **argv) {
|
void run_main (int argc, char **argv) {
|
||||||
#if SEXP_USE_MODULES
|
#if SEXP_USE_MODULES
|
||||||
char *impmod, *p;
|
char *impmod;
|
||||||
sexp_sint_t len;
|
|
||||||
#endif
|
#endif
|
||||||
char *arg, *prefix=NULL, *suffix=NULL, *main_symbol=NULL;
|
char *arg, *prefix=NULL, *suffix=NULL, *main_symbol=NULL, *main_module=NULL;
|
||||||
sexp_sint_t i, j, c, quit=0, print=0, init_loaded=0, mods_loaded=0,
|
sexp_sint_t i, j, c, quit=0, print=0, init_loaded=0, mods_loaded=0,
|
||||||
no_script=0, fold_case=SEXP_DEFAULT_FOLD_CASE_SYMS;
|
no_script=0, fold_case=SEXP_DEFAULT_FOLD_CASE_SYMS;
|
||||||
sexp_uint_t heap_size=0, heap_max_size=SEXP_MAXIMUM_HEAP_SIZE;
|
sexp_uint_t heap_size=0, heap_max_size=SEXP_MAXIMUM_HEAP_SIZE;
|
||||||
|
@ -400,14 +412,7 @@ void run_main (int argc, char **argv) {
|
||||||
/* explicitly setting a language */
|
/* explicitly setting a language */
|
||||||
#if SEXP_USE_MODULES
|
#if SEXP_USE_MODULES
|
||||||
check_nonull_arg(c, arg);
|
check_nonull_arg(c, arg);
|
||||||
len = strlen(arg)+strlen(prefix)+strlen(suffix);
|
impmod = make_import(prefix, arg, suffix);
|
||||||
impmod = (char*) malloc(len+1);
|
|
||||||
strcpy(impmod, prefix);
|
|
||||||
strcpy(impmod+strlen(prefix), arg);
|
|
||||||
strcpy(impmod+len-+strlen(suffix), suffix);
|
|
||||||
impmod[len] = '\0';
|
|
||||||
for (p=impmod; *p; p++)
|
|
||||||
if (*p == '.') *p=' ';
|
|
||||||
tmp = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, (c=='x' ? sexp_global(ctx, SEXP_G_META_ENV) : env)));
|
tmp = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, (c=='x' ? sexp_global(ctx, SEXP_G_META_ENV) : env)));
|
||||||
free(impmod);
|
free(impmod);
|
||||||
if (c == 'x') {
|
if (c == 'x') {
|
||||||
|
@ -502,6 +507,10 @@ void run_main (int argc, char **argv) {
|
||||||
sexp_global(ctx, SEXP_G_FOLD_CASE_P) = SEXP_TRUE;
|
sexp_global(ctx, SEXP_G_FOLD_CASE_P) = SEXP_TRUE;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case 'R':
|
||||||
|
main_module = argv[i][2] == '\0' ? "chibi.repl" : argv[i]+2;
|
||||||
|
if (main_symbol == NULL) main_symbol = "main";
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
main_symbol = argv[i][2] == '\0' ? "main" : argv[i]+2;
|
main_symbol = argv[i][2] == '\0' ? "main" : argv[i]+2;
|
||||||
break;
|
break;
|
||||||
|
@ -530,6 +539,15 @@ void run_main (int argc, char **argv) {
|
||||||
/* no script or main, run interactively */
|
/* no script or main, run interactively */
|
||||||
repl(ctx, env);
|
repl(ctx, env);
|
||||||
} else {
|
} else {
|
||||||
|
#if SEXP_USE_MODULES
|
||||||
|
/* load the module or script */
|
||||||
|
if (main_module != NULL) {
|
||||||
|
impmod = make_import("(load-module '(", main_module, "))");
|
||||||
|
env = check_exception(ctx, sexp_eval_string(ctx, impmod, -1, sexp_global(ctx, SEXP_G_META_ENV)));
|
||||||
|
if (sexp_vectorp(env)) env = sexp_vector_ref(env, SEXP_ONE);
|
||||||
|
free(impmod);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
if (i < argc && !no_script) { /* script usage */
|
if (i < argc && !no_script) { /* script usage */
|
||||||
#if SEXP_USE_MODULES
|
#if SEXP_USE_MODULES
|
||||||
/* reset the environment to have only the `import' and */
|
/* reset the environment to have only the `import' and */
|
||||||
|
@ -548,7 +566,6 @@ void run_main (int argc, char **argv) {
|
||||||
sexp_env_define(ctx, env, sym, tmp);
|
sexp_env_define(ctx, env, sym, tmp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* load the script */
|
|
||||||
sexp_context_tracep(ctx) = 1;
|
sexp_context_tracep(ctx) = 1;
|
||||||
tmp = sexp_env_bindings(env);
|
tmp = sexp_env_bindings(env);
|
||||||
#if SEXP_USE_MODULES
|
#if SEXP_USE_MODULES
|
||||||
|
@ -573,6 +590,8 @@ void run_main (int argc, char **argv) {
|
||||||
if (sexp_procedurep(tmp)) {
|
if (sexp_procedurep(tmp)) {
|
||||||
args = sexp_list1(ctx, args);
|
args = sexp_list1(ctx, args);
|
||||||
check_exception(ctx, sexp_apply(ctx, tmp, args));
|
check_exception(ctx, sexp_apply(ctx, tmp, args));
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "couldn't find main binding: %s in %s\n", main_symbol, main_module ? main_module : argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue