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 look 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 returns false on evaluating runtime C(++) statements or tokens that normal C(++) preprocessor can't perform; however, when invoked with prefix argument, 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 look 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 returns `false' on
evaluating runtime C(++) statements or tokens that normal C(++) preprocessor
can't perform; however, when invoked with prefix argument, 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))))