guile-srfi-123

guile-srfi-123 is an SRFI-123 implementation for Guile. (More on SRFI-123 on https://srfi.schemers.org/srfi-123/)
git clone https://kaka.farm/~git/guile-srfi-123
Log | Files | Refs

commit 05f5626f05f02ef5dbf2e89a1e05e02aa1c45d44
parent 0181dad8864a6573203eff6e2ee7f06f59d43e5a
Author: Yuval Langer <yuval.langer@gmail.com>
Date:   Sat, 25 Jan 2025 20:11:36 +0200

Add GOOPS implementation and related stuff.  Also the ares server script and copyright and AGPL-3-or-later licensing.

Diffstat:
Aares.sh | 6++++++
Mrun-tests-goops.scm | 28++++++++++++++++++++++------
Msrfi/srfi-123.scm | 4+++-
Msrfi/srfi-123/goops.scm | 339++++++++++++++++++++++++++++++++++---------------------------------------------
4 files changed, 175 insertions(+), 202 deletions(-)

diff --git a/ares.sh b/ares.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +guix shell \ + guile-next \ + guile-ares-rs \ + -- guile -c '((@ (ares server) run-nrepl-server))' diff --git a/run-tests-goops.scm b/run-tests-goops.scm @@ -1,7 +1,21 @@ -;;; generic-ref-set --- Generic accessor and modifier operators. +;;; run-tests-goops.scm --- Part of the guile-srfi-123 generic accessor and modifier operators library. +;; Copyright © 2025 Yuval Langer <yuval.langer@gmail.com> ;; Copyright © 2015 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com> +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU Affero General Public License as +;; published by the Free Software Foundation, either version 3 of the +;; License, or (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU Affero General Public License for more details. + +;; You should have received a copy of the GNU Affero General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + ;; Permission is hereby granted, free of charge, to any person obtaining ;; a copy of this software and associated documentation files (the ;; "Software"), to deal in the Software without restriction, including @@ -23,16 +37,18 @@ (use-modules ((scheme base) #:select (bytevector)) + + (rnrs exceptions) (rnrs hashtables) + (rnrs records inspection) + (rnrs records procedural) + (rnrs records syntactic) + (srfi srfi-4) (srfi srfi-64) (srfi srfi-111) (srfi srfi-123 goops) - (rnrs records syntactic) - (rnrs records procedural) - (rnrs records inspection) - (rnrs exceptions) -) + ) (define using-broken-srfi99 #f) diff --git a/srfi/srfi-123.scm b/srfi/srfi-123.scm @@ -25,11 +25,13 @@ (export ref ref* ~ register-getter-with-setter! $bracket-apply$ set! setter getter-with-setter) (import (scheme base) + (scheme case-lambda) + (rnrs hashtables) (rnrs records inspection) (rnrs records procedural) (rnrs records syntactic) - (scheme case-lambda) + (srfi 1) (srfi 4) (srfi 17) diff --git a/srfi/srfi-123/goops.scm b/srfi/srfi-123/goops.scm @@ -1,7 +1,21 @@ -;;; generic-ref-set --- Generic accessor and modifier operators. +;;; goops.scm --- Part of the guile-srfi-123 generic accessor and modifier operators library. +;; Copyright © 2025 Yuval Langer <yuval.langer@gmail.com> ;; Copyright © 2015 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com> +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU Affero General Public License as +;; published by the Free Software Foundation, either version 3 of the +;; License, or (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU Affero General Public License for more details. + +;; You should have received a copy of the GNU Affero General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + ;; Permission is hereby granted, free of charge, to any person obtaining ;; a copy of this software and associated documentation files (the ;; "Software"), to deal in the Software without restriction, including @@ -22,7 +36,16 @@ ;; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. (define-library (srfi srfi-123 goops) - (export ref ref* ~ register-getter-with-setter! $bracket-apply$ set! setter getter-with-setter) + (export + ref + ref* + ~ + register-getter-with-setter! + $bracket-apply$ + set! + setter + getter-with-setter + ) (import (scheme base) (scheme case-lambda) @@ -32,50 +55,21 @@ (rnrs records procedural) (rnrs records syntactic) - (srfi 1) - (srfi 4) - (srfi 17) - (srfi 26) - (srfi 31) - (srfi 43) - (srfi 111) + (srfi srfi-1) + (srfi srfi-4) + (srfi srfi-4 gnu) + (srfi srfi-17) + (srfi srfi-26) + (srfi srfi-31) + (srfi srfi-43) + (srfi srfi-111) + + (ice-9 match) (oop goops) ) (begin -;;; Helpers - - (define-syntax push! - (syntax-rules () - ((_ <list-var> <x>) - (set! <list-var> (cons <x> <list-var>))))) - - (define (alist->hashtable alist) - (let ((table (make-eqv-hashtable 100))) - (for-each (lambda (entry) - (hashtable-set! table (car entry) (cdr entry))) - alist) - table)) - - (define (pair-ref pair key) - (cond - ((eqv? 'car key) - (car pair)) - ((eqv? 'cdr key) - (cdr pair)) - (else - (list-ref pair key)))) - - (define (pair-set! pair key value) - (cond - ((eqv? 'car key) - (set-car! pair value)) - ((eqv? 'cdr key) - (set-cdr! pair value)) - (else - (list-set! pair key value)))) - ;;; Record inspection support (define (rtd-field-index rtd field) @@ -115,168 +109,123 @@ Raise an error if the field does not exist." ;;; which possibly dispatch to an SRFI-4 type's getter/setter, but also ;;; inserting the SRFI-4 getters/setters into the top-level dispatch tables. - (define srfi-4-getters - (list (cons s8vector? s8vector-ref) - (cons u8vector? u8vector-ref) - (cons s16vector? s16vector-ref) - (cons u16vector? u16vector-ref) - (cons s32vector? s32vector-ref) - (cons u32vector? u32vector-ref) - (cons s64vector? s64vector-ref) - (cons u64vector? u64vector-ref))) - (define srfi-4-setters - (list (cons s8vector? s8vector-set!) - (cons u8vector? u8vector-set!) - (cons s16vector? s16vector-set!) - (cons u16vector? u16vector-set!) - (cons s32vector? s32vector-set!) - (cons u32vector? u32vector-set!) - (cons s64vector? s64vector-set!) - (cons u64vector? u64vector-set!))) - (define srfi-4-types - (list s8vector? u8vector? s16vector? u16vector? s32vector? u32vector? - s64vector? u64vector?)) - (define srfi-4-getters-table (alist->hashtable srfi-4-getters)) - (define srfi-4-setters-table (alist->hashtable srfi-4-setters)) - (define (bytevector-ref bytevector index) - (let* ((type (find (lambda (pred) (pred bytevector)) srfi-4-types)) - (getter (if type - (ref srfi-4-getters-table type) - bytevector-u8-ref))) - (getter bytevector index))) - (define (bytevector-set! bytevector index value) - (let* ((type (find (lambda (pred) (pred bytevector)) srfi-4-types)) - (setter (if type - (ref srfi-4-setters-table type) - bytevector-u8-set!))) - (setter bytevector index value))) - -;;; SRFI-111 boxes support - - (define (box-ref box _field) - (unbox box)) - (define (box-set! box _field value) - (set-box! box value)) - (define box-getter (list (cons box? box-ref))) - (define box-setter (list (cons box? box-set!))) - (define box-type (list box?)) - -;;; Main - - (define %ref - (case-lambda - ((object field) - (let ((getter (lookup-getter object)) - (sparse? (sparse-type? object))) - (if sparse? - (let* ((not-found (cons #f #f)) - (result (getter object field not-found))) - (if (eqv? result not-found) - (error "Object has no entry for field." object field) - result)) - (getter object field)))) - ((object field default) - (let ((getter (lookup-getter object))) - (getter object field default))))) - - (define (%ref* object field . fields) - (if (null? fields) - (%ref object field) - (apply %ref* (%ref object field) fields))) - - (define (%set! object field value) - (let ((setter (lookup-setter object))) - (setter object field value))) - - (define ref - (getter-with-setter - %ref - (lambda (object field value) - (%set! object field value)))) + ;; XXX: (class-of (make-u8vector 0)) is the same as (class-of (make-u16vector 0)) or any of the rest. + (define-method (ref (object <uvec>) field) + (match object + ((? u8vector?) (u8vector-ref object field)) + ((? s8vector?) (s8vector-ref object field)) + ((? u16vector?) (u16vector-ref object field)) + ((? s16vector?) (s16vector-ref object field)) + ((? u32vector?) (u32vector-ref object field)) + ((? s32vector?) (s32vector-ref object field)) + ((? u64vector?) (u64vector-ref object field)) + ((? s64vector?) (s64vector-ref object field)) + ((? f32vector?) (f32vector-ref object field)) + ((? f64vector?) (f64vector-ref object field)) + ((? c32vector?) (c32vector-ref object field)) + ((? c64vector?) (c64vector-ref object field)) + ((? bytevector?) (bytevector-u8-ref object field)))) + + (define-method ((setter ref) (object <uvec>) field value) + (match object + ((? u8vector?) (u8vector-set! object field value)) + ((? s8vector?) (s8vector-set! object field value)) + ((? u16vector?) (u16vector-set! object field value)) + ((? s16vector?) (s16vector-set! object field value)) + ((? u32vector?) (u32vector-set! object field value)) + ((? s32vector?) (s32vector-set! object field value)) + ((? u64vector?) (u64vector-set! object field value)) + ((? s64vector?) (s64vector-set! object field value)) + ((? f32vector?) (f32vector-set! object field value)) + ((? f64vector?) (f64vector-set! object field value)) + ((? c32vector?) (c32vector-set! object field value)) + ((? c64vector?) (c64vector-set! object field value)) + ((? bytevector?) (bytevector-u8-set! object field value)))) + +;;; pairs support. + + (let ((type-class (class-of (cons '() '())))) + (define-method (ref (object type-class) field) + (cond + ((eqv? 'car field) + (car object)) + ((eqv? 'cdr field) + (cdr object)) + (else + (list-ref object field)))) + + (define-method (ref (object type-class) field value) + (cond + ((eqv? 'car field) + (set-car! object value)) + ((eqv? 'cdr field) + (set-cdr! object value)) + (else + (list-set! object field value))))) + +;;; string support. + + (define-method (ref (object <string>) field) + (string-ref object field)) + + (define-method ((setter ref) (object <string>) field value) + (string-set! object field value)) + ;; Wrong type argument in position 1 (expecting symbol): (setter ref) + +;;; bytevector support. + + (define-method (ref (object <bytevector>) field) + (bytevector-u8-ref object field)) + + (define-method ((setter ref) (object <bytevector>) field value) + (bytevector-u8-set! object field value)) + +;;; vector support. + + (define-method (ref (object <vector>) field) + (vector-ref object field)) + + (define-method ((setter ref) (object <vector>) field value) + (vector-set! object field value)) + + ;; hashtable support. + + (define-method (ref (object <hashtable>) field default) + (hashtable-ref object field default)) + + (define-method ((setter ref) (object <hashtable>) field default) + (hashtable-ref object field default)) + +;;; box support + + (let ((type-class (class-of (box '())))) + (define-method (ref (object type-class) field) + (unbox object)) + (define-method ((setter ref) (object type-class) field value) + (set-box! object value))) + + ;; TODO: + ;; record? + ;; record-getter (define ref* (getter-with-setter - %ref* - ;; XXX: Originally it used the SRFI-31 rec construct, but it just would not compile! - ;; - ;; (rec (set!* object field rest0 . rest) - ;; (if (null? rest) - ;; (%set! object field rest0) - ;; (apply set!* (ref object field) rest0 rest))) - ;; - ;; + (let () + (define (%ref* object field . fields) + (if (null? fields) + (ref object field) + (apply %ref* (ref object field) fields))) + %ref*) (let () (define (set!* object field rest0 . rest) - (if (null? rest) - (%set! object field rest0) - (apply set!* (ref object field) rest0 rest))) + (match (cons rest0 rest) + ((last-field new-value) + (set! (ref object last-field) new-value)) + ((rest0 rest ooo) + (apply set!* (ref object field) rest0 rest)))) set!*))) (define ~ ref*) (define $bracket-apply$ ref*) - - (define (lookup-getter object) - (or (hashtable-ref getter-table (type-of object) #f) - (error "No generic getter for object's type." object))) - - (define (lookup-setter object) - (or (hashtable-ref setter-table (type-of object) #f) - (error "No generic setter for object's type." object))) - - (define (sparse-type? object) - (memv (type-of object) sparse-types)) - - (define (type-of object) - (find (lambda (pred) (pred object)) type-list)) - - (define getter-table - (alist->hashtable - (append - (list (cons bytevector? bytevector-ref) - (cons hashtable? hashtable-ref) - (cons pair? pair-ref) - (cons string? string-ref) - (cons vector? vector-ref)) - record-getter - srfi-4-getters - box-getter))) - - (define setter-table - (alist->hashtable - (append - (list (cons bytevector? bytevector-set!) - (cons hashtable? hashtable-set!) - (cons pair? pair-set!) - (cons string? string-set!) - (cons vector? vector-set!)) - record-setter - srfi-4-setters - box-setter))) - - (define sparse-types - (list hashtable?)) - - (define type-list - ;; Although the whole SRFI intrinsically neglects performance, we still use - ;; the micro-optimization of ordering this list roughly according to most - ;; likely match. - (append - (list hashtable? vector? pair? bytevector? string?) - srfi-4-types - box-type - ;; The record type must be placed last so specific record types (e.g. box) - ;; take precedence. - record-type - ;; Place those types we don't support really last. - (list boolean? char? eof-object? null? number? port? procedure? symbol?))) - - (define (register-getter-with-setter! type getter sparse?) - (push! type-list type) - (set! (~ getter-table type) getter) - (set! (~ setter-table type) (setter getter)) - (when sparse? - (push! sparse-types type))) )) - -;;; srfi-123.scm ends here