Current section
Files
Jump to
Current section
Files
src/horatio-util.lfe
(defmodule horatio-util
(export (get-version 0)
(get-versions 0)
(gcd 2)
(->str 1)
(->atom 1)
(->float 1)
(normalise 1) (normalise 2)
(normalize 1) (normalize 2)
(fix-sign 1) (fix-sign 2)
(float->ratio 1)
(print-api-functions 0)))
(include-lib "horatio/include/data-types.lfe")
(defun get-version ()
(lr3-ver-util:get-app-version 'horatio))
(defun get-versions ()
(++ (lr3-ver-util:get-versions)
`(#(horatio ,(get-version)))))
(defun gcd
((a 0) a)
((0 b) b)
((a b) (when (== a b)) a)
((a b)
(gcd b (rem a b))))
(defun ->str
(((match-ratio numer n denom d))
(lists:flatten
(io_lib:format "~p/~p" `(,n ,d)))))
(defun ->atom (ratio)
(list_to_atom (->str ratio)))
(defun ->float
(((match-ratio numer n denom d))
(/ n d)))
(defun normalise
(((match-ratio numer n denom d))
(normalise n d)))
(defun normalise (n d)
(let ((`(,n ,d) (fix-sign n d))
(g (gcd n d)))
(ratio:new
(trunc (/ n g))
(trunc (/ d g)))))
(defun normalize (r)
(normalise r))
(defun normalize (n d)
(normalise n d))
(defun fix-sign
(((match-ratio numer n denom d))
(fix-sign n d)))
(defun fix-sign (n d)
(cond ((and (< n 0) (< d 0))
(list (abs n) (abs d)))
((< d 0)
(list (* -1 n) (abs d)))
('true
(list n d))))
(defun float->ratio
"Floating point math sometimes results in poor converstions to
ratios, requiring two passes of normalise."
((f) (when (is_float f))
(let* ((fl (float_to_list f '(#(decimals 20))))
(`(,int ,dec) (string:tokens fl "."))
(numer (list_to_integer (++ int dec)))
(denom (trunc (math:pow 10 (length dec)))))
(normalise
(normalise numer denom)))))
(defun check-function
((`#(,func-name ,arity))
(let ((skip '(module_info
get-version
get-versions
loaded-ratio-data-types
loaded-ratio-api
loaded-ratio
fix-sign
print-api-functions)))
(if (lists:member func-name skip)
'false
`#(true #(,func-name ,arity))))))
(defun get-api-functions ()
(lists:filtermap
#'check-function/1
(proplists:get_value 'exports (ratio:module_info))))
(defun print-function
((`#(,func-name ,arity))
(lfe_io:format "ratio:~p/~p~n" `(,func-name ,arity))))
(defun print-api-functions ()
(lists:foreach
#'print-function/1
(lists:sort (get-api-functions))))