开发者

Trouble grabbing lisp input from the web using hunchentoot and sbcl

A lisp question here. I've been slowly learning lisp over the last couple of months and have ran into a problem when trying to grab input from a web browser vs. grabbing input from a REPL.

The specific problem is when trying to evaluate this code:

Assume sexp is '(look north).

(member (car sexp) '(look walk pickup drop))

From the REPL in SBCL this works fine and as expected. However, when grabbing the sexp from hunchentoot even though sexp "looks" like it is the same as from the REPL it never seems to be able to consider the result of (car sexp) a memb开发者_StackOverflow社区er of '(look walk pickup drop).

I think it might be the character encoding of the file vs. character encoding of sexp when grabbed from the web browser but I have no idea how to test this hypothesis. Any pointers would be much appreciated!

Edit

The way I take the input in is based on based on the text adventure game from "Land of Lisp" by Conrad Barski and is detailed below.

(defun game-read (string-to-read)
  (let ((cmd (read-from-string
               (concatenate 'string "(" string-to-read ")"))))
    (describe cmd)
    (flet ((quote-it (x)
                     (list 'quote x)))
      (cons (car cmd) (mapcar #'quote-it (cdr cmd))))))

This is then wrapped in:

(defun game-eval (sexp)
  (if (member (car sexp) *allowed-commands*) ;Offending line                                                                          
      (eval sexp)
      '(i do not know that command.)))

where *allowed-commands* is:

(defparameter *allowed-commands* '(look walk pickup inventory))

The line that I have labelled as offending the one that works fine normally but when the string-to-read is from a request parameter fetched from hunchentoot as part of a request (car sexp) looks the same any way I know how to look at it but is not found in *allowed-commands*.


You need to make sure what the input is you get. Is it a symbol? Common Lisp has functions like TYPE-OF, INSPECT and DESCRIBE to get more information about data.

* (describe 'north)

COMMON-LISP-USER::NORTH
  [symbol]


* (type-of 'north)

SYMBOL

The next question is: if it is a symbol, in which package is it?

* (symbol-package 'north)

#<PACKAGE "COMMON-LISP-USER">

Are your other symbols in the same package?

The next question is: if it is a symbol or a string, how about capitalization?

* (symbol-name 'north)

"NORTH"

By default symbols are uppercase. That needs not be the case for your symbols read from input.

Now you can also play with MEMBER to make pure string comparisons:

* (member (symbol-name '|Foo|)
          '(foo bar baz)
          :key #'symbol-name :test #'equalp)

(FOO BAR BAZ)   ; this is the usual return value,
                ; the rest list with first item found


I've never used sbcl or Common Lisp, but this sounds like an interning problem. Try this query instead:

(member (intern (car sexp)) '(look walk pickup drop)))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