• Top
    • Documentation
    • Books
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
    • Interfacing-tools
    • Hardware-verification
      • Gl
      • Esim
      • Vl2014
        • Warnings
        • Primitives
        • Use-set
        • Syntax
        • Getting-started
        • Utilities
        • Loader
          • Preprocessor
            • Vl-iframe-p
            • Preprocessor-ifdef-minutia
            • Vl-preprocess-loop
              • Vl-read-until-end-of-define
              • Vl-expand-define
              • Vl-read-include
              • Vl-process-ifdef
              • Vl-substitute-into-macro-text
              • Vl-preprocess
              • Vl-define
              • Vl-process-define
              • Vl-process-undef
              • Preprocessor-include-minutia
              • Vl-split-define-text
              • Vl-read-timescale
              • Vl-line-up-define-formals-and-actuals
              • Vl-process-else
              • Vl-process-endif
              • Vl-istack-p
              • Vl-is-compiler-directive-p
              • Vl-check-remaining-formals-all-have-defaults
              • Vl-safe-previous-n
              • Vl-safe-next-n
              • Vl-defines
              • *vl-preprocess-clock*
            • Vl-loadconfig
            • Lexer
            • Vl-loadstate
            • Parser
            • Vl-load-merge-descriptions
            • Scope-of-defines
            • Vl-load-file
            • Vl-flush-out-descriptions
            • Vl-description
            • Vl-loadresult
            • Vl-read-file
            • Vl-find-basename/extension
            • Vl-find-file
            • Vl-read-files
            • Extended-characters
            • Vl-load
            • Vl-load-main
            • Vl-load-description
            • Vl-descriptions-left-to-load
            • Inject-warnings
            • Vl-load-descriptions
            • Vl-load-files
            • Vl-load-summary
            • Vl-collect-modules-from-descriptions
            • Vl-descriptionlist
          • Transforms
          • Lint
          • Mlib
          • Server
          • Kit
          • Printer
          • Esim-vl
          • Well-formedness
        • Sv
        • Fgl
        • Vwsim
        • Vl
        • X86isa
        • Svl
        • Rtl
      • Software-verification
      • Math
      • Testing-utilities
    • Preprocessor

    Vl-preprocess-loop

    Main loop for the preprocessor.

    Signature
    (vl-preprocess-loop echars defines filemap 
                        istack activep acc n config state) 
     
      → 
    (mv successp defines filemap acc remainder state)
    Arguments
    echars — Guard (vl-echarlist-p echars).
    defines — Guard (vl-defines-p defines).
    filemap — Guard (vl-filemap-p filemap).
    istack — Guard (vl-istack-p istack).
    activep — Guard (booleanp activep).
    n — Guard (natp n).
    config — Guard (vl-loadconfig-p config).

    We accumulate the transformed characters that are to be given to the lexer into acc, in reverse order.

    Definitions and Theorems

    Function: vl-preprocess-loop

    (defun vl-preprocess-loop (echars defines filemap
                                      istack activep acc n config state)
     (declare (xargs :stobjs (state)))
     (declare (xargs :guard (and (vl-echarlist-p echars)
                                 (vl-defines-p defines)
                                 (vl-filemap-p filemap)
                                 (vl-istack-p istack)
                                 (booleanp activep)
                                 (natp n)
                                 (vl-loadconfig-p config))))
     (let ((__function__ 'vl-preprocess-loop))
      (declare (ignorable __function__))
      (b*
       (((when (atom echars))
         (mv t defines filemap acc echars state))
        (echar1 (car echars))
        (char1 (vl-echar->char echar1))
        ((when (zp n))
         (mv
          (cw
           "Preprocessor error (~s0): ran out of steps. Macro expansion ~
                     or file inclusion loop?")
          defines filemap acc echars state))
        ((when (eql char1 #\"))
         (b* (((mv string prefix remainder)
               (vl-read-string echars (vl-lexstate-init config)))
              ((unless string)
               (mv nil defines filemap acc echars state)))
           (vl-preprocess-loop remainder defines filemap istack activep
                               (if activep (revappend prefix acc) acc)
                               n config state)))
        ((when (eql char1 #\\))
         (b* (((mv name prefix remainder)
               (vl-read-escaped-identifier echars))
              ((unless name)
               (mv (cw "Preprocessor error (~s0): stray backslash?~%"
                       (vl-location-string (vl-echar->loc echar1)))
                   defines filemap acc echars state)))
           (vl-preprocess-loop remainder defines filemap istack activep
                               (if activep (revappend prefix acc) acc)
                               n config state)))
        ((when (and (eql char1 #\/)
                    (consp (cdr echars))
                    (eql (vl-echar->char (second echars))
                         #\/)))
         (if
          (vl-matches-string-p "@VL" (cddr echars))
          (b*
            (((mv atts-text remainder)
              (b* (((mv & prefix remainder)
                    (vl-read-until-literal *nls* (rest-n 5 echars)))
                   ((mv comment1p pre-comment1 post-comment1)
                    (vl-read-until-literal "//" prefix))
                   ((mv comment2p pre-comment2 post-comment2)
                    (vl-read-until-literal "/*" prefix)))
                (cond ((and comment1p comment2p)
                       (if (< (len pre-comment1)
                              (len pre-comment2))
                           (mv pre-comment1
                               (append post-comment1 remainder))
                         (mv pre-comment2
                             (append post-comment2 remainder))))
                      (comment1p (mv pre-comment1
                                     (append post-comment1 remainder)))
                      (comment2p (mv pre-comment2
                                     (append post-comment2 remainder)))
                      (t (mv prefix remainder)))))
             (atts (append (vl-echarlist-from-str "(*")
                           atts-text
                           (vl-echarlist-from-str "*)"))))
            (vl-preprocess-loop (append atts remainder)
                                defines
                                filemap istack activep acc (- n 1)
                                config state))
          (b* (((mv & prefix remainder)
                (vl-read-until-literal *nls* (cddr echars)))
               ((when (vl-matches-string-p "+VL" prefix))
                (vl-preprocess-loop (append (rest-n 3 prefix) remainder)
                                    defines
                                    filemap istack activep acc (- n 1)
                                    config state))
               (prefix (list* (first echars)
                              (second echars)
                              prefix)))
            (vl-preprocess-loop remainder defines filemap istack activep
                                (if activep (revappend prefix acc) acc)
                                n config state))))
        ((when (and (eql char1 #\/)
                    (consp (cdr echars))
                    (eql (vl-echar->char (second echars))
                         #\*)))
         (b*
          (((mv successp prefix remainder)
            (vl-read-through-literal "*/" (cddr echars)))
           ((unless successp)
            (mv
             (cw
              "Preprocessor error (~s0): block comment is never closed.~%"
              (vl-location-string (vl-echar->loc echar1)))
             defines filemap acc echars state))
           ((when (vl-matches-string-p "+VL" prefix))
            (b* ((body (butlast (rest-n 3 prefix) 2)))
              (vl-preprocess-loop (append body remainder)
                                  defines
                                  filemap istack activep acc (- n 1)
                                  config state)))
           ((when (vl-matches-string-p "@VL" prefix))
            (b* ((body (append (vl-echarlist-from-str "(*")
                               (butlast (rest-n 3 prefix) 2)
                               (vl-echarlist-from-str "*)"))))
              (vl-preprocess-loop (append body remainder)
                                  defines
                                  filemap istack activep acc (- n 1)
                                  config state)))
           (prefix (list* (first echars)
                          (second echars)
                          prefix)))
          (vl-preprocess-loop remainder defines filemap istack activep
                              (if activep (revappend prefix acc) acc)
                              n config state)))
        ((when (not (eql char1 #\`)))
         (vl-preprocess-loop (cdr echars)
                             defines filemap istack activep
                             (if activep (cons (car echars) acc) acc)
                             n config state))
        ((mv & remainder)
         (vl-read-while-whitespace (cdr echars)))
        ((mv directive prefix remainder)
         (vl-read-identifier remainder))
        ((when (not directive))
         (mv (cw "Preprocessor error (~s0): stray ` character.~%"
                 (vl-location-string (vl-echar->loc echar1)))
             defines filemap acc echars state))
        ((when (not (vl-is-compiler-directive-p directive)))
         (b* (((unless activep)
               (vl-preprocess-loop remainder defines filemap
                                   istack activep acc n config state))
              ((mv successp expansion)
               (vl-expand-define directive defines remainder
                                 config (vl-echar->loc echar1)))
              ((unless successp)
               (mv nil
                   defines filemap acc expansion state)))
           (vl-preprocess-loop expansion defines filemap
                               istack activep acc (- (lnfix n) 1)
                               config state)))
        ((when (eql (vl-echar->char (car prefix)) #\\))
         (mv
          (cw
           "Preprocessor error (~s0): we do not allow the use of ~s1.~%"
           (vl-location-string (vl-echar->loc echar1))
           directive)
          defines filemap acc echars state))
        ((when (or (equal directive "define")
                   (equal directive "centaur_define")))
         (b* (((mv successp new-defines remainder)
               (vl-process-define (vl-echar->loc echar1)
                                  remainder defines activep config))
              ((unless successp)
               (mv nil defines filemap acc echars state)))
           (vl-preprocess-loop remainder new-defines filemap
                               istack activep acc n config state)))
        ((when (equal directive "undef"))
         (b* (((mv successp new-defines remainder)
               (vl-process-undef (vl-echar->loc echar1)
                                 remainder defines activep))
              ((unless successp)
               (mv nil defines filemap acc echars state)))
           (vl-preprocess-loop remainder new-defines filemap
                               istack activep acc n config state)))
        ((when (or (equal directive "ifdef")
                   (equal directive "ifndef")
                   (equal directive "elsif")))
         (b* (((mv successp
                   new-istack new-activep remainder)
               (vl-process-ifdef (vl-echar->loc echar1)
                                 directive
                                 remainder defines istack activep))
              ((unless successp)
               (mv nil defines filemap acc echars state)))
           (vl-preprocess-loop remainder defines filemap new-istack
                               new-activep acc n config state)))
        ((when (equal directive "else"))
         (b* (((mv successp new-istack new-activep)
               (vl-process-else (vl-echar->loc echar1)
                                istack activep))
              ((unless successp)
               (mv nil defines filemap acc echars state)))
           (vl-preprocess-loop remainder defines filemap new-istack
                               new-activep acc n config state)))
        ((when (equal directive "endif"))
         (b* (((mv successp new-istack new-activep)
               (vl-process-endif (vl-echar->loc echar1)
                                 istack activep))
              ((unless successp)
               (mv nil defines filemap acc echars state)))
           (vl-preprocess-loop remainder defines filemap new-istack
                               new-activep acc n config state)))
        ((when (equal directive "include"))
         (b*
          (((unless activep)
            (vl-preprocess-loop remainder defines filemap
                                istack activep acc n config state))
           ((mv filename ?prefix remainder)
            (vl-read-include remainder config))
           ((unless filename)
            (mv nil defines filemap acc echars state))
           ((mv realfile state)
            (vl-find-file filename
                          (vl-loadconfig->include-dirs config)
                          state))
           ((unless realfile)
            (mv
             (cw
              "Preprocessor error (~s0): unable to find ~s1.  The ~
                           include directories are ~&2."
              (vl-location-string (vl-echar->loc echar1))
              filename
              (vl-loadconfig->include-dirs config))
             defines filemap acc echars state))
           ((mv okp contents state)
            (cwtime (vl-read-file (string-fix realfile))
                    :mintime 1/2))
           ((unless okp)
            (mv (cw "Preprocessor error (~s0): unable to read ~s1."
                    (vl-location-string (vl-echar->loc echar1))
                    realfile)
                defines filemap acc echars state))
           (filemap (if (vl-loadconfig->filemapp config)
                        (cons (cons realfile
                                    (vl-echarlist->string contents))
                              filemap)
                      filemap)))
          (vl-preprocess-loop (append contents remainder)
                              defines
                              filemap istack activep acc (- n 1)
                              config state)))
        ((when (equal directive "timescale"))
         (b* (((mv prefix remainder)
               (vl-read-timescale remainder))
              ((unless prefix)
               (mv nil defines filemap acc echars state)))
           (vl-preprocess-loop remainder defines filemap
                               istack activep acc n config state)))
        ((when (or (equal directive "celldefine")
                   (equal directive "endcelldefine")
                   (equal directive "resetall")))
         (vl-preprocess-loop remainder defines filemap
                             istack activep acc n config state)))
       (mv (cw "Preprocessor error (~s0): we do not support ~s1.~%"
               (vl-location-string (vl-echar->loc echar1))
               directive)
           defines filemap acc echars state))))

    Theorem: booleanp-of-vl-preprocess-loop-success

    (defthm booleanp-of-vl-preprocess-loop-success
      (b* (((mv ?successp ?defines
                ?filemap ?acc ?remainder ?state)
            (vl-preprocess-loop echars defines filemap
                                istack activep acc n config state)))
        (booleanp successp))
      :rule-classes :type-prescription)

    Theorem: state-p1-of-vl-preprocess-loop

    (defthm state-p1-of-vl-preprocess-loop
     (implies
          (force (state-p1 state))
          (b* (((mv ?successp ?defines
                    ?filemap ?acc ?remainder ?state)
                (vl-preprocess-loop echars defines filemap
                                    istack activep acc n config state)))
            (state-p1 state))))

    Theorem: vl-preprocess-loop-basics

    (defthm vl-preprocess-loop-basics
     (implies
          (and (force (vl-echarlist-p echars))
               (force (vl-defines-p defines))
               (force (vl-filemap-p filemap))
               (force (vl-istack-p istack))
               (force (booleanp activep))
               (force (vl-echarlist-p acc))
               (force (state-p1 state)))
          (b* (((mv ?successp ?defines
                    ?filemap ?acc ?remainder ?state)
                (vl-preprocess-loop echars defines filemap
                                    istack activep acc n config state)))
            (and (vl-defines-p defines)
                 (vl-filemap-p filemap)
                 (vl-echarlist-p acc)
                 (vl-echarlist-p remainder)))))