unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Running non-scheme scripts: some thoughts
@ 2012-07-11 15:31 Ian Price
  2012-07-11 15:37 ` Andrew Gwozdziewycz
  2012-08-26 21:16 ` Ludovic Courtès
  0 siblings, 2 replies; 11+ messages in thread
From: Ian Price @ 2012-07-11 15:31 UTC (permalink / raw)
  To: guile-devel


Hi,

Though guile is really a multi-language vm, it does not provide a simple
way to run scripts for languages other scheme from the command line. I
think we should add a --language switch that takes a mandatory argument,
and use that to determine the language.

Other solutions for dealing with multiple languages have been proposed
before, including guessing the language from the file extension[0], or from
the file itself (via a something like racket's #lang).

While guile could move towards those at a later date, I think the
--language switch is a good one for now. Firstly, it could be
implemented simply with, I think, only modifications to (ice-9
command-line). Secondly, it is compatible with these other designs; a
future language guessing guile could honour --language, and where that
switch is not provided would be free to guess; a similar situation
would occurs if we went with a #lang type solution.

Anyway, some thought needs to be taken as to how this will integrate
with the other switches. In particular: -s, -c, -l, -e, and maybe
--listen, -q, and --use-srfi.

I think that if --language=LANG is specified, then the files given by
-s, and -l should be treated as though they contained LANG source
code. Similarly, the string argument to -c, as a string of LANG. -e
would ideally be a function in LANG, but I don't know the details of how
this works in the other languages, and so could be left off for now.

If guile was used interactively with the --language switch, it would
give you a guile repl already in that language, similar to if we did ,L.
I think this is how it should interact with --listen too, though I'm not
positive.

-q, or rather, when -q is not supplied, is tricky. I think we should
just assume that it is always going to be in Scheme. I'm open to
suggestions.

I don't know how module interaction works in other languages, so I also
can't comment on the suitability of --use-srfi.

So, thoughts? Counter-proposals? Flames? Have I missed out anything
particularly obvious?


tl;dr +1 to add a --language switch to guile :P


[0]. I don't personally like this solution, since it seems fragile, and
it's not clear how it would interact with the -x switch.
-- 
Ian Price

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Running non-scheme scripts: some thoughts
  2012-07-11 15:31 Running non-scheme scripts: some thoughts Ian Price
@ 2012-07-11 15:37 ` Andrew Gwozdziewycz
  2012-07-11 22:15   ` Krister Svanlund
  2012-08-26 21:16 ` Ludovic Courtès
  1 sibling, 1 reply; 11+ messages in thread
From: Andrew Gwozdziewycz @ 2012-07-11 15:37 UTC (permalink / raw)
  To: Ian Price; +Cc: guile-devel

On Wed, Jul 11, 2012 at 11:31 AM, Ian Price <ianprice90@googlemail.com> wrote:
>
> Hi,
>
> Though guile is really a multi-language vm, it does not provide a simple
> way to run scripts for languages other scheme from the command line. I
> think we should add a --language switch that takes a mandatory argument,
> and use that to determine the language.

Seems smarter to just have different executables:

    guile (and guile-scheme for completeness via hard/soft link)
    guile-elisp
    ...
    guile-LANG

That seems like it'd lead to far less confusion overall.

Andrew

-- 
http://www.apgwoz.com



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Running non-scheme scripts: some thoughts
  2012-07-11 15:37 ` Andrew Gwozdziewycz
@ 2012-07-11 22:15   ` Krister Svanlund
  2012-07-12  3:12     ` nalaginrut
  0 siblings, 1 reply; 11+ messages in thread
From: Krister Svanlund @ 2012-07-11 22:15 UTC (permalink / raw)
  To: Andrew Gwozdziewycz; +Cc: Ian Price, guile-devel

[-- Attachment #1: Type: text/plain, Size: 1157 bytes --]

Personally I would think that having Guile guess by extension would be the,
in most cases, most reliable. Otherwise there could be problems loading
several files in different languages etc.

I would think that one of the best solution would be to have a switch to
execute arbitrary commands such as ,L so you would call guile with `guile
--switch ",L elisp"`. The separate executables could then be done as
aliases if one wanted.

On Wed, Jul 11, 2012 at 5:37 PM, Andrew Gwozdziewycz <apgwoz@gmail.com>wrote:

> On Wed, Jul 11, 2012 at 11:31 AM, Ian Price <ianprice90@googlemail.com>
> wrote:
> >
> > Hi,
> >
> > Though guile is really a multi-language vm, it does not provide a simple
> > way to run scripts for languages other scheme from the command line. I
> > think we should add a --language switch that takes a mandatory argument,
> > and use that to determine the language.
>
> Seems smarter to just have different executables:
>
>     guile (and guile-scheme for completeness via hard/soft link)
>     guile-elisp
>     ...
>     guile-LANG
>
> That seems like it'd lead to far less confusion overall.
>
> Andrew
>
> --
> http://www.apgwoz.com
>
>

[-- Attachment #2: Type: text/html, Size: 1709 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Running non-scheme scripts: some thoughts
  2012-07-11 22:15   ` Krister Svanlund
@ 2012-07-12  3:12     ` nalaginrut
  2012-07-12  3:27       ` William ML Leslie
  0 siblings, 1 reply; 11+ messages in thread
From: nalaginrut @ 2012-07-12  3:12 UTC (permalink / raw)
  To: Krister Svanlund; +Cc: Ian Price, guile-devel

> Personally I would think that having Guile guess by extension would be
> the, in most cases, most reliable. Otherwise there could be problems
> loading several files in different languages etc.
> 
Yes, my vote is gussing by extension. But also provide an option --lang
to specify in case the extension name conflicts or other problems.


> I would think that one of the best solution would be to have a switch
> to execute arbitrary commands such as ,L so you would call guile with
> `guile --switch ",L elisp"`. The separate executables could then be
> done as aliases if one wanted.
> 
Personally, I think this "syntax" is a little too long. I prefer --lang.


Anyway, I'm happy that someone raised such a topic since I'm interested
in multi-language feature in Guile. ;-)



> 






^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Running non-scheme scripts: some thoughts
  2012-07-12  3:12     ` nalaginrut
@ 2012-07-12  3:27       ` William ML Leslie
  2012-07-12  7:40         ` Neil Jerram
  0 siblings, 1 reply; 11+ messages in thread
From: William ML Leslie @ 2012-07-12  3:27 UTC (permalink / raw)
  To: guile-devel

On 12 July 2012 13:12, nalaginrut <nalaginrut@gmail.com> wrote:
>> Personally I would think that having Guile guess by extension would be
>> the, in most cases, most reliable. Otherwise there could be problems
>> loading several files in different languages etc.
>>
> Yes, my vote is gussing by extension. But also provide an option --lang
> to specify in case the extension name conflicts or other problems.

For most entry-points, there is no extension. When you install your
program, you normally install it as /usr/bin/foo, rather than
/usr/bin/foo.[ss|scm|py|js|whatever].  This is the motivation for
guile-foo symlinks or --lang options.  I favour the symlinks slightly,
because not all languages are going to work with guile's extended
mesh-wow system, and indirection via env already costs you one
argument.

For modules, specifically in languages where the module system has
some abstraction above the filesystem, the mechanism that locates the
module should be responsible for setting the module language.  In
other words, allow guile to defer to the language implementation to
figure out the language of the loaded module in most situations.

I think that otherwise, it should be up to the code using the module
to supply the language with which it should be run.  Extensions are
one thing, but there is quite a bit that they can't handle, like
rakefiles.  And extensions don't allow you to specify a language
level, either.

-- 
William Leslie



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Running non-scheme scripts: some thoughts
  2012-07-12  3:27       ` William ML Leslie
@ 2012-07-12  7:40         ` Neil Jerram
  0 siblings, 0 replies; 11+ messages in thread
From: Neil Jerram @ 2012-07-12  7:40 UTC (permalink / raw)
  To: William ML Leslie; +Cc: guile-devel

William ML Leslie <william.leslie.ttg@gmail.com> writes:

> For most entry-points, there is no extension. When you install your
> program, you normally install it as /usr/bin/foo, rather than
> /usr/bin/foo.[ss|scm|py|js|whatever].  This is the motivation for
> guile-foo symlinks or --lang options.  I favour the symlinks slightly,
> because not all languages are going to work with guile's extended
> mesh-wow system, and indirection via env already costs you one
> argument.

Yes, and in the hoped future when Guile runs Python better and faster
than any other implementation, we certainly need the symlinks so that
someone can do

# cd /usr/bin && rm python && ln -s guile-python python

to let Guile run all existing Python programs on their system.

Then, clearly, "guile-python" needs to handle all the command line
arguments that are traditional for Python - not the traditional Guile
arguments - and munge them into a suitable startup incantation/sequence
for Guile.

And then there are two detailed arguments which both suggest handling
"guile-python" within the main Guile executable, instead of in an
accompanying shell script.  Firstly it's more flexible to transform
guile-python arguments directly into Guile startup code, instead of a
two step transformation first to traditional Guile arguments and then to
code.  (What if there isn't an appropriate traditional Guile argument?)
Secondly it feels more maintainable and integrated to have that logic
within the main Guile code, instead of in a shell script to one side.

I think that means the necessary support should be added to
compile-shell-switches in (ice-9 command-line), and to the C code in
script.c that calls that, to allow compile-shell-switches to set up for
different languages according to $0.

Regards,
        Neil



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Running non-scheme scripts: some thoughts
  2012-07-11 15:31 Running non-scheme scripts: some thoughts Ian Price
  2012-07-11 15:37 ` Andrew Gwozdziewycz
@ 2012-08-26 21:16 ` Ludovic Courtès
  2013-01-21 11:33   ` Andy Wingo
  1 sibling, 1 reply; 11+ messages in thread
From: Ludovic Courtès @ 2012-08-26 21:16 UTC (permalink / raw)
  To: guile-devel

Hello!

Ian Price <ianprice90@googlemail.com> skribis:

> tl;dr +1 to add a --language switch to guile :P

Seems like a good start; ‘guile-elisp’, etc. executables or symlinks can
still be added eventually if/when a huge user base for these language
implementations demands it.  :-)

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;'

Thanks,
Ludo’.




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Running non-scheme scripts: some thoughts
  2012-08-26 21:16 ` Ludovic Courtès
@ 2013-01-21 11:33   ` Andy Wingo
  2013-01-21 16:19     ` Ludovic Courtès
  0 siblings, 1 reply; 11+ messages in thread
From: Andy Wingo @ 2013-01-21 11:33 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

[-- Attachment #1: Type: text/plain, Size: 1145 bytes --]

On Sun 26 Aug 2012 23:16, ludo@gnu.org (Ludovic Courtès) writes:

> Ian Price <ianprice90@googlemail.com> 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


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-add-lang-argument.patch --]
[-- Type: text/x-diff, Size: 9954 bytes --]

From 0ccee2ea374187da14ec4f96ba6d84202517b800 Mon Sep 17 00:00:00 2001
From: Andy Wingo <wingo@pobox.com>
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


[-- Attachment #3: Type: text/plain, Size: 26 bytes --]


-- 
http://wingolog.org/

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: Running non-scheme scripts: some thoughts
  2013-01-21 11:33   ` Andy Wingo
@ 2013-01-21 16:19     ` Ludovic Courtès
  2013-01-22 14:59       ` Andy Wingo
  0 siblings, 1 reply; 11+ messages in thread
From: Ludovic Courtès @ 2013-01-21 16:19 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

Hello!

Andy Wingo <wingo@pobox.com> skribis:

> On Sun 26 Aug 2012 23:16, ludo@gnu.org (Ludovic Courtès) writes:

[...]

>>   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".

Right.

> 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.

Yes, I think we should do whatever it takes to have -l honor the current
language.

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

Agreed.

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

That’s probably OK.

> Thoughts?

Bikeshedding: I’d prefer --language.

Perhaps we could have a couple of tests for -c, for instance, as shell
scripts in test-suite/standalone?

Thanks!

Ludo’.



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Running non-scheme scripts: some thoughts
  2013-01-21 16:19     ` Ludovic Courtès
@ 2013-01-22 14:59       ` Andy Wingo
  2013-01-22 21:45         ` Ludovic Courtès
  0 siblings, 1 reply; 11+ messages in thread
From: Andy Wingo @ 2013-01-22 14:59 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

[-- Attachment #1: Type: text/plain, Size: 360 bytes --]

On Mon 21 Jan 2013 17:19, ludo@gnu.org (Ludovic Courtès) writes:

> Bikeshedding: I’d prefer --language.

Changed, and addressed your other comments.  Attached.

> Perhaps we could have a couple of tests for -c, for instance, as shell
> scripts in test-suite/standalone?

That would be great.  Would you be interested in doing this? :-)

Andy


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-add-language-argument.patch --]
[-- Type: text/x-diff, Size: 9700 bytes --]

From 3197ffffa1d1b51ecafb1565e984e98fdd0059f6 Mon Sep 17 00:00:00 2001
From: Andy Wingo <wingo@pobox.com>
Date: Mon, 21 Jan 2013 12:28:22 +0100
Subject: [PATCH] add --language 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 --language.
  (load/lang, eval-string/lang): New helpers.
  (compile-shell-switches): Parse a --language argument, and use it to
  set (current-language).
---
 module/ice-9/command-line.scm |  115 +++++++++++++++++++++++++++--------------
 1 file changed, 75 insertions(+), 40 deletions(-)

diff --git a/module/ice-9/command-line.scm b/module/ice-9/command-line.scm
index d60a6e3..b1d591b 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
@@ -118,21 +118,22 @@ If FILE begins with `-' the -s switch is mandatory.
 
   -L DIRECTORY   add DIRECTORY to the front of the module load path
   -x EXTENSION   add EXTENSION to the front of the load extensions
-  -l FILE        load Scheme source code from FILE
+  -l FILE        load source code from FILE
   -e FUNCTION    after reading script, apply FUNCTION to
                  command line arguments
+  --language=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\"
@@ -163,20 +164,34 @@ If FILE begins with `-' the -s switch is mandatory.
     (if fatal?
         (exit 1))))
 
-(define (eval-string str)
-  (call-with-input-string
-   str
-   (lambda (port)
-     (let lp ()
-       (let ((exp (read port)))
-         (if (not (eof-object? exp))
-             (begin
-               (eval exp (current-module))
-               (lp))))))))
+;; Try to avoid loading (ice-9 eval-string) and (system base compile) if
+;; possible.
+(define (eval-string/lang str)
+  (case (current-language)
+    ((scheme)
+     (call-with-input-string
+      str
+      (lambda (port)
+        (let lp ()
+          (let ((exp (read port)))
+            (if (not (eof-object? exp))
+                (begin
+                  (eval exp (current-module))
+                  (lp))))))))
+    (else
+     ((module-ref (resolve-module '(ice-9 eval-string)) 'eval-string) str))))
+
+(define (load/lang f)
+  (case (current-language)
+    ((scheme)
+     (load f))
+    (else
+     ((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 '())
+        (script-cell #f)
         (entry-point #f)
         (user-load-path '())
         (user-extensions '())
@@ -197,36 +212,39 @@ 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, script-cell 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 script-cell
                 (begin
-                  (set-car! do-script arg0)
+                  (set-car! script-cell arg0)
                   (finish args out))
-                (finish args (cons `(load ,arg0) out))))
+                (finish args
+                        (cons `((@@ (ice-9 command-line) load/lang) ,arg0)
+                              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 script-cell
                 (begin
-                  (set-car! do-script arg0)
+                  (set-car! script-cell arg0)
                   (finish (cdr args) out))
-                (finish (cdr args) (cons `(load ,arg0) out))))
+                (finish (cdr args)
+                        (cons `((@@ (ice-9 command-line) load/lang) ,arg0)
+                              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))
+                    (cons `((@@ (ice-9 command-line) eval-string/lang)
+                            ,(car args))
                           out)))
 
            ((string=? arg "--")         ; end args go interactive
@@ -236,7 +254,8 @@ If FILE begins with `-' the -s switch is mandatory.
             (if (null? args)
                 (error "missing argument to `-l' switch"))
             (parse (cdr args)
-                   (cons `(load ,(car args)) out)))
+                   (cons `((@@ (ice-9 command-line) load/lang) ,arg0)
+                         out)))
 
            ((string=? arg "-L")         ; add to %load-path
             (if (null? args)
@@ -273,14 +292,30 @@ If FILE begins with `-' the -s switch is mandatory.
             (parse (cdr args)
                    out))
 
+           ((string-prefix? "--language=" arg) ; language
+            (parse args
+                   (cons `(current-language
+                           ',(string->symbol
+                              (substring arg (string-length "--language="))))
+                         out)))
+
+           ((string=? "--language" arg) ; language
+            (when (null? args)
+              (error "missing argument to `--language' option"))
+            (parse (cdr args)
+                   (cons `(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)))
+            (when script-cell
+              (error "the -ds switch may only be specified once"))
+            (set! script-cell (list #f))
             (parse args
-                   (cons `(load . ,do-script) out)))
+                   (acons '(@@ (ice-9 command-line) load/lang)
+                          script-cell
+                          out)))
 
            ((string=? arg "--debug")
             (set! turn-on-debugging? #t)
@@ -364,8 +399,8 @@ 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 script-cell (not (car script-cell)))
+        (error "the `-ds' switch requires the use of `-s' as well"))
 
       ;; Make any remaining arguments available to the
       ;; script/command/whatever.
-- 
1.7.10.4


[-- Attachment #3: Type: text/plain, Size: 26 bytes --]


-- 
http://wingolog.org/

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: Running non-scheme scripts: some thoughts
  2013-01-22 14:59       ` Andy Wingo
@ 2013-01-22 21:45         ` Ludovic Courtès
  0 siblings, 0 replies; 11+ messages in thread
From: Ludovic Courtès @ 2013-01-22 21:45 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

Andy Wingo <wingo@pobox.com> skribis:

> On Mon 21 Jan 2013 17:19, ludo@gnu.org (Ludovic Courtès) writes:

[...]

>> Perhaps we could have a couple of tests for -c, for instance, as shell
>> scripts in test-suite/standalone?
>
> That would be great.  Would you be interested in doing this? :-)

Sure.  :-)

The patch looks good to me, so feel free to commit, and I’ll add that
afterward.

Ludo’.



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2013-01-22 21:45 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-11 15:31 Running non-scheme scripts: some thoughts Ian Price
2012-07-11 15:37 ` Andrew Gwozdziewycz
2012-07-11 22:15   ` Krister Svanlund
2012-07-12  3:12     ` nalaginrut
2012-07-12  3:27       ` William ML Leslie
2012-07-12  7:40         ` Neil Jerram
2012-08-26 21:16 ` Ludovic Courtès
2013-01-21 11:33   ` Andy Wingo
2013-01-21 16:19     ` Ludovic Courtès
2013-01-22 14:59       ` Andy Wingo
2013-01-22 21:45         ` Ludovic Courtès

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).