On Sat, 2013-03-30 at 17:17 -0400, Mark H Weaver wrote: > Nala Ginrut <nalagin...@gmail.com> writes: > > > Attached patch added an inspection command "source" to display the > > Scheme code of loaded module, it'll be useful for folks: > > > > -------------Scheme proc------------ > > scheme@(guile-user)> ,use (srfi srfi-1) > > scheme@(guile-user)> ,src any > > (define (any pred ls . lists) > > (check-arg procedure? pred any) > > (if (null? lists) > > (any1 pred ls) > > (let lp ((lists (cons ls lists))) > > (cond ((any1 null? lists) #f) > > ((any1 null? (map cdr lists)) > > (apply pred (map car lists))) > > (else > > (or (apply pred (map car lists)) > > (lp (map cdr lists)))))))) > > --------------------end------------------------- > > Nice hack! :) > > I'd be glad to see something like this in Guile core. This code is a > great demonstration, but it has some problems. > > > From 454af1f4326d600d6044de903b12812dfd9310ad Mon Sep 17 00:00:00 2001 > > From: Nala Ginrut <nalagin...@gmail.com> > > Date: Sat, 30 Mar 2013 21:48:35 +0800 > > Subject: [PATCH] Add src command in REPL to show Scheme code of loaded > > module > > > > * system/repl/command.scm: Add inspection command "source (,src)" > > which shows Scheme code of loaded module. > > --- > > module/system/repl/command.scm | 36 +++++++++++++++++++++++++++++++++++- > > 1 file changed, 35 insertions(+), 1 deletion(-) > > > > diff --git a/module/system/repl/command.scm b/module/system/repl/command.scm > > index 8ad00da..bda6dfe 100644 > > --- a/module/system/repl/command.scm > > +++ b/module/system/repl/command.scm > > @@ -65,7 +65,7 @@ > > (tracepoint tp) > > (traps) (delete del) (disable) (enable) > > (registers regs)) > > - (inspect (inspect i) (pretty-print pp)) > > + (inspect (inspect i) (pretty-print pp) (source src)) > > (system (gc) (statistics stat) (option o) > > (quit q continue cont)))) > > > > @@ -869,6 +869,40 @@ Pretty-print the result(s) of evaluating EXP." > > (pp x)) > > args)))) > > > > +(define (get-src source) > > + (define any (@ (srfi srfi-1) any)) > > + (define (skip-lines port n) > > + (cond > > + ((zero? n) port) > > + (else (read-line port) (skip-lines port (1- n))))) > > + > > + (let* ((file (source:file source)) > > + (line (source:line source)) > > + (fp (any (lambda (x) > > + (let ((f (string-append x "/" file))) > > + (if (file-exists? f) (open-input-file f) #f))) > > %load-path))) > > + (skip-lines fp line) > > + (let ((src (read fp))) > > + (close fp) > > + src))) > > This strategy of reading the code is not robust. > > * It assumes that the procedure is the first datum on the specified > line. This is not generally true.
Yes, I saw that. But I don't know how to get the procedure definition line from program-source, since there's no sufficient docs for that. Someone in IRC suggested me use the first datum. Could you point me out how to do that? ;-) > > * It assumes that there are no reader directives in the file (such as > #!curly-infix) that affect the operation of the reader. As is, your > code will not work with any procedure that uses curly-infix. > > * It assumes that the procedure is written in Scheme. > > Also, as we discussed on IRC, it would be better to show the original > characters in the file instead of the sexp representation. I want to > see the comments. I want to see the programmer-chosen indentation. If > they chose to use curly-infix for some expressions, I want to see that. > More generally, I want to see the presentation that the programmer > thought was most readable, i.e. the *source* code. > For these purposes above, I think there should be a modified 'read' to read the code from source file with comments. > > + > > +(define (print-src p) > > + (define (get-program-src p) > > + (let ((source (program-source p 0))) > > + (cond > > + ((not source) "It's inner procedure implemented with C") > > I'm not sure we can conclude that the procedure is implemented in C just > because 'program-source' returns #f. There might be other reasons why > that might happen. > Well, I'll take Daniel's suggestion to return #f if the source code is unavailable. > > + ((not (source:file source)) #f) > > + (else (get-src source))))) > > + (let ((src (and (program? p) (get-program-src p)))) > > + (and src (pp src)))) > > + > > +(define-meta-command (source repl (form)) > > + "source PROC > > +Pretty-print the source code of PROC" > > + (call-with-values (repl-prepare-eval-thunk repl (repl-parse repl form)) > > + (lambda args > > + (for-each print-src args)))) > > + > > > > ;;; > > ;;; System commands > > Regards, > Mark