2020-05-22 01:09:02 +03:00
|
|
|
;; Inspired by:
|
|
|
|
;; https://github.com/gambit/gambit/blob/master/gsc/_t-x86.scm#L1106 #L1160
|
|
|
|
(define (blodwen-os)
|
|
|
|
(cond
|
2023-11-11 07:39:27 +03:00
|
|
|
((memq (cadr (system-type)) '(apple)) "darwin")
|
|
|
|
((memq (caddr (system-type)) '(linux-gnu)) "unix")
|
|
|
|
((memq (caddr (system-type)) '(mingw32 mingw64)) "windows")
|
|
|
|
(else "unknown")))
|
2020-05-22 01:09:02 +03:00
|
|
|
|
2020-05-18 16:55:43 +03:00
|
|
|
;; TODO Convert to macro
|
|
|
|
(define (blodwen-read-args desc)
|
|
|
|
(if (fx= (vector-ref desc 0) 0)
|
|
|
|
'()
|
|
|
|
(cons (vector-ref desc 2)
|
|
|
|
(blodwen-read-args (vector-ref desc 3)))))
|
|
|
|
|
2021-09-08 18:46:19 +03:00
|
|
|
(define blodwen-lazy
|
|
|
|
(lambda (f)
|
2023-11-11 07:39:27 +03:00
|
|
|
(let ((evaluated #f) (res void))
|
2021-09-08 18:46:19 +03:00
|
|
|
(lambda ()
|
|
|
|
(if (not evaluated)
|
|
|
|
(begin (set! evaluated #t)
|
|
|
|
(set! res (f))
|
|
|
|
(set! f void))
|
|
|
|
(void))
|
|
|
|
res))))
|
|
|
|
|
2024-08-06 17:24:57 +03:00
|
|
|
(define (blodwen-delay-lazy f)
|
|
|
|
f)
|
|
|
|
|
|
|
|
(define (blodwen-force-lazy f)
|
|
|
|
(f))
|
|
|
|
|
2021-11-17 14:54:19 +03:00
|
|
|
(define (blodwen-toSignedInt x bits)
|
|
|
|
(if (bit-set? bits x)
|
|
|
|
(bitwise-ior x (arithmetic-shift -1 bits))
|
|
|
|
(bitwise-and x (- (arithmetic-shift 1 bits) 1))))
|
2021-05-04 10:22:06 +03:00
|
|
|
|
2021-11-17 14:54:19 +03:00
|
|
|
(define (blodwen-toUnsignedInt x bits)
|
|
|
|
(bitwise-and x (sub1 (arithmetic-shift 1 bits))))
|
2021-05-04 10:22:06 +03:00
|
|
|
|
2022-03-03 07:55:22 +03:00
|
|
|
(define (blodwen-euclidDiv a b)
|
|
|
|
(let ((q (quotient a b))
|
|
|
|
(r (remainder a b)))
|
|
|
|
(if (< r 0)
|
|
|
|
(if (> b 0) (- q 1) (+ q 1))
|
|
|
|
q)))
|
|
|
|
|
|
|
|
(define (blodwen-euclidMod a b)
|
|
|
|
(let ((r (remainder a b)))
|
|
|
|
(if (< r 0)
|
|
|
|
(if (> b 0) (+ r b) (- r b))
|
|
|
|
r)))
|
|
|
|
|
2021-05-04 10:22:06 +03:00
|
|
|
(define bu+ (lambda (x y bits) (blodwen-toUnsignedInt (+ x y) bits)))
|
|
|
|
(define bu- (lambda (x y bits) (blodwen-toUnsignedInt (- x y) bits)))
|
|
|
|
(define bu* (lambda (x y bits) (blodwen-toUnsignedInt (* x y) bits)))
|
|
|
|
(define bu/ (lambda (x y bits) (blodwen-toUnsignedInt (quotient x y) bits)))
|
|
|
|
|
|
|
|
(define bs+ (lambda (x y bits) (blodwen-toSignedInt (+ x y) bits)))
|
|
|
|
(define bs- (lambda (x y bits) (blodwen-toSignedInt (- x y) bits)))
|
|
|
|
(define bs* (lambda (x y bits) (blodwen-toSignedInt (* x y) bits)))
|
2022-03-03 07:55:22 +03:00
|
|
|
(define bs/ (lambda (x y bits) (blodwen-toSignedInt (blodwen-euclidDiv x y) bits)))
|
2021-05-04 10:22:06 +03:00
|
|
|
|
2021-11-17 14:54:19 +03:00
|
|
|
; To match Chez
|
|
|
|
(define (add1 x) (+ x 1))
|
|
|
|
(define (sub1 x) (- x 1))
|
2022-01-30 02:20:00 +03:00
|
|
|
(define (fxadd1 x) (fx+ x 1))
|
2021-11-17 14:54:19 +03:00
|
|
|
(define (fxsub1 x) (fx- x 1))
|
2020-05-18 16:55:43 +03:00
|
|
|
|
2021-11-17 14:54:19 +03:00
|
|
|
(define (integer->bits8 x) (bitwise-and x #xff))
|
|
|
|
(define (integer->bits16 x) (bitwise-and x #xffff))
|
|
|
|
(define (integer->bits32 x) (bitwise-and x #xffffffff))
|
|
|
|
(define (integer->bits64 x) (bitwise-and x #xffffffffffffffff))
|
2020-06-01 03:45:15 +03:00
|
|
|
|
2021-11-17 14:54:19 +03:00
|
|
|
(define (bits16->bits8 x) (bitwise-and x #xff))
|
|
|
|
(define (bits32->bits8 x) (bitwise-and x #xff))
|
|
|
|
(define (bits64->bits8 x) (bitwise-and x #xff))
|
|
|
|
(define (bits32->bits16 x) (bitwise-and x #xffff))
|
|
|
|
(define (bits64->bits16 x) (bitwise-and x #xffff))
|
|
|
|
(define (bits64->bits32 x) (bitwise-and x #xffffffff))
|
2020-08-20 17:01:09 +03:00
|
|
|
|
2021-03-04 23:59:56 +03:00
|
|
|
(define blodwen-bits-shl-signed
|
2021-06-04 12:35:07 +03:00
|
|
|
(lambda (x y bits) (blodwen-toSignedInt (arithmetic-shift x y) bits)))
|
2021-03-04 23:59:56 +03:00
|
|
|
|
|
|
|
|
2020-05-18 16:55:43 +03:00
|
|
|
(define-macro (blodwen-and . args) `(bitwise-and ,@args))
|
|
|
|
(define-macro (blodwen-or . args) `(bitwise-ior ,@args))
|
|
|
|
(define-macro (blodwen-xor . args) `(bitwise-xor ,@args))
|
2020-06-01 03:45:15 +03:00
|
|
|
(define-macro (blodwen-bits-shl x y bits)
|
|
|
|
`(remainder (arithmetic-shift ,x ,y)
|
2021-02-10 04:00:42 +03:00
|
|
|
(arithmetic-shift 1 ,bits)))
|
2020-05-18 16:55:43 +03:00
|
|
|
(define-macro (blodwen-shl x y) `(arithmetic-shift ,x ,y))
|
|
|
|
(define-macro (blodwen-shr x y) `(arithmetic-shift ,x (- ,y)))
|
|
|
|
|
|
|
|
(define-macro (exact-floor x)
|
|
|
|
(let ((s (gensym)))
|
|
|
|
`(let ((,s ,x))
|
|
|
|
(if (flonum? ,s) (##flonum->exact-int ,s) (##floor ,s)))))
|
|
|
|
|
2021-05-04 10:22:06 +03:00
|
|
|
(define exact-truncate
|
|
|
|
(lambda (x)
|
|
|
|
(inexact->exact (truncate x))))
|
|
|
|
|
|
|
|
(define exact-truncate-boundedInt
|
|
|
|
(lambda (x y)
|
|
|
|
(blodwen-toSignedInt (exact-truncate x) y)))
|
|
|
|
|
|
|
|
(define exact-truncate-boundedUInt
|
|
|
|
(lambda (x y)
|
|
|
|
(blodwen-toUnsignedInt (exact-truncate x) y)))
|
|
|
|
|
|
|
|
(define cast-char-boundedInt
|
|
|
|
(lambda (x y)
|
|
|
|
(blodwen-toSignedInt (char->integer x) y)))
|
|
|
|
|
|
|
|
(define cast-char-boundedUInt
|
|
|
|
(lambda (x y)
|
|
|
|
(blodwen-toUnsignedInt (char->integer x) y)))
|
|
|
|
|
|
|
|
(define cast-string-boundedInt
|
|
|
|
(lambda (x y)
|
|
|
|
(blodwen-toSignedInt (cast-string-int x) y)))
|
|
|
|
|
|
|
|
(define cast-string-boundedUInt
|
|
|
|
(lambda (x y)
|
|
|
|
(blodwen-toUnsignedInt (cast-string-int x) y)))
|
|
|
|
|
2020-05-18 16:55:43 +03:00
|
|
|
;; TODO Convert to macro
|
|
|
|
(define (cast-string-double x)
|
|
|
|
(define (cast-num x)
|
|
|
|
(if (number? x) x 0))
|
|
|
|
(define (destroy-prefix x)
|
|
|
|
(if (or (string=? x "") (char=? (string-ref x 0) #\#)) "" x))
|
2022-05-08 02:07:28 +03:00
|
|
|
(exact->inexact (cast-num (string->number (destroy-prefix x)))))
|
|
|
|
|
2020-05-18 16:55:43 +03:00
|
|
|
|
|
|
|
(define-macro (cast-string-int x)
|
2021-05-04 10:22:06 +03:00
|
|
|
`(exact-truncate (cast-string-double ,x)))
|
2020-05-18 16:55:43 +03:00
|
|
|
|
2020-08-25 14:30:57 +03:00
|
|
|
(define-macro (string-pack xs)
|
2023-11-11 07:39:27 +03:00
|
|
|
`(apply string ,xs))
|
|
|
|
|
|
|
|
(define (string-unpack s) (string->list s))
|
2020-09-19 15:36:57 +03:00
|
|
|
(define-macro (string-concat xs)
|
2023-11-11 07:39:27 +03:00
|
|
|
`(apply string-append ,xs))
|
2020-08-25 14:30:57 +03:00
|
|
|
|
2020-05-18 16:55:43 +03:00
|
|
|
(define-macro (string-cons x y)
|
|
|
|
`(string-append (string ,x) ,y))
|
|
|
|
|
|
|
|
(define-macro (string-reverse x)
|
|
|
|
`(list->string (reverse! (string->list ,x))))
|
|
|
|
|
|
|
|
;; TODO Convert to macro
|
|
|
|
(define (string-substr off len s)
|
|
|
|
(let* ((start (fxmax 0 off))
|
|
|
|
(end (fxmin (fx+ start (fxmax 0 len))
|
|
|
|
(string-length s))))
|
|
|
|
(substring s start end)))
|
|
|
|
|
|
|
|
(define-macro (get-tag x) `(vector-ref ,x 0))
|
|
|
|
|
2020-09-19 22:54:34 +03:00
|
|
|
(define (blodwen-string-iterator-new s)
|
2020-09-20 10:56:58 +03:00
|
|
|
0)
|
2020-09-19 22:54:34 +03:00
|
|
|
|
2020-12-31 20:36:07 +03:00
|
|
|
(define (blodwen-string-iterator-to-string _ s ofs f)
|
|
|
|
(f (substring s ofs (string-length s))))
|
|
|
|
|
2020-09-20 10:56:58 +03:00
|
|
|
(define (blodwen-string-iterator-next s ofs)
|
|
|
|
(if (>= ofs (string-length s))
|
|
|
|
(vector 0) ; EOF
|
|
|
|
(vector 1 (string-ref s ofs) (+ ofs 1))))
|
2020-09-19 22:54:34 +03:00
|
|
|
|
2020-05-18 16:55:43 +03:00
|
|
|
;; These two are only used in this file
|
|
|
|
(define-macro (either-left x) `(vector 0 ,x))
|
|
|
|
(define-macro (either-right x) `(vector 1 ,x))
|
|
|
|
|
|
|
|
(define-macro (blodwen-error-quit msg)
|
|
|
|
`(begin
|
|
|
|
(display ,msg)
|
|
|
|
(newline)
|
|
|
|
(exit 1)))
|
|
|
|
|
|
|
|
(define (blodwen-get-line p)
|
|
|
|
(if (input-port? p)
|
|
|
|
(let ((str (read-line p)))
|
|
|
|
(if (eof-object? str) "" str))
|
|
|
|
""))
|
|
|
|
|
|
|
|
(define (blodwen-get-char p)
|
|
|
|
(if (input-port? p)
|
|
|
|
(let ((chr (read-char p)))
|
|
|
|
(if (eof-object? chr) #\nul chr))
|
|
|
|
#\nul))
|
|
|
|
|
|
|
|
;; Threads
|
|
|
|
|
|
|
|
(define (blodwen-thread p)
|
|
|
|
(thread-start! (make-thread (lambda () (p '#(0))))))
|
|
|
|
|
|
|
|
(define (blodwen-get-thread-data ty)
|
|
|
|
(let ((data (thread-specific (current-thread))))
|
|
|
|
(if (eq? data #!void) #f data)))
|
|
|
|
|
2021-07-15 17:12:50 +03:00
|
|
|
(define (blodwen-set-thread-data ty a)
|
2020-05-18 16:55:43 +03:00
|
|
|
(thread-specific-set! (current-thread) a))
|
|
|
|
|
|
|
|
(define blodwen-mutex make-mutex)
|
|
|
|
(define blodwen-lock mutex-lock!)
|
|
|
|
(define blodwen-unlock mutex-unlock!)
|
|
|
|
(define blodwen-thisthread current-thread)
|
|
|
|
|
|
|
|
(define blodwen-condition make-condition-variable)
|
|
|
|
(define blodwen-condition-signal condition-variable-signal!)
|
|
|
|
(define blodwen-condition-broadcast condition-variable-broadcast!)
|
|
|
|
(define (blodwen-condition-wait c m)
|
|
|
|
(mutex-unlock! m c)
|
|
|
|
(mutex-lock! m))
|
|
|
|
(define (blodwen-condition-wait-timeout c m t) ; XXX
|
|
|
|
(mutex-unlock! m c t)
|
|
|
|
(mutex-lock! m))
|
|
|
|
|
|
|
|
(define blodwen-sleep thread-sleep!)
|
|
|
|
(define (blodwen-usleep s) (thread-sleep! (/ s 1e6)))
|
|
|
|
|
2021-04-03 11:34:33 +03:00
|
|
|
|
|
|
|
(define (blodwen-arg-count)
|
|
|
|
(length (command-line)))
|
|
|
|
|
|
|
|
(define (blodwen-arg n)
|
|
|
|
(if (< n (length (command-line))) (list-ref (command-line) n) ""))
|
2020-05-18 16:55:43 +03:00
|
|
|
|
|
|
|
(define (blodwen-hasenv var)
|
|
|
|
(if (getenv var #f) 1 0))
|