c-mera icon indicating copy to clipboard operation
c-mera copied to clipboard

Macro weirdness issue

Open pjstirling opened this issue 7 years ago • 2 comments

I'm not sure that an issue tracker is the appropriate place to ask this, but I do understand it's a convenient place for you.

I'm having trouble figuring what is going on here (I've hacked this out of my larger code base to try and get rid of stuff that should be irrelevant):

(defmacro decl% ((&rest bindings) &body body)
     `(if true
          (decl (,@bindings)
                ,@body)))

;#+nil                                                                                                                                                                                                             
(defmacro with-unsuccessful-cleanup (cleanup &body protected)
  (let ((label (gensym "CLEANUP_"))
	(result (gensym "RESULT-")))
    `(decl% ((int ,result = 0))
       (macrolet ((return (value)
                          (let ((result ',result)
				(label ',label))
                            `(progn
                               (= ,result ,value)
                               (goto ,label)))))
         ,@protected)
       (label ,label)
       (when (< ,result 0)
         ,cleanup)
       (return ,result))))

(function add-connection ((struct identity* id))
    -> int
  (with-unsuccessful-cleanup
      (free node)
    (with-unsuccessful-cleanup
        (fclose (pref node stream))
      (move-identity (& (pref node id))
                     id)
      (return 0))))

If I run cm c++ then I get the following output (and no C++ output): cm c++ test.lisp

;Compiler warnings :
;   In an anonymous lambda form: Undefined function move-identity
;   In an anonymous lambda form: Undeclared free variable id
Unbound variable: id

The message makes it sound like sbcl is expecting to be able to invoke move-identity, but that shouldn't be the case, surely?

If you delete the semi-colon on line 9 (to neuter with-unsuccessful-cleanup) then it stops complaining.

pjstirling avatar Jun 11 '17 18:06 pjstirling

Thats a little tricky:

Calls to undefined/unknown functions, that shall yield a call in the resulting/generated code can only be captured correctly inside a c-mera-function-body (function, decl, progn, ...), but not inside a lisp-function-body (macrolet..) Therefore, we need a extra progn inside the macrolet. (c-mera's progn generates a block of statements where unkown functions are captured and passed to the generated code as function-calls, in contrast to lisp's progn that returns the last element)

The following adjustment should do the trick:

(defmacro with-unsuccessful-cleanup (cleanup &body protected)
  (let ((label (gensym "CLEANUP_"))
	(result (gensym "RESULT-")))
    `(decl% ((int ,result = 0))
       (macrolet ((return (value)
                          (let ((result ',result)
				(label ',label))
                            `(progn
                               (= ,result ,value)
                               (goto ,label)))))
         (progn ,@protected))
       (label ,label)
       (when (< ,result 0)
         ,cleanup)
       (return ,result))))

lispbub avatar Jun 12 '17 09:06 lispbub

I think you are now hitting the things that would make a README file into a manual :)

We are actually working on something like that, but are swamped right now so progress is slow. That's also the reason I prefer having those discussions here where we can easily find them again :)

kiselgra avatar Jun 19 '17 11:06 kiselgra