reader-event

Started by cormullion, October 25, 2009, 03:00:38 PM

Previous topic - Next topic

cormullion

I'm having trouble making any progress with reader-event.


newLISP v.10.1.6 on OSX IPv4 UTF-8, execute 'newlisp -h' for more info.

> (reader-event re)
nil
>
> (+ 2 2)
4
> (define (re ex) (println "expression was " (string ex)))
(lambda (ex) (println "expression was " (string ex)))
> (+ 2 2)
4
> (reader-event re)
Segmentation fault


I think you should be able to do this  - re-define the expression currently used as the reader-event. If not, it should be prevented from being redefined...?

Lutz

#1
Redefining any function while it is executing will almost always lead to a crash.



Define the function to be used in 'reader-event' first, then register it with reader-event. As soon as reader-event is defined all code read in by newlISP will pass through this function.



The best way to develop for 'reader-event' is, to test the function first manually before registering:


> (define (re ex) (println "expression was " (string ex)))
(lambda (ex) (println "expression was " (string ex)))
> (re '(+ 2 2))
expression was (+ 2 2)
"(+ 2 2)"
> (reader-event re)
$reader-event
> (+ 2 2)
expression was (+ 2 2)
"(+ 2 2)"
> abc
expression was abc
"abc"
>


The return value of the event function, is what newLISP will see for evaluation. That is why in your example, we will always see a string of what we entered, because its the return value of the event function. An event function should analyze the entered expression looking for specific patterns and then return the expression with specific patterns in it transformed.

Lutz

#2
Turns out the the problem was not caused by redefining the handler while executing, but defining the handler with an unquoted nil. As a workaround, if disabling 'reader-event' always use a quoted nil. A future version will not care if quoted or unquoted.

cormullion

#3
Thanks Lutz! I'd considered that possibility, but had reasoned with myself that newLISP might have finished executing the current reader-event function before assigning the new function to reader-event... It looks that way from where I sit... :)



I'll continue my investigations.



By  'translation', I presume you mean the first 1 to 7 steps listed in the section Namespaces and the translation and evaluation cycle of the document Expression Evaluation in newLISP ... ? Does this mean that you could somehow 'translate' newLISP code and save the results of the translation for later execution. (Although that looks a bit tricky to me.) Must be some time savings there?

Lutz

#4
QuoteMust be some time savings there?

newLISP translates source into an internal binary format at a speed of about 10 Mbyte per second on a 1.83 Ghz Mac Mini. So a somewhat bigger program of about a 100K would take only about 10 ms to be translated into newLISP's internal binary s-expression format consisting of linked lists of lisp cells.



Internally the binary format carries absolute memory references (pointers). For saving we would have to translate these in to relative references and then have a relocating loader program do an address fixup whe n bringing the stuff back into memory. In a similar way work binary program loaders in an OS.



I believe such a loader would have a hard time to match newLISP's translation speed from human readable source.



But for the sake of arguing, lets assume such a binary loader could drive the the time close to 0 ms. The overall run/execution time of our 100K program would still be much bigger then 10ms. So little would be gained to make a fast translation process faster by pre-translating and binary loading.