chickadee » jiffi » foreign-lambda**

(foreign-lambda** ...)syntax
(foreign-safe-lambda** ...)syntax

Like foreign-lambda* and foreign-safe-lambda*, except the function body strings can be constructed dynamically at macro expansion time using sprintf. These are building blocks for higher-level macros that generate function bodies based on the macro's arguments.


(foreign-lambda**   ; or foreign-safe-lambda**

RETURN-TYPE is a foreign type specifier describing the return value.

Each ARG-TYPE is a foreign type specifier describing the argument. Each ARG_NAME is a non-quoted symbol which is used as the variable name within the function body. It must be a valid C variable name.

Each BODY-CLAUSE becomes a separate line of the function body. It can either be a string, or a list of the form (FORMAT-STRING FORMAT-ARG ...), which are arguments passed to sprintf to construct the string.

Because the body string is constructed at macro expansion time, each FORMAT-ARG must be an expression that can be evaluated at macro expansion time in the default environment, such as a quoted symbol, a string, a number, or a call to a built-in procedure.

For obscure technical reasons, you must use C_return(...) instead of the normal return statement to return a value from C.


(define return-foo
   () ; no arguments

(return-foo)   ; ⇒ "foo"

;; Silly example that expands into a foreign-lambda** that performs a
;; simple integer math operation described by the macro caller.
;; X and Y are evaluated at macro-expansion time.
(define-syntax c-math
  (syntax-rules ()
    ((math-fn X OPERATOR Y)
      () ; no arguments
      ("C_return(~A ~A ~A);" X 'OPERATOR Y)))))

;; Body becomes "C_return(40 + 2);"
(define return-42 (c-math (* 8 5) + (/ 4 2)))

(return-42)    ; ⇒ 42