Bug? Functions works once and then start returning docstrings?!


#1

Sorry, I don’t have the build of uLisp to hand, but pretty recent.
This is the only code, entered after a hard reset.

Code:

(defun char-is-digit-p (c)
	"Is this char a digit?"
	(and (>= (char-code c) (char-code #\0)) (<= (char-code c) (char-code #\9))))

(defun char-to-int (c)
	(- (char-code c) (char-code #\0)))
	
(defun _accumulate (a s)
	"Recursively Parse s as an integer."
	(if (= (length s) 0) 
		(return a))
	(if (char-is-digit-p (char s 0))
		(return (_accumulate (+ (* 10 a) (char-to-int (char s 0))) (subseq s 1)))
		(return nil)))
		
(defun parse-as-int (s) "Parse s as an int." (_accumulate 0 s))

output:

23587> (trace _accumulate)
(_accumulate)

23587> (_accumulate 0 "123")
0: (_accumulate 0 "123")
  1: (_accumulate 1 "23")
    2: (_accumulate 12 "3")
      3: (_accumulate 123 "")
      3: _accumulate returned 123
    2: _accumulate returned 123
  1: _accumulate returned 123
0: _accumulate returned 123
123

23587> (_accumulate 0 "123")
0: (_accumulate 0 "123")
0: _accumulate returned "Recursively Parse s as an integer."
"Recursively Parse s as an integer."

So the function works as expected ONCE, but then functions with docstrings start returning the docstrings!

Removing all the docstrings and trying again (after a hard reset) :

23614> (parse-as-int "123")
123

23614> (parse-as-int "123")
nil

23614> (trace parse-as-int)
(parse-as-int)

23614> (parse-as-int "123")
0: (parse-as-int "123")
0: parse-as-int returned nil
nil

New to lisp, but uLisp is has been great fun (Cardputer and PicoCalc)!
Thanks,
Ian


#2

Same when run on PicoCalc.


#3

The bug is being triggered by your use of return in the function _accumulate.

The return function should only be used to exit from a loop, do, do*, dotimes, or dolist block. It’s not needed in the _accumulate function, which should be written:

(defun _accumulate (a s)
  "Recursively Parse s as an integer."
  (if (= (length s) 0) 
      a
    (if (char-is-digit-p (char s 0))
        (_accumulate (+ (* 10 a) (char-to-int (char s 0))) (subseq s 1))
      nil)))

Your example then works correctly.

In fact return should give an error if it’s not in a loop, do, do*, dotimes, or dolist block; I’ll fix this in a future release. Thank you for reporting this.


#6