Capn Doo
Capn Doo

Reputation: 1

"*** - EVAL: undefined function X" in Lisp

I'm making an interpreter for an esoteric programming language, and I made this program for it. However, instead of giving the desired output, it outputs

*** - EVAL: undefined function X

Can anyone help clarify the problem with this program?

I've already tried googling this error, and checking similar questions on this site.

(setq acc 0)        
(loop              
    (setq x (read-char))                  
    (when (x = #\i)(acc(+ acc 1))) 
    (when (x = #\d)(acc(- acc 1)))        
    (when (x = #\s)(acc(* acc acc)))      
    (when (x = #\o)(write(acc)))  
    (when (x = #\h)(return x))        
    (when (acc <0 or acc =255)(acc =0)))

The input "iiiso" should give the output 9. However, the actual output is

*** - EVAL: undefined function X

Upvotes: 0

Views: 854

Answers (2)

user5920214
user5920214

Reputation:

Here is an interpreter for a language which is a bit like Deadfish which makes no attempt to be stupidly terse and clever but does attempt to be a bit Lispy (perhaps in a slightly annoyingly-purist sense). In particular:

  • there is no assignment;
  • looping is via tail calls;
  • rather the program returns a list of what it would have printed (in fact it returns two values: what it would have printed and the final value of the accumulator);
  • it does have side-effects though: it reads from the input stream.

This is almost-confirming CL:

  • CL implementations don't have to support tail call optimisation, so this is allowed to run out of stack on large programs;
  • I think that #\Tab is only a semi-standard character name.

I am not sure this is quite correct:

  • this program fixes up the accumulator at the start of the loop, which I am not sure is right;
  • I am not clear what Deadfish programs are meant to do with input which is not part of the language – this one will puke.

Here:

(defun deadfish (&key (in *standard-input*)
                      (initial-value 0))
  ;; Deadfish from a stream
  (labels ((dfl (acc results)
             (case acc
               ((-1 256)
                (dfl 0 results))
               (otherwise
                (let ((c (read-char in nil in)))
                  (if (eql c in)
                      (values (reverse results) acc)
                    (ecase c
                      ((#\h) (values (reverse results) acc))
                      ((#\i) (dfl (1+ acc) results))
                      ((#\d) (dfl (1- acc) results))
                      ((#\s) (dfl (* acc acc) results))
                      ((#\o) (dfl acc (cons acc results)))
                      ((#\Newline #\Space #\Tab)
                       (dfl acc results)))))))))
    (dfl initial-value '())))

(defun deadfish/string (string &key 
                               (initial-value 0))
  ;; Deadfish from a string
  (with-input-from-string (in string)
    (deadfish :in in :initial-value initial-value)))

And

> (map 'string #'code-char
       (deadfish/string
        "iisiiiisiiiiiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiooiiio
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddo
dddddddddddddddddddddsddoddddddddoiiioddddddoddddddddo"))
"Hello world"

Interestingly this program may be more correct than many implementations:

> (deadfish/string "iiissssssssssoh")
(373391848741020043532959754184866588225409776783734007750636931722079040617265251229993688938803977220468765065431475158108727054592160858581351336982809187314191748594262580938807019951956404285571818041046681288797402925517668012340617298396574731619152386723046235125934896058590588284654793540505936202376547807442730582144527058988756251452817793413352141920744623027518729185432862375737063985485319476416926263819972887006907013899256524297198527698749274196276811060702333710356481)
373391848741020043532959754184866588225409776783734007750636931722079040617265251229993688938803977220468765065431475158108727054592160858581351336982809187314191748594262580938807019951956404285571818041046681288797402925517668012340617298396574731619152386723046235125934896058590588284654793540505936202376547807442730582144527058988756251452817793413352141920744623027518729185432862375737063985485319476416926263819972887006907013899256524297198527698749274196276811060702333710356481

Upvotes: 1

sds
sds

Reputation: 60014

You really need to start with a good lisp book, e.g., PCL or ACL. You will save yourself a lot of time.

Lisp syntax is different from C.

In C, equality == is an infix operator, used as x == 1. In Lisp equality predicates =, eql &c are ordinary functions.

Thus you need to write (eql x #\i).

This is, however, just one of many other problems with your code. You do need to get a textbook.

See also clisp: variable has no value.

Upvotes: 4

Related Questions