Function: hif-evaluate-macro

hif-evaluate-macro is an interactive and byte-compiled function defined in hideif.el.gz.

Signature

(hif-evaluate-macro RSTART REND)

Documentation

Evaluate the macro expansion result for the active region.

If no region is currently active, find the current #ifdef/#define and evaluate the result; otherwise it looks for current word at point. Currently it supports only math calculations, strings or argumented macros can not be expanded. This function by default ignores parsing error and return false on evaluating runtime C(++) statements or tokens that normal C(++) preprocessor can't perform; however, when this command is prefixed, it will display the error instead.

Probably introduced at or before Emacs version 25.1.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/hideif.el.gz
(defun hif-evaluate-macro (rstart rend)
  "Evaluate the macro expansion result for the active region.
If no region is currently active, find the current #ifdef/#define and evaluate
the result; otherwise it looks for current word at point.
Currently it supports only math calculations, strings or argumented macros can
not be expanded.
This function by default ignores parsing error and return `false' on evaluating
runtime C(++) statements or tokens that normal C(++) preprocessor can't perform;
however, when this command is prefixed, it will display the error instead."
  (interactive
   (if (not (use-region-p))
       '(nil nil)
     (list (region-beginning) (region-end))))
  (run-hooks 'hide-ifdef-evalulate-enter-hook)
  (let ((case-fold-search nil)
        (currpnt (point))
        bounds)
    (save-excursion
      (unless (use-region-p)
        (setq rstart nil rend nil)
        (beginning-of-line)
        (if (and (re-search-forward hif-macro-expr-prefix-regexp nil t)
                 (= (line-number-at-pos currpnt) (line-number-at-pos)))
            (if (string= "define" (match-string 2))
                (re-search-forward hif-macroref-regexp nil t))
          (goto-char currpnt)
          (setq bounds (bounds-of-thing-at-point 'word)
                ;; TODO: BOUNDS need a C++ syntax word boundary finder
                rstart (car bounds)
                rend   (cdr bounds))))
      (let* ((start (or rstart (point)))
             (end   (or rend (progn (hif-end-of-line) (point))))
             (defined nil)
             (simple 't)
             (tokens (ignore-errors ; Prevent C statement things like
                                        ; 'do { ... } while (0)'
                       (hif-tokenize start end)))
             ;; Note that on evaluating we can't simply define the symbol
             ;; even if we are currently at a #define line, as this #define
             ;; might actually be wrapped up in a #if 0 block.  We can only
             ;; define that explicitly with `hide-ifdef-define'.
             (expr (or (and (<= (length tokens) 1) ; Simple token
                            (setq defined
                                  (or (assq (car tokens) hide-ifdef-env)
                                      (assq (car tokens) hif-predefine-alist)))
                            (setq simple (atom (hif-lookup (car tokens))))
                            (hif-lookup (car tokens)))
                       (and tokens
                            (condition-case err
                                (hif-parse-exp tokens)
                              (error
                               ;; when prefixed, pass the error on for later
                               ;; `hide-ifdef-evaluator'
                               (if current-prefix-arg err))))))
             (exprstring (hif-stringify tokens))
             (result (condition-case err
                         (funcall hide-ifdef-evaluator expr)
                       ;; in case of arithmetic error or others
                       (error (error "Error: line %d %S when evaluating `%s'"
                                     (line-number-at-pos) err exprstring)))))
        (setq
         result
         (cond
          ((= (length tokens) 0)
           (message "`%s'" exprstring))
          ((= (length tokens) 1) ; Simple token
           (if simple
               (if defined
                   (hif-display-macro exprstring result)
                 (if (and (hif-is-number exprstring)
                          result (numberp result))
                     (message "%S (%#x)" result result)
                   (if (and (hif-is-float exprstring)
                            result (numberp result))
                       (message "%S (%s)" result exprstring)
                     (if (string-match hif-string-literal-regexp exprstring)
                         (message "%s" exprstring)
                       (message "`%s' is not defined" exprstring)))))
             (if defined
                 (hif-display-macro exprstring (cdr defined) result)
               (message "`%s' is not defined" exprstring))))
          ((integerp result)
           (if (or (= 0 result) (= 1 result))
               (message "%S <= `%s'" result exprstring)
             (message "%S (%#x) <= `%s'" result result exprstring)))
          ((null result)
           (message "%S <= `%s'" 'false exprstring))
          ((eq t result)
           (message "%S <= `%s'" 'true exprstring))
          (t
           (message "%S <= `%s'" result exprstring))))
        (run-hooks 'hide-ifdef-evalulate-leave-hook)
        result))))