[Git][cmucl/cmucl][rtoy-print-using-ryu] 3 commits: Fix a few typos in format-fixed-ryu
Raymond Toy pushed to branch rtoy-print-using-ryu at cmucl / cmucl Commits: 7efabb20 by Raymond Toy at 2026-05-29T14:02:59-07:00 Fix a few typos in format-fixed-ryu Stray "stream" after the format-f sexp and extra nil at the end of the first cond clause. - - - - - a519742d by Raymond Toy at 2026-05-29T14:45:23-07:00 Add macro def-format-ryu to handle ryu functions The functions format-fixed-ryu, format-exp-ryu, and format-general-ryu all look the same except for the ryu function that is called. Therefore, add a macro that can be used to define all of these functions. And make lisp::format-f handle the case of non-zero k by calling format::format-fixed-aux-bd directly. Then the check for non-zero k in format-fixed-aux can be elided. This makes all the format-foo-aux look similar. - - - - - 05b7706f by Raymond Toy at 2026-05-29T16:42:20-07:00 Macroize all the format-foo-aux functions The functions `format-{fixed,exp,general}-aux` are all basically the same except for then names of the functions that are called for the ryu printer and the B&D printer. Create a macro to abstract this out by taking the base name and created the appropriate functions names that are called. - - - - - 3 changed files: - src/code/format.lisp - src/code/ryu-print.lisp - src/i18n/locale/cmucl.pot Changes: ===================================== src/code/format.lisp ===================================== @@ -1572,35 +1572,48 @@ (format-princ stream number nil nil w 1 0 pad))) +(defmacro def-format-ryu (name (stream number &rest args) &body body) + (multiple-value-bind (docstring forms) + (if (and (stringp (first body)) (rest body)) + (values (list (first body)) (rest body)) + (values nil body)) + `(defun ,name (,stream ,number ,@args) + ,@docstring + (cond + ((and (floatp ,number) + (or (float-infinity-p ,number) + (float-nan-p ,number))) + (prin1 number ,stream)) + (t + ,@forms) + (values))))) + +(defmacro def-format-aux (base-name (stream number &rest args) &body body) + (let ((docstring + (if (and (stringp (first body)) (rest body)) + (list (first body)) + nil))) + (let ((defun-name (symbolicate base-name "-AUX")) + (name-ryu (symbolicate base-name "-RYU")) + (name-bd (symbolicate base-name "-AUX-BD"))) + `(defun ,defun-name (,stream ,number ,@args) + ,@docstring + (cond + ((and lisp::*use-ryu-printer* + (typep ,number '(or single-float double-float))) + (,name-ryu ,stream ,number ,@args)) + (t + (,name-bd ,stream, number ,@args))))))) + ;;; We return true if we overflowed, so that ~G can output the overflow char ;;; instead of spaces. ;;; -(defun format-fixed-aux (stream number w d k ovf pad atsign) - (declare (type float number)) - ;; Dispatch to either the Burger and Dybvig implementation or the - ;; Ryu-based implementation. The Ryu code only handles single- and - ;; double-float values, so any other float type (notably - ;; DOUBLE-DOUBLE-FLOAT) always falls through to the B&D path. - (cond - ((and lisp::*use-ryu-printer* - (or (null k) (zerop k)) - (typep number '(or single-float double-float))) - (format-fixed-ryu stream number w d k ovf pad atsign)) - (t - (format-fixed-aux-bd stream number w d k ovf pad atsign)))) - -(defun format-fixed-ryu (stream number w d k ovf pad atsign) +(def-format-aux format-fixed (stream number w d k ovf pad atsign)) + +(def-format-ryu format-fixed-ryu (stream number w d k ovf pad atsign) "Ryu-based implementation of the ~F directive. Delegates to LISP::FORMAT-F, which returns the formatted field as a string." - (cond - ((and (floatp number) - (or (float-infinity-p number) - (float-nan-p number))) - (prin1 number stream) - nil) - (t - (lisp::format-f stream number w d (or k 0) ovf pad atsign) stream))) - nil) + (lisp::format-f stream number w d (or k 0) ovf pad atsign)) (defun format-fixed-aux-bd (stream number w d k ovf pad atsign) "Burger and Dybvig based implementation of the ~F directive." @@ -1884,40 +1897,19 @@ (write-string estr stream)))))))) (values)) -(defun format-exp-ryu (stream number w d e k ovf pad marker atsign) +(def-format-ryu format-exp-ryu (stream number w d e k ovf pad marker atsign) "Ryu-based implementation of the ~E directive. Delegates to LISP::FORMAT-E, which returns the formatted field as a string." - (cond - ((and (floatp number) - (or (float-infinity-p number) - (float-nan-p number))) - (prin1 number stream)) - (t - ;; LISP::FORMAT-E uses a literal #\d as the default exponent - ;; marker when EXPONENTCHAR is NIL, but the CL ~E directive - ;; chooses the marker based on the value's type and - ;; *READ-DEFAULT-FLOAT-FORMAT* (see FORMAT-EXPONENT-MARKER). - ;; Resolve the default here so the same rule applies. - (lisp::format-e stream number w d e k ovf pad - (or marker (format-exponent-marker number)) - atsign))) - (values)) - -(defun format-exp-aux (stream number w d e k ovf pad marker atsign) - ;; Dispatch to either the Burger and Dybvig implementation or the - ;; Ryu-based implementation. The Ryu code only handles single- and - ;; double-float values, so any other float type (notably - ;; DOUBLE-DOUBLE-FLOAT) always falls through to the B&D path. - (cond - ((and lisp::*use-ryu-printer* - (floatp number) - (typep number '(or single-float double-float)) - (not (or (float-infinity-p number) - (float-nan-p number)))) - (format-exp-ryu stream number w d e k ovf pad marker atsign)) - (t - (format-exp-aux-bd stream number w d e k ovf pad marker atsign)))) + ;; LISP::FORMAT-E uses a literal #\d as the default exponent + ;; marker when EXPONENTCHAR is NIL, but the CL ~E directive + ;; chooses the marker based on the value's type and + ;; *READ-DEFAULT-FLOAT-FORMAT* (see FORMAT-EXPONENT-MARKER). + ;; Resolve the default here so the same rule applies. + (lisp::format-e stream number w d e k ovf pad + (or marker (format-exponent-marker number)) + atsign)) +(def-format-aux format-exp (stream number w d e k ovf pad marker atsign)) (def-format-directive #\G (colonp atsignp params) (when colonp @@ -1954,33 +1946,14 @@ ;;; toy@rtp.ericsson.se: Same change as for format-exp-aux. -(defun format-general-aux (stream number w d e k ovf pad marker atsign) - ;; Dispatch to either the Burger and Dybvig implementation or the - ;; Ryu-based implementation. The Ryu code only handles single- and - ;; double-float values, so any other float type (notably - ;; DOUBLE-DOUBLE-FLOAT) always falls through to the B&D path. - (cond - ((and lisp::*use-ryu-printer* - (floatp number) - (typep number '(or single-float double-float))) - (format-general-ryu stream number w d e k ovf pad marker atsign)) - (t - (format-general-aux-bd stream number w d e k ovf pad marker atsign)))) - -(defun format-general-ryu (stream number w d e k ovf pad marker atsign) +(def-format-aux format-general (stream number w d e k ovf pad marker atsign)) + +(def-format-ryu format-general-ryu (stream number w d e k ovf pad marker atsign) "Ryu-based implementation of the ~G directive. Delegates to LISP::FORMAT-G, which returns the formatted field as a string." - (cond - ((and (floatp number) - (or (float-infinity-p number) - (float-nan-p number))) - (prin1 number stream) - nil) - (t - (lisp::format-g stream number w d e (or k 1) ovf pad - (or marker (format-exponent-marker number)) - atsign))) - (values)) + (lisp::format-g stream number w d e (or k 1) ovf pad + (or marker (format-exponent-marker number)) + atsign)) (defun format-general-aux-bd (stream number w d e k ovf pad marker atsign) "Burger and Dybvig based implementation of the ~G directive." ===================================== src/code/ryu-print.lisp ===================================== @@ -635,13 +635,13 @@ (declare (type (or single-float double-float) value) (fixnum k) (type (or null (and unsigned-byte fixnum)) w d)) - (cond ((not (zerop k)) - ;; Complex case that doesn't fit with what d2s and d2fixed - ;; returns. Especially when d+k is negative so that some - ;; digits are shifted right past the desired precision. - ;; We'd have to round the result. Just use our existing - ;; code to handle this case with the correct rounding. - (format::format-fixed-aux stream value w d k overflowchar padchar at-sign-p)) + (cond ((and k (not (zerop k))) + ;; Complex case that doesn't fit with what d2s and d2fixed + ;; returns. Especially when d+k is negative so that some + ;; digits are shifted right past the desired precision. We'd + ;; have to round the result. Just use our existing code to + ;; handle this case with the correct rounding. + (format::format-fixed-aux-bd stream value w d k overflowchar padchar at-sign-p)) (d (format-f-fixed stream value w d overflowchar padchar at-sign-p)) (t ===================================== src/i18n/locale/cmucl.pot ===================================== @@ -7487,6 +7487,13 @@ msgid "" " double-float's exponent, so 0 <= n <= 324." msgstr "" +#: src/code/ryu-print.lisp +msgid "" +"Number of decimal digits needed to display the ACTUAL-EXP in a width\n" +" of E. If E is NIL, the actual number of digits is returned.\n" +" Otherwise, the max of E and the number of digits is returned." +msgstr "" + #: src/code/ryu-print.lisp msgid "" "Find the largest d (precision) value that fits in width W given the\n" View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/7fbbfafe00b19036c820dfe... -- View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/7fbbfafe00b19036c820dfe... You're receiving this email because of your account on gitlab.common-lisp.net. Manage all notifications: https://gitlab.common-lisp.net/-/profile/notifications | Help: https://gitlab.common-lisp.net/help
participants (1)
-
Raymond Toy (@rtoy)