SilkScript Stepper Hack
Kelly Murray
kem@Franz.COM
Mon, 05 May 1997 19:54:41 -0700
I hacked up a little something to give some idea of what is possible
using silkscript and a web-browser interface.
It doesn't do much really, but I've only spent an hour or two on it.
I hope it sparks some interest in how easy it can be do this stuff.
You can run this example by accessing
http://www.franz.com:8000/stepper-demo
Note the port is 8000, not the default one of 80.
-Kelly Murray
----
(procedure demo-stepper (&key state cmd pc)
(http-response "200 OK" "Content-type: " "text/html")
(let nstate = (if state then (parse-integer state) else 0)
npc = (if pc then (parse-integer pc) else 0)
do
(clickon " Step " :calls (demo-stepper :cmd "step" :pc (1+ npc)))
(text " | ")
(clickon " Trace " :calls (demo-stepper :cmd "trace"))
(text " | ")
(clickon " Evaluate " :calls (demo-stepper :cmd "value"))
(verbatim ()
(text "(procedure " (:green "demo-stepper") " ([:cmd] [:pc])" :crlf)
(output-source
'(let nstate = (if state then (parse-integer state) else 0)
npc = (if pc then (parse-integer pc) else 0)
do
(clickon " Step " :calls (demo-stepper :cmd "step" :pc (1+ npc)))
(text " | ")
(clickon " Trace " :calls (demo-stepper :cmd "trace"))
(text " | ")
(clickon " Evaluate " :calls (demo-stepper :cmd "value")))'
0 (or cmd "step") 0 npc)
)
)
)
(function output-atomic-source (code indent cmd pc this-pc)
(if (eq pc this-pc)
then
(color :red)
(if (stringp code)
then (text """ code """)
else (text code))
(color :black)
elseif (stringp code)
then
(clickon (text-string """ code """) :calls (demo-stepper :cmd cmd :pc pc))
else
(clickon code :calls (demo-stepper :cmd cmd :pc pc))
)
pc)
(function output-progn-source (code indent cmd pc this-pc)
(loop for arg in code
do
(text :crlf)
(loop for x from 0 to indent do (text " "))
(set pc = (output-source arg indent cmd (1+ pc) this-pc))
)
pc)
(function output-call-source (code indent cmd pc this-pc)
(text "(")
(if (eq pc this-pc)
then
(color :red) (text (first code)) (color :black)
else
(clickon (first code) :calls (demo-stepper :cmd cmd :pc pc)))
(loop for arg in (rest code)
do
(text " ")
(set pc = (output-source arg indent cmd (1+ pc) this-pc))
)
(text ")")
pc)
(function output-if-source (code indent cmd pc this-pc)
(loop for x from 0 to indent do (text " "))
(text "(")
(if (eq pc this-pc)
then
(color :red) (text (pop code)) (color :black)
else
(clickon (pop code) :calls (demo-stepper :cmd cmd :pc pc)))
(text " ")
(set pc = (output-source (pop code) indent cmd (1+ pc) this-pc))
(text " " (pop code) " ")
(loop while code
for item = (pop code)
do
(if (member item '(then else elseif)')
then
(text " " item " ")
else
(set pc = (output-source item indent cmd (1+ pc) this-pc))
))
(text ")")
pc)
(function output-let-source (code indent cmd pc this-pc)
(loop for x from 0 to indent do (text " "))
(text "(")
(if (eq pc this-pc)
then
(color :red) (text (first code)) (color :black)
else
(clickon (first code) :calls (demo-stepper :cmd cmd :pc pc)))
(text " ")
(let items = (rest code)
item = (pop items)
do
(if (not (eq item 'do'))
then
;; do first variable binding
(set pc = (output-source item indent cmd (1+ pc) this-pc))
(text " = ") (pop items)
(set pc = (output-source (pop items) indent cmd (1+ pc) this-pc)))
;;
(loop while items
for item = (pop items)
with body = nil
do
(if (eq item 'do')
then
(set indent = (+ indent 2))
(text :crlf)
(loop for x from 0 to indent do (text " "))
(text "do")
(set body = t)
elseif (null body) ;; still doing variable bindings
then
(text :crlf)
(loop for x from 0 to (+ indent 5) do (text " "))
(set pc = (output-source item indent cmd (1+ pc) this-pc))
(text " = ") (pop items) ;; ignore it
(set pc = (output-source (pop items) indent cmd (1+ pc) this-pc))
else
(text :crlf)
(loop for x from 0 to indent do (text " "))
(set pc = (output-source item (- indent 5) cmd (1+ pc) this-pc))
)))
(text ")")
pc)
(function output-source (code indent cmd pc this-pc)
(if (null code)
then
(text " nil ")
elseif (listp code)
then
(select (first code)
case 'let'
(output-let-source code indent cmd pc this-pc)
case 'if'
(output-if-source code indent cmd pc this-pc)
case 'progn'
(output-progn-source code indent cmd pc this-pc)
other
(output-call-source code indent cmd pc this-pc)
)
else
(output-atomic-source code indent cmd pc this-pc)
)
)