Skip to content

Commit

Permalink
Add invistra-numeral
Browse files Browse the repository at this point in the history
  • Loading branch information
yitzchak committed Jan 18, 2024
1 parent f4e854c commit 605af02
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ jobs:
- name: Run ANSI Tests
run: |
lisp -i ${{ matrix.lisp }} -e "(ql:quickload :invistra-extrinsic/test)" -e "(invistra-extrinsic/test/ansi:test :exit t)"
- name: Run Numeral Tests
run: |
lisp -i ${{ matrix.lisp }} -e "(defparameter cl-user::*exit-on-test-failures* t)" -e "(ql:quickload :invistra-numeral/test)" -e "(parachute:test :invistra-numeral/test)"
86 changes: 86 additions & 0 deletions code/numeral/numeral.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
(in-package #:invistra-numeral)

(defclass numeral-directive (invistra:directive)
((pattern :accessor numeral-pattern
:initarg :pattern)))

(defmethod invistra:parameter-specifications ((client t) (directive numeral-directive))
'((:type integer :default 0)
(:type character :default #\Space)
(:type character :default #\,)
(:type integer :default 3)))

(defmacro define-numeral-directive (client-class char pattern)
`(defmethod invistra:specialize-directive
((client ,client-class) (char (eql ,char)) directive (end-directive t))
(change-class directive 'numeral-directive
:pattern ',pattern)))

#|(defmethod numeral-pattern ((name null))
'#1=(#("0" "1" "2" "3" "4" "5" "6" "7" "8" "9")
. #1#))
(defmethod numeral-pattern ((name (eql #\O)))
'(#(nil "I" "II" "III" "IIII")
#("" "V")
#("" "X" "XX" "XXX" "XXXX")
#("" "L")
#("" "C" "CC" "CCC" "CCCC")
#("" "D")
#("" "M" "MM" "MMM" "MMMM")))
(defmethod numeral-pattern ((name (eql #\R)))
'(#(nil "I" "II" "III" "IV" "V" "VI" "VII" "VIII" "IX")
#("" "X" "XX" "XXX" "XL" "L" "LX" "LXX" "LXXX" "XC")
#("" "C" "CC" "CCC" "CD" "D" "DC" "DCC" "DCCC" "CM")
#("" "M" "MM" "MMM" "MMMM")))
(defmethod numeral-pattern ((name (eql #\E)))
'(#(nil "𐌠" "𐌠𐌠" "𐌠𐌠𐌠" "𐌠𐌠𐌠𐌠")
#("" "𐌡")
#("" "𐌢" "𐌢𐌢" "𐌢𐌢𐌢" "𐌢𐌢𐌢𐌢")
#("" "𐌣")
#("" "𐌟" "𐌟𐌟" "𐌟𐌟𐌟" "𐌟𐌟𐌟𐌟")))
(defmethod numeral-pattern ((name (eql #\K)))
'#1=(#("𝋀" "𝋁" "𝋂" "𝋃" "𝋄"
"𝋅" "𝋆" "𝋇" "𝋈" "𝋉"
"𝋊" "𝋋" "𝋌" "𝋍" "𝋎"
"𝋏" "𝋐" "𝋑" "𝋒" "𝋓")
. #1#))|#

(defun print-numeral-arg (client colon-p at-sign-p pattern mincol padchar commachar comma-interval)
(prog ((q (invistra:consume-next-argument t))
(r 0)
(c 0)
parts
(comma-part (string commachar))
result
pad-length
place)
repeat
(setq place (pop pattern))
(multiple-value-setq (q r)
(floor q (length place)))
(push (aref place r) parts)
(unless (zerop q)
(when colon-p
(setq c (mod (incf c) comma-interval))
(when (zerop c)
(push (string comma-part) parts)))
(go repeat))
(setf result (apply #'concatenate 'string parts)
pad-length (max 0 (- mincol (inravina:stream-measure-string invistra:*destination* result))))
(write-string result invistra:*destination*)))

(defmethod invistra:interpret-item (client (directive numeral-directive) &optional parameters)
(apply #'print-numeral-arg client
(invistra:colon-p directive) (invistra:at-sign-p directive)
(numeral-pattern directive)
parameters))

(defmethod invistra:compile-item (client (directive numeral-directive) &optional parameters)
`((print-numeral-arg ,(incless:client-form client)
,(invistra:colon-p directive) ,(invistra:at-sign-p directive)
,(numeral-pattern directive)
,@parameters)))
3 changes: 3 additions & 0 deletions code/numeral/packages.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(defpackage #:invistra-numeral
(:use #:cl)
(:export #:define-numeral-directive))
16 changes: 16 additions & 0 deletions code/numeral/test/directive.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
(in-package #:invistra-numeral/test)

(defclass numeral-client (incless-extrinsic:extrinsic-client) ())

(defvar *kaktovik-numeral-pattern*
'#1=(#("𝋀" "𝋁" "𝋂" "𝋃" "𝋄"
"𝋅" "𝋆" "𝋇" "𝋈" "𝋉"
"𝋊" "𝋋" "𝋌" "𝋍" "𝋎"
"𝋏" "𝋐" "𝋑" "𝋒" "𝋓")
. #1#))

(invistra-numeral:define-numeral-directive numeral-client #\K *kaktovik-numeral-pattern*)

(defmacro my-formatter (control-string)
(let ((incless-extrinsic:*client* (make-instance 'numeral-client)))
(invistra:formatter incless-extrinsic:*client* control-string)))
4 changes: 4 additions & 0 deletions code/numeral/test/packages.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(cl:in-package #:common-lisp-user)

(defpackage #:invistra-numeral/test
(:use #:cl #:parachute))
8 changes: 8 additions & 0 deletions code/numeral/test/test.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(in-package #:invistra-numeral/test)

(define-test "kaktovik.01"
(let ((incless-extrinsic:*client* (make-instance 'numeral-client)))
(is equal
"𝋒𝋆𝋀"
(with-output-to-string (stream)
(funcall (my-formatter "~k") stream (+ (* 18 20 20) (* 6 20)))))))
34 changes: 34 additions & 0 deletions invistra-numeral.asd
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
(cl:in-package #:asdf-user)

(defsystem "invistra-numeral"
:description "Additional numeral printers for Invistra"
:license "BSD"
:author "Tarn W. Burton"
:maintainer "Tarn W. Burton"
:version (:read-file-form "version.sexp")
:homepage "https://github.com/s-expressionists/Invistra"
:bug-tracker "https://github.com/s-expressionists/Invistra/issues"
:depends-on ("invistra")
:components ((:module code
:pathname "code/numeral/"
:serial t
:components ((:file "packages")
(:file "numeral")))))

(defsystem "invistra-numeral/test"
:description "Tests for additional numeral printers for Invistra"
:license "BSD"
:author "Tarn W. Burton"
:maintainer "Tarn W. Burton"
:version (:read-file-form "version.sexp")
:homepage "https://github.com/s-expressionists/Invistra"
:bug-tracker "https://github.com/s-expressionists/Invistra/issues"
:depends-on ("invistra-extrinsic"
"invistra-numeral"
"parachute")
:components ((:module code
:pathname "code/numeral/test/"
:serial t
:components ((:file "packages")
(:file "directive")
(:file "test")))))

0 comments on commit 605af02

Please sign in to comment.