2016-12-18 2 views
0

Я хочу определить макрос, который инкапсулирует частый шаблон ниже. Код для FLI lispworks.Как создать макрос с произвольными скобками, которые являются асимметричными (не спаренными)

(fli:with-foreign-string ;; class name pointer 
(cn-p ec bc :external-format (external-format)) "BUTTON" 
(fli:with-foreign-string ;; window name pointer 
    (wn-p ec bc :external-format (external-format)) "Configuartion:server" 
    (let ((grpbx (createwindowex 0 cn-p wn-p 
           (logior ws_visible ws_child bs_groupbox) 
           0 0 300 420 hwnd 1 (GetModuleHandle-current 0) 0))) 
    (fli:with-foreign-string ;; class name pointer 
    (cn-p ec bc :external-format (external-format)) "EDIT" 
    (fli:with-foreign-string ;; window name pointer 
     (wn-p ec bc :external-format (external-format)) "192.168.200.200" 
     (createwindowex 0 cn-p wn-p 
         (logior ws_visible ws_child ws_border) 
         10 30 150 30 hwnd 1 (GetModuleHandle-current 0) 0) 
    ))))) 

Макрос Я хочу создать что-то, как показано ниже: STRs параметр представляет собой список строк, например, ("КНОПКА" "Configuartion: сервер") выше, Str-Syms накапливает преобразованные строки, которые будут подаваться в CreateWindowEx. Что меня смутило, что строки, которые будут использоваться (сп-р и WN-р) находятся в середине тела, и я должен был разделить тело на 2 части: часть-межа и & body bdy.

Но проблема части-BDY, который является первой частью LET блока (до CreateWindowEx), имеет множество круглых скобок, которого счетчик часть только в передающем части (& тела BDY). Это означает, что круглые скобки в part-bdy не открыты и вызывают ошибку при оценке. У вас есть умная идея, чтобы посоветовать мне ее решить?

(defmacro with-foreign-string (strs str-syms part-bdy &body bdy) 
    (let ((g (gensym))) 
    (if (null strs) 
     (append part-bdy str-syms bdy) 
     `(fli:with-foreign-string 
     (,g ec bc :external-format (external-format)) ,(car strs) 
     (with-foreign-string ,(cdr strs) ,(cons g str-syms) ,part-bdy ,@bdy))))) 
+3

Макрос манипулирует кодом, а не скобками. Не могли бы вы добавить некоторые подробности, например. дать небольшой, но полный пример? Благодарю. – coredump

+1

Кажется, вы пытаетесь вставить свои сгенерированные символы в середину тела. Вместо этого вы должны предоставить символам 'LET'-подобную конструкцию' (с-foreign-strings ((имя класса «BUTTON») (имя окна «...»)) ... (createwindowx 0 имя-класса имя-окна ...)) ' – jkiiski

ответ

1

Просто хочу поделиться тем, что я изменил макрос, как показано ниже:

(defmacro with-foreign-str (strs str-syms bdy) 
    (if (null strs) 
    bdy 
     `(let ((,(car str-syms) (gensym))) 
     (fli:with-foreign-string 
    (,(car str-syms) ec bc :external-format (external-format)) ,(car strs) 
    (with-foreign-str ,(cdr strs) ,(cdr str-syms) ,bdy))))) 

затем код кода выше без использования макроса можно переписать следующим образом:

(WITH-FOREIGN-STR ("BUTTON" "Configuartion: server") (cn-p wn-p) 
    (let ((grpbx (createwindowex 0 cn-p wn-p 
       (logior ws_visible ws_child bs_groupbox) 
       0 0 300 420 hwnd 1 (GetModuleHandle-current 0) 0))) 
      (WITH-FOREIGN-STR ("EDIT" "192.168.200.95") (cn-p3 wn-p3) 
       (createwindowex 0 cn-p3 wn-p3 
           (logior ws_visible ws_child ws_border) 
       10 30 150 30 hwnd 1 (GetModuleHandle-current 0) 0)))) 

Это все еще не так чист, но в любом случае мне удастся упростить код с помощью макроса. Было не так много ответов только потому, что я думаю из-за API FLI и win32 в коде.

Смежные вопросы