skx / yal

Yet another lisp interpreter
GNU General Public License v2.0
16 stars 0 forks source link

Type conversion would be beneficial #80

Closed skx closed 1 year ago

skx commented 1 year ago

I've got a bunch of binary operations working for my (embedded) use-case, but they're fiddlier than they need to be.

Converting a number to binary is easy:

(set! dec_base (fn* ( n b )
                    "Convert the given number to a string representation of the number in the given base.

Example: (dec_base 254 2)  ; int -> binary
Example: (dec_base 201 16) ; int -> hex"
    (if (< n b)
        (chr (+ n (if (< n 10) 48 55)))
      (join (list (dec_base (/ n b) b) (dec_base (% n b) b)))
    )))

But to convert back I've fallen back to using eval:

(set! bin2dec (fn* (n)
                   "Convert the given binary string to an integer.

Example: (print (bin2dec \"1101\"))
See-also:  dec_base, hex2dec"
                   (eval (join (list "0b" n)))))

(set! hex2dec (fn* (n)
                   "Convert the given hex string to an integer.

Example: (print (hex2dec \"ff\"))
See-also:  dec_base, bin2dec"
                   (eval (join (list "0x" n)))))

Using eval like this is probably safe, but it feels like a code-smell.

Adding a conversion/parsing routine as native would help. Consider moving the rest to the stdlib once I've validated they're sane:

;;; bits.lisp - Binary functions

;; This file contains binary functions "and", "or", and "xor" for bits
;; and integers.
;;
;; We have some numerical conversion routines for converting between
;; integers and hex/binary numbers.
;;
;; Finally we also have some routines for testing whether a given bit
;; in a number is set, or unset.  As well as forcibly clearing or setting
;; them.
;;
;; NOTE: Most of these routines will fail for "large" values.  64-bit is
;; fine, after that good luck.
;;
skx commented 1 year ago

Two choices. We can add:

Or we could add:

We could add wrappers for (binary) and (hex) using (base).