guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Running non-scheme scripts: some thoughts


From: Andy Wingo
Subject: Re: Running non-scheme scripts: some thoughts
Date: Mon, 21 Jan 2013 12:33:46 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux)

On Sun 26 Aug 2012 23:16, address@hidden (Ludovic Courtès) writes:

> Ian Price <address@hidden> skribis:
>
>> tl;dr +1 to add a --language switch to guile :P
>
> Seems like a good start; one would need to make sure ‘--language’
> interacts usefully with ‘-c’ and ‘-e’, for instance.  Perhaps
> something like:
>
>   guile -c '(display "good")' --language=ecmascript -c '2 + 2;'

A first patch is attached.  It depends on fluid->parameter and
current-language being a parameter, patches I will push soonish.

Getting this right is a bit tricky.  First of all your example doesn't
work because things stop after a "-c".  In my attached patch, -c and -s
respect the current language, but -l does not.  I have the feeling that
we should lower `current-language' to boot-9, to allow some flexibility
while avoiding loading up the compiler unless we have to.

Another thing is that --lang does not appear to set the language for the
first REPL invocation.  We should fix that too, I suppose.

Finally, -e uses the Scheme reader.  -e is a pretty strange argument
anyway, but hey.

Thoughts?

Andy

>From 0ccee2ea374187da14ec4f96ba6d84202517b800 Mon Sep 17 00:00:00 2001
From: Andy Wingo <address@hidden>
Date: Mon, 21 Jan 2013 12:28:22 +0100
Subject: [PATCH] add --lang argument

* module/ice-9/command-line.scm (*usage*): Make usage of capitalization
  and sentences consistent (lower-case and semicolons, as in ls
  --help).
  Be less specific about languages (Scheme is the default but not the
  only language).
  Document --lang.
  (load/current-language): Helper, called if --lang is set.
  (compile-shell-switches): Parse a --lang argument.  If it is passed,
  use the full eval-string instead of our local copy.
---
 module/ice-9/command-line.scm |  107 +++++++++++++++++++++++++++++------------
 1 file changed, 76 insertions(+), 31 deletions(-)

diff --git a/module/ice-9/command-line.scm b/module/ice-9/command-line.scm
index d60a6e3..1a648bb 100644
--- a/module/ice-9/command-line.scm
+++ b/module/ice-9/command-line.scm
@@ -1,6 +1,6 @@
 ;;; Parsing Guile's command-line
 
-;;; Copyright (C) 1994-1998, 2000-2011, 2012 Free Software Foundation, Inc.
+;;; Copyright (C) 1994-1998, 2000-2011, 2012, 2013 Free Software Foundation, 
Inc.
 
 ;;;; This library is free software; you can redistribute it and/or
 ;;;; modify it under the terms of the GNU Lesser General Public
@@ -106,10 +106,10 @@ There is NO WARRANTY, to the extent permitted by law."))
           (_ "General help using GNU software: 
<http://www.gnu.org/gethelp/>\n")))
 
 (define *usage*
-  (_ "Evaluate Scheme code, interactively or from a script.
+  (_ "Evaluate code with Guile, interactively or from a script.
 
-  [-s] FILE      load Scheme source code from FILE, and exit
-  -c EXPR        evalute Scheme expression EXPR, and exit
+  [-s] FILE      load source code from FILE, and exit
+  -c EXPR        evalute expression EXPR, and exit
   --             stop scanning arguments; run interactively
 
 The above switches stop argument processing, and pass all
@@ -121,18 +121,19 @@ If FILE begins with `-' the -s switch is mandatory.
   -l FILE        load Scheme source code from FILE
   -e FUNCTION    after reading script, apply FUNCTION to
                  command line arguments
+  --lang=LANG    change language; default: scheme
   -ds            do -s script at this point
   --debug        start with the \"debugging\" VM engine
-  --no-debug     start with the normal VM engine, which also supports debugging
-                 Default is to enable debugging for interactive
+  --no-debug     start with the normal VM engine (backtraces but
+                 no breakpoints); default is --debug for interactive
                  use, but not for `-s' and `-c'.
   --auto-compile compile source files automatically
   --fresh-auto-compile  invalidate auto-compilation cache
-  --no-auto-compile  disable automatic source file compilation
-                 Default is to enable auto-compilation of source
+  --no-auto-compile  disable automatic source file compilation;
+                 default is to enable auto-compilation of source
                  files.
-  --listen[=P]   Listen on a local port or a path for REPL clients.
-                 If P is not given, the default is local port 37146.
+  --listen[=P]   listen on a local port or a path for REPL clients;
+                 if P is not given, the default is local port 37146
   -q             inhibit loading of user init file
   --use-srfi=LS  load SRFI modules for the SRFIs in LS,
                  which is a list of numbers like \"2,13,14\"
