• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
      • Gl
      • Esim
      • Vl2014
      • Sv
      • Fgl
      • Vwsim
      • Vl
        • Syntax
        • Loader
          • Preprocessor
            • Vl-iframe
            • Preprocessor-ifdef-minutia
            • Vl-preprocess
            • Vl-preprocess-loop
            • Vl-includeskips
            • Vl-read-until-end-of-define
            • Vl-define-formallist->defaults
            • Vl-define
            • Vl-expand-define
              • Vl-parse-define-actual
              • Vl-parse-define-actuals
            • Vl-read-include
            • Vl-substitute-into-macro-text
            • Vl-process-ifdef
            • Ppst
            • Vl-read-define-default-text
            • Vl-process-define
            • Preprocessor-include-minutia
            • Vl-trim-for-preproc
            • Vl-line-up-define-formals-and-actuals
            • Vl-process-undef
            • Vl-split-define-text
            • Vl-def-context
            • Vl-process-endif
            • Scan-backward-for-non-whitespace
            • Vl-ifdef-context
            • Scan-backward-for-whitespace
            • Vl-atvl-atts-text
            • Scan-for-non-whitespace
            • Vl-check-remaining-formals-all-have-defaults
            • Vl-process-else
            • Vl-is-compiler-directive-p
            • Vl-includeskips-controller-lookup
            • Vl-ifdef-use-map
            • Vl-defines
            • Vl-def-use-map
            • Vl-nice-bytes
            • Vl-safe-previous-n
            • Vl-safe-next-n
            • Vl-ppst-pad
            • Vl-filename-to-string-literal
            • Vl-maybe-update-filemap
            • *vl-preprocess-clock*
            • Vl-ppst->warnings
            • Vl-ppst->iskips
            • Vl-ppst->ifdefmap
            • Vl-ppst->idcache
            • Vl-istack
            • Vl-ppst->istack
            • Vl-ppst->includes
            • Vl-ppst->filemap
            • Vl-ppst->defmap
            • Vl-ppst->defines
            • Vl-ppst->config
            • Vl-ppst->bytes
            • Vl-ppst->activep
            • Vl-ppst->acc
            • Vl-ppst-record-ifdef-use
            • Vl-ppst-record-def-use
            • Vl-ifdef-context-list
            • Vl-def-context-list
            • Vl-ppst-update-warnings
            • Vl-ppst-update-istack
            • Vl-ppst-update-iskips
            • Vl-ppst-update-includes
            • Vl-ppst-update-ifdefmap
            • Vl-ppst-update-idcache
            • Vl-ppst-update-filemap
            • Vl-ppst-update-defmap
            • Vl-ppst-update-defines
            • Vl-ppst-update-config
            • Vl-ppst-update-activep
            • Vl-ppst-update-bytes
            • Vl-ppst-update-acc
            • Vl-ppst-unsound-nreverse-acc
          • Vl-loadconfig
          • Vl-loadstate
          • Lexer
          • Parser
          • Vl-load-merge-descriptions
          • Vl-find-basename/extension
          • Vl-load-file
          • Vl-loadresult
          • Scope-of-defines
          • Vl-find-file
          • Vl-flush-out-descriptions
          • Vl-description
          • Vl-read-file
          • Vl-includeskips-report-gather
          • Vl-load-main
          • Extended-characters
          • Vl-load
          • Vl-load-description
          • Vl-descriptions-left-to-load
          • Inject-warnings
          • Vl-preprocess-debug
          • Vl-write-preprocessor-debug-file
          • Vl-read-file-report-gather
          • Vl-load-descriptions
          • Vl-load-files
          • Translate-off
          • Vl-load-read-file-hook
          • Vl-read-file-report
          • Vl-loadstate-pad
          • Vl-load-summary
          • Vl-collect-modules-from-descriptions
          • Vl-loadstate->warnings
          • Vl-iskips-report
          • Vl-descriptionlist
        • Warnings
        • Getting-started
        • Utilities
        • Printer
        • Kit
        • Mlib
        • Transforms
      • X86isa
      • Svl
      • Rtl
    • Software-verification
    • Math
    • Testing-utilities
  • Preprocessor

Vl-expand-define

Expand uses of defines like `foo and `max(a,b).

Signature
(vl-expand-define name echars loc ppst) 
  → 
