2010-11-26 27 views
6

de Haskell main se limita a lo que quiero: evaluar cuando el archivo se carga por sí mismo (por ejemplo ./myfile.hs o runhaskell myfile.hs) y en ningún otro caso. main no se ejecutará cuando el archivo sea importado por otro archivo. newLISP también tiene esta funcionalidad.¿Common Lisp equivalente a la función principal de Haskell? función

¿Hay código equivalente para Common Lisp?

leí el source code para CLISP. Esto es lo que sucede cuando el usuario entra o clisp myfile.lisp./myfile.lisp:

  1. CLISP ahorra myfile.lisp como p->argv_execute_file.
  2. CLISP crea la expresión (LOAD "p->argv_execute_file") y la empuja hacia la pila Lisp.
  3. CLISP guarda cualquier argumento de línea de comandos adicional en una lista.
  4. CLISP almacena los argumentos en la variable Lisp *args*.

CLISP nunca comete una variable Lisp refiriéndose a p->argv_execute_file, así que no hay manera de discernir si myfile.lisp se cargó directamente, por parte del usuario en el REPL, o por otro fichero Lisp. Si solo (car *args*) fuera myfile.lisp, mi tarea sería fácil.

Nota: Shebangs dan problemas CLISP si el archivo se carga desde el REPL, por lo que poner este código en ~/.clisprc.lisp:

(set-dispatch-macro-character #\# #\! 
(lambda (stream character n) 
    (declare (ignore character n)) 
    (read-line stream nil nil t) 
    nil)) 
+0

¿Por qué necesita un equivalente a la función principal? –

Respuesta

2

encontré una solution. Es un poco de trucos de concha, pero funciona. Pronto modificaré esto para trabajar en implementaciones de CL que no sean CLISP.

#!/bin/sh 
#| 
exec clisp -q -q $0 $0 ${1+"[email protected]"} 
exit 
|# 

;;; Usage: ./scriptedmain.lisp 

(defun main (args) 
(format t "Hello World!~%") 
(quit)) 

;;; With help from Francois-Rene Rideau 
;;; http://tinyurl.com/cli-args 
(let ((args 
     #+clisp ext:*args* 
     #+sbcl sb-ext:*posix-argv* 
     #+clozure (ccl::command-line-arguments) 
     #+gcl si:*command-args* 
     #+ecl (loop for i from 0 below (si:argc) collect (si:argv i)) 
     #+cmu extensions:*command-line-strings* 
     #+allegro (sys:command-line-arguments) 
     #+lispworks sys:*line-arguments-list* 
    )) 

    (if (member (pathname-name *load-truename*) 
       args 
       :test #'(lambda (x y) (search x y :test #'equalp))) 
    (main args))) 
0

(eval-when (situation*) ...)

actualización pena por la respuesta confusa.

puedo estar equivocado, pero parece ser imposible de hacer lo que quiere exactamente. Haría un script de shell y llamaría al clisp -i myfile.lisp -x (main).

¿Hay alguna razón para no hacerlo ejecutable (descrito here)?

P.S. Common Lisp es un lenguaje y clisp es una de las implementaciones.

+0

: load-toplevel solo funciona mientras el código se está compilando y: ejecuta las llamadas main cada vez que se carga el archivo, no del todo la funcionalidad deseada. – mcandre

+0

@mcandre ': load-toplevel' funciona cuando se carga el archivo, pero todo lo demás es correcto, voy a actualizar la respuesta, gracias. – khachik

+0

clisp -i myscript.cl no funcionaría bien como un shebang. Además, clisp no permite -x argumentos al cargar un script. Pero gracias de cualquier manera :) – mcandre