@@ -174,10 +175,22 @@ If FILE begins with `-' the -s switch is mandatory.
                (eval exp (current-module))
                (lp))))))))
 
+;; We try to avoid loading (system base language) and (system base
+;; compile) if possible.  Note that if --lang is not passed, we emit a
+;; call to the normal `load' instead of a call to this function.
+(define (load/current-language f)
+  (if (eq? ((module-ref (resolve-interface '(system base language))
+                        'current-language))
+           'scheme)
+      (load f)
+      ((module-ref (resolve-module '(system base compile)) 'compile-file)
+       f #:to 'value)))
+
 (define* (compile-shell-switches args #:optional (usage-name "guile"))
   (let ((arg0 "guile")
-        (do-script '())
+        (load-form #f)
         (entry-point #f)
+        (lang-set? #f)
         (user-load-path '())
         (user-extensions '())
         (interactive? #t)
@@ -197,37 +210,43 @@ If FILE begins with `-' the -s switch is mandatory.
               (args (cdr args)))
           (cond
            ((not (string-prefix? "-" arg)) ; foo
-            ;; If we specified the -ds option, do-script is the cdr of
-            ;; an expression like (load #f).  We replace the car (i.e.,
+            ;; If we specified the -ds option, load-form is a pointer to
+            ;; an expression like (load #f).  We replace the cadr (i.e.,
             ;; the #f) with the script name.
             (set! arg0 arg)
             (set! interactive? #f)
-            (if (pair? do-script)
+            (if load-form
                 (begin
-                  (set-car! do-script arg0)
+                  (set-car! (cdr load-form) arg0)
                   (finish args out))
-                (finish args (cons `(load ,arg0) out))))
+                (begin
+                  (set! load-form (list 'load arg0))
+                  (finish args (cons load-form out)))))
 
            ((string=? arg "-s")         ; foo
             (if (null? args)
                 (error "missing argument to `-s' switch"))
             (set! arg0 (car args))
             (set! interactive? #f)
-            (if (pair? do-script)
+            (if load-form
                 (begin
-                  (set-car! do-script arg0)
+                  (set-car! (cdr load-form) arg0)
                   (finish (cdr args) out))
-                (finish (cdr args) (cons `(load ,arg0) out))))
+                (begin
+                  (set! load-form (list 'load arg0))
+                  (finish (cdr args) (cons load-form out)))))
            
            ((string=? arg "-c")         ; evaluate expr
             (if (null? args)
                 (error "missing argument to `-c' switch"))
             (set! interactive? #f)
-            (finish (cdr args)
-                    ;; Use our own eval-string to avoid loading (ice-9
-                    ;; eval-string), which loads the compiler.
-                    (cons `((@@ (ice-9 command-line) eval-string) ,(car args))
-                          out)))
+            (let ((eval
+                   ;; Try to avoid loading (ice-9 eval-string) if we
+                   ;; can, because it loads the compiler.
+                   (if lang-set?
+                       `((@@ (ice-9 eval-string) eval-string) ,(car args))
+                       `((@@ (ice-9 command-line) eval-string) ,(car args)))))
+              (finish (cdr args) (cons eval out))))
 
            ((string=? arg "--")         ; end args go interactive
             (finish args out))
@@ -236,6 +255,12 @@ If FILE begins with `-' the -s switch is mandatory.
             (if (null? args)
                 (error "missing argument to `-l' switch"))
             (parse (cdr args)
+                   ;; Currently, this always loads Scheme, as mentioned
+                   ;; in the usage note.  It would be better for it to
+                   ;; respect (current-language), but practically that
+                   ;; means putting (current-language) into boot-9, as
+                   ;; otherwise we would have to load (system base
+                   ;; language) which is a stat-party.  FIXME?
                    (cons `(load ,(car args)) out)))
 
            ((string=? arg "-L")         ; add to %load-path
@@ -273,14 +298,30 @@ If FILE begins with `-' the -s switch is mandatory.
             (parse (cdr args)
                    out))
 
+           ((string-prefix? "--lang=" arg) ; language
+            (set! lang-set? #t)
+            (parse args
+                   (cons `((@ (system base language) current-language)
+                           ',(string->symbol
+                              (substring arg (string-length "--lang="))))
+                         out)))
+
+           ((string=? "--lang" arg) ; language
+            (when (null? args)
+              (error "missing argument to `--lang' option"))
+            (set! lang-set? #t)
+            (parse (cdr args)
+                   (cons `((@ (system base language) current-language)
+                           ',(string->symbol (car args)))
+                         out)))
+
            ((string=? arg "-ds")        ; do script here
             ;; We put a dummy "load" expression, and let the -s put the
             ;; filename in.
-            (if (pair? do-script)
-                (error "the -ds switch may only be specified once")
-                (set! do-script (list #f)))
-            (parse args
-                   (cons `(load . ,do-script) out)))
+            (when load-form
+              (error "the -ds switch may only be specified once"))
+            (set! load-form (list 'load #f))
+            (parse args (cons load-form out)))
 
            ((string=? arg "--debug")
             (set! turn-on-debugging? #t)
@@ -364,8 +405,12 @@ If FILE begins with `-' the -s switch is mandatory.
 
     (define (finish args out)
       ;; Check to make sure the -ds got a -s.
-      (if (and (pair? do-script) (not (car do-script)))
-          (error "the `-ds' switch requires the use of `-s' as well"))
+      (when (and load-form (not (cadr load-form)))
+        (error "the `-ds' switch requires the use of `-s' as well"))
+
+      ;; Use a different loader if --lang was set.
+      (when (and load-form lang-set?)
+        (set-car! load-form '(@@ (ice-9 command-line) load/current-language)))
 
       ;; Make any remaining arguments available to the
       ;; script/command/whatever.
-- 
1.7.10.4

-- 
http://wingolog.org/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]