开发者

Macro and array crossing

开发者 https://www.devze.com 2023-02-04 19:40 出处:网络
I am having a problem with a lisp macro. I would like to create a macro which generate a switch case according to an array.

I am having a problem with a lisp macro. I would like to create a macro which generate a switch case according to an array.

Here is the code to generate the switch-case:

(defun split-elem(val)
  `(,(car val) ',(cdr val)))

(defmacro generate-switch-case (var opts)
  `(case ,var
     ,(mapcar #'split-elem opts)))

I can use it with a code like this:

(generate-switch-case onevar ((a . A) (b . B)))

But when I try to do something like this:

(defparameter *operators* '((+ . OPERATOR-PLUS)
                            (- . OPERATOR-MINUS)
                            (/ . OPERATOR-DIVIDE)
                            (= . OPERATOR-EQUAL)
                            (* . OPERATOR-MULT)))

(defmacro tokenize (data ops)
  (let ((sym (string->list data)))
    (mapcan (lambda (x) (generate-switch-case x ops)) sym)))

(tokenize data *operators*)

I got this error: *** - MAPCAR: A proper list must not end with OPS, but I don't understand why.

When I print the type of ops I get SYMBOL I was expecting CONS, is开发者_C百科 it related?

Also, for my function tokenize, how many times is the lambda evaluated (or the macro expanded)?

Thanks.


This makes no sense. You trying to use macros, where functions are sufficient.

What you want is similar to this:

(defun tokenize (data ops)
    (mapcar (lambda (d)
               (cdr (assoc d ops)))
            (string->list data)))

CASE is a macro that expects a bunch of fixed clauses. It does not take clauses that are computed at runtime. If list data should drive computation, then use functions like ASSOC.

GENERATE-SWITCH-CASE is also an odd name, since the macro IS a switch case.

GENERATE-SWITCH-CASE also does expect a list as a second argument. But in TOKENIZE you call it with a symbol OPS. Remember, macros compute with Lisp source code.

Next, there are also no ARRAYs involved. Lisp has arrays, but in your example is none.

Typical advice:

  1. if you want to write a MACRO, think again. Write it as a function.

  2. if you still want to write a macro, Go to 1.

0

精彩评论

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