From ec3a8ace63d1d42524c5a93c59cf7fe5ff1f0548 Mon Sep 17 00:00:00 2001 From: Neil Jerram Date: Wed, 14 Dec 2005 00:21:11 +0000 Subject: [PATCH] * api-evaluation.texi (Loading): Document custom reader. * boot-9.scm (load-module): Support an optional custom reader arg, implemented by passing on to r4rs's load. * r4rs.scm (load): Support an optional custom reader arg, implemented by passing on to primitive-load. * load.c (the_reader, the_reader_fluid_num): New. (scm_primitive_load): Support custom reader. (scm_init_load): Init the_reader and the_reader_fluid_num; export the_reader as `current-reader'. --- doc/ref/ChangeLog | 4 ++++ doc/ref/api-evaluation.texi | 31 ++++++++++++++++++++++++++----- ice-9/ChangeLog | 8 ++++++++ ice-9/boot-9.scm | 16 +++++++++------- ice-9/r4rs.scm | 8 +++++--- libguile/ChangeLog | 5 +++++ libguile/load.c | 22 +++++++++++++++++++++- 7 files changed, 78 insertions(+), 16 deletions(-) diff --git a/doc/ref/ChangeLog b/doc/ref/ChangeLog index c3580dd16..ace7d30bd 100644 --- a/doc/ref/ChangeLog +++ b/doc/ref/ChangeLog @@ -1,3 +1,7 @@ +2005-12-14 Neil Jerram + + * api-evaluation.texi (Loading): Document custom reader. + 2005-12-06 Marius Vollmer * api-init.texi, api-scheduling.texi, libguile-concepts.texi: diff --git a/doc/ref/api-evaluation.texi b/doc/ref/api-evaluation.texi index b41e88a0a..9110f6667 100644 --- a/doc/ref/api-evaluation.texi +++ b/doc/ref/api-evaluation.texi @@ -409,12 +409,24 @@ the current module. @subsection Loading Scheme Code from File @rnindex load -@deffn {Scheme Procedure} load filename +@deffn {Scheme Procedure} load filename [reader] Load @var{filename} and evaluate its contents in the top-level -environment. The load paths are not searched. If the variable -@code{%load-hook} is defined, it should be bound to a procedure that -will be called before any code is loaded. See documentation for -@code{%load-hook} later in this section. +environment. The load paths are not searched. + +@var{reader} if provided should be either @code{#f}, or a procedure with +the signature @code{(lambda (port) @dots{})} which reads the next +expression from @var{port}. If @var{reader} is @code{#f} or absent, +Guile's built-in @code{read} procedure is used (@pxref{Scheme Read}). + +The @var{reader} argument takes effect by setting the value of the +@code{current-reader} fluid (see below) before loading the file, and +restoring its previous value when loading is complete. The Scheme code +inside @var{filename} can itself change the current reader procedure on +the fly by setting @code{current-reader} fluid. + +If the variable @code{%load-hook} is defined, it should be bound to a +procedure that will be called before any code is loaded. See +documentation for @code{%load-hook} later in this section. @end deffn @deffn {Scheme Procedure} load-from-path filename @@ -452,6 +464,15 @@ in the @code{%load-extensions} list; @code{%search-load-path} will try each extension automatically. @end deffn +@defvar current-reader +@code{current-reader} holds the read procedure that is currently being +used by the above loading procedures to read expressions (from the file +that they are loading). @code{current-reader} is a fluid, so it has an +independent value in each dynamic root and should be read and set using +@code{fluid-ref} and @code{fluid-set!} (@pxref{Fluids and Dynamic +States}). +@end defvar + @defvar %load-hook A procedure to be called @code{(%load-hook @var{filename})} whenever a file is loaded, or @code{#f} for no such call. @code{%load-hook} is diff --git a/ice-9/ChangeLog b/ice-9/ChangeLog index 5c5e54e22..9d6dd505a 100644 --- a/ice-9/ChangeLog +++ b/ice-9/ChangeLog @@ -1,3 +1,11 @@ +2005-12-14 Neil Jerram + + * boot-9.scm (load-module): Support an optional custom reader arg, + implemented by passing on to r4rs's load. + + * r4rs.scm (load): Support an optional custom reader arg, + implemented by passing on to primitive-load. + 2005-12-06 Marius Vollmer From Stephen Compall. diff --git a/ice-9/boot-9.scm b/ice-9/boot-9.scm index 6f0818523..775b8509c 100644 --- a/ice-9/boot-9.scm +++ b/ice-9/boot-9.scm @@ -1635,17 +1635,19 @@ (define basic-load load) -(define (load-module filename) +(define (load-module filename . reader) (save-module-excursion (lambda () (let ((oldname (and (current-load-port) (port-filename (current-load-port))))) - (basic-load (if (and oldname - (> (string-length filename) 0) - (not (char=? (string-ref filename 0) #\/)) - (not (string=? (dirname oldname) "."))) - (string-append (dirname oldname) "/" filename) - filename)))))) + (apply basic-load + (if (and oldname + (> (string-length filename) 0) + (not (char=? (string-ref filename 0) #\/)) + (not (string=? (dirname oldname) "."))) + (string-append (dirname oldname) "/" filename) + filename) + reader))))) diff --git a/ice-9/r4rs.scm b/ice-9/r4rs.scm index 6e93853a2..93b0d8f81 100644 --- a/ice-9/r4rs.scm +++ b/ice-9/r4rs.scm @@ -206,6 +206,8 @@ procedures, their behavior is implementation dependent." (set! %load-hook %load-announce) -(define (load name) - (start-stack 'load-stack - (primitive-load name))) +(define (load name . reader) + (with-fluid* current-reader (and (pair? reader) (car reader)) + (lambda () + (start-stack 'load-stack + (primitive-load name))))) diff --git a/libguile/ChangeLog b/libguile/ChangeLog index f57b52ec5..e37af5096 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,5 +1,10 @@ 2005-12-14 Neil Jerram + * load.c (the_reader, the_reader_fluid_num): New. + (scm_primitive_load): Support custom reader. + (scm_init_load): Init the_reader and the_reader_fluid_num; export + the_reader as `current-reader'. + * scmsigs.c (do_read_without_guile): Use the "raw_data" passed in (rather than an uninitialized pointer on the stack). diff --git a/libguile/load.c b/libguile/load.c index 4b51a0bb6..8527ac93f 100644 --- a/libguile/load.c +++ b/libguile/load.c @@ -42,6 +42,7 @@ #include "libguile/validate.h" #include "libguile/load.h" +#include "libguile/fluids.h" #include #include @@ -61,6 +62,10 @@ Applied to the full name of the file. */ static SCM *scm_loc_load_hook; +/* The current reader (a fluid). */ +static SCM the_reader = SCM_BOOL_F; +static size_t the_reader_fluid_num = 0; + SCM_DEFINE (scm_primitive_load, "primitive-load", 1, 0, 0, (SCM filename), "Load the file named @var{filename} and evaluate its contents in\n" @@ -88,9 +93,19 @@ SCM_DEFINE (scm_primitive_load, "primitive-load", 1, 0, 0, while (1) { - SCM form = scm_read (port); + SCM reader, form; + + /* Lookup and use the current reader to read the next + expression. */ + reader = SCM_FAST_FLUID_REF (the_reader_fluid_num); + if (reader == SCM_BOOL_F) + form = scm_read (port); + else + form = scm_call_1 (reader, port); + if (SCM_EOF_OBJECT_P (form)) break; + scm_primitive_eval_x (form); } @@ -501,6 +516,11 @@ scm_init_load () scm_nullstr))); scm_loc_load_hook = SCM_VARIABLE_LOC (scm_c_define ("%load-hook", SCM_BOOL_F)); + the_reader = scm_make_fluid (); + the_reader_fluid_num = SCM_FLUID_NUM (the_reader); + SCM_FAST_FLUID_SET_X (the_reader_fluid_num, SCM_BOOL_F); + scm_c_define("current-reader", the_reader); + init_build_info (); #include "libguile/load.x"