From: <sca...@on...> - 2012-03-15 11:01:57
|
Pascal, That's a good idea, but what I want to know if there are some macro, directive or command that redirect all input/output to a stream, like sockets. My lisp application is an AI, so when I call some functions to start the inference, the application ask me some questions about the file that I'm trying to inference. Because I need to interact all the time with the application, asking some questions, that is why I would like if there are some macro to redirect all, input/output... The lisp console is perfect because appears all, but you allways need commands. The idea is to make a Java graphical interface so users don't need commands, only buttons or menu options so I thought all communication passes to Java and no lisp console. Thanks ----Mensaje original----De: pj...@in...Fecha: 14/03/2012 21:23Para: "santi"<sca...@on...>CC: <cli...@li...>Asunto: Re: [clisp-list] connecting CLISP and Java"santi" <sca...@on...> writes:> Hi Pascal,>> Finally I've tried to use sockets and repl so you said to me. I can> connect with CLISP using sockets with Java and can execute some> functions!!!. In LISP I implement this server code:>> http://clisp.org/impnotes/socket.html>> But I've got one problem. In the functions of my LISP program, there> are some functions that use the LISP format function and when I try to> call from Java, the response appears in the LISP console but no in the> Java console. I've thought that I need to redirect the default output> to the sockets, so the format responses must appear in the Java> console despite LISP console. I've tried this:>> (let ((*standard-output* <SOCKET>))>> I've tried this too:>> (let ((*standard-output* (LET ((server (SOCKET:SOCKET-SERVER)))> (FORMAT t "~&Waiting for a connection on ~S:~D~%"> (SOCKET:SOCKET-SERVER-HOST server) (SOCKET:SOCKET-SERVER-PORT server))> (UNWIND-PROTECT> ;; infinite loop, terminate with Control+C> (LOOP (WITH-OPEN-STREAM (socket (SOCKET:SOCKET-ACCEPT server))> (MULTIPLE-VALUE-BIND (local-host local-port) (SOCKET:SOCKET-STREAM-LOCAL socket)> (MULTIPLE-VALUE-BIND (remote-host remote-port) (SOCKET:SOCKET-STREAM-PEER socket)> (FORMAT T "~&Connection: ~S:~D -- ~S:~D~%"> remote-host remote-port local-host local-port)))> ;; loop is terminated when the remote host closes the connection or on EXT:EXIT> (LOOP (WHEN (EQ :eof (SOCKET:SOCKET-STATUS (cons socket :input))) (RETURN))> (PRINT (EVAL (READ socket)) socket)> ;; flush everything left in socket> (LOOP :for c = (READ-CHAR-NO-HANG socket nil nil) :while c)> (TERPRI socket))))> ;; make sure server is closed> (SOCKET:SOCKET-SERVER-CLOSE server)))> )))>> But doesn't works.>> Do you know, who can I redirect the LISP output console to the Java consoleI would redirect the lisp streams to some string stream (or if youexpect large output, redirect to a temporary file stream, but an inmemory string enough for normal usage), and when evaluation is finished,I would send those strings to the java application to do whatever itwants to do with them (such as outputting them to the Java console).Something like this:(defun server-repl (socket) (loop ; Loop (let ((request (read-request socket))) ; Read (let ((results) (error) (errout) (stdout (with-output-to-string (*standard-output*) (setf errout (with-output-to-string (*error-output*) (let* ((*standard-input* (make-concatenated-stream)) (*trace-output* *standard-output*) (*terminal-io* (make-two-way-stream *standard-input* *standard-output*)) (*query-io* *terminal-io*) (*debug-io* *terminal-io*)) (handler-case (setf results (multiple-value-list (execute-request request))) ; Eval (error (err) (setf error (princ-to-string err)))))))))) (send-answer socket (make-answer :error error ; Print :result results :stdout stdout :stderr errout))))))You have to implement the missing functions, read-request,execute-request, send-answer. You may want to redirect differently thestreams. Eg. you may want to send errors and *error-output* or*trace-output* messages to a log file. You may want to not redirect*debug-io*, so that you can still debug the lisp process on the terminalyou launched it. Or you may want to redirect *query-io* to your ownsubclass of Gray streams so that you can send queries back to the Javaapplication for user interaction and send back the answers to the*query-io* stream for reading. But the idea is that: you bind the stream variables to whatever streamyou want, such as string streams, to collect the data, and when done,you send that data along with the result to the client application. -- __Pascal Bourguignon__ http://www.informatimago.com/A bad day in () is better than a good day in {}. |
From: Sam S. <sd...@gn...> - 2012-03-15 16:54:48
|
> * sca...@on... <fpneobaryy@bab.pbz> [2012-03-15 12:01:42 +0100]: > > what I want to know if there are some macro, directive or command that > redirect all input/output to a stream, like sockets. strictly speaking, no. lisp can always open a new stream pointing anywhere. however, "nice" programs use "official" streams (http://www.lispworks.com/documentation/HyperSpec/Body/v_debug_.htm), so if you bind, say, *standard-output* to your socket stream, the lisp program will write to it. you should take a look at the source code and see where the program writes and from where it reads and bind the appropriate variables. -- Sam Steingold (http://sds.podval.org/) on Ubuntu 11.10 (oneiric) X 11.0.11004000 http://www.childpsy.net/ http://jihadwatch.org http://pmw.org.il http://openvotingconsortium.org http://americancensorship.org http://ffii.org Perl: all stupidities of UNIX in one. |
From: Pascal J. B. <pj...@in...> - 2012-03-15 17:05:48
|
"sca...@on..." <sca...@on...> writes: > Pascal, > > That's a good idea, but what I want to know if there are some macro, > directive or command that redirect all input/output to a stream, like > sockets. I just showed you. There are a few special variable bound to streams that lisp code use (in addition to their own streams). To "redirect" you just need to bind those variables to a different stream. (let ((*standard-output* socket)) (print 'hello)) ; goes to the socket > My lisp application is an AI, so when I call some functions to start > the inference, the application ask me some questions about the file > that I'm trying to inference. Because I need to interact all the time > with the application, asking some questions, that is why I would like > if there are some macro to redirect all, input/output... That's where you need to write a Gray stream subclass, binding an instance to *query-io* or *terminal-io* depending on the stream used by the library to ask user questions (it ought to use *query-io*, but not all programmers are that good). This Gray strema subclass will be able to communicate with the Java application to implement the user interaction. So, I already explained you all you need to know, go search about it (http://cliki.net http://google.com), and implement it. -- __Pascal Bourguignon__ http://www.informatimago.com/ A bad day in () is better than a good day in {}. |