diff --git a/goldfish/liii/base.scm b/goldfish/liii/base.scm index 85f27098c..e3e158d2c 100644 --- a/goldfish/liii/base.scm +++ b/goldfish/liii/base.scm @@ -19,7 +19,40 @@ (srfi srfi-2) (srfi srfi-8) ) ;import - (export + (re-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 floor/ s7-floor ceiling s7-ceiling truncate truncate/ s7-truncate + round s7-round floor-quotient floor-remainder gcd lcm s7-lcm modulo exact-integer-sqrt + numerator denominator exact-integer? number->string string->number + ; 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 utf8-string-length u8-substring bytevector-advance-utf8 + ; 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 @@ -38,6 +71,10 @@ string->keyword symbol->keyword keyword->symbol + ) ;re-export + (export + ; workaround for binding s7 primitives + (rename vector-append vector-append) ; Extra routines loose-car loose-cdr @@ -73,34 +110,51 @@ ) ;lambda ) ;if ) ;define - + (define (any? x) #t) - ; 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)) - ) ;if - ) ;do - `(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) - ) ;let - ) ;if - ) ;define-macro + (define-syntax let1 + (syntax-rules () + ((_ name1 value1 body ...) + (let ((name1 value1)) + body ...)))) + + (define-syntax typed-lambda + (lambda (stx) + (define (split-args args) + (let loop ((args args)) + (syntax-case args () + ;; 结束条件 + (() (values '() '())) + + ;; 带有类型的变量: ((var type) . rest) + (((var type) . rest) + (let-values (((clean-rest checks-rest) (loop (syntax rest)))) + (values (cons (syntax var) clean-rest) + (cons #'(unless (type var) + (error 'type-error "~S is not ~S" 'var 'type)) + checks-rest)))) + + ;; 普通变量或 rest 变量: (var . rest) 或只是 var + ((var . rest) + (let-values (((clean-rest checks-rest) (loop (syntax rest)))) + (values (cons (syntax var) clean-rest) checks-rest))) + + ;; 点号后面的最后一个标识符 (例如 rest) + (var + (if (identifier? (syntax var)) + (values (syntax var) '()) + (raise-syntax-error #f "Invalid argument specification" stx (syntax var))))))) + + (syntax-case stx () + ((_ args body1 body2 ...) + (let-values (((clean-args checks) (split-args (syntax args)))) + (with-syntax ((clean-args clean-args) + ((check ...) checks) + ((body ...) #'(body1 body2 ...))) + #'(lambda clean-args + check ... + body ...))))))) - ) ;begin -) ;define-library + ) ; end of begin +) ; end of define-library diff --git a/goldfish/liii/bitwise.scm b/goldfish/liii/bitwise.scm index a289ed67f..446881778 100644 --- a/goldfish/liii/bitwise.scm +++ b/goldfish/liii/bitwise.scm @@ -17,7 +17,7 @@ (define-library (liii bitwise) (import (srfi srfi-151) (liii error)) ; S7 built-in - (export lognot logand logior logxor ash) + (re-export lognot logand logior logxor ash) ; from (srfi srfi-151) (export 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 diff --git a/goldfish/liii/case.scm b/goldfish/liii/case.scm deleted file mode 100644 index 9a4145679..000000000 --- a/goldfish/liii/case.scm +++ /dev/null @@ -1,502 +0,0 @@ -; -; 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* - ) ;let - ) ;case*-labels - - (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)) - ) ;begin - ) ;and - ) ;or - ) ;let - ) ;case*-match? - (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))) - ) ;and - ) ;let - ) ;or - ) ;and - ) ;define - - (define (ellipsis-pair-position pos pat) - (and (pair? pat) - (if (ellipsis? (car pat)) - pos - (ellipsis-pair-position (+ pos 1) (cdr pat)) - ) ;if - ) ;and - ) ;define - - (define (ellipsis-vector-position pat vlen) - (let loop ((pos 0)) - (and (< pos vlen) - (if (ellipsis? (pat pos)) - pos - (loop (+ pos 1)) - ) ;if - ) ;and - ) ;let - ) ;define - - (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))) - ) ;and - ) ;let* - ) ;ellipsis-label - (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 - (if (not (procedure? func-val)) - (error 'wrong-type-arg "~S is not a function\n" func) - ) ;if - func-val))) - ) ;let - ) ;let - ) ;and - ) ;let - (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)))) - ) ;set! - ) ;if - (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 - ) ;or - ) ;values - - ((= 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)) - ) ;set! - ) ;if - (values (copy sel (make-list pos)) - (copy pat (make-list pos)) - (or (not func) - (func (cadr (labels ellipsis-label))) - ) ;or - ) ;values - ) ; - - (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)) - ) ;set! - ) ;if - (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))) - ) ;or - ) ;values - ) ;let - ) ;else - ) ;cond - - (cond - ((= pos 0) - (if ellipsis-label - (set! (labels ellipsis-label) - (list 'quote (copy sel (make-list (- sel-len new-pat-len)))) - ) ;set! - ) ;if - (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)))) - ) ;or - ) ;values - - ((= pos new-pat-len) - (if ellipsis-label - (set! (labels ellipsis-label) - (list 'quote (copy sel (make-list (- sel-len new-pat-len)) pos)) - ) ;set! - ) ;if - (values (subvector sel 0 new-pat-len) - (subvector pat 0 new-pat-len) - (or (not func) - (func (cadr (labels ellipsis-label))) - ) ;or - ) ;values - ) ; - - (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)) - ) ;set! - ) ;if - (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))) - ) ;or - ) ;values - ) ;let - ) ;else - ) ;cond - ) ;if - ) ;let - ) ;let - ) ;define - - (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) - ) ;if - (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)) - ) ;lambda - - ;; 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 - ) ;lambda - ) ; - - ((char=? (func 0) #\") ; labelled regex, # - (lambda (x) - (set! (labels label) x) - (handle-regex func) - ) ;lambda - ) ; - - (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)) - ) ;lambda - ) ;if - ) ;if - ) ;let - ) ;else - ) ;cond - ) ;let - - ;; if no colon either #