Main loop for the preprocessor.
(vl-preprocess-loop echars defines filemap istack activep acc n config state) → (mv successp defines filemap acc remainder state)
We accumulate the transformed characters that are to be given to the lexer into acc, in reverse order.
Function:
(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:
(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:
(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:
(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)))))