Basic function kinda works

This commit is contained in:
2021-04-26 11:53:28 -04:00
parent 4d9e0f4cac
commit 782fa68221
3 changed files with 123 additions and 40 deletions
+1 -1
View File
@@ -2,4 +2,4 @@ from hissp.reader import transpile
transpile(__package__, "livesort", "test_livesort") transpile(__package__, "livesort", "test_livesort")
del transpile del transpile
from livesort_hssp.livesort import livesort, render from livesort_hssp.livesort import Livesort
+60 -32
View File
@@ -1,44 +1,72 @@
(hissp.basic.._macro_.prelude) (hissp.basic.._macro_.prelude)
(defmacro setq (symbol value)
"lol this isn't even my lisp"
`(setitem (locals) (quote ,symbol) ,value))
(define livesort (deftype Livesort ()
(lambda (next-line ; iterable function __init__
(lambda (self
next-line ; iterable function yielding lines of text
print ; function to write output print ; function to write output
height ; window/screen height in lines height ; window/screen height in lines
width ; window/screen width in characters width ; window/screen width in characters
) )
(let (lines (list) ; sorted lines (attach self next-line print height width :
cursor 0 ; line number to keep on screen and highlight lines (list) ; sorted input lines
quitting? False ; set flag to exit loop screen (list (mul height '(None))))
) None) ; __init__ required to return `None`
;; the cursor is thought to exist between line `cursor` and `cursor - 1`
(any-for line next-line
(let (lineno (bisect..bisect lines line))
(unless (gt lineno cursor)
(setq cursor (add cursor 1)))
(.insert lines lineno line)
(print (.format "c{}" (render lines cursor height width))))
quitting?))))
(define render sortline
(lambda (lines ; sequence of sorted lines (lambda (self line)
cursor ; line to keep on-screen "Insort a line and update the cursor position"
height ; window height (when (.strip line)
width ; and width (let (lineno (bisect..bisect self.lines line))
) ;; Normally would use `..insort` but there's going to be more
(.join "\n" (.insert self.lines lineno line))))
(map (lambda (line) (getitem line (slice 0 width)))
(getitem lines
(let (r (ifloordiv height 2))
(slice (max 0 (sub cursor r))
(min (len lines) (add cursor r)))))))))
render
(lambda (self)
"Produce a list of the lines which should be visible, cropped to `width`"
(list (map (lambda (line) (getitem line (slice None self.width)))
(getitem self.lines (slice None self.height)))))
display
(lambda (self)
"Compare `(self.render)` to `self.screen` and return a string that
will update the display."
(let (output (list)
lines (self.render)
changed? (list))
(.append output "") ; Home cursor
(any-for lineno (range self.height)
(let (line (if-else (lt lineno (len lines))
(getitem lines lineno)
""))
(unless (eq line (getitem self.screen lineno))
(setitem self.screen lineno line)
(.append changed? line)
;; ^[[K to erase any characters that follow on this line
(.append output (.format "{}"
(.rstrip line (chr 0x0a)))))
(.append output (chr 0x0a))) ; Move to beginning of next line
False)
;; If something changed, don't bother outputting the last cursor
;; movement code. If nothing changed, don't bother outputting
;; anything.
(if-else changed?
(.join "" (getitem output (slice None -1)))
"")))
livesort
(lambda (self)
"Process every input line, updating screen each line"
(any-for line self.next-line
(.sortline self line)
(.print self (.display self))
False)))
(when (eq __name__ '__main__) (when (eq __name__ '__main__)
(livesort sys..stdin (.livesort (Livesort sys..stdin
sys..stdout.write (lambda (data)
(sys..stdout.write data)
(sys..stdout.flush))
(int (|| (os..getenv 'LINES) "24")) (int (|| (os..getenv 'LINES) "24"))
(int (|| (os..getenv 'COLUMNS) "80")))) (int (|| (os..getenv 'COLUMNS) "80")))))
+57 -2
View File
@@ -1,8 +1,63 @@
(hissp.basic.._macro_.prelude) (hissp.basic.._macro_.prelude)
(deftype TestLivesort (unittest..TestCase) (deftype TestLivesort (unittest..TestCase)
setUp
(lambda (self)
(attach self :
input-buf (list)
output-buf (list)
ls (livesort_hssp.livesort..Livesort self.input-buf
self.output-buf.append
4
8)))
tearDown
(lambda (self)
(delattr self 'ls)
(delattr self 'output-buf)
(delattr self 'input-buf))
test_Livesort
(lambda (self)
(cascade self
(.assertEqual self.ls.next-line self.input-buf)
(.assertEqual self.ls.print self.output-buf.append)
(.assertEqual self.ls.height 4)
(.assertEqual self.ls.width 8)
(.assertFalse self.ls.lines)
(.assertTrue self.ls.screen))
(any-for line self.ls.screen
(not (self.assertEqual None line))))
test_sortline
(lambda (self)
(self.assertFalse self.ls.lines)
(self.ls.sortline "line 2")
(self.assertEqual self.ls.lines (list '(.#"line 2")))
(self.ls.sortline "line 1")
(self.assertEqual self.ls.lines (list '(.#"line 1" .#"line 2"))))
test_render test_render
(lambda (self) (lambda (self)
(.assertEqual self "----" (livesort_hssp..render '(.#"-----") 0 4 4)))) (self.ls.sortline "line 1")
(self.assertEqual (self.ls.render)
(list '(.#"line 1"))))
(when (eq __name__ '__main__) (hissp.reader..transpile __package__ 'test_livesort)) test_display
(lambda (self)
;; I got fed up trying to write this sensibly, will go away after refacor
(self.assertEqual "


" (self.ls.display))
(self.ls.sortline "line 1")
(self.assertEqual "line 1
" (self.ls.display)))
test_livesort ; note (unfortunate) capitalization
(lambda (self)
(self.input-buf.append "line 1")
(self.ls.livesort)
_#(self.assertEqual self.output-buf (list '(.#"line 1")))))