Catching output (for make iNewLisp, like iPython)

Q&A's, tips, howto's
Locked
IVShilov
Posts: 23
Joined: Wed Apr 12, 2017 1:58 am

Catching output (for make iNewLisp, like iPython)

Post by IVShilov »

On python I work with ipython IDE and found it very useful.
Does it possible to have for newlisp have a table of pairs:
- IN with input command,
- OUT with saved corresponding output
for analyse it and get useful snippets written in past?

Input can be catched in reader-event, but I have no idea how to catch output - no output-event, no $last-output variable.

IVShilov
Posts: 23
Joined: Wed Apr 12, 2017 1:58 am

Re: Catching output (for make iNewLisp, like iPython)

Post by IVShilov »

Ok, I read forum and see many post with self made REPL.
Despite of this posts dated more than five years ago, it takes away half of my fear to broke normal interpretation process :)

Problem statement: have data structure in memory like a table with columns:

timestamp | IN | timestamp | OUT | timestamp | last-error | type-of-out | sys-info

As I understand interpretation process, when I type a str-IN and press ENTER,
1. command-event catch str-IN and can returns empty string to stop interpretation in usual way.
2. Internally calls (read-expr str-IN) it produce expr-CMD, or nothing in case of comment or empty string.
3. reader-event takes expr-CMD, it "can do transformation on the expression before it gets evaluated" and can stop evaluation process by returning nil. It returns (modifyed) expr-CMD.
4. Internally calls (eval expr-CMD) -> expr-RESULT.
5. Internally calls (string expr-RESULT) -> str-OUT.
6. Internally calls (print str-OUT) - it show these string according to pretty-print settings.
7. prompt-event calls to show prompt to signal Human that transmission is over.

(Human in turn read machine output from screen, eval (treat) result in his contexts in his mind and prints it to Machine and hit ENTER to transmit message, loop go on.)

Ok, maybe be I mistaken about steps [1-7], so try to check it out.

IVShilov
Posts: 23
Joined: Wed Apr 12, 2017 1:58 am

Re: Catching output (for make iNewLisp, like iPython)

Post by IVShilov »

At first, trace usual way of interpretation:

Code: Select all

(setq  LOG '()  row '() ) ; whole tracelog and one variable for trace REPL once
;; As I understand interpretation process, when I type a str-IN and press ENTER,

;; 1. command-event catch str-IN and can returns empty string to stop interpretation in usual way.
(command-event
 (fn (str-IN)
   (setq CE-timestamp (date (date-value) 0 "%x %X"))

   (println (list {command-event} CE-timestamp str-IN))
   (setq row '())
   (setq row (append row (list CE-timestamp str-IN)))
   str-IN
   ))

;; 2. Internally calls (read-expr str-IN) it produce expr-CMD, or nothing in case of comment or empty string.

;; 3. reader-event takes expr-CMD, it "can do transformation on the expression before it gets evaluated"
;; and can stop evaluation process by returning nil. It returns (modifyed) expr-CMD.
(reader-event
 (fn (expr-CMD)
   (setq RE-timestamp (date (date-value) 0 "%x %X"))
   (println (list {reader-event} RE-timestamp expr-CMD))
   (setq row (append row (list RE-timestamp expr-CMD) ))
   expr-CMD
   ))

;; 4. Internally calls (eval expr-CMD) -> expr-RESULT.
;; 5. Internally calls (string expr-RESULT) -> str-OUT.
;; 6. Internally calls (print str-OUT) - it show these string according to pretty-print settings.

;; 7. prompt-event calls to show prompt to signal Human that transmission is over. 
(prompt-event
 (fn (ctx)				; manual: "The current context before calling the prompt-event code is passed as a parameter to the function."
   (setq PE-timestamp (date (date-value) 0 "%x %X"))
   (setq row (append row (list PE-timestamp ctx)))
   (println (list {prompt-event} PE-timestamp ctx))
   (println {Complete trace of command- reader- prompt- events: } row)
   (push row LOG -1)			; наконец, добавляем это всё в копимый LOG
   (string ctx ":" (real-path) "$ ")	; return special prompt 
   ))

;; now your move, Human
Result:

Code: Select all

MAIN:r:\bin\emacs-25.2-i686\bin$ (+1 1)
("command-event" "2019.03.30 14:14:51" "(+1 1)\n")
("reader-event" "2019.03.30 14:14:51" (1 1))

ERR: illegal parameter type : 1
("prompt-event" "2019.03.30 14:14:51" MAIN)
Complete trace of command- reader- prompt- events: ("2019.03.30 14:14:51" "(+1 1)\n" "2019.03.30 14:14:51" (1 1) "2019.03.30 14:14:51" MAIN)
MAIN:r:\bin\emacs-25.2-i686\bin$ row
("command-event" "2019.03.30 14:14:56" "row\n")
("reader-event" "2019.03.30 14:14:56" row)
("2019.03.30 14:14:56" "row\n" "2019.03.30 14:14:56" row)
("prompt-event" "2019.03.30 14:14:56" MAIN)
Complete trace of command- reader- prompt- events: ("2019.03.30 14:14:56" "row\n" "2019.03.30 14:14:56" row "2019.03.30 14:14:56" MAIN)
MAIN:r:\bin\emacs-25.2-i686\bin$ LOG
("command-event" "2019.03.30 14:15:00" "LOG\n")
("reader-event" "2019.03.30 14:15:00" LOG)
(("2019.03.30 14:14:44" "(setq LOG '())\n" "2019.03.30 14:14:44" (setq LOG '()) "2019.03.30 14:14:44" MAIN) ("2019.03.30 14:14:51" "(+1 1)\n" "2019.03.30 14:14:51" (1 1) "2019.03.30 14:14:51" MAIN) ("2019.03.30 14:14:56" 
  "row\n" "2019.03.30 14:14:56" row "2019.03.30 14:14:56" MAIN))
("prompt-event" "2019.03.30 14:15:00" MAIN)
Complete trace of command- reader- prompt- events: ("2019.03.30 14:15:00" "LOG\n" "2019.03.30 14:15:00" LOG "2019.03.30 14:15:00" MAIN)
MAIN:r:\bin\emacs-25.2-i686\bin$ 
Obviously, there must ERR includes in LOG, but it can be done later, much more important check positive scenario: have a row in prompt-event try to do steps 4-5-6 parallel with usual interpretation process and compare results.
Any feedback will be gratefully accept.
P.S. Sorry for my poor english (and poor code too :) - please do not shoot the pianist, he is doing his best.

Locked