1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-22 20:40:29 +02:00

Beginnings of <slot> slot definition class

* module/oop/goops.scm (define-macro-folder): Factor out this helper.
  (fold-class-slots): Implement using define-macro-folder.
  (fold-slot-slots): New definition, for slots of <slot-definition>.
  (define-slot-indexer): New helper.  Use to define indexes for slots of
  <class> and of <slot>.
This commit is contained in:
Andy Wingo 2015-01-16 15:44:48 +01:00
parent 567a6d1ee7
commit 26a6aaefac

View file

@ -150,11 +150,12 @@
;;; ;;;
;;; We then define the slots that must appear in all classes (<class> ;;; We then define the slots that must appear in all classes (<class>
;;; objects). These slots must appear in order. We'll use this list to ;;; objects) and slot definitions (<slot> objects). These slots must
;;; statically compute offsets for the various fields, to compute the ;;; appear in order. We'll use this list to statically compute offsets
;;; struct layout for <class> instances, and to compute the slot ;;; for the various fields, to compute the struct layout for <class>
;;; definition lists for <class>. Because the list is needed at ;;; instances, and to compute the slot definition lists for <class>.
;;; expansion-time, we define it as a macro. ;;; Because the list is needed at expansion-time, we define it as a
;;; macro.
;;; ;;;
(define-syntax macro-fold-left (define-syntax macro-fold-left
(syntax-rules () (syntax-rules ()
@ -168,52 +169,72 @@
((_ folder seed (head . tail)) ((_ folder seed (head . tail))
(folder head (macro-fold-right folder seed tail))))) (folder head (macro-fold-right folder seed tail)))))
(define-syntax fold-class-slots (define-syntax-rule (define-macro-folder macro-folder value ...)
(lambda (x) (define-syntax macro-folder
(define slots (lambda (x)
'((layout <protected-read-only-slot>) (syntax-case x ()
(flags <hidden-slot>) ((_ fold visit seed)
(self <self-slot>) ;; The datum->syntax makes it as if each `value' were present
(instance-finalizer <hidden-slot>) ;; in the initial form, which allows them to be used as
(print) ;; (components of) introduced identifiers.
(name <protected-hidden-slot>) #`(fold visit seed #,(datum->syntax #'visit '(value ...))))))))
(nfields <hidden-slot>)
(%reserved <hidden-slot>) (define-macro-folder fold-class-slots
(redefined) (layout <protected-read-only-slot>)
(direct-supers) (flags <hidden-slot>)
(direct-slots) (self <self-slot>)
(direct-subclasses) (instance-finalizer <hidden-slot>)
(direct-methods) (print)
(cpl) (name <protected-hidden-slot>)
(slots) (nfields <hidden-slot>)
(getters-n-setters))) (%reserved <hidden-slot>)
(syntax-case x () (redefined)
((_ fold visit seed) (direct-supers)
;; The datum->syntax makes it as if the identifiers in `slots' (direct-slots)
;; were present in the initial form, which allows them to be used (direct-subclasses)
;; as (components of) introduced identifiers. (direct-methods)
#`(fold visit seed #,(datum->syntax #'visit slots)))))) (cpl)
(slots)
(getters-n-setters))
(define-macro-folder fold-slot-slots
(name #:init-keyword #:name)
(allocation #:init-keyword #:allocation #:init-value #:instance)
(init-form #:init-keyword #:init-form)
(init-thunk #:init-keyword #:init-thunk #:init-value #f)
(options)
(getter #:init-keyword #:getter)
(setter #:init-keyword #:setter)
(index #:init-keyword #:index)
(size #:init-keyword #:size))
;;; ;;;
;;; Statically define variables for slot offsets: `class-index-layout' ;;; Statically define variables for slot offsets: `class-index-layout'
;;; will be 0, `class-index-flags' will be 1, and so on. ;;; will be 0, `class-index-flags' will be 1, and so on, and the same
;;; for `slot-index-name' and such for <slot>.
;;; ;;;
(let-syntax ((define-class-index (let-syntax ((define-slot-indexer
(lambda (x) (syntax-rules ()
(define (id-append ctx a b) ((_ define-index prefix)
(datum->syntax ctx (symbol-append (syntax->datum a) (define-syntax define-index
(syntax->datum b)))) (lambda (x)
(define (tail-length tail) (define (id-append ctx a b)
(syntax-case tail () (datum->syntax ctx (symbol-append (syntax->datum a)
((begin) 0) (syntax->datum b))))
((visit head tail) (1+ (tail-length #'tail))))) (define (tail-length tail)
(syntax-case x () (syntax-case tail ()
((_ (name . _) tail) ((begin) 0)
#`(begin ((visit head tail) (1+ (tail-length #'tail)))))
(define-syntax #,(id-append #'name #'class-index- #'name) (syntax-case x ()
(identifier-syntax #,(tail-length #'tail))) ((_ (name . _) tail)
tail)))))) #`(begin
(fold-class-slots macro-fold-left define-class-index (begin))) (define-syntax #,(id-append #'name #'prefix #'name)
(identifier-syntax #,(tail-length #'tail)))
tail)))))))))
(define-slot-indexer define-class-index class-index-)
(define-slot-indexer define-slot-index slot-index-)
(fold-class-slots macro-fold-left define-class-index (begin))
(fold-slot-slots macro-fold-left define-slot-index (begin)))
;;; ;;;
;;; Structs that are vtables have a "flags" slot, which corresponds to ;;; Structs that are vtables have a "flags" slot, which corresponds to