Working functions don't work when re-entered


#1

I’m encountering a problem when testing my uLisp code on a Teensy 4.1 (or Pico) via Minicom. I paste my lisp code, and test, and everything works fine (yay!). But if I have to modify that code and repaste it into minicom, it doesn’t work anymore (even if I makunbound globals). I actually have to remove/reinsert the teensy 4.1 in order to start over…

First try after pasting my code…

59556> y  
("$c = $." "$v x y $.")

59556> (tokenize y)
(("$c" . mmconst) ("=" . mmlabel) ("$." . mmend) ("$v" . mmvar) ("x" . mmlabel) ("y" . mmlabel) ("$." . mmend))

But if I repaste the same code…

59556> y
("$c = $." "$v x y $.")

59556> (tokenize y)
nil

Note that available cells is the same after pasting/repasting my code into minicom. In this example, I just pasted in the very same code.

I’m not sure what could be happening… I’m new to uLisp (and new to Lisp, also) so don’t hesitate to let me know if I’m doing something wrong.

Here’s my code; sorry it’s lengthy; I’m not asking anyone to troubleshoot it but so you can test what I’m doing yourself… (The Tokenize routine “lex’s” a list of strings containing MetaMath code. In this example, Y contains a couple of simple MetaMath statements.)

(defvar mmkeywords
  '((#\[ . mmbgninc) (#\] . mmendinc)
    (#\c . mmconst) (#\. . mmend)
    (#\{ . mmbgnblock) (#\} . mmendblock)
    (#\v . mmvar) (#\d . mmdisjoint)
    (#\f . mmfloat) (#\e . mmessential)
    (#\a . mmaxiom) (#\p . mmproof1)
    (#\= . mmproof2))
)

(defvar mmwhitespace '(#\Tab #\Newline #\Return #\Space))

(defvar y '("$c = $." "$v x y $."))

(defun tokenize (stringlist)
  (let (tokenlist c nextc label token dpair skip)
    (setq tokenlist '())
    (setq label '"")
    (setq skip nil)
    (dolist (aline stringlist)
      (dotimes (i (length aline))
        (cond
          (skip
            (setq skip nil)
          )
          (t
            (setq c (char aline i))
            (cond
              ((member c mmwhitespace)
                (when (> (length label) 0)
                  (setq dpair (cons label 'mmlabel))
                  (setq tokenlist (reverse (cons dpair (reverse tokenlist))))
                  (setq label '"")
                )
              )
              ((and (eq c #\$) (> (length aline) i))
                (setq nextc (char aline (+ i 1)))
                (setq skip t)
                (setq token (cdr (assoc nextc mmkeywords)))
                (cond
                  (token
                    (setq label (concatenate 'string (string c) (string nextc)))
                    (setq dpair (cons label token))
                    (setq tokenlist (reverse (cons dpair (reverse tokenlist))))
                    (setq label '"")
                  )
                  (t
                    (format t "illegal character after $: ~a~%" nextc)
                    (break)
                  )
                )
              )
              ((and (eq c #\$) (<= (length aline) i))
                (format t "illegal $ at end of line~%")
                (break)
              )
              (t
                (setq label (concatenate 'string (string label) (string c)))
              )
            )
          )
        )
      )
      (when (> (length label) 0)
        (setq dpair (cons label 'mmlabel))
        (setq tokenlist (reverse (cons dpair (reverse tokenlist))))
        (setq label '"")
      )
    )
    (return tokenlist)
  )
)

#2

I’ll investigate!


#3

Thanks! Also, I just tried the same experiment with uLisp 4.1 for ARM (without any of my own mods). I tried both with minicom and with the arduino serial monitor. Same results.


#4

I can reproduce what you describe. Now to try and work out why it’s happening!


#5

OK, I think I know what the problem is.

I don’t think it’s anything to do with you pasting the same code twice. I get the same effect if I try evaluating (tokenize y) twice:

20164> (tokenize y)
(("$c" . mmconst) ("=" . mmlabel) ("$." . mmend) ("$v" . mmvar) ("x" . mmlabel) ("y" . mmlabel) ("$." . mmend))

20164> (tokenize y)
nil

I think it’s caused by your statement:

(return tokenlist)

at the end of tokenize. This should be causing an error because return is only used to break out of a clause such as loop, and I think it’s corrupting something. To return a value from a function you simply give the value. So the statement should be replaced by:

tokenlist

When I make that change everything seems to work fine. I’ll make a note that return should give an error if it’s not in block such as loop.

Let me know if this fixes it for you.


#6

You’re right. This fixed it for me. I really appreciate it! And sorry for making you debug my code (after all)!

I eventually figured out what Return was really for, when I had to break out of a loop, but I never realized Return was NOT for what I thought, so this makes a lot of sense to me.

Thanks again!
B


#7