Loading and saving uLisp functions to a file


#1

Hi,

at the uLisp page there’s a function to load uLisp functions from a file. It looks rather similar to:

(defun load (filename)
    (with-sd-card (s filename)
       (loop
          (let ((line (read s))) 
             (if (null line) (return (globals)) (eval line))))))

Now I wrote a function to save the whole environment to a textfile:

(defun save (fn)
  (princ "Saving:")
    (with-sd-card (str fn 2)
      (mapcar
        (lambda (n)
           (princ " ") (princ n)
           (princ "(defvar " str)
           (princ n str)
           (princ " '" str)
           (pprint (eval n) str)
           (princ ")" str)
           (terpri str) (terpri str))
        (globals)))
 nothing)

You can test these functions with:

(defvar data '(1 4 9 16 25 36 49))
(defvar four 4)
((defun fac (n) (if (< n 2) 1 (* n (fac (- n 1)))))
(save "test.lsp")

Restart the board, then:

(require 'load)  -- I stored this function in my LispLibrary
(load "test.lsp")
(globals) -- returns (save fac data four)
four      -- returns 4
data      -- returns (1 4 9 16 25 36 49)
fac       -- returns (lambda (n) (if (< n 2) 1 (* n (fac (- n 1)))))

The formatting in the created file is not perfect, but it is working and the functions and variables can be read back using (load).
So you can develop a few functions with uLisp and save your work in a textfile, which will not depend on the version of uLisp used (as images are).
If ‘resetautorun’ is defined in your uLisp version you can create a small image to load the rest of the code from textfiles at systemstart.
Comments are welcome!

As I am a lisp newby, what do you think about the code of (save) (it took me a while to get it working ;-) )?
How would be the ‘lispy’ way of writing the function (save)?

Best regards,
Klaus


#2

Hi,
I have some problem in reading a previous saved file. In most cases (load) works as expected, but with the file I uploaded (ds1631.lsp) I always get “Error: <sd-stream 1> is not an integer” when executing (load “ds1631,lsp”). I’m sure the file is readable.
I didn’t find an error in the file, any suggestions?
Thanks & regards,
Klaus

Here’s the content of the file ‘ds1631.lsp’:
(the code reads the ds1631 i2c temperature sensor and displays the current temperature in Celsius)

(defvar convert-ds1631 '(lambda nil (with-i2c (str 79) (write-byte 81 str))))
(defvar read-ds1631 '(lambda nil
  (with-i2c (str 79)
    (write-byte 170 str)
    (restart-i2c str 2)
    (let* ((hi (read-byte str)) (lo (read-byte str))) (/ (+ (ash hi 8) lo) 256)))))
(defvar read '(lambda (n)
  (dotimes (x n)
    (princ (+ x 1))
    (princ " ")
    (convert-ds1631)
    (delay 1000)
    (princ (read-ds1631))
    (delay 1000)
    (terpri))))
(defvar init-ds1631 '(lambda nil
  (with-i2c (str 79) (write-byte 172 str) (write-byte 13 str))
  (delay 100)
  (with-i2c (str 79)
    (write-byte 161 str)
    (write-byte 196 str)
    (write-byte 0 str))
  (delay 100)
  (with-i2c (str 79)
    (write-byte 162 str)
    (write-byte 196 str)
    (write-byte 0 str))))
(defvar ds1631 '(lambda nil (init-ds1631) (convert-ds1631) (read-ds1631)))

#3

I’ve verified the problem you’ve reported with ESP uLisp Version 2.6a, but it seems to be a general problem with using (read) from an SD card. The examples on the page SD card interface failed too.

But trying it again later, the examples worked fine. Not sure what the problem is.
David


#4

Hi David,
thanks for investigating to this topic.

I think the content of the file has an influence here. I used your mcp9809 program and saved it in a file and this can be loaded without problems.
When I load my ds1631 file and the error occurs, I can’t load anything from the sd-card and I have to reset the board.
Maybe there is an illegal file pointer or an open file which is not handled correctly?
I’ll invest too as soon as I find some free time…

Klaus


#5

I found that this works:

(with-sd-card (str "Greeting.txt" 2)
  (print "Hello" str))
(with-sd-card (str "Greeting.txt")
  (read str))

but then if I eject the SD card, put it back in, and try again, it fails, returning nil.


#6

Hi David,
when ejecting the SD card I get the same behaviour.
I think this is ok, because I would not recommend removing the card from a running system. (Consumer) type sd-cards are easy to destroy if power fails during a write cycle…

I solved the problem reading my file:
There was no problem at file-system layer, I overwrote the function (read) in my code and this leads to the error. Sorry, as often the problem was in front of the screen ;-). Renaming the functions makes it work as it should.

Best regards,
Klaus


#7

Great - glad you found the problem!