Skip to content

Instantly share code, notes, and snippets.

@vseloved
Created August 19, 2019 06:37
Show Gist options
  • Save vseloved/ae04844ddfb9ebc2dd87a328b999d01b to your computer and use it in GitHub Desktop.
Save vseloved/ae04844ddfb9ebc2dd87a328b999d01b to your computer and use it in GitHub Desktop.
Prototype of dimensional numbers implementation
(set-dispatch-macro-character #\# #\M #'read-dimensional-number)
(set-dispatch-macro-character #\# #\I #'read-dimensional-number)
(defun read-dimensional-number (s c n)
(declare (ignore n))
(let* ((prev-case (readtable-case *readtable*))
(val (unwind-protect
(progn (setf (readtable-case *readtable*) :preserve)
(symbol-name (read s nil)))
(setf (readtable-case *readtable*) prev-case)))
(split-pos (position-if-not (lambda (ch)
(or (digit-char-p ch)
(member ch '(#\- #\.))))
val)))
(convert-to-SI c
(read-from-string (subseq val 0 split-pos))
(intern (subseq val split-pos) :keyword))))
(defgeneric convert-to-SI (system number unit))
(defmethod convert-to-SI ((system (eql #\M)) number (unit (eql :m/s2)))
number)
(defmethod convert-to-SI ((system (eql #\M)) number (unit (eql :kJ)))
(* 1000 number))
(defmethod convert-to-SI ((system (eql #\M)) number (unit (eql :cal)))
(* 4.184 number))
(defmethod convert-to-SI ((system (eql #\I)) number (unit (eql :lb)))
(* 453.592 number))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment