Function: hif-macro-supply-arguments

hif-macro-supply-arguments is a byte-compiled function defined in hideif.el.gz.

Signature

(hif-macro-supply-arguments MACRO-NAME ACTUAL-PARMS)

Documentation

Expand a macro call, replace ACTUAL-PARMS in the macro body.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/hideif.el.gz
;; Perform token replacement:
(defun hif-macro-supply-arguments (macro-name actual-parms)
  "Expand a macro call, replace ACTUAL-PARMS in the macro body."
  (let* ((SA                   (assq macro-name hide-ifdef-env))
         (macro                (and SA
                                    (cdr SA)
                                    (eq (cadr SA) 'hif-define-macro)
                                    (cddr SA)))
         (formal-parms         (and macro (car macro)))
         (macro-body           (and macro (cadr macro)))
         actual-count
         formal-count
         formal
         etc)

    (when (and actual-parms formal-parms macro-body)
      ;; For each actual parameter, evaluate each one and associate it
      ;; with an actual parameter, put it into local table and finally
      ;; evaluate the macro body.
      (if (setq etc (eq (car formal-parms) 'hif-etc))
          ;; Take care of `hif-etc' first. Prefix `hif-comma' back if needed.
          (setq formal-parms (cdr formal-parms)))
      (setq formal-count (length formal-parms)
            actual-count (length actual-parms))

      (if (> formal-count actual-count)
          (error "Too few parameters for macro %S" macro-name)
        (if (< formal-count actual-count)
            (or etc
                (error "Too many parameters for macro %S" macro-name))))

      ;; Perform token replacement on the MACRO-BODY with the parameters
      (while (setq formal (pop formal-parms))
        ;; Prevent repetitive substitution, thus cannot use `subst'
        ;; for example:
        ;; #define mac(a,b) (a+b)
        ;; #define testmac mac(b,y)
        ;; testmac should expand to (b+y): replace of argument a and b
        ;; occurs simultaneously, not sequentially. If sequentially,
        ;; according to the argument order, it will become:
        ;; 1. formal parm #1 'a' replaced by actual parm 'b', thus (a+b)
        ;;    becomes (b+b)
        ;; 2. formal parm #2 'b' replaced by actual parm 'y', thus (b+b)
        ;;    becomes (y+y).
        (setq macro-body
              ;; Unlike `subst', `substitute' replace only the top level
              ;; instead of the whole tree; more importantly, it's not
              ;; destructive.
              (cl-substitute (if (and etc (null formal-parms))
                                 (hif-delimit actual-parms 'hif-comma)
                               (car actual-parms))
                             formal macro-body))
        (setq actual-parms (cdr actual-parms)))

        ;; Replacement completed, stringifiy and concatenate the token list.
        ;; Stringification happens must take place before flattening, otherwise
        ;; only the first token will be stringified.
        (setq macro-body
              (flatten-tree (hif-token-stringification macro-body)))

        ;; Token concatenation happens here, keep single 'hif-space
        (hif-keep-single (hif-token-concatenation macro-body) 'hif-space))))