initial import

This commit is contained in:
Kyle Isom 2025-04-09 22:46:32 -07:00
parent 8ecbfeab1e
commit 23b4fb6d47
16 changed files with 1524 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
secrets.lsp

363
armasm.lsp Normal file
View File

@ -0,0 +1,363 @@
; ARM Thumb Assembler for uLisp - Version 10 - 18th November 2024
; see http://www.ulisp.com/show?2YRU
;
; Extract register number
(defun regno (sym)
(case sym (sp 13) (lr 14) (pc 15)
(t (read-from-string (subseq (string sym) 1)))))
; Pack arguments into bit fields
(defun emit (bits &rest args)
(let ((word 0) (shift -28))
(mapc #'(lambda (value)
(let ((width (logand (ash bits shift) #xf)))
(incf shift 4)
(unless (zerop (ash value (- width))) (error "Won't fit"))
(setq word (logior (ash word width) value))))
args)
word))
(defun offset (label) (ash (- label *pc* 4) -1))
; data
(defun $word (val)
(append
(unless (zerop (mod *pc* 4)) (list ($nop)))
(list (logand val #xffff) (logand (ash val -16) #xffff))))
; Shared routines, ordered by first four bits
; lsl lsr 0
(defun lsl-lsr-0 (op argd argm immed5)
(emit #x41533000 0 op immed5 (regno argm) (regno argd)))
; asr 0
(defun asr-0 (op argd argm immed5)
(emit #x41533000 1 op immed5 (regno argm) (regno argd)))
; add sub 1
(defun add-sub-1 (op argd argn argm)
(cond
((numberp argm)
(emit #x61333000 #b000111 op argm (regno argn) (regno argd)))
((null argm)
(emit #x61333000 #b000110 op (regno argn) (regno argd) (regno argd)))
(t
(emit #x61333000 #b000110 op (regno argm) (regno argn) (regno argd)))))
; mov sub 2 3
(defun mov-sub-2-3 (op2 op argd immed8)
(emit #x41380000 op2 op (regno argd) immed8))
; add mov 4
(defun add-mov-4 (op argd argm)
(let ((rd (regno argd))
(rm (regno argm)))
(cond
((and (>= rd 8) (>= rm 8))
(emit #x61333000 #b010001 op #b011 (- rm 8) (- rd 8)))
((>= rm 8)
(emit #x61333000 #b010001 op #b001 (- rm 8) rd))
((>= rd 8)
(emit #x61333000 #b010001 op #b010 rm (- rd 8))))))
; reg-reg
(defun reg-reg (op argd argm)
(emit #xa3300000 op (regno argm) (regno argd)))
; bx blx 4
(defun bx-blx (op argm)
(emit #x81430000 #b01000111 op (regno argm) 0))
; str ldr 4, 6, 9
(defun str-ldr (op argd arg2)
(cond
((numberp arg2)
(when (= op 0) (error "str not allowed with label"))
(let ((arg (- (truncate (+ arg2 2) 4) (truncate *pc* 4) 1)))
(emit #x41380000 4 1 (regno argd) (max 0 arg))))
((listp arg2)
(let ((argn (first arg2))
(immed (or (eval (second arg2)) 0)))
(unless (zerop (mod immed 4)) (error "not multiple of 4"))
(cond
((eq (regno argn) 15)
(when (= op 0) (error "str not allowed with pc"))
(emit #x41380000 4 1 (regno argd) (truncate immed 4)))
((eq (regno argn) 13)
(emit #x41380000 9 op (regno argd) (truncate immed 4)))
(t
(emit #x41533000 6 op (truncate immed 4) (regno argn) (regno argd))))))
(t (error "illegal argument"))))
(defun str-ldr-5 (op argd arg2)
(cond
((listp arg2)
(let ((argn (first arg2))
(argm (second arg2)))
(emit #x43333000 5 op (regno argm) (regno argn) (regno argd))))
(t (error "illegal argument"))))
; add-10
(defun add-10 (op argd immed8)
(emit #x41380000 #b1010 op (regno argd) (truncate immed8 4)))
; add-sub-11
(defun add-sub-11 (op immed7)
(emit #x81700000 #b11010000 op (truncate immed7 4)))
; push pop 11
(defun push-pop (op lst)
(let ((byte 0)
(r 0))
(mapc #'(lambda (x)
(cond
((and (= op 0) (eq x 'lr)) (setq r 1))
((and (= op 1) (eq x 'pc)) (setq r 1))
(t (setq byte (logior byte (ash 1 (regno x))))))) lst)
(emit #x41218000 11 op 2 r byte)))
; b cond 13
(defun b-cond-13 (cnd label)
(let ((soff8 (logand (offset label) #xff)))
(emit #x44800000 13 cnd soff8)))
(defun cpside (op aif)
(emit #xb1130000 #b10110110011 op 0 aif))
; Alphabetical list of mnemonics
(defun $adc (argd argm)
(reg-reg #b0100000101 argd argm))
(defun $add (argd argn &optional argm)
(cond
((numberp argm)
(cond
((eq (regno argn) 15)
(add-10 0 argd argm))
((eq (regno argn) 13)
(add-10 1 argd argm))
(t (add-sub-1 0 argd argn argm))))
((and (numberp argn) (null argm))
(cond
((eq (regno argd) 13)
(add-sub-11 0 argn))
(t
(mov-sub-2-3 3 0 argd argn))))
(t
(cond
((or (>= (regno argd) 8) (>= (regno argn) 8))
(add-mov-4 0 argd argn))
(t
(add-sub-1 0 argd argn argm))))))
(defun $and (argd argm)
(reg-reg #b0100000000 argd argm))
(defun $asr (argd argm &optional arg2)
(unless arg2 (setq arg2 argm argm argd))
(cond
((numberp arg2)
(asr-0 0 argd argm arg2))
((eq argd argm)
(reg-reg #b0100000100 argd arg2))
(t (error "First 2 registers must be the same"))))
(defun $b (label)
(emit #x41b00000 #xe 0 (logand (offset label) #x7ff)))
(defun $bcc (label)
(b-cond-13 3 label))
(defun $bcs (label)
(b-cond-13 2 label))
(defun $beq (label)
(b-cond-13 0 label))
(defun $bge (label)
(b-cond-13 10 label))
(defun $bgt (label)
(b-cond-13 12 label))
(defun $bhi (label)
(b-cond-13 8 label))
(defun $bhs (label)
(b-cond-13 2 label))
(defun $ble (label)
(b-cond-13 13 label))
(defun $blo (label)
(b-cond-13 3 label))
(defun $blt (label)
(b-cond-13 11 label))
(defun $bmi (label)
(b-cond-13 4 label))
(defun $bne (label)
(b-cond-13 1 label))
(defun $bpl (label)
(b-cond-13 5 label))
(defun $bic (argd argm)
(reg-reg #b0100001110 argd argm))
(defun $bl (label)
(list
(emit #x5b000000 #b11110 (logand (ash (offset label) -11) #x7ff))
(emit #x5b000000 #b11111 (logand (offset label) #x7ff))))
(defun $blx (argm)
(bx-blx 1 argm))
(defun $bx (argm)
(bx-blx 0 argm))
(defun $cmn (argd argm)
(reg-reg #b0100001011 argd argm))
(defun $cmp (argd argm)
(cond
((numberp argm)
(mov-sub-2-3 2 1 argd argm))
(t
(reg-reg #b0100001010 argd argm))))
(defun $cpsid (aif)
(cpside 1 aif))
(defun $cpsie (aif)
(cpside 0 aif))
(defun $eor (argd argm)
(reg-reg #b0100000001 argd argm))
(defun $ldr (argd arg2)
(str-ldr 1 argd arg2))
(defun $ldrb (argd arg2)
(str-ldr-5 6 argd arg2))
(defun $ldrh (argd arg2)
(str-ldr-5 5 argd arg2))
(defun $ldrsb (argd arg2)
(str-ldr-5 3 argd arg2))
(defun $ldrsh (argd arg2)
(str-ldr-5 7 argd arg2))
(defun $lsl (argd argm &optional arg2)
(unless arg2 (setq arg2 argm argm argd))
(cond
((numberp arg2)
(lsl-lsr-0 0 argd argm arg2))
((eq argd argm)
(reg-reg #b0100000010 argd arg2))
(t (error "First 2 registers must be the same"))))
(defun $lsr (argd argm &optional arg2)
(unless arg2 (setq arg2 argm argm argd))
(cond
((numberp arg2)
(lsl-lsr-0 1 argd argm arg2))
((eq argd argm)
(reg-reg #b0100000011 argd arg2))
(t (error "First 2 registers must be the same"))))
(defun $mov (argd argm)
(cond
((numberp argm)
(mov-sub-2-3 2 0 argd argm))
((or (>= (regno argd) 8) (>= (regno argm) 8))
(add-mov-4 1 argd argm))
(t ; Synonym of LSLS Rd, Rm, #0
(lsl-lsr-0 0 argd argm 0))))
(defun $mul (argd argm)
(reg-reg #b0100001101 argd argm))
(defun $mvn (argd argm)
(reg-reg #b0100001111 argd argm))
(defun $neg (argd argm)
(reg-reg #b0100001001 argd argm))
(defun $nop () ; mov r8,r8
(add-mov-4 1 'r8 'r8))
(defun $orr (argd argm)
(reg-reg #b0100001100 argd argm))
(defun $push (lst)
(push-pop 0 lst))
(defun $pop (lst)
(push-pop 1 lst))
(defun $rev (argd argm)
(reg-reg #b1011101000 argd argm))
(defun $rev16 (argd argm)
(reg-reg #b1011101001 argd argm))
(defun $revsh (argd argm)
(reg-reg #b1011101010 argd argm))
(defun $ror (argd argm)
(reg-reg #b0100000111 argd argm))
(defun $sbc (argd argm)
(reg-reg #b0100000110 argd argm))
(defun $str (argd arg2)
(str-ldr 0 argd arg2))
(defun $strb (argd arg2)
(str-ldr-5 2 argd arg2))
(defun $sub (argd argn &optional argm)
(cond
((not (numberp argn))
(add-sub-1 1 argd argn argm))
((eq (regno argd) 13)
(add-sub-11 1 argn))
(t
(mov-sub-2-3 3 1 argd argn))))
(defun $sxtb (argd argm)
(reg-reg #b1011001001 argd argm))
(defun $sxth (argd argm)
(reg-reg #b1011001000 argd argm))
(defun $tst (argd argm)
(reg-reg #b0100001000 argd argm))
(defun $uxtb (argd argm)
(reg-reg #b1011001011 argd argm))
(defun $uxth (argd argm)
(reg-reg #b1011001010 argd argm))

53
attiny.lsp Normal file
View File

@ -0,0 +1,53 @@
; The ATtiny database v3 - 9th April 2019
; See http://www.ulisp.com/show?2I60
;
(defvar *data*
'((attinyX5 (pins 8) (io 5) (adc 4) (pwm 3) (usi 1) (timer8 2) (crystal) (pll))
(attiny85 (family attinyx5) (flash 8192) (ram 512) (eeprom 512) (price soic 72) (price pdip 90))
(attiny45 (family attinyx5) (flash 4096) (ram 256) (eeprom 256) (price soic 77) (price pdip 85))
(attiny25 (family attinyx5) (flash 2048) (ram 128) (eeprom 128) (price soic 79) (price pdip 83))
(attinyX4 (pins 14) (io 11) (adc 8) (pwm 4) (usi 1) (timer8 1) (timer16 1) (crystal))
(attiny84 (family attinyX4) (flash 8192) (ram 512) (eeprom 512) (price soic 60) (price pdip 87))
(attiny44 (family attinyX4) (flash 4096) (ram 256) (eeprom 256) (price soic 56) (price pdip 86))
(attiny24 (family attinyX4) (flash 2048) (ram 128) (eeprom 128) (price soic 52) (price pdip 83))
(attinyX313 (pins 20) (io 17) (pwm 3) (uart 1) (usi 1) (timer8 1) (timer16 1) (crystal))
(attiny4313 (family attinyX313) (flash 4096) (ram 256) (eeprom 256) (price soic 70) (price pdip 98))
(attiny2313 (family attinyX313) (flash 2048) (ram 128) (eeprom 128) (price soic 82) (price pdip 99))
(attinyX41 (pins 14) (io 11) (adc 12) (uart 2) (i2c slave) (timer8 1) (timer16 2) (crystal))
(attiny841 (family attinyX41) (flash 8192) (ram 512) (eeprom 512) (price soic 78))
(attiny441 (family attinyX41) (flash 4096) (ram 256) (eeprom 256) (price soic 73))
(attinyX61 (pins 20) (io 15) (adc 11) (pwm 3) (usi 1) (timer8 1) (timer16 1) (crystal) (pll))
(attiny861 (family attinyX61) (flash 8192) (ram 512) (eeprom 512) (price soic 92) (price pdip 110))
(attiny461 (family attinyX61) (flash 4096) (ram 256) (eeprom 256) (price soic 85) (price pdip 129))
(attiny261 (family attinyX61) (flash 2048) (ram 128) (eeprom 128) (price soic 83) (price pdip 107))
(attinyX7 (pins 20) (io 16) (adc 11) (pwm 3) (uart 1) (usi 1) (timer8 1) (timer16 1) (crystal) (lin))
(attiny167 (family attinyX7) (flash 16384) (ram 512) (eeprom 512) (price soic 111))
(attiny87 (family attinyX7) (flash 8192) (ram 512) (eeprom 512) (price soic 124))
(attinyX8 (pins 28) (io 27) (adc 8) (pwm 4) (i2c master) (i2c slave) (usi 1) (timer8 1) (timer16 1))
(attiny88 (family attinyX8) (flash 8192) (ram 512) (eeprom 64) (price tqfp 76) (price pdip 143))
(attiny48 (family attinyX8) (flash 4096) (ram 256) (eeprom 64) (price tqfp 78) (price pdip 131))
(attinyX34 (pins 20) (io 17) (adc 12) (pwm 4) (i2c slave) (uart 2) (usi 1) (timer8 1) (timer16 1) (crystal))
(attiny1634 (family attinyX34) (flash 16384) (ram 1024) (eeprom 256) (price soic 118))
(attinyX28 (pins 32) (io 27) (adc 28) (pwm 4) (i2c slave) (uart 1) (timer8 1) (timer16 1))
(attiny828 (family attinyX28) (flash 8192) (ram 512) (eeprom 512) (price tqfp 84))
(attinyX3 (pins 20) (io 15) (adc 4) (pwm 4) (usi 1) (timer8 1) (timer16 1) (boost))
(attiny43 (family attinyX3) (flash 4096) (ram 512) (eeprom 64) (price soic 147))
(attiny9/10 (pins 6) (io 4) (adc 4) (pwm 2) (timer16 1))
(attiny4/5 (pins 6) (io 4) (pwm 2) (timer16 1))
(attiny10 (family attiny9/10) (flash 1024) (ram 32) (price sot 25))
(attiny9 (family attiny9/10) (flash 512) (ram 32) (price sot 25))
(attiny5 (family attiny4/5) (flash 1024) (ram 32) (price sot 23))
(attiny4 (family attiny4/5) (flash 512) (ram 32) (price sot 27))))

38
bels.lsp Normal file
View File

@ -0,0 +1,38 @@
;
; Ringing the changes
; see http://www.ulisp.com/show?1G42
;
(defvar *bell-pin* 3)
(defun fnd (x lst)
(cond
((null lst) nil)
((< x (car lst)) (car lst))
(t (fnd x (cdr lst)))))
(defun sub (new old lst)
(cond
((null lst) nil)
((eq old (car lst)) (cons new (cdr lst)))
(t (cons (car lst) (sub new old (cdr lst))))))
(defun nxt (lst)
(cond
((not (apply > (cdr lst))) (cons (car lst) (nxt (cdr lst))))
((> (car lst) (cadr lst)) nil)
(t (let* ((rest (reverse (cdr lst)))
(old (fnd (car lst) rest)))
(cons old (sub (car lst) old rest))))))
(defun all (fun lst)
(when lst
(funcall fun lst)
(all fun (nxt lst))))
(defun bel (lis)
(mapc
(lambda (x) (note *bell-pin* x 4) (delay 500) (note) (delay 125))
lis)
(delay 500))

45
edit.lsp Normal file
View File

@ -0,0 +1,45 @@
(defvar *cmds* nil)
(defun %edit (fun)
(cond
((null *cmds*) fun)
((eq (car *cmds*) #\b) (pop *cmds*) fun)
((eq (car *cmds*) #\e) (pop *cmds*) (%edit (list fun)))
((eq (car *cmds*) #\h) (pop *cmds*) (%edit (cons 'highlight (list fun))))
((consp (car *cmds*))
(let ((val (cdar *cmds*)))
(case (caar *cmds*)
(#\r (pop *cmds*) (%edit val))
((#\c #\i) (pop *cmds*) (%edit (cons val fun)))
(#\f (cond
((null fun) nil)
((equal val fun) (pop *cmds*) (%edit fun))
((atom fun) fun)
(t (cons (%edit (car fun)) (%edit (cdr fun)))))))))
((atom fun) (pop *cmds*) (%edit fun))
((eq (car *cmds*) #\d) (pop *cmds*) (%edit (cons (car fun) (%edit (cdr fun)))))
((eq (car *cmds*) #\a) (pop *cmds*) (%edit (cons (%edit (car fun)) (cdr fun))))
((eq (car *cmds*) #\x) (pop *cmds*) (%edit (cdr fun)))
(t fun)))
(defun edit (name)
(let ((fun (eval name))
cc)
(setq *cmds* nil)
(loop
(write-byte 12)
(setq cc (append cc (list #\h)))
(setq *cmds* cc)
(pprint (%edit fun))
(setq cc (butlast cc))
(let ((c (get-key)))
(case c
(#\q (set name fun) (return name))
(#\s (setq *cmds* cc) (set name (%edit fun)) (return name))
(#\z (when cc (setq cc (butlast cc))))
((#\r #\c #\i #\f #\e)
(write-byte 11) (princ c) (princ #\:)
(setq cc (append cc (list (cons c (read))))))
((#\d #\a #\x #\b)
(setq cc (append cc (list c))))
(t (write-byte 7)))))))

100
mand.lsp Normal file
View File

@ -0,0 +1,100 @@
(defun mandelbrot (x0 y0 scale)
(set-rotation 2)
(fill-screen)
(dotimes (y 240)
(let ((b0 (+ (/ (- y 120) 120 scale) y0)))
(dotimes (x 320)
(let* ((a0 (+ (/ (- x 160) 120 scale) x0))
(c 80) (a a0) (b b0) a2)
(loop
(setq a2 (+ (- (* a a) (* b b)) a0))
(setq b (+ (* 2 a b) b0))
(setq a a2)
(decf c)
(when (or (> (+ (* a a) (* b b)) 4) (zerop c)) (return)))
(draw-pixel x y (if (plusp c) (hsv (* 359 (/ c 80)) 1 1) 0)))))))
(defvar fern-cd
#2A((0 0 0 0.25 0 -0.14 0.02)
(0.85 0.02 -0.02 0.83 0 1.0 0.84)
(0.09 -0.28 0.3 0.11 0 0.6 0.07)
(-0.09 0.28 0.3 0.09 0 0.7 0.07)))
(defvar *width* 320)
(defvar *height* 360)
(defvar *factor* (/ *height* 7))
(defvar *x-offset* (/ *width* 2))
(defvar *y-offset* (/ *height* 24))
(defvar *dark-green* #b0000001111100000)
(defvar *fern* fern-cd)
(defun fn (n)
#'(lambda (x y)
(list (+ (* (aref *fern* n 0) x)
(* (aref *fern* n 1) y)
(aref *fern* n 4))
(+ (* (aref *fern* n 2) x)
(* (aref *fern* n 3) y)
(aref *fern* n 5)))))
(defun choose-transform ()
(let ((r (random 1.0)) (p 0))
(dotimes (i 4)
(when (<= r (incf p (aref *fern* i 6)))
(return (fn i))))))
(defun plot-pixel (x y)
(let ((xx (round (+ (* *factor* y) *y-offset*)))
(yy (round (- *width* (+ (* *factor* x) *x-offset*)))))
(draw-pixel xx yy *dark-green*)))
(defun fern (&optional (iterations 50000))
(fill-screen #xFFFF)
(let ((x 0) (y 0))
(dotimes (i iterations)
(plot-pixel x y)
(let ((xy (funcall (choose-transform) x y)))
(setq x (first xy))
(setq y (second xy))))))
(defun sierpinski (x0 y0 size gen)
(when (plusp gen)
(let ((s (ash size -1))
(n (1- gen)))
(fill-rect x0 y0 size size (col gen))
(sierpinski (+ x0 (ash s -1)) y0 s n)
(sierpinski x0 (+ y0 s) s n)
(sierpinski (+ x0 s) (+ y0 s) s n))))
(defun q (n)
(if (<= n 2) 1
(+
(q (- n (q (- n 1))))
(q (- n (q (- n 2)))))))
(defun speedup (fn)
(let ((c nil))
(lambda (x)
(or (cdr (assoc x c))
(let ((r (funcall fn x)))
(setq c (cons (cons x r) c))
r)))))
(setq q (speedup q))
(defun qplot (width height)
(fill-screen)
(let ((x0 0) (y0 0) x1 y1
(yellow #b1111111111100000)
(salmon #b1111110000010000))
(draw-line 10 (- height 10) (1- width) (- height 10))
(draw-line 10 (- height 10) 10 10)
(dotimes (n 6)
(draw-char 0 (- height (* n (truncate height 6)) 14) (code-char (+ n 48)) yellow))
(dotimes (n 10)
(draw-char (+ (* n (truncate width 10)) 12) (- height 7) (code-char (+ n 48)) yellow))
(dotimes (n width)
(setq x1 n y1 (q n))
(draw-line (+ x0 10) (- height y0 10) (+ x1 10) (- height y1 10) salmon)
(setq x0 x1 y0 y1))))

24
pkg.lsp Normal file
View File

@ -0,0 +1,24 @@
(defvar *packages* nil)
(defun load-package (filename)
(let* ((path (concatenate 'string filename ".pkg"))
(forms (load path)))
(setf *packages* (append-to-list
(cons filename forms)
(remove-if (lambda (x)
(string= (car x) filename))
*packages*)))))
(defun save-package (filename lst)
(with-sd-card (str filename 2)
(dolist (f lst)
(symbol-def f str))))
(defun unload-package (package)
(dolist (sym (cdr (assoc package *packages*)))
(makunbound sym)))
(defun add-to-package (filename list)
(with-sd-card (str filename 1)
(dolist (f lst)
(symdef str))))

89
query.lsp Normal file
View File

@ -0,0 +1,89 @@
; uLisp Query Language - 9th April 2019
; See http://www.ulisp.com/show?2I60
;
; Database
(defvar *rules* nil)
(defun add (rule)
(unless (assoc (car rule) *rules*) (push (list (car rule)) *rules*))
(push (cdr rule) (cdr (assoc (car rule) *rules*)))
t)
; Match
(defun match (x y &optional binds)
(cond
((eq x y) (if binds binds '((t))))
((assoc x binds) (match (binding x binds) y binds))
((assoc y binds) (match x (binding y binds) binds))
((var? x) (cons (cons x y) binds))
((var? y) (cons (cons y x) binds))
(t
(when (and (consp x) (consp y))
(let ((m (match (car x) (car y) binds)))
(when m (match (cdr x) (cdr y) m)))))))
(defun var? (x)
(and (symbolp x) (eq (char (string x) 0) #\?)))
(defun binding (x binds)
(let ((b (assoc x binds)))
(when b
(or (binding (cdr b) binds)
(cdr b)))))
; Inference
(defun query (expr &optional binds)
(case (car expr)
(and (query-and (reverse (cdr expr)) binds))
(or (query-or (cdr expr) binds))
(not (query-not (second expr) binds))
(test (query-test (second expr) binds))
(t (lookup (car expr) (cdr expr) binds))))
(defun lookup (pred args &optional binds)
(mapcan
(lambda (x)
(let ((m (match args x binds)))
(when m (list m))))
(cdr (assoc pred *rules*))))
(defun query-and (clauses binds)
(if (null clauses)
(list binds)
(mapcan (lambda (b) (query (car clauses) b))
(query-and (cdr clauses) binds))))
(defun query-or (clauses binds)
(apply 'append (mapcar (lambda (c) (query c binds)) clauses)))
(defun query-not (clause binds)
(unless (query clause binds)
(list binds)))
(defun subs (lst binds)
(cond
((null lst) nil)
((atom lst) (if (assoc lst binds) (cdr (assoc lst binds)) lst))
(t (cons (subs (car lst) binds) (subs (cdr lst) binds)))))
(defun query-test (tst binds)
(when (eval (subs tst binds))
(list binds)))
(defun answer (expr output)
(dolist (binds (query expr nil))
(mapc (lambda (p) (princ p) (princ #\space)) (subs output binds))
(terpri)))
(defun read-data ()
(dolist (rules *data*)
(let ((pred (first rules))
(data (cdr rules)))
(mapc (lambda (rule) (add (cons (first rule) (cons pred (cdr rule))))) data)))
t)

395
r5asm.lsp Normal file
View File

@ -0,0 +1,395 @@
; RISC-V Assembler - Version 4 - 18th October 2024
; see http://www.ulisp.com/show?310Z
;
; Extract register number
(defun regno (sym)
(case sym (zero 0) (ra 1) (sp 2) (gp 3) (tp 4) ((s0 fp) 8) (s1 9)
(t (let* ((s (string sym))
(c (char s 0))
(n (read-from-string (subseq s 1))))
(case c (#\x n) (#\a (+ n 10)) (#\s (+ n 16)) (#\t (if (<= n 2) (+ n 5) (+ n 25))))))))
; Short 3-bit register s0, s1, a0 to a5
(defun cregp (rd) (<= 8 (regno rd) 15))
(defun cregno (sym) (logand (regno sym) #x7))
; Pack arguments into bit fields
(defun emit (bits &rest args)
(let ((word 0))
(mapc #'(lambda (width value)
(unless (zerop (ash value (- width))) (error* "Won't fit"))
(setq word (logior (ash word width) value)))
bits args)
word))
; 32-bit emit
(defun emit32 (bits &rest args)
(let ((word (apply #'emit bits args)))
(list (logand word #xffff) (logand (ash word -16) #xffff))))
; Errors
(defun error* (txt) (format t "(pc=#x~x) ~a~%" *pc* txt))
; Test range of immediate signed values
(defun immp (x b)
(<= (- (ash 1 (1- b))) x (1- (ash 1 (1- b)))))
; Extract bitfield
(defun bits (x a &optional b)
(if b (logand (ash x (- b)) (1- (ash 1 (- a b -1))))
(logand (ash x (- a)) 1)))
(defun offset (label) (- label *pc*))
; Instruction formats
(defun reg (funct7 rs2 rs1 funct3 rd op)
(emit32 '(7 5 5 3 5 7) funct7 (regno rs2) (regno rs1) funct3 (regno rd) op))
(defun creg (op3 op1 op2 rd op2b rs2)
(cond
((and (cregp rd) (cregp rs2))
(emit '(3 1 2 3 2 3 2) op3 op1 op2 (cregno rd) op2b (cregno rs2) 1))
(t (error* "C won't fit"))))
(defun immed (imm12 rs1 funct3 rd op)
(cond
((immp imm12 12)
(emit32 '(12 5 3 5 7) (logand imm12 #xfff) (regno rs1) funct3 (regno rd) op))
(t
(error* "Immediate value out of range"))))
(defun cimmed (imm12 rs1 funct3 rd op)
(emit32 '(12 5 3 5 7) imm12 (regno rs1) funct3 (regno rd) op))
(defun branch (imm12 rs2 rs1 funct3 funct7)
(let ((off (offset imm12)))
(emit32 '(1 6 5 5 3 4 1 7)
(bits off 12) (bits off 10 5) (regno rs2)
(regno rs1) funct3 (bits off 4 1) (bits off 11) funct7)))
(defun jump (imm20 imm10-1 imm11 imm19-12 rd op)
(emit32 '(1 10 1 8 5 7) imm20 imm10-1 imm11 imm19-12 rd op))
(defun muldiv (rs2 rs1 funct3 rd funct7)
(emit32 '(7 5 5 3 5 7) 1 (regno rs2) (regno rs1) funct3 (regno rd) funct7))
(defun store (imm src base op)
(emit32 '(7 5 5 3 5 7) (bits imm 11 5) (regno src) (regno base) op (bits imm 4 0) #x23))
(defun cimm6 (rd imm op1 op2)
(emit '(3 1 5 5 2) op1 (bits imm 5) (regno rd) (bits imm 4 0) op2))
(defun cimm6* (rd imm op1 op2 op3)
(emit '(3 1 2 3 5 2) op1 (bits imm 5) op2 (cregno rd) (bits imm 4 0) op3))
;
; Alphabetical list of mnemonics
;
(defun $add (rd rs1 rs2)
(cond
((eq rd rs1)
(emit '(3 1 5 5 2) 4 1 (regno rd) (regno rs2) 2))
(t (reg 0 rs2 rs1 0 rd #x33))))
(defun $addi (rd rs1 imm)
(cond
((and (eq rd rs1) (immp imm 6))
(cimm6 rd imm 0 1))
((and (= (regno rd) 2) (= (regno rs1) 2) (immp imm 10))
(emit '(3 1 5 1 1 2 1 2) 3 (bits imm 9) 2 (bits imm 4) (bits imm 6) (bits imm 8 7) (bits imm 5) 1))
(t (immed imm rs1 0 rd #x13))))
(defun $and (rd rs1 rs2)
(cond
((and (eq rd rs1) (cregp rd) (cregp rs2))
(creg 4 0 3 rd 3 rs2))
(t (reg 0 rs2 rs1 7 rd #x33))))
(defun $andi (rd rs1 imm)
(cond
((and (eq rd rs1) (cregp rd) (immp imm 5))
(cimm6* rd imm 4 2 1))
(t (immed imm rs1 7 rd #x13))))
(defun $auipc (rd imm)
(cond
((zerop (logand imm #xfff))
(emit32 '(20 5 7) (bits imm 31 12) (regno rd) #x17))
(t (error* "auipc no good"))))
(defun $beq (rs1 rs2 imm12)
(branch imm12 rs2 rs1 0 #x63))
(defun $beqz (rs imm)
(let ((off (offset imm)))
(cond
((and (immp off 8) (cregp rs))
(emit '(3 1 2 3 2 2 1 2) 6 (bits off 8) (bits off 4 3)
(cregno rs) (bits off 7 6) (bits off 2 1) (bits off 5) 1))
(t ($beq rs 'x0 imm)))))
(defun $bge (rs1 rs2 imm12)
(branch imm12 rs2 rs1 5 #x63))
(defun $bgeu (rs1 rs2 imm12)
(branch imm12 rs2 rs1 7 #x63))
(defun $bgez (rs1 imm12)
($bge rs1 'x0 imm12))
(defun $bgt (rs1 rs2 imm12)
($blt rs2 rs1 imm12))
(defun $bgtu (rs1 rs2 imm12)
($bltu rs2 rs1 imm12))
(defun $bgtz (rs1 imm12)
($blt 'x0 rs1 imm12))
(defun $ble (rs1 rs2 imm12)
($bge rs2 rs1 imm12))
(defun $bleu (rs1 rs2 imm12)
($bgeu rs2 rs1 imm12))
(defun $blez (rs2 imm12)
($bge 'x0 rs2 imm12))
(defun $blt (rs1 rs2 imm12)
(branch imm12 rs2 rs1 4 #x63))
(defun $bltu (rs1 rs2 imm12)
(branch imm12 rs2 rs1 6 #x63))
(defun $bltz (rs1 imm12)
($blt rs1 'x0 imm12))
(defun $bne (rs1 rs2 imm12)
(branch imm12 rs2 rs1 1 #x63))
(defun $bnez (rs imm)
(let ((off (offset imm)))
(cond
((and (immp off 8) (cregp rs))
(emit '(3 1 2 3 2 2 1 2) 7 (bits off 8) (bits off 4 3)
(cregno rs) (bits off 7 6) (bits off 2 1) (bits off 5) 1))
(t ($bne rs 'x0 imm)))))
(defun $div (rd rs1 rs2)
(muldiv rs2 rs1 4 rd #x33))
(defun $divu (rd rs1 rs2)
(muldiv rs2 rs1 5 rd #x33))
(defun $divw (rd rs1 rs2)
(muldiv rs2 rs1 4 rd #x3b))
(defun $divuw (rd rs1 rs2)
(muldiv rs2 rs1 5 rd #x3b))
(defun $fence () (emit32 '(16 16) #x0ff0 #x000f))
(defun $j (label)
(let ((off (offset label)))
(emit '(3 1 1 2 1 1 1 3 1 2) 5 (bits off 11) (bits off 4) (bits off 9 8)
(bits off 10) (bits off 6) (bits off 7) (bits off 3 1) (bits off 5) 1)))
; C.JAL is RV32 only
(defun $jal (rd &optional label)
(when (null label) (setq label rd rd 'ra))
(let ((off (offset label)))
(emit32 '(1 10 1 8 5 7) (bits off 20) (bits off 10 1) (bits off 11) (bits off 19 12) (regno rd) #x6f)))
(defun $jalr (label lst)
(let ((off (+ (offset label) 4)))
(emit32 '(12 5 3 5 7) (bits off 11 0) (regno (car lst)) 0 (regno (car lst)) #x67)))
(defun $jr (rs1)
(emit '(3 1 5 5 2) 4 0 (regno rs1) 0 2))
; In next four, imm can be omitted and defaults to 0
(defun $lb (rd imm &optional lst)
(unless lst (setq lst imm imm 0))
(immed imm (car lst) 0 rd 3))
(defun $lbu (rd imm &optional lst)
(unless lst (setq lst imm imm 0))
(immed imm (car lst) 4 rd 3))
(defun $lh (rd imm &optional lst)
(unless lst (setq lst imm imm 0))
(immed imm (car lst) 1 rd 3))
(defun $lhu (rd imm &optional lst)
(unless lst (setq lst imm imm 0))
(immed imm (car lst) 5 rd 3))
; li pseudoinstruction - will load 32-bit immediates
(defun $li (rd imm)
(cond
((immp imm 6) ; 16 bit
(cimm6 rd imm 2 1))
((immp imm 12) ; 32 bit
($addi rd 'x0 imm))
(t (let ((imm12 (logand imm #x00000fff)) ; 64 bit
(imm20 (logand (ash imm -12) #xfffff)))
(append
($lui rd (if (= (logand imm12 #x800) #x800) (+ imm20 #x1000) imm20))
; $addi
(emit32 '(12 5 3 5 7) imm12 (regno rd) 0 (regno rd) #x13))))))
(defun $lui (rd imm)
(cond
((and (immp imm 6) (/= imm 0) (/= (regno rd) 0) (/= (regno rd) 2)) ; 16 bit
(cimm6 rd imm 3 1))
(t
(emit32 '(20 5 7) imm (regno rd) #x37))
(t (error* "lui no good"))))
(defun $lw (rd imm lst)
(cond
((listp lst)
(let ((base (car lst)))
(cond
; rs1 = sp
((and (= (regno base) 2))
(emit '(3 1 5 3 2 2) 2 (bits imm 5) (regno rd) (bits imm 4 2) (bits imm 7 6) 2))
; rs1 = general
((and (cregp rd) (cregp base))
(emit '(3 3 3 1 1 3 2) 2 (bits imm 5 3) (cregno base) (bits imm 2) (bits imm 6) (cregno rd) 0))
(t (immed imm base 2 rd 3)))))
(t (error* "Illegal 3rd arg"))))
(defun $mul (rd rs1 rs2)
(muldiv rs2 rs1 0 rd #x33))
(defun $mulh (rd rs1 rs2)
(muldiv rs2 rs1 1 rd #x33))
(defun $mulhsu (rd rs1 rs2)
(muldiv rs2 rs1 2 rd #x33))
(defun $mulhu (rd rs1 rs2)
(muldiv rs2 rs1 3 rd #x33))
(defun $mv (rd rs1)
(emit '(3 1 5 5 2) 4 0 (regno rd) (regno rs1) 2))
(defun $neg (rd rs2)
($sub rd 'x0 rs2))
(defun $nop ()
($addi 'x0 'x0 0))
(defun $not (rd rs1)
($xori rd rs1 -1))
(defun $or (rd rs1 rs2)
(cond
((and (eq rd rs1) (cregp rd) (cregp rs2))
(creg 4 0 3 rd 2 rs2))
(t (reg 0 rs2 rs1 6 rd #x33))))
(defun $ori (rd rs1 imm)
(immed imm rs1 6 rd #x13))
(defun $rem (rd rs1 rs2)
(muldiv rs2 rs1 6 rd #x33))
(defun $remu (rd rs1 rs2)
(muldiv rs2 rs1 7 rd #x33))
(defun $ret ()
($jr 'ra))
; In $sb, $sh, and $sw, imm can be omitted and defaults to 0
(defun $sb (src imm &optional lst)
(unless lst (setq lst imm imm 0))
(store imm src (car lst) 0))
(defun $seqz (rd rs1)
($sltiu rd rs1 1))
(defun $sgtz (rd rs2)
($slt rd 'x0 rs2))
(defun $sh (src imm &optional lst)
(unless lst (setq lst imm imm 0))
(store imm src (car lst) 1))
(defun $sll (rd rs1 rs2)
(reg 0 rs2 rs1 1 rd #x33))
(defun $slli (rd rs1 imm)
(cond
((and (eq rd rs1))
(cimm6 rd imm 0 2))
(t (emit32 '(6 6 5 3 5 7) 0 imm (regno rs1) 1 (regno rd) #x13))))
(defun $slt (rd rs1 rs2)
(reg 0 rs2 rs1 2 rd #x33))
(defun $slti (rd rs1 imm)
(immed imm rs1 2 rd #x13))
(defun $sltiu (rd rs1 imm)
(immed imm rs1 3 rd #x13))
(defun $sltu (rd rs1 rs2)
(reg 0 rs2 rs1 3 rd #x33))
(defun $sltz (rd rs1)
($slt rd rs1 'x0))
(defun $snez (rd rs2)
($sltu rd 'x0 rs2))
(defun $sra (rd rs1 rs2)
(reg #x20 rs2 rs1 2 rd #x33))
(defun $srai (rd rs1 imm)
(cond
((and (eq rd rs1) (cregp rd))
(cimm6* rd imm 4 1 1))
(t (emit32 '(6 6 5 3 5 7) #x10 imm (regno rs1) 5 (regno rd) #x13))))
(defun $srl (rd rs1 rs2)
(reg 0 rs2 rs1 5 rd #x33))
(defun $srli (rd rs1 imm)
(cond
((and (eq rd rs1) (cregp rd))
(cimm6* rd imm 4 0 1))
(t (emit32 '(6 6 5 3 5 7) 0 imm (regno rs1) 5 (regno rd) #x13))))
(defun $sub (rd rs1 rs2)
(cond
((and (eq rd rs1) (cregp rd) (cregp rs2))
(creg 4 0 3 rd 0 rs2))
(t (reg #x20 rs2 rs1 0 rd #x33))))
(defun $sw (src imm &optional lst)
(unless lst (setq lst imm imm 0))
(let ((base (car lst)))
(cond
; base = sp
((and (= (regno base) 2))
(emit '(3 4 2 5 2) 6 (bits imm 5 2) (bits imm 7 6) (regno src) 2))
; base = general
((and (cregp src) (cregp base))
(emit '(3 3 3 1 1 3 2) 6 (bits imm 5 3) (cregno base) (bits imm 2) (bits imm 6) (cregno src) 0))
(t (store imm src base 2)))))
(defun $xor (rd rs1 rs2)
(cond
((and (eq rd rs1) (cregp rd) (cregp rs2))
(creg 4 0 3 rd 1 rs2))
(t (reg 0 rs2 rs1 4 rd #x33))))
(defun $xori (rd rs1 imm)
(immed imm rs1 4 rd #x13))

161
r5asmpi.lsp Normal file
View File

@ -0,0 +1,161 @@
; RISC-V Assembler extensions for RP2350 - Version 1 - 18th October 2024
; see http://www.ulisp.com/show?4Y5E
;
; Instruction formats
(defun bit13 (op1 op2 rs1 op3 rd)
(emit32 '(7 5 5 3 5 7) op1 op2 (regno rs1) op3 (regno rd) #x13))
(defun bitimm5 (op1 imm5 rs1 op2 rd)
(emit32 '(7 5 5 3 5 7) op1 (logand imm5 #x1f) (regno rs1) op2 (regno rd) #x13))
; Additional compressed formats
(defun $mul (rd rs1 rs2)
(cond
((and (eq rd rs1) (cregp rd) (cregp rs2))
(emit '(3 3 3 2 3 2) 4 7 (cregno rd) 2 (cregno rs2) 1))
(t (muldiv rs2 rs1 0 rd #x33))))
(defun $sb (src imm &optional lst)
(unless lst (setq lst imm imm 0))
(cond
((and (cregp src) (cregp (car lst)) (<= 0 imm 3))
(emit '(3 3 3 1 1 3 2) 4 2 (cregno (car lst)) (bits imm 0) (bits imm 1) (cregno src) 0))
(t (store imm src (car lst) 0))))
(defun $sh (src imm &optional lst)
(unless lst (setq lst imm imm 0))
(cond
((and (cregp src) (cregp (car lst)) (or (= imm 0) (= im 2))
(emit '(3 3 3 1 1 3 2) 4 3 (cregno (car lst)) 0 (bits imm 1) (cregno src) 0))
(t (store imm src (car lst) 1)))))
; Add compressed formats to $lbu, $lh, and $lhu. No $lb compressed format
(defun $lbu (rd imm &optional lst)
(unless lst (setq lst imm imm 0))
(cond
((and (cregp rd) (cregp (car lst)) (<= 0 imm 3))
(emit '(3 3 3 1 1 3 2) 4 0 (cregno (car lst)) (bits imm 0) (bits imm 1) (cregno rd) 0))
(t (immed imm (car lst) 4 rd 3))))
(defun $lh (rd imm &optional lst)
(unless lst (setq lst imm imm 0))
(cond
((and (cregp rd) (cregp (car lst)) (or (= imm 0) (= im 2))
(emit '(3 3 3 1 1 3 2) 4 1 (cregno (car lst)) 1 (bits imm 1) (cregno rd) 0))
(t (immed imm (car lst) 1 rd 3)))))
(defun $lhu (rd imm &optional lst)
(unless lst (setq lst imm imm 0))
(cond
((and (cregp rd) (cregp (car lst)) (or (= imm 0) (= im 2))
(emit '(3 3 3 1 1 3 2) 4 1 (cregno (car lst)) 0 (bits imm 1) (cregno rd) 0))
(t (immed imm (car lst) 5 rd 3)))))
(defun $xori (rd rs1 imm)
(cond
((and (eq rd rs1) (cregp rd) (= imm -1))
(emit '(3 3 3 2 3 2) 4 7 (cregno rd) 3 5 1))
(t (immed imm rs1 4 rd #x13))))
; New instructions
(defun $andn (rd rs1 rs2)
(reg #x20 rs2 rs1 3 rd #x33))
(defun $bclr (rd rs1 rs2)
(reg #x24 rs2 rs1 1 rd #x33))
(defun $bclri (rd rs1 imm5)
(bitimm5 #x24 imm5 rs1 1 rd))
(defun $bext (rd rs1 rs2)
(reg #x24 rs2 rs1 5 rd #x33))
(defun $bexti (rd rs1 imm5)
(bitimm5 #x24 imm5 rs1 5 rd))
(defun $binv (rd rs1 rs2)
(reg #x34 rs2 rs1 1 rd #x33))
(defun $binvi (rd rs1 imm5)
(bitimm5 #x34 imm5 rs1 1 rd))
(defun $brev8 (rd rs1)
(bit13 #x34 7 rs1 5 rd))
(defun $bset (rd rs1 rs2)
(reg #x14 rs2 rs1 1 rd #x33))
(defun $bseti (rd rs1 imm5)
(bitimm5 #x14 imm5 rs1 1 rd))
(defun $clz (rd rs1)
(bit13 #x30 0 rs1 1 rd))
(defun $cpop (rd rs1)
(bit13 #x30 2 rs1 1 rd))
(defun $ctz (rd rs1)
(bit13 #x30 1 rs1 1 rd))
(defun $max (rd rs1 rs2)
(reg #x05 rs2 rs1 6 rd #x33))
(defun $maxu (rd rs1 rs2)
(reg #x05 rs2 rs1 7 rd #x33))
(defun $min (rd rs1 rs2)
(reg #x05 rs2 rs1 4 rd #x33))
(defun $minu (rd rs1 rs2)
(reg #x05 rs2 rs1 5 rd #x33))
(defun $orc.b (rd rs1)
(bit13 #x14 7 rs1 5 rd))
(defun $orn (rd rs1 rs2)
(reg #x20 rs2 rs1 5 rd #x33))
(defun $pack (rd rs1 rs2)
(reg #x04 rs2 rs1 4 rd #x33))
(defun $packh (rd rs1 rs2)
(reg #x04 rs2 rs1 7 rd #x33))
(defun $rev8 (rd rs1)
(bit13 #x34 #x18 rs1 5 rd))
(defun $rol (rd rs1 rs2)
(reg #x30 rs2 rs1 1 rd #x33))
(defun $ror (rd rs1 rs2)
(reg #x30 rs2 rs1 5 rd #x33))
(defun $rori (rd rs1 imm5)
(bitimm5 #x30 imm5 rs1 5 rd))
(defun $sext.b (rd rs1)
(bit13 #x30 #x04 rs1 1 rd))
(defun $sext.h (rd rs1)
(bit13 #x30 #x05 rs1 1 rd))
(defun $unzip (rd rs1)
(bit13 #x04 #x0f rs1 5 rd))
(defun $xnor (rd rs1 rs2)
(reg #x20 rs2 rs1 4 rd #x33))
(defun $zext.b (rd rs1)
($andi rd rs1 #xff)))
(defun $zext.h (rd rs1)
(emit32 '(7 5 5 3 5 7) #x04 0 (regno rs1) 4 (regno rd) #x33))
(defun $zip (rd rs1)
(bit13 #x04 #x0f rs1 1 rd))

57
rtc.lsp Normal file
View File

@ -0,0 +1,57 @@
(defvar *rtc-port* 0)
(defun bcd-to-dec (x)
"(bcd-to-dec x)
Convert the BCD-encoded number x to a decimal value."
(+
(* 10 (ash x -4))
(logand x #xf)))
(defun dec-to-bcd (x)
"(dec-to-bcd x)
Converts the decimal value to a BCD-encoded number.
Number must be in the range 0 to 99."
(+
(ash (floor x 10) 4)
(logand (rem x 10) #xf)))
(defun rtc-p ()
"(rtc-p)
Returns t if the RTC is connected."
(with-i2c (str *rtc-port* #x68)
(streamp str)))
(defun rtc-set (h m s)
"(rtc-set hr min sec)
Set the time on a DS3231 RTC. Times are in BCD, so use
the appropriate reader macro, e.g. (rtc-set #x12 #x34 #x00)
for 12:34:00."
(let ((h (dec-to-bcd h))
(m (dec-to-bcd m))
(s (dec-to-bcd s)))
(with-i2c (str *rtc-port* #x68)
(write-byte 0 str)
(write-byte s str)
(write-byte m str)
(write-byte h str))))
(defun rtc-get ()
(with-i2c (str *rtc-port* #x68)
(write-byte 0 str)
(restart-i2c str 3)
(mapcar bcd-to-dec
(reverse
(list
(read-byte str)
(read-byte str)
(read-byte str))))))
(defun rtc-now ()
"(rtc-now)
Set the time using the RTC."
(apply now (rtc-get)))
(defun now-rtc ()
"(now-rtc)
Sets the RTC time using the now function."
(apply rtc-set (now)))

22
sync.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
if [ "$(uname -s)" = "Linux" ]
then
DEFAULT_MOUNT="/media/kyle/ULISP"
else
DEFAULT_MOUNT="/Volumes/ULISP"
fi
MEDIA="${1:-${DEFAULT_MOUNT}}"
if [ ! -d "${MEDIA}" ]
then
echo "[!] ${MEDIA} isn't mounted!"
exit 1
fi
echo "[+] transferring lisp files to ${MEDIA}..."
cp *.lsp "$MEDIA"
echo "[+] unmounting ${MEDIA}"
umount "$MEDIA"
echo "[+] transfer complete"

86
tak.lsp Normal file
View File

@ -0,0 +1,86 @@
(defun tak (x y z)
(if (not (< y x))
z
(tak
(tak (1- x) y z)
(tak (1- y) z x)
(tak (1- z) x y))))
(defun benchmark-tak ()
(tak 18 12 6))
(defun fib (n)
(if (< n 3) 1
(+ (fib (- n 1)) (fib (- n 2)))))
(defun benchmark-fib ()
(fib 23))
(defun q (n)
(if (<= n 2) 1
(+
(q (- n (q (- n 1))))
(q (- n (q (- n 2)))))))
(defun benchmark-q ()
(q 21))
(defun q2 (x y)
(if (or (< x 1) (< y 1)) 1
(+ (q2 (- x (q2 (1- x) y)) y)
(q2 x (- y (q2 x (1- y)))))))
(defun benchmark-q2 ()
(q2 7 8))
(defun factor (n)
(cond
((zerop (mod n 2)) 2)
((zerop (mod n 3)) 3)
(t (let ((d 5) (i 2))
(loop
(when (> (* d d) n) (return n))
(when (zerop (mod n d)) (return d))
(incf d i) (setq i (- 6 i)))))))
(defvar *factor-prime* 2142142141)
(defun benchmark-factor ()
(factor *factor-prime*))
(defun sieve (size)
(let ((a (make-array size :element-type 'bit))
max)
(setf (aref a 0) 1 (aref a 1) 1)
(dotimes (i size max)
(when (zerop (aref a i))
(setq max i)
(do ((j (* 2 i) (+ j i))) ((>= j size)) (setf (aref a j) 1))))))
(defun benchmark-sieve ()
(sieve 100000))
(defun benchmark-check (fun expected)
(let ((answer (fun)))
(unless (eq answer expected)
(error "benchmark failed: have ~a, expected ~a~%"
answer
expected)
t)))
(defun benchmark-time-it (fun expected)
(time (benchmark-check fun expected)))
(defun benchmark ()
(print '(tak 18 12 6))
(benchmark-time-it benchmark-tak 7)
(print '(fib 23))
(benchmark-time-it benchmark-fib 28657)
(print '(q 21))
(benchmark-time-it benchmark-q 12)
(print '(q2 7 8))
(benchmark-time-it benchmark-q2 31)
(print '(factor 2142142141))
(benchmark-time-it benchmark-factor *factor-prime*)
(print '(sieve 100000))
(benchmark-time-it benchmark-sieve 99991))

30
tools.lsp Normal file
View File

@ -0,0 +1,30 @@
(defun pprintf (sym str)
"(pprintf sym str)
Pretty-print the function pointed to by sym to
the stream, which follows the 'format directives."
(let ((form (eval sym)))
(format str "(defun ~a ~a~%~{ ~a~^~%~})"
(string sym)
(cadr form)
(cddr form))))
(defun copy-file (source dest)
(with-sd-card (writer dest 2)
(with-sd-card (reader source)
(loop
(let ((data (read-byte reader)))
(when (null data)
(return))
(write-byte data writer))))))
(defun i2c-scan (port)
(dotimes (addr 127)
(with-i2c (str port addr)
(when str (print addr)))))
(defun i2c-scan2 (port)
(dotimes (addr 127)
(with-i2c (str port addr)
(format t "~,20'x: " addr)
(if str (print t)
(print nil)))))

26
ulos.lsp Normal file
View File

@ -0,0 +1,26 @@
;
; ULOS simple object system
; see http://forum.ulisp.com/t/a-simple-object-system-for-ulisp/622
;
; Define an object
(defun object (&optional parent slots)
(let ((obj (when parent (list (cons 'parent parent)))))
(loop
(when (null slots) (return obj))
(push (cons (first slots) (second slots)) obj)
(setq slots (cddr slots)))))
; Get the value of a slot in an object or its parents
(defun value (obj slot)
(when (symbolp obj) (setq obj (eval obj)))
(let ((pair (assoc slot obj)))
(if pair (cdr pair)
(let ((p (cdr (assoc 'parent obj))))
(and p (value p slot))))))
; Update a slot in an object
(defun update (obj slot value)
(when (symbolp obj) (setq obj (eval obj)))
(let ((pair (assoc slot obj)))
(when pair (setf (cdr pair) value))))

34
wifi.lsp Normal file
View File

@ -0,0 +1,34 @@
(defvar *http-use-tls* t)
(defun toggle-http-tls ()
(setf *http-use-tls* (not *http-use-tls*)))
(defun get-http-port ()
(if *http-use-tls* 443 8000))
(defun wifi-dial ()
(wifi-connect *wifi-ssid* *wifi-password*))
(defun curl (host url)
(let ((println #'(lambda (x s) (format s "~a~a~%" x #\return))))
(with-client (s host (get-http-port))
(println (format nil "GET ~a HTTP/1.0" url) s)
(println (format nil "Host: ~a" host) s)
(println "Connection: close" s)
(println "" s)
(loop (unless (zerop (available s)) (return)))
(loop
(delay 100)
(when (zerop (available s)) (return))
(princ (read-line s))
(terpri)))))
(defun nc-read (host port)
(with-client (s host port)
(loop (unless (zerop (available s)) (return)))
(loop
(delay 100)
(when (zerop (available s)) (return))
(princ (read-line s))
(terpri))))