other
(in-package "STD")
other
(include-book "xdoc/top" :dir :system)
other
(include-book "support")
other
(set-state-ok t)
other
(program)
other
(defxdoc defval :parents (std/util defconst) :short "A replacement for @(see defconst) with @(see xdoc) integration." :long "<h5>Basic Example</h5> @({ (defval *defval-example-number* :parents (defval) :short "Example of a constant for @(see defval)." :long "<p>This number is not very important.</p>" (fib 5)) }) <p>This is equivalent to just doing a @(see defxdoc) followed by a @(see defconst), except that the @(':long') string will be automatically extended with the defining event for @('*defval-example-number*').</p> <h5>General Form</h5> @({ (defval *name* [keyword options] body ;; defining expression [/// other events]) Option Default :parents nil :short nil :long nil :showdef t :showval nil :prepwork nil }) <p>The @(':parents'), @(':short'), and @(':long') options are as in @(see defxdoc). Typically you should specify at least @(':parents'), perhaps implicitly with @(see xdoc::set-default-parents), to get bare-bones documentation put into your manual in the right place.</p> <p>The @(':showdef') and @(':showval') options control what kind of documentation will be added to your @(':long') section, if any. These options are independent, i.e., you can say that you want either, both, or neither kinds of automatic documentation.</p> <p>When @(':showdef') is enabled, which is the default, @('defval') will automatically extend your @(':long') string with a the <i>definition</i> of the constant. For instance, here's what this looks like for @('*defval-example-number*'):</p> <box> <p><b>Definition:</b> @('*defval-example-number*')</p> @({(defconst *defval-example-number* (fib 5))}) </box> <p>In contrast, when @(':showval') is enabled, @('defval') will extend @(':long') with the <i>value</i> of your constant, e.g.,</p> <box> <p><b>Value:</b></p> @({8}) </box> <p>The optional @(':prepwork') argument can be used to put arbitrary events before the constant. This could be used, for instance, to define functions that are going to be used in the definition of the constant. These events will be documented as in the usual @(see defsection) style.</p> <p>The optional @('///') syntax is like that of @(see define). After the @('///') you can put related events that should come after the definition. These events will be included in the documentation, as in @(see defsection).</p> <h5>Warning about Large Constants</h5> <p>Either @(':showdef') or @(':showval') <b>can cause problems</b> when the printed representation of your constant's definition or value is very large. Trying to put huge values into the documentation could cause performance problems when generating or viewing the manual.</p> <p>This is much more likely to be a problem with @(':showval'), since even very small definitions like @('(make-list 100000)') can produce large values. Because of this, @('defval') disables @(':showval') disabled by default.</p> <p>This is unlikely to be a problem for @(':showdef') when you are writing your own @('defval') forms. However, if you are using @(see make-event) or other macros to generate @('defval') forms, you will need to be careful.</p>")
other
(defconst *defval-valid-keywords* '(:parents :short :long :showdef :showval :prepwork))
defval-extract-keywordsfunction
(defun defval-extract-keywords (ctx legal-kwds args kwd-alist) "Returns (mv kwd-alist other-args)" (declare (xargs :guard (and (symbol-listp legal-kwds) (no-duplicatesp legal-kwds) (alistp kwd-alist)))) (b* ((__function__ 'defval-extract-keywords) ((when (atom args)) (mv kwd-alist args)) (arg1 (first args)) ((unless (and (keywordp arg1) (member arg1 legal-kwds) (consp (cdr args)))) (b* (((mv kwd-alist other-args) (defval-extract-keywords ctx legal-kwds (cdr args) kwd-alist))) (mv kwd-alist (cons arg1 other-args)))) ((when (assoc arg1 kwd-alist)) (raise "~x0: multiple occurrences of keyword ~x1." ctx arg1) (mv nil nil)) (value (second args)) (kwd-alist (acons arg1 value kwd-alist))) (defval-extract-keywords ctx legal-kwds (cddr args) kwd-alist)))
defval-fnfunction
(defun defval-fn (name body kwd-alist other-events state) (declare (xargs :mode :program :stobjs state)) (b* ((__function__ 'defval) (showdef (getarg :showdef t kwd-alist)) (showval (getarg :showval nil kwd-alist)) (prepwork (getarg :prepwork nil kwd-alist)) (short (getarg :short nil kwd-alist)) (long (getarg :long nil kwd-alist)) (parents-p (assoc :parents kwd-alist)) (parents (cdr parents-p)) (parents (if parents-p parents (or (get-default-parents (w state)) '(undocumented)))) ((unless (booleanp showdef)) (raise ":showdef must be a boolean, but is ~x0." showdef)) ((unless (booleanp showval)) (raise ":showval must be a boolean, but is ~x0." showval)) ((unless (true-listp prepwork)) (raise ":prepwork must be a true-listp, but is ~x0." prepwork)) ((unless (symbol-listp parents)) (raise ":parents must be a symbol list, but is ~x0." parents)) ((unless (or (stringp long) (true-listp long))) (raise ":long must be a string or a true-listp, but is ~x0." long)) ((unless (or (stringp short) (true-listp short))) (raise ":short must be a string or a true-listp, but is ~x0." short)) (long (or long "")) (name-str (concatenate 'string (symbol-package-name name) "::" (symbol-name name))) (long (if showdef `(concatenate 'string ,STD::LONG "@(def " ,STD::NAME-STR ")") long)) (long (if showval `(concatenate 'string ,STD::LONG "<p><b>Value:</b></p>" "@(`(:code " ,STD::NAME-STR ")`)") long))) `(defsection ,STD::NAME ,@(AND STD::PARENTS `(:PARENTS ,STD::PARENTS)) ,@(AND STD::SHORT `(:SHORT ,STD::SHORT)) ,@(AND STD::LONG `(:LONG ,STD::LONG)) ,@STD::PREPWORK (defconst ,STD::NAME ,STD::BODY) . ,(AND STD::OTHER-EVENTS `((STD::WITH-OUTPUT :STACK :POP (PROGN . ,STD::OTHER-EVENTS)))))))
defvalmacro
(defmacro defval (name &rest args) (b* ((__function__ 'defval) ((unless (symbolp name)) (raise "Name must be a symbol.")) (ctx (list 'defval name)) ((mv main-stuff other-events) (split-/// ctx args)) ((mv kwd-alist other-args) (defval-extract-keywords ctx *defval-valid-keywords* main-stuff nil)) ((unless (tuplep 1 other-args)) (raise "Wrong number of arguments to defval.")) (body (first other-args))) `(with-output :stack :push :off (summary observation prove proof-tree event) (make-event `(progn ,(STD::DEFVAL-FN ',STD::NAME ',STD::BODY ',STD::KWD-ALIST ',STD::OTHER-EVENTS STD::STATE) (value-triple '(defval ,',STD::NAME)))))))