Bug in 2.9 / Metro M4


#1

Dear @johnsondavies ,

You will not be happy, but… my newest AI, see “Artificial Intelligence III”, works OK (in the ready-to-paste-variant) on ulisp 2.8, with the lastest repairs, but not on 2.9, in particular, I discovered the following discrepancy:

It checks for empty input by means of this:

      (setq *in* (append (read) (list *terminator*)))
...
      (cond ((null (cdr *in*)) (return '())))

Now the funny part is - it DOES terminate in 2.8 (and in SBCL), but not in 2.9.


#2

On the contrary - I’m happy that you’re finding bugs!

I’ll investigate.


#3

Hi @Aeneas, I’ve written this test program that attempts to replicate your bug:

(defvar *in* '())

(defun test10 ()
  (loop
   (setq *in* (append (read) (list 'trm)))
   (print *in*)
   (cond 
    ((null (cdr *in*)) (return '())))))

(test10)

However, it seems to work fine with ARM uLisp 2.9 - it exits from the loop when I enter nil.

Can you make something that demonstrates the bug?


#4

Dear @johnsondavies ,

I confirm, I CAN reproduce the bug.

What I now exactly did:

  1. I flashed my Grand Central with uLisp 2.9, which was only modified so as to contain:
#elif defined(ARDUINO_GRAND_CENTRAL_M4)
  #define WORKSPACESIZE 29820-SDSIZE      /* Objects (8*bytes) */
  #define DATAFLASHSIZE 8192000           /* 8 MBytes */
  #define SYMBOLTABLESIZE 8192            /* Bytes */
  uint8_t _end;

  1. I pasted the “ready-to-paste”-variant from here:
  1. I did: (save-image)

  2. I said (run)

  3. I gave as input: ()

  4. It did not terminate (as it should), but replied.


#5

OK, this is again a “(return '()) does not return”-bug.

What I did so far:

I modified the last loop into:

(defun run ()
(loop (progn
      (princ '-READ---) 
      (setq *in* (append (read) (list *terminator*)))
      (terpri) (princ 'IN---) (princ *in*) (princ " ") (princ (length *in*))
      (terpri)
      (cond ((null (cdr *in*)) (progn (print 'NOTRETURNING) (return '()))))
      (setq *lastknowledge*
            (tkl *lastknowlen* (append *lastknowledge* *in*)))
      (setq *topics* (tpx (rnl *lastknowledge*) *knowledge*))
      (setq *out* (creep-continuations (tkl *seclen* *lastknowledge*)
                    *knowledge*))
      (cond ((and (null (cddr *out*)) (null (car *out*))) (setq *out* '()))
            (t (setq *out* (append (rnl *out*)
                                    (list *terminator*)
                                   '()))))
      (setq *knowledge*
            (append (ncr (length (append *in* *out*))
                            *knowledge*)
                    *in* *out*))
      (lpr (rnl (cons 'REPLY-- (apply-instincts *out*)))))))

and indeed, I got the following output:

27669> (run)
-READ---()
IN---(trm) 1

NOTRETURNING (REPLY--)
-READ---

So it DOES evaluate the cond-branch correctly, but fails to return.


#6

OK, now something interesting:

THIS does NOT trigger the bug - it terminates on () just fine:

(defvar *terminator* 'TRM)

(defvar *in* '())

(defun run ()
(loop (progn
      (princ '-READ---) 
      (setq *in* (append (read) (list *terminator*)))
      (terpri)
      (cond ((null (cdr *in*)) (return '()))))))

EDIT: Changing WORKSPACESIZE 29820-SDSIZE to 29800 changes nothing in the result, so I believe the issue is not some clobbering from there.


#7

OK, interesting: even changing the final loop to this does NOT activate “return” - i.e. with a “forced” (unconditional) return:


(defun run ()
(loop (progn
      (princ '-READ---) 
      (setq *in* (append (read) (list *terminator*)))
      (terpri)
      (cond ((null (cdr *in*)) (return '())))
      (print 'FORCEDRETURN) (return '())
      (setq *lastknowledge*
            (tkl *lastknowlen* (append *lastknowledge* *in*)))
      (setq *topics* (tpx (rnl *lastknowledge*) *knowledge*))
      (setq *out* (creep-continuations (tkl *seclen* *lastknowledge*)
                    *knowledge*))
      (cond ((and (null (cddr *out*)) (null (car *out*))) (setq *out* '()))
            (t (setq *out* (append (rnl *out*)
                                    (list *terminator*)
                                   '()))))
      (setq *knowledge*
            (append (ncr (length (append *in* *out*))
                            *knowledge*)
                    *in* *out*))
      (lpr (rnl (cons 'REPLY-- (apply-instincts *out*)))))))


#8

Thanks - that helped me to track it down. The problem occurs if you have a progn block inside the loop block.

I’ve uploaded a new version, ARM 2.9a, which should fix the problem with your existing program. Let me know how you get on!

Thanks for finding it!

Regards, David


#9

Dear David,

I confirm, this WORKS now, thank you so much for fixing it! I think you can close this topic now.

(I am very amused how your little pet project started to be THE most remarkable microcontroller language around, and certainly my favourite, not being all that much into Python.)

Kind regards,

Nino

P.S.: You might consider announcing uLisp 2.9 on the main page - it still announces 2.8… :)


#10

Great - thanks! The reason for the delay in announcing 2.9 is that I haven’t done the other platforms yet. On my to-do list!


#11