Validate a character of a character constant.
(valid-c-char cchar prefix? ienv) → (mv erp code)
If validation succeeds, we return the character code.
The grammar [C17:6.4.4.4/1] excludes (direct) character codes
for single quote and new-line.
For the latter, we check both line feed and carriage return.
Note that our lexer normalizes both to line feed,
and excludes line feed when lexing
[C17:6.4.4.4/4] says that, based on the (possibly absent) prefix
of the character constant of which this character is part,
the character code of an octal or hexadecimal escape must fit in
Function:
(defun valid-c-char (cchar prefix? ienv) (declare (xargs :guard (and (c-char-p cchar) (cprefix-optionp prefix?) (ienvp ienv)))) (b* (((reterr) 0) (max (if prefix? 1114111 (ienv->uchar-max ienv)))) (c-char-case cchar :char (cond ((= cchar.code (char-code #\')) (retmsg$ "Single quote cannot be used directly ~ in a character constant.")) ((= cchar.code 10) (retmsg$ "Line feed cannot be used directly ~ in a character constant.")) ((= cchar.code 13) (retmsg$ "Carriage return cannot be used directly ~ in a character constant.")) ((> cchar.code max) (retmsg$ "The character with code ~x0 ~ exceed the maximum ~x1 allowed for ~ a character constant with prefix ~x2." cchar.code max (cprefix-option-fix prefix?))) (t (retok cchar.code))) :escape (valid-escape cchar.escape max))))
Theorem:
(defthm maybe-msgp-of-valid-c-char.erp (b* (((mv acl2::?erp ?code) (valid-c-char cchar prefix? ienv))) (maybe-msgp erp)) :rule-classes :rewrite)
Theorem:
(defthm natp-of-valid-c-char.code (b* (((mv acl2::?erp ?code) (valid-c-char cchar prefix? ienv))) (natp code)) :rule-classes :rewrite)
Theorem:
(defthm valid-c-char-of-c-char-fix-cchar (equal (valid-c-char (c-char-fix cchar) prefix? ienv) (valid-c-char cchar prefix? ienv)))
Theorem:
(defthm valid-c-char-c-char-equiv-congruence-on-cchar (implies (c-char-equiv cchar cchar-equiv) (equal (valid-c-char cchar prefix? ienv) (valid-c-char cchar-equiv prefix? ienv))) :rule-classes :congruence)
Theorem:
(defthm valid-c-char-of-cprefix-option-fix-prefix? (equal (valid-c-char cchar (cprefix-option-fix prefix?) ienv) (valid-c-char cchar prefix? ienv)))
Theorem:
(defthm valid-c-char-cprefix-option-equiv-congruence-on-prefix? (implies (cprefix-option-equiv prefix? prefix?-equiv) (equal (valid-c-char cchar prefix? ienv) (valid-c-char cchar prefix?-equiv ienv))) :rule-classes :congruence)
Theorem:
(defthm valid-c-char-of-ienv-fix-ienv (equal (valid-c-char cchar prefix? (ienv-fix ienv)) (valid-c-char cchar prefix? ienv)))
Theorem:
(defthm valid-c-char-ienv-equiv-congruence-on-ienv (implies (ienv-equiv ienv ienv-equiv) (equal (valid-c-char cchar prefix? ienv) (valid-c-char cchar prefix? ienv-equiv))) :rule-classes :congruence)