From e4407f4d53e97eda18fdb6964d73e740596259a0 Mon Sep 17 00:00:00 2001 From: VSteveHL Date: Tue, 15 Jul 2025 14:18:16 +0800 Subject: [PATCH 1/6] copy r7rs file from goldfish and rename them --- tests/resources/r7rs/liii/alist.scm.txt | 52 ++ tests/resources/r7rs/liii/argparse.scm.txt | 139 ++++++ .../resources/r7rs/liii/array-buffer.scm.txt | 127 +++++ tests/resources/r7rs/liii/base.scm.txt | 115 +++++ tests/resources/r7rs/liii/base64.scm.txt | 136 ++++++ tests/resources/r7rs/liii/bitwise.scm.txt | 37 ++ tests/resources/r7rs/liii/case.scm.txt | 344 +++++++++++++ tests/resources/r7rs/liii/check.scm.txt | 51 ++ tests/resources/r7rs/liii/chez.scm.txt | 26 + tests/resources/r7rs/liii/comparator.scm.txt | 35 ++ tests/resources/r7rs/liii/cut.scm.txt | 20 + tests/resources/r7rs/liii/datetime.scm.txt | 193 ++++++++ tests/resources/r7rs/liii/either.scm.txt | 122 +++++ tests/resources/r7rs/liii/error.scm.txt | 59 +++ tests/resources/r7rs/liii/hash-table.scm.txt | 35 ++ tests/resources/r7rs/liii/lang.scm.txt | 153 ++++++ tests/resources/r7rs/liii/list.scm.txt | 151 ++++++ tests/resources/r7rs/liii/logging.scm.txt | 144 ++++++ tests/resources/r7rs/liii/oop.scm.txt | 440 +++++++++++++++++ tests/resources/r7rs/liii/option.scm.txt | 94 ++++ tests/resources/r7rs/liii/os.scm.txt | 137 ++++++ tests/resources/r7rs/liii/path.scm.txt | 341 +++++++++++++ tests/resources/r7rs/liii/range.scm.txt | 90 ++++ tests/resources/r7rs/liii/rich-char.scm.txt | 179 +++++++ .../r7rs/liii/rich-hash-table.scm.txt | 102 ++++ tests/resources/r7rs/liii/rich-list.scm.txt | 452 ++++++++++++++++++ tests/resources/r7rs/liii/rich-string.scm.txt | 348 ++++++++++++++ tests/resources/r7rs/liii/rich-vector.scm.txt | 446 +++++++++++++++++ tests/resources/r7rs/liii/set.scm.txt | 69 +++ tests/resources/r7rs/liii/sort.scm.txt | 22 + tests/resources/r7rs/liii/stack.scm.txt | 60 +++ tests/resources/r7rs/liii/string.scm.txt | 64 +++ tests/resources/r7rs/liii/sys.scm.txt | 28 ++ tests/resources/r7rs/liii/uuid.scm.txt | 25 + tests/resources/r7rs/liii/vector.scm.txt | 58 +++ .../resources/r7rs/{ => scheme}/base.scm.txt | 0 .../resources/r7rs/{ => scheme}/boot.scm.txt | 0 .../r7rs/{ => scheme}/case-lambda.scm.txt | 0 .../resources/r7rs/{ => scheme}/char.scm.txt | 0 .../resources/r7rs/{ => scheme}/file.scm.txt | 0 .../r7rs/{ => scheme}/inexact.scm.txt | 0 .../r7rs/{ => scheme}/process-context.scm.txt | 0 .../resources/r7rs/{ => scheme}/time.scm.txt | 0 tests/resources/r7rs/srfi/sicp.scm.txt | 20 + tests/resources/r7rs/srfi/srfi-1.scm.txt | 355 ++++++++++++++ tests/resources/r7rs/srfi/srfi-113.scm.txt | 29 ++ tests/resources/r7rs/srfi/srfi-125.scm.txt | 161 +++++++ tests/resources/r7rs/srfi/srfi-128.scm.txt | 376 +++++++++++++++ tests/resources/r7rs/srfi/srfi-13.scm.txt | 380 +++++++++++++++ tests/resources/r7rs/srfi/srfi-132.scm.txt | 188 ++++++++ tests/resources/r7rs/srfi/srfi-133.scm.txt | 183 +++++++ tests/resources/r7rs/srfi/srfi-151.scm.txt | 168 +++++++ tests/resources/r7rs/srfi/srfi-16.scm.txt | 20 + tests/resources/r7rs/srfi/srfi-2.scm.txt | 11 + tests/resources/r7rs/srfi/srfi-216.scm.txt | 33 ++ tests/resources/r7rs/srfi/srfi-26.scm.txt | 70 +++ tests/resources/r7rs/srfi/srfi-39.scm.txt | 35 ++ tests/resources/r7rs/srfi/srfi-78.scm.txt | 165 +++++++ tests/resources/r7rs/srfi/srfi-8.scm.txt | 28 ++ tests/resources/r7rs/srfi/srfi-9.scm.txt | 7 + 60 files changed, 7123 insertions(+) create mode 100644 tests/resources/r7rs/liii/alist.scm.txt create mode 100644 tests/resources/r7rs/liii/argparse.scm.txt create mode 100644 tests/resources/r7rs/liii/array-buffer.scm.txt create mode 100644 tests/resources/r7rs/liii/base.scm.txt create mode 100644 tests/resources/r7rs/liii/base64.scm.txt create mode 100644 tests/resources/r7rs/liii/bitwise.scm.txt create mode 100644 tests/resources/r7rs/liii/case.scm.txt create mode 100644 tests/resources/r7rs/liii/check.scm.txt create mode 100644 tests/resources/r7rs/liii/chez.scm.txt create mode 100644 tests/resources/r7rs/liii/comparator.scm.txt create mode 100644 tests/resources/r7rs/liii/cut.scm.txt create mode 100644 tests/resources/r7rs/liii/datetime.scm.txt create mode 100644 tests/resources/r7rs/liii/either.scm.txt create mode 100644 tests/resources/r7rs/liii/error.scm.txt create mode 100644 tests/resources/r7rs/liii/hash-table.scm.txt create mode 100644 tests/resources/r7rs/liii/lang.scm.txt create mode 100644 tests/resources/r7rs/liii/list.scm.txt create mode 100644 tests/resources/r7rs/liii/logging.scm.txt create mode 100644 tests/resources/r7rs/liii/oop.scm.txt create mode 100644 tests/resources/r7rs/liii/option.scm.txt create mode 100644 tests/resources/r7rs/liii/os.scm.txt create mode 100644 tests/resources/r7rs/liii/path.scm.txt create mode 100644 tests/resources/r7rs/liii/range.scm.txt create mode 100644 tests/resources/r7rs/liii/rich-char.scm.txt create mode 100644 tests/resources/r7rs/liii/rich-hash-table.scm.txt create mode 100644 tests/resources/r7rs/liii/rich-list.scm.txt create mode 100644 tests/resources/r7rs/liii/rich-string.scm.txt create mode 100644 tests/resources/r7rs/liii/rich-vector.scm.txt create mode 100644 tests/resources/r7rs/liii/set.scm.txt create mode 100644 tests/resources/r7rs/liii/sort.scm.txt create mode 100644 tests/resources/r7rs/liii/stack.scm.txt create mode 100644 tests/resources/r7rs/liii/string.scm.txt create mode 100644 tests/resources/r7rs/liii/sys.scm.txt create mode 100644 tests/resources/r7rs/liii/uuid.scm.txt create mode 100644 tests/resources/r7rs/liii/vector.scm.txt rename tests/resources/r7rs/{ => scheme}/base.scm.txt (100%) rename tests/resources/r7rs/{ => scheme}/boot.scm.txt (100%) rename tests/resources/r7rs/{ => scheme}/case-lambda.scm.txt (100%) rename tests/resources/r7rs/{ => scheme}/char.scm.txt (100%) rename tests/resources/r7rs/{ => scheme}/file.scm.txt (100%) rename tests/resources/r7rs/{ => scheme}/inexact.scm.txt (100%) rename tests/resources/r7rs/{ => scheme}/process-context.scm.txt (100%) rename tests/resources/r7rs/{ => scheme}/time.scm.txt (100%) create mode 100644 tests/resources/r7rs/srfi/sicp.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-1.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-113.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-125.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-128.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-13.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-132.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-133.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-151.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-16.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-2.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-216.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-26.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-39.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-78.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-8.scm.txt create mode 100644 tests/resources/r7rs/srfi/srfi-9.scm.txt diff --git a/tests/resources/r7rs/liii/alist.scm.txt b/tests/resources/r7rs/liii/alist.scm.txt new file mode 100644 index 00000000..c6743a55 --- /dev/null +++ b/tests/resources/r7rs/liii/alist.scm.txt @@ -0,0 +1,52 @@ +; +; BSD License by Peter Danenberg +; + +(define-library (liii alist) +(import (liii base) + (liii list) + (liii error) + (scheme case-lambda)) +(export alist? alist-cons alist-ref alist-ref/default vector->alist) +(begin + +(define (alist? l) + (and (list? l) + (every pair? l))) + +(define alist-ref + (case-lambda + ((alist key) + (alist-ref + alist + key + (lambda () (key-error "alist-ref: key not found " key)))) + ((alist key thunk) + (alist-ref alist key thunk eqv?)) + ((alist key thunk =) + (let ((value (assoc key alist =))) + (if value + (cdr value) + (thunk)))))) + +(define alist-ref/default + (case-lambda + ((alist key default) + (alist-ref alist key (lambda () default))) + ((alist key default =) + (alist-ref alist key (lambda () default) =)))) + +; MIT License +; Copyright guenchi (c) 2018 - 2019 +(define vector->alist + (typed-lambda ((x vector?)) + (if (zero? (length x)) '() + (let loop ((x (vector->list x)) (n 0)) + (cons (cons n (car x)) + (if (null? (cdr x)) + '() + (loop (cdr x) (+ n 1)))))))) + +) ; end of begin +) ; end of library + diff --git a/tests/resources/r7rs/liii/argparse.scm.txt b/tests/resources/r7rs/liii/argparse.scm.txt new file mode 100644 index 00000000..e4d499aa --- /dev/null +++ b/tests/resources/r7rs/liii/argparse.scm.txt @@ -0,0 +1,139 @@ +; +; Copyright (C) 2024 The Goldfish Scheme Authors +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +; License for the specific language governing permissions and limitations +; under the License. +; + +(define-library (liii argparse) +(import (liii base) + (liii error) + (liii list) + (liii string) + (liii hash-table) + (liii alist) + (liii sys)) +(export make-argument-parser) +(begin + +(define (make-arg-record name type short-name default) + (list name type short-name default default)) + +(define (convert-value value type) + (case type + ((number) + (if (number? value) + value + (let ((num (string->number value))) + (if num + num + (error "Invalid number format" value))))) + ((string) + (if (string? value) + value + (error "Value is not a string"))) + (else (error "Unsupported type" type)))) + +(define (arg-type? type) + (unless (symbol? type) + (type-error "type of the argument must be symbol")) + (member type '(string number))) + +(define (%add-argument args-ht args) + (let* ((options (car args)) + (name (alist-ref options 'name + (lambda () (value-error "name is required for an option")))) + (type (alist-ref/default options 'type 'string)) + (short-name (alist-ref/default options 'short #f)) + (default (alist-ref/default options 'default #f)) + (arg-record (make-arg-record name type short-name default))) + (unless (string? name) + (type-error "name of the argument must be string")) + (unless (arg-type? type) + (value-error "Invalid type of the argument" type)) + (unless (or (not short-name) (string? short-name)) + (type-error "short name of the argument must be string if given")) + (hash-table-set! args-ht name arg-record) + (when short-name + (hash-table-set! args-ht short-name arg-record)))) + +(define (%get-argument args-ht args) + (let ((found (hash-table-ref/default args-ht (car args) #f))) + (if found + (fifth found) + (error "Argument not found" (car args))))) + +(define (long-form? arg) + (and (string? arg) + (>= (string-length arg) 3) + (string-starts? arg "--"))) + +(define (short-form? arg) + (and (string? arg) + (>= (string-length arg) 2) + (char=? (string-ref arg 0) #\-))) + +(define (retrieve-args args) + (if (null? args) + (cddr (argv)) + (car args))) + +(define (%parse-args args-ht prog-args) + (let loop ((args (retrieve-args prog-args))) + (if (null? args) + args-ht + (let ((arg (car args))) + (cond + ((long-form? arg) + (let* ((name (substring arg 2)) + (found (hash-table-ref args-ht name))) + (if found + (if (null? (cdr args)) + (error "Missing value for argument" name) + (begin + (let ((value (convert-value (cadr args) (cadr found)))) + (set-car! (cddddr found) value)) + (loop (cddr args)))) + (value-error (string-append "Unknown option: --" name))))) + + ((short-form? arg) + (let* ((name (substring arg 1)) + (found (hash-table-ref args-ht name))) + (if found + (if (null? (cdr args)) + (error "Missing value for argument" name) + (begin + (let ((value (convert-value (cadr args) (cadr found)))) + (set-car! (cddddr found) value)) + (loop (cddr args)))) + (value-error (string-append "Unknown option: -" name))))) + + (else (loop (cdr args)))))))) + +(define (make-argument-parser) + (let ((args-ht (make-hash-table))) + (lambda (command . args) + (case command + ((add) (%add-argument args-ht args)) + ((add-argument) (%add-argument args-ht args)) + ((get) (%get-argument args-ht args)) + ((get-argument) (%get-argument args-ht args)) + ((parse) (%parse-args args-ht args)) + ((parse-args) (%parse-args args-ht args)) + (else + (if (and (null? args) (symbol? command)) + (%get-argument args-ht (list (symbol->string command))) + (error "Unknown parser command" command))))))) + +) ; end of begin +) ; end of define-library + diff --git a/tests/resources/r7rs/liii/array-buffer.scm.txt b/tests/resources/r7rs/liii/array-buffer.scm.txt new file mode 100644 index 00000000..d48f87b1 --- /dev/null +++ b/tests/resources/r7rs/liii/array-buffer.scm.txt @@ -0,0 +1,127 @@ +; +; Copyright (C) 2024 The Goldfish Scheme Authors +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +; License for the specific language governing permissions and limitations +; under the License. +; + +(define-library (liii array-buffer) +(import (liii lang) (liii error)) +(export array-buffer) +(begin + +(define-case-class array-buffer + ((data vector?) + (size integer?) + (capacity integer?)) + +(chained-define (@from-vector vec) + (let ((len (vector-length vec))) + (array-buffer (copy vec) len len))) + +(chained-define (@from-list lst) + (let ((len (length lst))) + (array-buffer (copy lst (make-vector len)) len len))) + +(typed-define (check-bound (n integer?)) + (when (or (< n 0) (>= n size)) + (index-error + ($ "access No." :+ n :+ " of array-buffer [0:" :+ size :+ ")" :get)))) + +(define (%collect) + (copy data (make-vector size))) + +(define (%length) size) + +(define (%apply n) + (check-bound n) + (vector-ref data n)) + +(chained-define (%set! n v) + (check-bound n) + (vector-set! data n v) + (%this)) + +(define (%update! . args) + (apply %set! args)) + +(chained-define (%extend! n) + (when (< capacity n) + (if (= capacity 0) + (set! capacity n) + (let loop () + (when (< capacity n) + (set! capacity (* 2 capacity)) + (loop)))) + (set! data (copy data (make-vector capacity) 0 size))) + (%this)) + +(define (%size-hint! . args) (apply %extend! args)) + +(chained-define (%resize! n) + (%extend! n) + (set! size n) + (%this)) + +(chained-define (%trim-to-size! n) + (%extend! n) + (set! size n) + (when (> capacity (* 2 size)) + (set! data (copy data (make-vector size))) + (set! capacity size)) + (%this)) + +(chained-define (%add-one! x) + (%extend! (+ size 1)) + (vector-set! data size x) + (set! size (+ size 1)) + (%this)) + +(chained-define (%clear!) + (set! size 0) + (%this)) + +(chained-define (%clear/shrink!) + (set! size 0) + (set! capacity 1) + (set! data (make-vector 1)) + (%this)) + +(chained-define (%insert! index elem) + (%extend! (+ size 1)) + (set! size (+ size 1)) + (check-bound index) + (let loop ((p (- size 1))) + (when (> p index) + (vector-set! data p (vector-ref data (- p 1))) + (loop (- p 1)))) + (vector-set! data index elem) + (%this)) + +(typed-define (%equals (that case-class?)) + (and (that :is-instance-of 'array-buffer) + ((%to-vector) :equals (that :to-vector)))) + +(define (%to-vector) + (rich-vector (copy data (make-vector size)))) + +(define (%to-list) + (vector->list data 0 size)) + +(define (%to-rich-list) + (box (%to-list))) + +) ; end of array-buffer + +) ; end of begin +) ; end of define-library + diff --git a/tests/resources/r7rs/liii/base.scm.txt b/tests/resources/r7rs/liii/base.scm.txt new file mode 100644 index 00000000..b84faad1 --- /dev/null +++ b/tests/resources/r7rs/liii/base.scm.txt @@ -0,0 +1,115 @@ +; +; Copyright (C) 2024 The Goldfish Scheme Authors +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +; License for the specific language governing permissions and limitations +; under the License. +; + +(define-library (liii base) +(import (scheme base) + (srfi srfi-2) + (srfi srfi-8)) +(export + ; (scheme base) defined by R7RS + let-values + ; R7RS 5: Program Structure + define-values define-record-type + ; R7RS 6.2: Numbers + square exact inexact max min floor s7-floor ceiling s7-ceiling truncate s7-truncate + round s7-round floor-quotient gcd lcm s7-lcm exact-integer-sqrt + numerator denominator + ; R7RS 6.3: Booleans + boolean=? + ; R7RS 6.4: list + pair? cons car cdr set-car! set-cdr! caar cadr cdar cddr + null? list? make-list list length append reverse list-tail + list-ref list-set! memq memv member assq assv assoc list-copy + ; R7RS 6.5: Symbol + symbol? symbol=? string->symbol symbol->string + ; R7RS 6.6: Characters + digit-value + ; R7RS 6.7: String + string-copy + ; R7RS 6.8 Vector + vector->string string->vector vector-copy vector-copy! vector-fill! + ; R7RS 6.9 Bytevectors + bytevector? make-bytevector bytevector bytevector-length bytevector-u8-ref + bytevector-u8-set! bytevector-copy bytevector-append + utf8->string string->utf8 u8-string-length u8-substring bytevector-advance-u8 + ; Input and Output + call-with-port port? binary-port? textual-port? input-port-open? output-port-open? + open-binary-input-file open-binary-output-file close-port eof-object + ; Control flow + string-map vector-map string-for-each vector-for-each + ; Exception + raise guard read-error? file-error? + ; SRFI-2 + and-let* + ; SRFI-8 + receive + ; Extra routines + loose-car loose-cdr compose identity any? + ; Extra structure + let1 typed-lambda +) +(begin + +(define* (u8-substring str (start 0) (end #t)) + (utf8->string (string->utf8 str start end))) + +(define (loose-car pair-or-empty) + (if (eq? '() pair-or-empty) + '() + (car pair-or-empty))) + +(define (loose-cdr pair-or-empty) + (if (eq? '() pair-or-empty) + '() + (cdr pair-or-empty))) + +(define identity (lambda (x) x)) + +(define (compose . fs) + (if (null? fs) + (lambda (x) x) + (lambda (x) + ((car fs) ((apply compose (cdr fs)) x))))) + +(define (any? x) #t) + +(define-macro (let1 name1 value1 . body) + `(let ((,name1 ,value1)) + ,@body)) + +; 0 clause BSD, from S7 repo stuff.scm +(define-macro (typed-lambda args . body) + ; (typed-lambda ((var [type])...) ...) + (if (symbol? args) + (apply lambda args body) + (let ((new-args (copy args))) + (do ((p new-args (cdr p))) + ((not (pair? p))) + (if (pair? (car p)) + (set-car! p (caar p)))) + `(lambda ,new-args + ,@(map (lambda (arg) + (if (pair? arg) + `(unless (,(cadr arg) ,(car arg)) + (error 'type-error + "~S is not ~S~%" ',(car arg) ',(cadr arg))) + (values))) + args) + ,@body)))) + +) ; end of begin +) ; end of define-library + diff --git a/tests/resources/r7rs/liii/base64.scm.txt b/tests/resources/r7rs/liii/base64.scm.txt new file mode 100644 index 00000000..e51e1550 --- /dev/null +++ b/tests/resources/r7rs/liii/base64.scm.txt @@ -0,0 +1,136 @@ +; +; Copyright (C) 2024 The Goldfish Scheme Authors +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +; License for the specific language governing permissions and limitations +; under the License. +; + +(define-library (liii base64) +(import (liii base) + (liii bitwise)) +(export + string-base64-encode bytevector-base64-encode base64-encode + string-base64-decode bytevector-base64-decode base64-decode +) +(begin +(define-constant BYTE2BASE64_BV + (string->utf8 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")) + +(define-constant BASE64_PAD_BYTE + (char->integer #\=)) + +(define bytevector-base64-encode + (typed-lambda ((bv bytevector?)) + (define (encode b1 b2 b3) + (let* ((p1 b1) + (p2 (if b2 b2 0)) + (p3 (if b3 b3 0)) + (combined (bitwise-ior (ash p1 16) (ash p2 8) p3)) + (c1 (bitwise-and (ash combined -18) #x3F)) + (c2 (bitwise-and (ash combined -12) #x3F)) + (c3 (bitwise-and (ash combined -6) #x3F)) + (c4 (bitwise-and combined #x3F))) + (values + (BYTE2BASE64_BV c1) + (BYTE2BASE64_BV c2) + (if b2 (BYTE2BASE64_BV c3) BASE64_PAD_BYTE) + (if b3 (BYTE2BASE64_BV c4) BASE64_PAD_BYTE)))) + + (let* ((input-N (bytevector-length bv)) + (output-N (* 4 (ceiling (/ input-N 3)))) + (output (make-bytevector output-N))) + (let loop ((i 0) (j 0)) + (when (< i input-N) + (let* ((b1 (bv i)) + (b2 (if (< (+ i 1) input-N) (bv (+ i 1)) #f)) + (b3 (if (< (+ i 2) input-N) (bv (+ i 2)) #f))) + (receive (r1 r2 r3 r4) (encode b1 b2 b3) + (bytevector-u8-set! output j r1) + (bytevector-u8-set! output (+ j 1) r2) + (bytevector-u8-set! output (+ j 2) r3) + (bytevector-u8-set! output (+ j 3) r4) + (loop (+ i 3) (+ j 4)))))) + output))) + +(define string-base64-encode + (typed-lambda ((str string?)) + (utf8->string (bytevector-base64-encode (string->utf8 str))))) + +(define (base64-encode x) + (cond ((string? x) + (string-base64-encode x)) + ((bytevector? x) + (bytevector-base64-encode x)) + (else + (type-error "input must be string or bytevector")))) + +(define-constant BASE64_TO_BYTE_V + (let1 byte2base64-N (bytevector-length BYTE2BASE64_BV) + (let loop ((i 0) (v (make-vector 256 -1))) + (if (< i byte2base64-N) + (begin + (vector-set! v (BYTE2BASE64_BV i) i) + (loop (+ i 1) v)) + v)))) + +(define (bytevector-base64-decode bv) + (define (decode c1 c2 c3 c4) + (let* ((b1 (BASE64_TO_BYTE_V c1)) + (b2 (BASE64_TO_BYTE_V c2)) + (b3 (BASE64_TO_BYTE_V c3)) + (b4 (BASE64_TO_BYTE_V c4))) + (if (or (negative? b1) (negative? b2) + (and (negative? b3) (not (equal? c3 BASE64_PAD_BYTE))) + (and (negative? b4) (not (equal? c4 BASE64_PAD_BYTE)))) + (value-error "Invalid base64 input") + (values + (bitwise-ior (ash b1 2) (ash b2 -4)) + (bitwise-and (bitwise-ior (ash b2 4) (ash b3 -2)) #xFF) + (bitwise-and (bitwise-ior (ash b3 6) b4) #xFF) + (if (negative? b3) 1 (if (negative? b4) 2 3)))))) + + (let* ((input-N (bytevector-length bv)) + (output-N (* input-N 3/4)) + (output (make-bytevector output-N))) + + (unless (zero? (modulo input-N 4)) + (value-error "length of the input bytevector must be 4X")) + + (let loop ((i 0) (j 0)) + (if (< i input-N) + (receive (r1 r2 r3 cnt) + (decode (bv i) (bv (+ i 1)) (bv (+ i 2)) (bv (+ i 3))) + (bytevector-u8-set! output j r1) + (when (>= cnt 2) + (bytevector-u8-set! output (+ j 1) r2)) + (when (>= cnt 3) + (bytevector-u8-set! output (+ j 2) r3)) + (loop (+ i 4) (+ j cnt))) + (let ((final (make-bytevector j))) + (vector-copy! final 0 output 0 j) + final))))) + +(define string-base64-decode + (typed-lambda ((str string?)) + (utf8->string (bytevector-base64-decode (string->utf8 str))))) + +(define (base64-decode x) + (cond ((string? x) + (string-base64-decode x)) + ((bytevector? x) + (bytevector-base64-decode x)) + (else + (type-error "input must be string or bytevector")))) + +) ; end of begin +) ; end of define-library + diff --git a/tests/resources/r7rs/liii/bitwise.scm.txt b/tests/resources/r7rs/liii/bitwise.scm.txt new file mode 100644 index 00000000..370b82e7 --- /dev/null +++ b/tests/resources/r7rs/liii/bitwise.scm.txt @@ -0,0 +1,37 @@ +; +; Copyright (C) 2024 The Goldfish Scheme Authors +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +; License for the specific language governing permissions and limitations +; under the License. +; + +(define-library (liii bitwise) +(import (srfi srfi-151) + (liii error)) +(export + ; from (srfi srfi-151) + bitwise-not bitwise-and bitwise-ior bitwise-xor bitwise-eqv bitwise-or bitwise-nor bitwise-nand + bit-count bitwise-orc1 bitwise-orc2 bitwise-andc1 bitwise-andc2 + arithmetic-shift integer-length bitwise-if + bit-set? copy-bit bit-swap any-bit-set? every-bit-set? first-set-bit + bit-field bit-field-any? bit-field-every? bit-field-clear bit-field-set + ; S7 built-in + lognot logand logior logxor + ash +) +(begin + +(define bitwise-or bitwise-ior) + +) ; end of begin +) ; end of library + diff --git a/tests/resources/r7rs/liii/case.scm.txt b/tests/resources/r7rs/liii/case.scm.txt new file mode 100644 index 00000000..68e575c5 --- /dev/null +++ b/tests/resources/r7rs/liii/case.scm.txt @@ -0,0 +1,344 @@ +; +; Copyright (C) 2024 The Goldfish Scheme Authors +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +; License for the specific language governing permissions and limitations +; under the License. +; + +(define-library (liii case) +(import (liii base)) +(export case*) +(begin + +; 0 clause BSD, from S7 repo case.scm +(define case* + (let ((case*-labels (lambda (label) + (let ((labels ((funclet ((funclet 'case*) 'case*-helper)) 'labels))) + (labels (symbol->string label))))) ; if ellipsis, this has been quoted by case* + + (case*-match? (lambda* (matchee pattern (e (curlet))) + (let ((matcher ((funclet ((funclet 'case*) 'case*-helper)) 'handle-sequence))) + (or (equivalent? matchee pattern) + (and (or (pair? matchee) + (vector? matchee)) + (begin + (fill! ((funclet ((funclet 'case*) 'case*-helper)) 'labels) #f) ; clear labels + ((matcher pattern e) matchee))))))) + (case*-helper + (with-let (unlet) + (define labels (make-hash-table)) + + (define (ellipsis? pat) + (and (undefined? pat) + (or (equal? pat #<...>) + (let ((str (object->string pat))) + (and (char-position #\: str) + (string=? "...>" (substring str (- (length str) 4)))))))) + + (define (ellipsis-pair-position pos pat) + (and (pair? pat) + (if (ellipsis? (car pat)) + pos + (ellipsis-pair-position (+ pos 1) (cdr pat))))) + + (define (ellipsis-vector-position pat vlen) + (let loop ((pos 0)) + (and (< pos vlen) + (if (ellipsis? (pat pos)) + pos + (loop (+ pos 1)))))) + + (define (splice-out-ellipsis sel pat pos e) + (let ((sel-len (length sel)) + (new-pat-len (- (length pat) 1)) + (ellipsis-label (and (not (eq? (pat pos) #<...>)) + (let* ((str (object->string (pat pos))) + (colon (char-position #\: str))) + (and colon + (substring str 2 colon)))))) + (let ((func (and (string? ellipsis-label) + (let ((comma (char-position #\, ellipsis-label))) + (and comma + (let ((str (substring ellipsis-label (+ comma 1)))) + (set! ellipsis-label (substring ellipsis-label 0 comma)) + (let ((func-val (symbol->value (string->symbol str) e))) + (if (undefined? func-val) + (error 'unbound-variable "function ~S is undefined\n" func)) + (if (not (procedure? func-val)) + (error 'wrong-type-arg "~S is not a function\n" func)) + func-val))))))) + (if (pair? pat) + (cond ((= pos 0) ; ellipsis at start of pattern + (if ellipsis-label + (set! (labels ellipsis-label) + (list 'quote (copy sel (make-list (- sel-len new-pat-len)))))) + (values (list-tail sel (- sel-len new-pat-len)) + (cdr pat) + (or (not func) + (func (cadr (labels ellipsis-label)))))) ; value is (quote ...) and we want the original list here + + ((= pos new-pat-len) ; ellipsis at end of pattern + (if ellipsis-label + (set! (labels ellipsis-label) + (list 'quote (copy sel (make-list (- sel-len pos)) pos)))) + (values (copy sel (make-list pos)) + (copy pat (make-list pos)) + (or (not func) + (func (cadr (labels ellipsis-label)))))) + + (else ; ellipsis somewhere in the middle + (let ((new-pat (make-list new-pat-len)) + (new-sel (make-list new-pat-len))) + (if ellipsis-label + (set! (labels ellipsis-label) + (list 'quote (copy sel (make-list (- sel-len new-pat-len)) pos)))) + (copy pat new-pat 0 pos) + (copy pat (list-tail new-pat pos) (+ pos 1)) + (copy sel new-sel 0 pos) + (copy sel (list-tail new-sel pos) (- sel-len pos)) + (values new-sel new-pat + (or (not func) + (func (cadr (labels ellipsis-label)))))))) + + (cond ((= pos 0) + (if ellipsis-label + (set! (labels ellipsis-label) + (list 'quote (copy sel (make-list (- sel-len new-pat-len)))))) + (values (subvector sel (max 0 (- sel-len new-pat-len)) sel-len) ; was new-pat-len (max 0 (- sel-len new-pat-len)) + (subvector pat 1 (+ new-pat-len 1)) ; new-pat-len 1 + (or (not func) + (func (cadr (labels ellipsis-label)))))) + + ((= pos new-pat-len) + (if ellipsis-label + (set! (labels ellipsis-label) + (list 'quote (copy sel (make-list (- sel-len new-pat-len)) pos)))) + (values (subvector sel 0 new-pat-len) + (subvector pat 0 new-pat-len) + (or (not func) + (func (cadr (labels ellipsis-label)))))) + + (else + (let ((new-pat (make-vector new-pat-len)) + (new-sel (make-vector new-pat-len))) + (if ellipsis-label + (set! (labels ellipsis-label) + (list 'quote (copy sel (make-list (- sel-len new-pat-len)) pos)))) + (copy pat new-pat 0 pos) + (copy pat (subvector new-pat pos new-pat-len) (+ pos 1)) ; (- new-pat-len pos) pos) copy: (+ pos 1)) + (copy sel new-sel 0 pos) + (copy sel (subvector new-sel pos new-pat-len) (- sel-len pos)) + ; (- new-pat-len pos) pos) copy: (- sel-len pos)) + (values new-sel new-pat + (or (not func) + (cadr (func (labels ellipsis-label)))))))))))) + + (define (handle-regex x) #f) + ;(define handle-regex + ; (let ((rg ((*libc* 'regex.make))) ; is this safe? + ; (local-regcomp (*libc* 'regcomp)) + ; (local-regerror (*libc* 'regerror)) + ; (local-regexec (*libc* 'regexec)) + ; (local-regfree (*libc* 'regfree))) + ; (lambda (reg) + ;(lambda (x) + ; (and (string? x) + ; (let ((res (local-regcomp rg (substring reg 1 (- (length reg) 1)) 0))) + ; (unless (zero? res) + ; (error 'regex-error "~S~%" (local-regerror res rg))) + ; (set! res (local-regexec rg x 0 0)) + ; (local-regfree rg) + ; (zero? res))))))) + + (define (undefined->function undef e) ; handle the pattern descriptor ("undef") of the form #< whatever >, "e" = caller's curlet + (let* ((str1 (object->string undef)) + (str1-end (- (length str1) 1))) + (if (not (char=? (str1 str1-end) #\>)) + (error 'wrong-type-arg "pattern descriptor does not end in '>': ~S\n" str1)) + (let ((str (substring str1 2 str1-end))) + (if (= (length str) 0) ; #<> = accept anything + (lambda (x) #t) + (let ((colon (char-position #\: str))) + (cond (colon ; # might be # or # + (let ((label (substring str 0 colon)) ; str is label:... + (func (substring str (+ colon 1)))) ; func might be "" + (cond ((labels label) ; see if we already have saved something under this label + (lambda (sel) ; if so, return function that will return an error + (error 'syntax-error "label ~S is defined twice: old: ~S, new: ~S~%" label (labels label) sel))) + + ;; otherwise the returned function needs to store the current sel-item under label in labels + ((zero? (length func)) + (lambda (x) + (set! (labels label) x) ; #, set label, accept anything + #t)) + + ((char=? (func 0) #\") ; labelled regex, # + (lambda (x) + (set! (labels label) x) + (handle-regex func))) + + (else ; # + (let ((func-val (symbol->value (string->symbol func) e))) + (if (undefined? func-val) + (error 'unbound-variable "function ~S is undefined\n" func) + (if (not (procedure? func-val)) + (error 'wrong-type-arg "~S is not a function\n" func) + (lambda (x) ; set label and call func + (set! (labels label) x) + (func-val x))))))))) + + ;; if no colon either #