(mv successp new-echars ppst)
Arguments
name — Name of the directive we've just read, like "foo" for `foo.
    Guard (stringp name).
echars — Remaining text after the name. For simple macros like `foo we will just need to append the definition's body onto these characters. For macros with arguments we will need to extract the actuals from these characters.
    Guard (vl-echarlist-p echars).
loc — Location for error messages and for the resulting expansion text.
    Guard (vl-location-p loc).
Returns
successp — Type (booleanp successp).
new-echars — On success, the updated characters with the macro invocation replaced by its expansion.
    Type (vl-echarlist-p new-echars).

Note that variables in `define are lazy, e.g., if you do:

`define foo 3
`define bar `foo
`define foo 4

Then from here on `bar should also expand to 4. To accomplish this, we're going to modify the echars that are remaining in the input. That is, the output of vl-expand-define is going to get preprocessed. This does not always terminate! (Hence the termination counter on vl-preprocess-loop.

Subtle. If we simply inserted the echars stored in the defines table, then locations on these characters would refer to their original position in the file. This might lead to confusing error messages, telling you that something is wrong and showing you line numbers for a `define that looks just fine. So instead, we change all of the locations for the inserted text to point at the grave character for the macro usage. That is, if `foo occurs on line 37 from characters 5 through 8, then we'll make every character of foo's expansion occur at 37:5.

Definitions and Theorems

Function: vl-expand-define

(defun vl-expand-define (name echars loc ppst)
 (declare (xargs :stobjs (ppst)))
 (declare (xargs :guard (and (stringp name)
                             (vl-echarlist-p echars)
                             (vl-location-p loc))))
 (let ((__function__ 'vl-expand-define))
  (declare (ignorable __function__))
  (b*
   ((echars (vl-echarlist-fix echars))
    (lookup (vl-find-define name (vl-ppst->defines)))
    ((unless lookup)
     (let ((ppst (vl-ppst-fatal :msg "~a0: `~s1 is not defined."
                                :args (list loc name))))
       (mv nil echars ppst)))
    ((vl-define lookup))
    ((when (atom lookup.formals))
     (b* (((mv okp rev-replacement-body ppst)
           (vl-substitute-into-macro-text
                (vl-change-echarlist-locations
                     (vl-echarlist-from-str lookup.body)
                     loc)
                nil name loc nil ppst))
          ((unless okp) (mv nil echars ppst))
          (replacement-body (rev rev-replacement-body))
          (echars (append replacement-body echars)))
       (mv t echars ppst)))
    ((mv ?ws echars)
     (vl-read-while-whitespace echars))
    ((unless (and (consp echars)
                  (eql (vl-echar->char (car echars))
                       #\()))
     (let ((ppst (vl-ppst-fatal :msg "~a0: `~s1 requires arguments."
                                :args (list loc name))))
       (mv nil echars ppst)))
    (echars (cdr echars))
    ((mv successp actuals echars ppst)
     (vl-parse-define-actuals name echars loc ppst))
    ((unless successp) (mv nil echars ppst))
    ((mv successp subst ppst)
     (vl-line-up-define-formals-and-actuals
          lookup.formals actuals name loc ppst))
    ((unless successp) (mv nil echars ppst))
    ((mv okp rev-replacement-body ppst)
     (vl-substitute-into-macro-text
          (vl-change-echarlist-locations
               (vl-echarlist-from-str lookup.body)
               loc)
          subst name loc nil ppst))
    ((unless okp) (mv nil echars ppst))
    (replacement-body (rev rev-replacement-body))
    (echars (append replacement-body echars)))
   (mv t echars ppst))))

Theorem: booleanp-of-vl-expand-define.successp

(defthm booleanp-of-vl-expand-define.successp
  (b* (((mv ?successp ?new-echars ?ppst)
        (vl-expand-define name echars loc ppst)))
    (booleanp successp))
  :rule-classes :type-prescription)

Theorem: vl-echarlist-p-of-vl-expand-define.new-echars

(defthm vl-echarlist-p-of-vl-expand-define.new-echars
  (b* (((mv ?successp ?new-echars ?ppst)
        (vl-expand-define name echars loc ppst)))
    (vl-echarlist-p new-echars))
  :rule-classes :rewrite)

Subtopics

Vl-parse-define-actual
Collect a single argument to a text macro, like `max(a+b, c).
Vl-parse-define-actuals
Collect the arguments to a macro, like `max(a+b, c).