[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


From: Francesco Potorti`
Subject: cmaceval
Date: Tue, 04 Dec 2001 16:51:53 +0100

c-macro-eval takes the region from a C buffer, proprocesses it and feeds
it to Calc, which computes the result.  Calc is smart enough to handle
even expressions with variables, computing all the constant expressions
it can.  With an argument, the result is shown in many formats (instead
of signed decimal only).

This is an old program of mine, that originally was intended as part of
cmacexp.el, but which stayed out mostly because calc.el was not bundled
with Emacs.  Since the next version of Emacs will probably include calc,
I propose it again here, hereby assigning the copyright to the FSF.

In my opinion, this should be part of cmacexp.el.  

===File ~/elisp/cmaceval.el=================================
;;; cmaceval.el --- Compute the value of a C expression   -*-coding: latin-1-*-

;; Copyright (C) 1995-2000 Francesco Potortì
;; Copyright (C) 2001 FSF

;; Author: Francesco Potorti` <address@hidden>
;; Keywords: c

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.

;; This program is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;; Commentary:

;; With an argument, print signed, unsigned, hex and
;; boolean representations.

(defun c-macro-eval (start end &optional flag) "\
Expand region using cpp and evaluate it using calc.
Interactively print value in minibuffer and push it on the kill ring.
With a C-u argument shows the evaluation in a variety of formats.
With two C-u's prompts the user for a string of flags to the preprocessor.

Non interactively returns value of region between START and END
as a string.  Several formats are used if optional FLAG is non-nil."

  (interactive "r\nP")
  (require 'cmacexp)
  (require 'calc)
  (if (or c-macro-prompt-flag (equal flag '(16)))
      (setq c-macro-cppflags
            (read-string "Preprocessor arguments: "

  ;; Expand the region.
  (if (interactive-p) (message (c-macro-default-message)))
  (let ((evaluation
         (c-macro-expansion start end
                            (concat c-macro-preprocessor " "
        (evalbuf (get-buffer-create " *Macro Evaluation*")))
          (set-buffer evalbuf)
          (setq buffer-read-only nil)
          (insert evaluation)

          ;; Evaluate expression(s).
          (if (interactive-p)
              (message "Invoking calc..."))
          (setq evaluation
                (let ((calc-eval-error t))
                  (calc-eval (list (buffer-string) 'calc-language 'c))))
            (insert (calc-eval (list evaluation
                                     'calc-language 'c
                                     'calc-simplify-mode 'binary))
                    "(u)" " == "
                    (calc-eval (list evaluation
                                     'calc-language 'c
                                     'calc-word-size (- calc-word-size)
                                     'calc-simplify-mode 'binary))
                    "(d)" " == "
                    (calc-eval (list evaluation
                                     'calc-language 'c
                                     'calc-number-radix 16
                                     'calc-simplify-mode 'binary))
              (insert " == " (calc-eval (list evaluation
                                              'calc-language 'c
                                              'calc-number-radix 16
                                              'calc-simplify-mode 'binary))))
            (while (re-search-forward "0x\\([^,]+\\)\\(, \\|\\'\\)" nil t)
              (if (string= "0"
                           (buffer-substring (match-beginning 1)
                                             (match-end 1)))
                  (replace-match "FALSE\\2")
                (replace-match "TRUE\\2"))))
            (insert evaluation)))

          ;; Output the evaluation.
          (if (interactive-p)
                (copy-region-as-kill 1 (point-max))
                (message (buffer-string)))
      (kill-buffer evalbuf))))

(defun c-macro-default-message ()
  (format "Invoking %s%s%s on region..."
          (if (string= "" c-macro-cppflags) "" " ")

reply via email to

[Prev in Thread] Current Thread [Next in Thread]