Catching output (for make iNewLisp, like iPython)

Started by IVShilov, March 29, 2019, 08:15:35 AM

Previous topic - Next topic

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

#1
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

#2
At first, trace usual way of interpretation:
(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:
MAIN:r:binemacs-25.2-i686bin$ (+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:binemacs-25.2-i686bin$ row
("command-event" "2019.03.30 14:14:56" "rown")
("reader-event" "2019.03.30 14:14:56" row)
("2019.03.30 14:14:56" "rown" "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" "rown" "2019.03.30 14:14:56" row "2019.03.30 14:14:56" MAIN)
MAIN:r:binemacs-25.2-i686bin$ LOG
("command-event" "2019.03.30 14:15:00" "LOGn")
("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"
  "rown" "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" "LOGn" "2019.03.30 14:15:00" LOG "2019.03.30 14:15:00" MAIN)
MAIN:r:binemacs-25.2-i686bin$


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.