2015-01-19 22:41:57 +01:00
|
|
|
|
;;;; goops.scm -- The Guile Object-Oriented Programming System
|
|
|
|
|
|
;;;;
|
|
|
|
|
|
;;;; Copyright (C) 1998-2003,2006,2009-2011,2013-2015 Free Software Foundation, Inc.
|
2013-01-26 15:41:05 +01:00
|
|
|
|
;;;; Copyright (C) 1993-1998 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
|
|
|
|
|
|
;;;;
|
2003-04-05 19:15:35 +00:00
|
|
|
|
;;;; This library is free software; you can redistribute it and/or
|
|
|
|
|
|
;;;; modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
|
;;;; License as published by the Free Software Foundation; either
|
2009-06-17 00:22:09 +01:00
|
|
|
|
;;;; version 3 of the License, or (at your option) any later version.
|
2013-01-26 15:41:05 +01:00
|
|
|
|
;;;;
|
2003-04-05 19:15:35 +00:00
|
|
|
|
;;;; This library is distributed in the hope that it will be useful,
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2003-04-05 19:15:35 +00:00
|
|
|
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
;;;; Lesser General Public License for more details.
|
2013-01-26 15:41:05 +01:00
|
|
|
|
;;;;
|
2003-04-05 19:15:35 +00:00
|
|
|
|
;;;; You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
;;;; License along with this library; if not, write to the Free Software
|
2005-05-23 19:57:22 +00:00
|
|
|
|
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
2013-01-26 15:41:05 +01:00
|
|
|
|
;;;;
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;;
|
2013-01-26 15:41:05 +01:00
|
|
|
|
;;;; This file was based upon stklos.stk from the STk distribution
|
|
|
|
|
|
;;;; version 4.0.1 by Erick Gallesio <eg@unice.fr>.
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define-module (oop goops)
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
#:use-module (srfi srfi-1)
|
Move GOOPS boot to Scheme
* module/oop/goops.scm (build-<class>-slots): New helper, replacing
build_class_class_slots.
(build-slots-list, %compute-getters-n-setters, %compute-layout): New
private helpers, moved here from C.
(%prep-layout!): Reimplement in Scheme.
(make-standard-class): New private helper, replacing
scm_basic_make_class.
(<class>, <top>, <object>): Define in Scheme.
(<foreign-slot>, <protected-slot>, <hidden-slot>, <opaque-slot>,
<read-only-slot>, <self-slot>, <protected-opaque-slot>,
<protected-hidden-slot>, <protected-read-only-slot>, <scm-slot>,
<int-slot>, <float-slot>, <double-slot>, <procedure-class>,
<applicable-struct-class>, <method>, <accessor-method>, <applicable>,
<applicable-struct>, <generic>, <extended-generic>,
<generic-with-setter>, <accessor>, <extended-generic-with-setter>,
<extended-accessor>): Define in Scheme.
(<boolean>, <char>, <list>, <pair>, <null>, <string>, <symbol>,
<vector>, <foreign>, <hashtable>, <fluid>, <dynamic-state>, <frame>,
<vm-continuation>, <bytevector>, <uvec>, <array>, <bitvector>,
<number>, <complex>, <real>, <integer>, <fraction>, <keyword>,
<unknown>, <procedure>, <primitive-generic>, <port>, <input-port>,
<output-port>, <input-output-port>): Define in Scheme.
(compute-slots): Use build-slots-list helper.
* libguile/goops.h:
* libguile/goops.c (scm_basic_basic_make_class, scm_sys_compute_slots)
(scm_sys_prep_layout_x): Remove. These were available to C, but were
undocumented internals that were dangerous, confusing, and
unnecessary.
* libguile/goops.c: Add note about variable versus value references.
Remove internal C routines that were just used during boot, as they
have been moved to Scheme.
(scm_basic_make_class): Change to call out to make-standard-class in
Scheme.
(scm_sys_make_root_class, scm_sys_bless_applicable_struct_vtable_x)
(scm_sys_bless_pure_generic_vtable_x, scm_sys_init_layout_x): New
private helpers.
(scm_sys_goops_early_init): Change to capture values defined in
Scheme.
2015-01-04 13:41:09 -05:00
|
|
|
|
#:use-module (ice-9 match)
|
2015-01-12 21:43:48 +01:00
|
|
|
|
#:use-module ((language tree-il primitives)
|
|
|
|
|
|
:select (add-interesting-primitive!))
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
#:export-syntax (define-class class standard-define-class
|
|
|
|
|
|
define-generic define-accessor define-method
|
|
|
|
|
|
define-extended-generic define-extended-generics
|
|
|
|
|
|
method)
|
|
|
|
|
|
#:export ( ;; The root of everything.
|
|
|
|
|
|
<top>
|
|
|
|
|
|
<class> <object>
|
|
|
|
|
|
|
|
|
|
|
|
;; Slot types.
|
2015-01-23 14:51:22 +01:00
|
|
|
|
<slot>
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
<foreign-slot> <protected-slot> <hidden-slot> <opaque-slot>
|
|
|
|
|
|
<read-only-slot> <self-slot> <protected-opaque-slot>
|
|
|
|
|
|
<protected-hidden-slot> <protected-read-only-slot>
|
|
|
|
|
|
<scm-slot> <int-slot> <float-slot> <double-slot>
|
|
|
|
|
|
|
|
|
|
|
|
;; Methods are implementations of generic functions.
|
2011-07-07 00:57:19 +02:00
|
|
|
|
<method> <accessor-method>
|
|
|
|
|
|
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
;; Applicable objects, either procedures or applicable structs.
|
|
|
|
|
|
<procedure-class> <applicable>
|
|
|
|
|
|
<procedure> <primitive-generic>
|
2011-07-07 00:57:19 +02:00
|
|
|
|
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
;; Applicable structs.
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
<applicable-struct-class> <applicable-struct-with-setter-class>
|
|
|
|
|
|
<applicable-struct> <applicable-struct-with-setter>
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
<generic> <extended-generic>
|
|
|
|
|
|
<generic-with-setter> <extended-generic-with-setter>
|
|
|
|
|
|
<accessor> <extended-accessor>
|
|
|
|
|
|
|
|
|
|
|
|
;; Types with their own allocated typecodes.
|
|
|
|
|
|
<boolean> <char> <list> <pair> <null> <string> <symbol>
|
|
|
|
|
|
<vector> <bytevector> <uvec> <foreign> <hashtable>
|
2013-11-19 21:32:42 +01:00
|
|
|
|
<fluid> <dynamic-state> <frame> <vm> <vm-continuation>
|
Keywords have a tc7
* libguile/tags.h (scm_tc7_keyword): Allocate a tc7, so that the VM can
have cheap keyword? tests.
* libguile/keywords.c:
* libguile/keywords.h: Adapt.
* libguile/goops.c (scm_class_of, scm_sys_goops_early_init): Capture
<keyword>.
* libguile/print.c (iprin1): Inline keyword printer.
* libguile/evalext.c (scm_self_evaluating_p): Add keywords here.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_tc16_keyword): Deprecate.
* module/language/cps/compile-bytecode.scm (compile-fun): Add keyword?
case, and bitvector? case while we're at it.
* module/language/cps/effects-analysis.scm (define-primitive-effects):
Add bytevector?, keyword?, and bitvector? cases.
* module/language/cps/primitives.scm (*branching-primcall-arities*): Add
keyword?.
* module/language/cps/types.scm (bitvector?, keyword?, bytevector?): Add
branch inferrers.
* module/language/tree-il/primitives.scm (*interesting-primitive-names*):
(*effect-free-primitives*):
(*effect+exception-free-primitives*): Add bytevector?, keyword?, and
bitvector?.
* module/oop/goops.scm (<keyword>): New class.
* module/system/base/types.scm (%tc7-keyword, cell->object): Add cases.
* module/system/vm/assembler.scm (br-if-keyword): New definition.
* module/system/vm/disassembler.scm (code-annotation): Add br-if-tc7
case for keywords.
* test-suite/tests/types.test ("clonable objects"): Update now that
keywords are cloneable.
2015-01-19 16:57:42 +01:00
|
|
|
|
<keyword>
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
|
|
|
|
|
|
;; Numbers.
|
|
|
|
|
|
<number> <complex> <real> <integer> <fraction>
|
|
|
|
|
|
|
|
|
|
|
|
;; Unknown.
|
|
|
|
|
|
<unknown>
|
|
|
|
|
|
|
|
|
|
|
|
;; Particular SMOB data types. All SMOB types have
|
|
|
|
|
|
;; corresponding classes, which may be obtained via class-of,
|
|
|
|
|
|
;; once you have an instance. Perhaps FIXME to provide a
|
|
|
|
|
|
;; smob-type-name->class procedure.
|
|
|
|
|
|
<arbiter> <promise> <thread> <mutex> <condition-variable>
|
|
|
|
|
|
<regexp> <hook> <bitvector> <random-state> <async>
|
Keywords have a tc7
* libguile/tags.h (scm_tc7_keyword): Allocate a tc7, so that the VM can
have cheap keyword? tests.
* libguile/keywords.c:
* libguile/keywords.h: Adapt.
* libguile/goops.c (scm_class_of, scm_sys_goops_early_init): Capture
<keyword>.
* libguile/print.c (iprin1): Inline keyword printer.
* libguile/evalext.c (scm_self_evaluating_p): Add keywords here.
* libguile/deprecated.h:
* libguile/deprecated.c (scm_tc16_keyword): Deprecate.
* module/language/cps/compile-bytecode.scm (compile-fun): Add keyword?
case, and bitvector? case while we're at it.
* module/language/cps/effects-analysis.scm (define-primitive-effects):
Add bytevector?, keyword?, and bitvector? cases.
* module/language/cps/primitives.scm (*branching-primcall-arities*): Add
keyword?.
* module/language/cps/types.scm (bitvector?, keyword?, bytevector?): Add
branch inferrers.
* module/language/tree-il/primitives.scm (*interesting-primitive-names*):
(*effect-free-primitives*):
(*effect+exception-free-primitives*): Add bytevector?, keyword?, and
bitvector?.
* module/oop/goops.scm (<keyword>): New class.
* module/system/base/types.scm (%tc7-keyword, cell->object): Add cases.
* module/system/vm/assembler.scm (br-if-keyword): New definition.
* module/system/vm/disassembler.scm (code-annotation): Add br-if-tc7
case for keywords.
* test-suite/tests/types.test ("clonable objects"): Update now that
keywords are cloneable.
2015-01-19 16:57:42 +01:00
|
|
|
|
<directory> <array> <character-set>
|
2011-07-26 11:48:37 +02:00
|
|
|
|
<dynamic-object> <guardian> <macro>
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
|
|
|
|
|
|
;; Modules.
|
|
|
|
|
|
<module>
|
|
|
|
|
|
|
|
|
|
|
|
;; Ports.
|
|
|
|
|
|
<port> <input-port> <output-port> <input-output-port>
|
|
|
|
|
|
|
|
|
|
|
|
;; Like SMOB types, all port types have their own classes,
|
|
|
|
|
|
;; which can be accessed via `class-of' once you have an
|
|
|
|
|
|
;; instance. Here we export bindings just for file ports.
|
|
|
|
|
|
<file-port>
|
|
|
|
|
|
<file-input-port> <file-output-port> <file-input-output-port>
|
|
|
|
|
|
|
|
|
|
|
|
is-a? class-of
|
|
|
|
|
|
ensure-metaclass ensure-metaclass-with-supers
|
|
|
|
|
|
make-class
|
|
|
|
|
|
make-generic ensure-generic
|
|
|
|
|
|
make-extended-generic
|
|
|
|
|
|
make-accessor ensure-accessor
|
|
|
|
|
|
add-method!
|
2015-01-09 20:07:06 +01:00
|
|
|
|
class-slot-ref class-slot-set! slot-unbound slot-missing
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
slot-definition-name slot-definition-options
|
|
|
|
|
|
slot-definition-allocation
|
|
|
|
|
|
|
|
|
|
|
|
slot-definition-getter slot-definition-setter
|
|
|
|
|
|
slot-definition-accessor
|
|
|
|
|
|
slot-definition-init-value slot-definition-init-form
|
2015-01-09 20:07:06 +01:00
|
|
|
|
slot-definition-init-thunk slot-definition-init-keyword
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
slot-init-function class-slot-definition
|
|
|
|
|
|
method-source
|
|
|
|
|
|
compute-cpl compute-std-cpl compute-get-n-set compute-slots
|
|
|
|
|
|
compute-getter-method compute-setter-method
|
|
|
|
|
|
allocate-instance initialize make-instance make
|
|
|
|
|
|
no-next-method no-applicable-method no-method
|
|
|
|
|
|
change-class update-instance-for-different-class
|
|
|
|
|
|
shallow-clone deep-clone
|
|
|
|
|
|
class-redefinition
|
|
|
|
|
|
apply-generic apply-method apply-methods
|
|
|
|
|
|
compute-applicable-methods %compute-applicable-methods
|
|
|
|
|
|
method-more-specific? sort-applicable-methods
|
|
|
|
|
|
class-subclasses class-methods
|
|
|
|
|
|
goops-error
|
|
|
|
|
|
min-fixnum max-fixnum
|
2015-01-09 20:07:06 +01:00
|
|
|
|
|
2015-01-16 13:18:05 +01:00
|
|
|
|
instance?
|
|
|
|
|
|
slot-ref slot-set! slot-bound? slot-exists?
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
class-name class-direct-supers class-direct-subclasses
|
|
|
|
|
|
class-direct-methods class-direct-slots class-precedence-list
|
|
|
|
|
|
class-slots
|
|
|
|
|
|
generic-function-name
|
|
|
|
|
|
generic-function-methods method-generic-function
|
|
|
|
|
|
method-specializers method-formals
|
|
|
|
|
|
primitive-generic-generic enable-primitive-generic!
|
|
|
|
|
|
method-procedure accessor-method-slot-definition
|
2015-01-19 22:41:57 +01:00
|
|
|
|
make find-method get-keyword))
|
2001-05-19 00:19:25 +00:00
|
|
|
|
|
2015-01-13 23:04:57 +01:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Booting GOOPS is a tortuous process. We begin by loading a small
|
|
|
|
|
|
;;; set of primitives from C.
|
|
|
|
|
|
;;;
|
2015-01-12 21:43:48 +01:00
|
|
|
|
(eval-when (expand load eval)
|
2014-12-24 11:07:47 -05:00
|
|
|
|
(load-extension (string-append "libguile-" (effective-version))
|
2015-01-12 21:43:48 +01:00
|
|
|
|
"scm_init_goops_builtins")
|
2013-11-30 16:40:17 +01:00
|
|
|
|
(add-interesting-primitive! 'class-of))
|
2009-11-06 12:40:20 +01:00
|
|
|
|
|
2015-01-13 23:04:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; We then define the slots that must appear in all classes (<class>
|
2015-01-16 15:44:48 +01:00
|
|
|
|
;;; objects) and slot definitions (<slot> objects). These slots must
|
|
|
|
|
|
;;; appear in order. We'll use this list to statically compute offsets
|
|
|
|
|
|
;;; for the various fields, to compute the struct layout for <class>
|
|
|
|
|
|
;;; instances, and to compute the slot definition lists for <class>.
|
|
|
|
|
|
;;; Because the list is needed at expansion-time, we define it as a
|
|
|
|
|
|
;;; macro.
|
2015-01-13 23:04:57 +01:00
|
|
|
|
;;;
|
2015-01-09 19:10:51 +01:00
|
|
|
|
(define-syntax macro-fold-left
|
|
|
|
|
|
(syntax-rules ()
|
|
|
|
|
|
((_ folder seed ()) seed)
|
|
|
|
|
|
((_ folder seed (head . tail))
|
|
|
|
|
|
(macro-fold-left folder (folder head seed) tail))))
|
|
|
|
|
|
|
2015-01-07 18:42:27 -05:00
|
|
|
|
(define-syntax macro-fold-right
|
|
|
|
|
|
(syntax-rules ()
|
|
|
|
|
|
((_ folder seed ()) seed)
|
|
|
|
|
|
((_ folder seed (head . tail))
|
|
|
|
|
|
(folder head (macro-fold-right folder seed tail)))))
|
|
|
|
|
|
|
2015-01-16 15:44:48 +01:00
|
|
|
|
(define-syntax-rule (define-macro-folder macro-folder value ...)
|
|
|
|
|
|
(define-syntax macro-folder
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
((_ fold visit seed)
|
|
|
|
|
|
;; The datum->syntax makes it as if each `value' were present
|
|
|
|
|
|
;; in the initial form, which allows them to be used as
|
|
|
|
|
|
;; (components of) introduced identifiers.
|
|
|
|
|
|
#`(fold visit seed #,(datum->syntax #'visit '(value ...))))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define-macro-folder fold-class-slots
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(layout #:class <protected-read-only-slot>)
|
|
|
|
|
|
(flags #:class <hidden-slot>)
|
|
|
|
|
|
(self #:class <self-slot>)
|
|
|
|
|
|
(instance-finalizer #:class <hidden-slot>)
|
2015-01-16 15:44:48 +01:00
|
|
|
|
(print)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(name #:class <protected-hidden-slot>)
|
|
|
|
|
|
(nfields #:class <hidden-slot>)
|
|
|
|
|
|
(%reserved #:class <hidden-slot>)
|
2015-01-16 15:44:48 +01:00
|
|
|
|
(redefined)
|
|
|
|
|
|
(direct-supers)
|
|
|
|
|
|
(direct-slots)
|
|
|
|
|
|
(direct-subclasses)
|
|
|
|
|
|
(direct-methods)
|
|
|
|
|
|
(cpl)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(slots))
|
2015-01-16 15:44:48 +01:00
|
|
|
|
|
|
|
|
|
|
(define-macro-folder fold-slot-slots
|
|
|
|
|
|
(name #:init-keyword #:name)
|
|
|
|
|
|
(allocation #:init-keyword #:allocation #:init-value #:instance)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(init-keyword #:init-keyword #:init-keyword #:init-value #f)
|
2015-01-16 15:44:48 +01:00
|
|
|
|
(init-form #:init-keyword #:init-form)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(init-value #:init-keyword #:init-value)
|
2015-01-16 15:44:48 +01:00
|
|
|
|
(init-thunk #:init-keyword #:init-thunk #:init-value #f)
|
|
|
|
|
|
(options)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(getter #:init-keyword #:getter #:init-value #f)
|
|
|
|
|
|
(setter #:init-keyword #:setter #:init-value #f)
|
|
|
|
|
|
(accessor #:init-keyword #:accessor #:init-value #f)
|
|
|
|
|
|
;; These last don't have #:init-keyword because they are meant to be
|
|
|
|
|
|
;; set by `allocate-slots', not in compute-effective-slot-definition.
|
|
|
|
|
|
(slot-ref #:init-value #f)
|
|
|
|
|
|
(slot-set! #:init-value #f)
|
|
|
|
|
|
(index #:init-value #f)
|
|
|
|
|
|
(size #:init-value #f))
|
2015-01-09 19:10:51 +01:00
|
|
|
|
|
2015-01-13 23:04:57 +01:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; Statically define variables for slot offsets: `class-index-layout'
|
2015-01-16 15:44:48 +01:00
|
|
|
|
;;; will be 0, `class-index-flags' will be 1, and so on, and the same
|
|
|
|
|
|
;;; for `slot-index-name' and such for <slot>.
|
2015-01-13 23:04:57 +01:00
|
|
|
|
;;;
|
2015-01-16 15:44:48 +01:00
|
|
|
|
(let-syntax ((define-slot-indexer
|
|
|
|
|
|
(syntax-rules ()
|
|
|
|
|
|
((_ define-index prefix)
|
|
|
|
|
|
(define-syntax define-index
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(define (id-append ctx a b)
|
|
|
|
|
|
(datum->syntax ctx (symbol-append (syntax->datum a)
|
|
|
|
|
|
(syntax->datum b))))
|
|
|
|
|
|
(define (tail-length tail)
|
|
|
|
|
|
(syntax-case tail ()
|
|
|
|
|
|
((begin) 0)
|
|
|
|
|
|
((visit head tail) (1+ (tail-length #'tail)))))
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
((_ (name . _) tail)
|
|
|
|
|
|
#`(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)))
|
2015-01-13 23:04:57 +01:00
|
|
|
|
|
Manipulate GOOPS vtable flags from Scheme, for speed
* libguile/goops.h: Remove unimplemented declarations of
scm_make_next_method, scm_sys_invalidate_method_cache_x, and
stklos_version.
(scm_sys_invalidate_class_x): Remove helper definition. This was
exported in the past but shouldn't have been.
* libguile/goops.c (scm_sys_make_vtable_vtable): Rename from
scm_sys_make_root_class, and don't do anything about flags.
(scm_sys_bless_applicable_struct_vtables_x, scm_class_p)
(scm_sys_invalidate_class_x): Remove; we do these in Scheme now.
(scm_init_goops_builtins): Define Scheme values for vtable flags.
* module/oop/goops.scm (vtable-flag-goops-metaclass)
(class-add-flags!, class-clear-flags!, class-has-flags?)
(class?, instance?): New definitions.
(<class>): Add GOOPS metaclass flags from Scheme.
(<applicable-struct-class>, <applicable-struct-with-setter-class>):
Add flags from Scheme.
(make, initialize): Add class flags as appropriate.
(class-redefinition): Clear the "valid" flag on the old class.
(check-slot-args): Use instance? instead of a CPL check.
2015-01-16 11:26:25 +01:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; Structs that are vtables have a "flags" slot, which corresponds to
|
|
|
|
|
|
;;; class-index-flags. `vtable-flag-vtable' indicates that instances of
|
|
|
|
|
|
;;; a vtable are themselves vtables, and `vtable-flag-validated'
|
|
|
|
|
|
;;; indicates that the struct's layout has been validated. goops.c
|
2015-01-19 15:57:23 +01:00
|
|
|
|
;;; defines a few additional flags: one to indicate that a vtable is
|
|
|
|
|
|
;;; actually a class, one to indicate that the class is "valid" (meaning
|
|
|
|
|
|
;;; that it hasn't been redefined), and one to indicate that instances
|
|
|
|
|
|
;;; of a class are slot definition objects (<slot> instances).
|
Manipulate GOOPS vtable flags from Scheme, for speed
* libguile/goops.h: Remove unimplemented declarations of
scm_make_next_method, scm_sys_invalidate_method_cache_x, and
stklos_version.
(scm_sys_invalidate_class_x): Remove helper definition. This was
exported in the past but shouldn't have been.
* libguile/goops.c (scm_sys_make_vtable_vtable): Rename from
scm_sys_make_root_class, and don't do anything about flags.
(scm_sys_bless_applicable_struct_vtables_x, scm_class_p)
(scm_sys_invalidate_class_x): Remove; we do these in Scheme now.
(scm_init_goops_builtins): Define Scheme values for vtable flags.
* module/oop/goops.scm (vtable-flag-goops-metaclass)
(class-add-flags!, class-clear-flags!, class-has-flags?)
(class?, instance?): New definitions.
(<class>): Add GOOPS metaclass flags from Scheme.
(<applicable-struct-class>, <applicable-struct-with-setter-class>):
Add flags from Scheme.
(make, initialize): Add class flags as appropriate.
(class-redefinition): Clear the "valid" flag on the old class.
(check-slot-args): Use instance? instead of a CPL check.
2015-01-16 11:26:25 +01:00
|
|
|
|
;;;
|
|
|
|
|
|
(define vtable-flag-goops-metaclass
|
|
|
|
|
|
(logior vtable-flag-vtable vtable-flag-goops-class))
|
|
|
|
|
|
|
|
|
|
|
|
(define-inlinable (class-add-flags! class flags)
|
|
|
|
|
|
(struct-set! class class-index-flags
|
|
|
|
|
|
(logior flags (struct-ref class class-index-flags))))
|
|
|
|
|
|
|
|
|
|
|
|
(define-inlinable (class-clear-flags! class flags)
|
|
|
|
|
|
(struct-set! class class-index-flags
|
|
|
|
|
|
(logand (lognot flags) (struct-ref class class-index-flags))))
|
|
|
|
|
|
|
|
|
|
|
|
(define-inlinable (class-has-flags? class flags)
|
|
|
|
|
|
(eqv? flags
|
|
|
|
|
|
(logand (struct-ref class class-index-flags) flags)))
|
|
|
|
|
|
|
|
|
|
|
|
(define-inlinable (class? obj)
|
|
|
|
|
|
(class-has-flags? (struct-vtable obj) vtable-flag-goops-metaclass))
|
|
|
|
|
|
|
2015-01-19 15:57:23 +01:00
|
|
|
|
(define-inlinable (slot? obj)
|
|
|
|
|
|
(and (struct? obj)
|
|
|
|
|
|
(class-has-flags? (struct-vtable obj) vtable-flag-goops-slot)))
|
|
|
|
|
|
|
Manipulate GOOPS vtable flags from Scheme, for speed
* libguile/goops.h: Remove unimplemented declarations of
scm_make_next_method, scm_sys_invalidate_method_cache_x, and
stklos_version.
(scm_sys_invalidate_class_x): Remove helper definition. This was
exported in the past but shouldn't have been.
* libguile/goops.c (scm_sys_make_vtable_vtable): Rename from
scm_sys_make_root_class, and don't do anything about flags.
(scm_sys_bless_applicable_struct_vtables_x, scm_class_p)
(scm_sys_invalidate_class_x): Remove; we do these in Scheme now.
(scm_init_goops_builtins): Define Scheme values for vtable flags.
* module/oop/goops.scm (vtable-flag-goops-metaclass)
(class-add-flags!, class-clear-flags!, class-has-flags?)
(class?, instance?): New definitions.
(<class>): Add GOOPS metaclass flags from Scheme.
(<applicable-struct-class>, <applicable-struct-with-setter-class>):
Add flags from Scheme.
(make, initialize): Add class flags as appropriate.
(class-redefinition): Clear the "valid" flag on the old class.
(check-slot-args): Use instance? instead of a CPL check.
2015-01-16 11:26:25 +01:00
|
|
|
|
(define-inlinable (instance? obj)
|
|
|
|
|
|
(class-has-flags? (struct-vtable obj) vtable-flag-goops-class))
|
|
|
|
|
|
|
2015-01-13 23:04:57 +01:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; Now that we know the slots that must be present in classes, and
|
|
|
|
|
|
;;; their offsets, we can create the root of the class hierarchy.
|
|
|
|
|
|
;;;
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
;;; Note that the `direct-supers', `direct-slots', `cpl', and `slots'
|
|
|
|
|
|
;;; fields will be updated later, once we can create slot definition
|
|
|
|
|
|
;;; objects and once we have definitions for <top> and <object>.
|
2015-01-13 23:04:57 +01:00
|
|
|
|
;;;
|
|
|
|
|
|
(define <class>
|
|
|
|
|
|
(let-syntax ((cons-layout
|
|
|
|
|
|
;; A simple way to compute class layout for the concrete
|
|
|
|
|
|
;; types used in <class>.
|
|
|
|
|
|
(syntax-rules (<protected-read-only-slot>
|
|
|
|
|
|
<self-slot>
|
|
|
|
|
|
<hidden-slot>
|
|
|
|
|
|
<protected-hidden-slot>)
|
|
|
|
|
|
((_ (name) tail)
|
|
|
|
|
|
(string-append "pw" tail))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
((_ (name #:class <protected-read-only-slot>) tail)
|
2015-01-13 23:04:57 +01:00
|
|
|
|
(string-append "pr" tail))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
((_ (name #:class <self-slot>) tail)
|
2015-01-13 23:04:57 +01:00
|
|
|
|
(string-append "sr" tail))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
((_ (name #:class <hidden-slot>) tail)
|
2015-01-13 23:04:57 +01:00
|
|
|
|
(string-append "uh" tail))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
((_ (name #:class <protected-hidden-slot>) tail)
|
|
|
|
|
|
(string-append "ph" tail)))))
|
2015-01-13 23:04:57 +01:00
|
|
|
|
(let* ((layout (fold-class-slots macro-fold-right cons-layout ""))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(nfields (/ (string-length layout) 2))
|
Manipulate GOOPS vtable flags from Scheme, for speed
* libguile/goops.h: Remove unimplemented declarations of
scm_make_next_method, scm_sys_invalidate_method_cache_x, and
stklos_version.
(scm_sys_invalidate_class_x): Remove helper definition. This was
exported in the past but shouldn't have been.
* libguile/goops.c (scm_sys_make_vtable_vtable): Rename from
scm_sys_make_root_class, and don't do anything about flags.
(scm_sys_bless_applicable_struct_vtables_x, scm_class_p)
(scm_sys_invalidate_class_x): Remove; we do these in Scheme now.
(scm_init_goops_builtins): Define Scheme values for vtable flags.
* module/oop/goops.scm (vtable-flag-goops-metaclass)
(class-add-flags!, class-clear-flags!, class-has-flags?)
(class?, instance?): New definitions.
(<class>): Add GOOPS metaclass flags from Scheme.
(<applicable-struct-class>, <applicable-struct-with-setter-class>):
Add flags from Scheme.
(make, initialize): Add class flags as appropriate.
(class-redefinition): Clear the "valid" flag on the old class.
(check-slot-args): Use instance? instead of a CPL check.
2015-01-16 11:26:25 +01:00
|
|
|
|
(<class> (%make-vtable-vtable layout)))
|
|
|
|
|
|
(class-add-flags! <class> (logior vtable-flag-goops-class
|
|
|
|
|
|
vtable-flag-goops-valid))
|
2015-01-13 23:04:57 +01:00
|
|
|
|
(struct-set! <class> class-index-name '<class>)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(struct-set! <class> class-index-nfields nfields)
|
2015-01-13 23:04:57 +01:00
|
|
|
|
(struct-set! <class> class-index-direct-supers '())
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(struct-set! <class> class-index-direct-slots '())
|
2015-01-13 23:04:57 +01:00
|
|
|
|
(struct-set! <class> class-index-direct-subclasses '())
|
|
|
|
|
|
(struct-set! <class> class-index-direct-methods '())
|
|
|
|
|
|
(struct-set! <class> class-index-cpl '())
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(struct-set! <class> class-index-slots '())
|
2015-01-13 23:04:57 +01:00
|
|
|
|
(struct-set! <class> class-index-redefined #f)
|
|
|
|
|
|
<class>)))
|
Move GOOPS boot to Scheme
* module/oop/goops.scm (build-<class>-slots): New helper, replacing
build_class_class_slots.
(build-slots-list, %compute-getters-n-setters, %compute-layout): New
private helpers, moved here from C.
(%prep-layout!): Reimplement in Scheme.
(make-standard-class): New private helper, replacing
scm_basic_make_class.
(<class>, <top>, <object>): Define in Scheme.
(<foreign-slot>, <protected-slot>, <hidden-slot>, <opaque-slot>,
<read-only-slot>, <self-slot>, <protected-opaque-slot>,
<protected-hidden-slot>, <protected-read-only-slot>, <scm-slot>,
<int-slot>, <float-slot>, <double-slot>, <procedure-class>,
<applicable-struct-class>, <method>, <accessor-method>, <applicable>,
<applicable-struct>, <generic>, <extended-generic>,
<generic-with-setter>, <accessor>, <extended-generic-with-setter>,
<extended-accessor>): Define in Scheme.
(<boolean>, <char>, <list>, <pair>, <null>, <string>, <symbol>,
<vector>, <foreign>, <hashtable>, <fluid>, <dynamic-state>, <frame>,
<vm-continuation>, <bytevector>, <uvec>, <array>, <bitvector>,
<number>, <complex>, <real>, <integer>, <fraction>, <keyword>,
<unknown>, <procedure>, <primitive-generic>, <port>, <input-port>,
<output-port>, <input-output-port>): Define in Scheme.
(compute-slots): Use build-slots-list helper.
* libguile/goops.h:
* libguile/goops.c (scm_basic_basic_make_class, scm_sys_compute_slots)
(scm_sys_prep_layout_x): Remove. These were available to C, but were
undocumented internals that were dangerous, confusing, and
unnecessary.
* libguile/goops.c: Add note about variable versus value references.
Remove internal C routines that were just used during boot, as they
have been moved to Scheme.
(scm_basic_make_class): Change to call out to make-standard-class in
Scheme.
(scm_sys_make_root_class, scm_sys_bless_applicable_struct_vtable_x)
(scm_sys_bless_pure_generic_vtable_x, scm_sys_init_layout_x): New
private helpers.
(scm_sys_goops_early_init): Change to capture values defined in
Scheme.
2015-01-04 13:41:09 -05:00
|
|
|
|
|
2015-01-13 23:04:57 +01:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; Accessors to fields of <class>.
|
|
|
|
|
|
;;;
|
<class> accessors implemented in Scheme
* libguile/goops.c (scm_class_p): New internal helper, exported to
goops.scm.
(scm_class_name, scm_class_direct_supers, scm_class_direct_slots):
(scm_class_direct_subclasses, scm_class_direct_methods):
(scm_class_precedence_list, scm_class_slots): Dispatch to Scheme.
(scm_sys_goops_early_init): Capture <class> accessors.
* module/oop/goops.scm (define-class-accessor): New helper.
(class-name, class-direct-supers, class-direct-slots):
(class-direct-subclasses, class-direct-methods)
(class-precedence-list, class-slots): Define in Scheme.
(compute-std-cpl, compute-cpl): Move lower.
2015-01-09 21:01:03 +01:00
|
|
|
|
(define-syntax-rule (define-class-accessor name docstring field)
|
|
|
|
|
|
(define (name obj)
|
|
|
|
|
|
docstring
|
|
|
|
|
|
(let ((val obj))
|
|
|
|
|
|
(unless (class? val)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a class: ~S"
|
|
|
|
|
|
(list val) #f))
|
|
|
|
|
|
(struct-ref val field))))
|
|
|
|
|
|
|
|
|
|
|
|
(define-class-accessor class-name
|
|
|
|
|
|
"Return the class name of @var{obj}."
|
|
|
|
|
|
class-index-name)
|
|
|
|
|
|
(define-class-accessor class-direct-supers
|
|
|
|
|
|
"Return the direct superclasses of the class @var{obj}."
|
|
|
|
|
|
class-index-direct-supers)
|
|
|
|
|
|
(define-class-accessor class-direct-slots
|
|
|
|
|
|
"Return the direct slots of the class @var{obj}."
|
|
|
|
|
|
class-index-direct-slots)
|
|
|
|
|
|
(define-class-accessor class-direct-subclasses
|
|
|
|
|
|
"Return the direct subclasses of the class @var{obj}."
|
|
|
|
|
|
class-index-direct-subclasses)
|
|
|
|
|
|
(define-class-accessor class-direct-methods
|
|
|
|
|
|
"Return the direct methods of the class @var{obj}."
|
|
|
|
|
|
class-index-direct-methods)
|
|
|
|
|
|
(define-class-accessor class-precedence-list
|
|
|
|
|
|
"Return the class precedence list of the class @var{obj}."
|
|
|
|
|
|
class-index-cpl)
|
|
|
|
|
|
(define-class-accessor class-slots
|
|
|
|
|
|
"Return the slot list of the class @var{obj}."
|
|
|
|
|
|
class-index-slots)
|
|
|
|
|
|
|
2015-01-12 21:16:25 +01:00
|
|
|
|
(define (class-subclasses c)
|
2015-01-13 23:04:57 +01:00
|
|
|
|
"Compute a list of all subclasses of @var{c}, direct and indirect."
|
2015-01-12 21:16:25 +01:00
|
|
|
|
(define (all-subclasses c)
|
|
|
|
|
|
(cons c (append-map all-subclasses
|
|
|
|
|
|
(class-direct-subclasses c))))
|
|
|
|
|
|
(delete-duplicates (cdr (all-subclasses c)) eq?))
|
|
|
|
|
|
|
|
|
|
|
|
(define (class-methods c)
|
2015-01-13 23:04:57 +01:00
|
|
|
|
"Compute a list of all methods that specialize on @var{c} or
|
|
|
|
|
|
subclasses of @var{c}."
|
2015-01-12 21:16:25 +01:00
|
|
|
|
(delete-duplicates (append-map class-direct-methods
|
|
|
|
|
|
(cons c (class-subclasses c)))
|
|
|
|
|
|
eq?))
|
|
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define (is-a? obj class)
|
|
|
|
|
|
"Return @code{#t} if @var{obj} is an instance of @var{class}, or
|
|
|
|
|
|
@code{#f} otherwise."
|
|
|
|
|
|
(and (memq class (class-precedence-list (class-of obj))) #t))
|
|
|
|
|
|
|
2015-01-13 23:04:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
;;; At this point, <class> is missing slot definitions, but we can't
|
|
|
|
|
|
;;; create slot definitions until we have a slot definition class.
|
|
|
|
|
|
;;; Continue with manual object creation until we're able to bootstrap
|
|
|
|
|
|
;;; more of the protocol. Again, the CPL and class hierarchy slots
|
|
|
|
|
|
;;; remain uninitialized.
|
2015-01-13 23:04:57 +01:00
|
|
|
|
;;;
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define* (get-keyword key l #:optional default)
|
|
|
|
|
|
"Determine an associated value for the keyword @var{key} from the list
|
|
|
|
|
|
@var{l}. The list @var{l} has to consist of an even number of elements,
|
|
|
|
|
|
where, starting with the first, every second element is a keyword,
|
|
|
|
|
|
followed by its associated value. If @var{l} does not hold a value for
|
|
|
|
|
|
@var{key}, the value @var{default} is returned."
|
|
|
|
|
|
(unless (keyword? key)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a keyword: ~S" (list key) #f))
|
|
|
|
|
|
(let lp ((l l))
|
|
|
|
|
|
(match l
|
|
|
|
|
|
(() default)
|
|
|
|
|
|
((kw arg . l)
|
|
|
|
|
|
(unless (keyword? kw)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a keyword: ~S" (list kw) #f))
|
|
|
|
|
|
(if (eq? kw key) arg (lp l))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define *unbound* (list 'unbound))
|
|
|
|
|
|
|
|
|
|
|
|
(define-inlinable (unbound? x)
|
|
|
|
|
|
(eq? x *unbound*))
|
|
|
|
|
|
|
|
|
|
|
|
(define (%allocate-instance class)
|
|
|
|
|
|
(let ((obj (allocate-struct class (struct-ref class class-index-nfields))))
|
|
|
|
|
|
(%clear-fields! obj *unbound*)
|
|
|
|
|
|
obj))
|
|
|
|
|
|
|
|
|
|
|
|
(define <slot>
|
|
|
|
|
|
(let-syntax ((cons-layout
|
|
|
|
|
|
;; All slots are "pw" in <slot>.
|
|
|
|
|
|
(syntax-rules ()
|
|
|
|
|
|
((_ _ tail) (string-append "pw" tail)))))
|
|
|
|
|
|
(let* ((layout (fold-slot-slots macro-fold-right cons-layout ""))
|
|
|
|
|
|
(nfields (/ (string-length layout) 2))
|
|
|
|
|
|
(<slot> (make-struct/no-tail <class> (make-struct-layout layout))))
|
|
|
|
|
|
(class-add-flags! <slot> (logior vtable-flag-goops-class
|
2015-01-18 21:01:31 +01:00
|
|
|
|
vtable-flag-goops-slot
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
vtable-flag-goops-valid))
|
|
|
|
|
|
(struct-set! <slot> class-index-name '<slot>)
|
|
|
|
|
|
(struct-set! <slot> class-index-nfields nfields)
|
|
|
|
|
|
(struct-set! <slot> class-index-direct-supers '())
|
|
|
|
|
|
(struct-set! <slot> class-index-direct-slots '())
|
|
|
|
|
|
(struct-set! <slot> class-index-direct-subclasses '())
|
|
|
|
|
|
(struct-set! <slot> class-index-direct-methods '())
|
|
|
|
|
|
(struct-set! <slot> class-index-cpl (list <slot>))
|
|
|
|
|
|
(struct-set! <slot> class-index-slots '())
|
|
|
|
|
|
(struct-set! <slot> class-index-redefined #f)
|
|
|
|
|
|
<slot>)))
|
|
|
|
|
|
|
2015-01-19 22:41:57 +01:00
|
|
|
|
;;; Access to slot objects is performance-sensitive for slot-ref, so in
|
|
|
|
|
|
;;; addition to the type-checking accessors that we export, we also
|
|
|
|
|
|
;;; define some internal inlined helpers that just do an unchecked
|
|
|
|
|
|
;;; struct-ref in cases where we know the object must be a slot, as
|
|
|
|
|
|
;;; when accessing class-slots.
|
|
|
|
|
|
;;;
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(define-syntax-rule (define-slot-accessor name docstring %name field)
|
|
|
|
|
|
(begin
|
|
|
|
|
|
(define-syntax-rule (%name obj)
|
|
|
|
|
|
(struct-ref obj field))
|
|
|
|
|
|
(define (name obj)
|
|
|
|
|
|
docstring
|
|
|
|
|
|
(unless (slot? obj)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a slot: ~S"
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(list obj) #f))
|
|
|
|
|
|
(%name obj))))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
|
|
|
|
|
|
(define-slot-accessor slot-definition-name
|
|
|
|
|
|
"Return the name of @var{obj}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-name slot-index-name)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-allocation
|
|
|
|
|
|
"Return the allocation of the slot @var{obj}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-allocation slot-index-allocation)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-init-keyword
|
|
|
|
|
|
"Return the init keyword of the slot @var{obj}, or @code{#f}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-init-keyword slot-index-init-keyword)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-init-form
|
|
|
|
|
|
"Return the init form of the slot @var{obj}, or the unbound value"
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-init-form slot-index-init-form)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-init-value
|
|
|
|
|
|
"Return the init value of the slot @var{obj}, or the unbound value."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-init-value slot-index-init-value)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-init-thunk
|
|
|
|
|
|
"Return the init thunk of the slot @var{obj}, or @code{#f}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-init-thunk slot-index-init-thunk)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-options
|
|
|
|
|
|
"Return the initargs given when creating the slot @var{obj}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-options slot-index-options)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-getter
|
|
|
|
|
|
"Return the getter of the slot @var{obj}, or @code{#f}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-getter slot-index-getter)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-setter
|
|
|
|
|
|
"Return the setter of the slot @var{obj}, or @code{#f}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-setter slot-index-setter)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-accessor
|
|
|
|
|
|
"Return the accessor of the slot @var{obj}, or @code{#f}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-accessor slot-index-accessor)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-slot-ref
|
|
|
|
|
|
"Return the slot-ref procedure of the slot @var{obj}, or @code{#f}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-slot-ref slot-index-slot-ref)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-slot-set!
|
|
|
|
|
|
"Return the slot-set! procedure of the slot @var{obj}, or @code{#f}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-slot-set! slot-index-slot-set!)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-index
|
|
|
|
|
|
"Return the allocated struct offset of the slot @var{obj}, or @code{#f}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-index slot-index-index)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-slot-accessor slot-definition-size
|
|
|
|
|
|
"Return the number fields used by the slot @var{obj}, or @code{#f}."
|
2015-01-19 12:20:50 +01:00
|
|
|
|
%slot-definition-size slot-index-size)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
|
|
|
|
|
|
;; Boot definition.
|
|
|
|
|
|
(define (direct-slot-definition-class class initargs)
|
|
|
|
|
|
(get-keyword #:class initargs <slot>))
|
|
|
|
|
|
|
|
|
|
|
|
;; Boot definition.
|
|
|
|
|
|
(define (make-slot class initargs)
|
|
|
|
|
|
(let ((slot (make-struct/no-tail class)))
|
|
|
|
|
|
(define-syntax-rule (init-slot offset kw default)
|
|
|
|
|
|
(struct-set! slot offset (get-keyword kw initargs default)))
|
|
|
|
|
|
(init-slot slot-index-name #:name #f)
|
|
|
|
|
|
(init-slot slot-index-allocation #:allocation #:instance)
|
|
|
|
|
|
(init-slot slot-index-init-keyword #:init-keyword #f)
|
|
|
|
|
|
(init-slot slot-index-init-form #:init-form *unbound*)
|
|
|
|
|
|
(init-slot slot-index-init-value #:init-value *unbound*)
|
|
|
|
|
|
(struct-set! slot slot-index-init-thunk
|
|
|
|
|
|
(or (get-keyword #:init-thunk initargs #f)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(let ((val (%slot-definition-init-value slot)))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(if (unbound? val)
|
|
|
|
|
|
#f
|
|
|
|
|
|
(lambda () val)))))
|
|
|
|
|
|
(struct-set! slot slot-index-options initargs)
|
|
|
|
|
|
(init-slot slot-index-getter #:getter #f)
|
|
|
|
|
|
(init-slot slot-index-setter #:setter #f)
|
|
|
|
|
|
(init-slot slot-index-accessor #:accessor #f)
|
|
|
|
|
|
(init-slot slot-index-slot-ref #:slot-ref #f)
|
|
|
|
|
|
(init-slot slot-index-slot-set! #:slot-set! #f)
|
|
|
|
|
|
(init-slot slot-index-index #:index #f)
|
|
|
|
|
|
(init-slot slot-index-size #:size #f)
|
|
|
|
|
|
slot))
|
|
|
|
|
|
|
|
|
|
|
|
;; Boot definition.
|
|
|
|
|
|
(define (make class . args)
|
|
|
|
|
|
(unless (memq <slot> (class-precedence-list class))
|
|
|
|
|
|
(error "Unsupported class: ~S" class))
|
|
|
|
|
|
(make-slot class args))
|
|
|
|
|
|
|
|
|
|
|
|
;; Boot definition.
|
|
|
|
|
|
(define (compute-direct-slot-definition class initargs)
|
|
|
|
|
|
(apply make (direct-slot-definition-class class initargs) initargs))
|
|
|
|
|
|
|
|
|
|
|
|
(define (compute-direct-slot-definition-initargs class slot-spec)
|
|
|
|
|
|
(match slot-spec
|
|
|
|
|
|
((? symbol? name) (list #:name name))
|
|
|
|
|
|
(((? symbol? name) . initargs)
|
|
|
|
|
|
(cons* #:name name
|
|
|
|
|
|
;; If there is an #:init-form, the `class' macro will have
|
|
|
|
|
|
;; already added an #:init-thunk. Still, if there isn't an
|
|
|
|
|
|
;; #:init-thunk already but we do have an #:init-value,
|
|
|
|
|
|
;; synthesize an #:init-thunk initarg. This will ensure
|
|
|
|
|
|
;; that the #:init-thunk gets passed on to the effective
|
|
|
|
|
|
;; slot definition too.
|
|
|
|
|
|
(if (get-keyword #:init-thunk initargs)
|
|
|
|
|
|
initargs
|
|
|
|
|
|
(let ((value (get-keyword #:init-value initargs *unbound*)))
|
|
|
|
|
|
(if (unbound? value)
|
|
|
|
|
|
initargs
|
|
|
|
|
|
(cons* #:init-thunk (lambda () value) initargs))))))))
|
|
|
|
|
|
|
|
|
|
|
|
(let ()
|
|
|
|
|
|
(define-syntax cons-slot
|
|
|
|
|
|
(syntax-rules ()
|
|
|
|
|
|
((_ (name #:class class) tail)
|
|
|
|
|
|
;; Special case to avoid referencing specialized <slot> kinds,
|
|
|
|
|
|
;; which are not defined yet.
|
|
|
|
|
|
(cons (list 'name) tail))
|
|
|
|
|
|
((_ (name . initargs) tail)
|
|
|
|
|
|
(cons (list 'name . initargs) tail))))
|
|
|
|
|
|
(define-syntax-rule (initialize-direct-slots! class fold-slots)
|
|
|
|
|
|
(let ((specs (fold-slots macro-fold-right cons-slot '())))
|
|
|
|
|
|
(define (make-direct-slot-definition spec)
|
|
|
|
|
|
(let ((initargs (compute-direct-slot-definition-initargs class spec)))
|
|
|
|
|
|
(compute-direct-slot-definition class initargs)))
|
|
|
|
|
|
(struct-set! class class-index-direct-slots
|
|
|
|
|
|
(map make-direct-slot-definition specs))))
|
|
|
|
|
|
|
|
|
|
|
|
(initialize-direct-slots! <class> fold-class-slots)
|
|
|
|
|
|
(initialize-direct-slots! <slot> fold-slot-slots))
|
2015-01-13 23:04:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
;;; OK, at this point we have initialized `direct-slots' on both <class>
|
|
|
|
|
|
;;; and <slot>. We need to define a standard way to make subclasses:
|
|
|
|
|
|
;;; how to compute the precedence list of subclasses, how to compute the
|
|
|
|
|
|
;;; list of slots in a subclass, and what layout to use for instances of
|
|
|
|
|
|
;;; those classes.
|
2015-01-13 23:04:57 +01:00
|
|
|
|
;;;
|
<class> accessors implemented in Scheme
* libguile/goops.c (scm_class_p): New internal helper, exported to
goops.scm.
(scm_class_name, scm_class_direct_supers, scm_class_direct_slots):
(scm_class_direct_subclasses, scm_class_direct_methods):
(scm_class_precedence_list, scm_class_slots): Dispatch to Scheme.
(scm_sys_goops_early_init): Capture <class> accessors.
* module/oop/goops.scm (define-class-accessor): New helper.
(class-name, class-direct-supers, class-direct-slots):
(class-direct-subclasses, class-direct-methods)
(class-precedence-list, class-slots): Define in Scheme.
(compute-std-cpl, compute-cpl): Move lower.
2015-01-09 21:01:03 +01:00
|
|
|
|
(define (compute-std-cpl c get-direct-supers)
|
2015-01-13 21:07:42 +01:00
|
|
|
|
"The standard class precedence list computation algorithm."
|
<class> accessors implemented in Scheme
* libguile/goops.c (scm_class_p): New internal helper, exported to
goops.scm.
(scm_class_name, scm_class_direct_supers, scm_class_direct_slots):
(scm_class_direct_subclasses, scm_class_direct_methods):
(scm_class_precedence_list, scm_class_slots): Dispatch to Scheme.
(scm_sys_goops_early_init): Capture <class> accessors.
* module/oop/goops.scm (define-class-accessor): New helper.
(class-name, class-direct-supers, class-direct-slots):
(class-direct-subclasses, class-direct-methods)
(class-precedence-list, class-slots): Define in Scheme.
(compute-std-cpl, compute-cpl): Move lower.
2015-01-09 21:01:03 +01:00
|
|
|
|
(define (only-non-null lst)
|
|
|
|
|
|
(filter (lambda (l) (not (null? l))) lst))
|
|
|
|
|
|
|
|
|
|
|
|
(define (merge-lists reversed-partial-result inputs)
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((every null? inputs)
|
|
|
|
|
|
(reverse! reversed-partial-result))
|
|
|
|
|
|
(else
|
|
|
|
|
|
(let* ((candidate (lambda (c)
|
|
|
|
|
|
(and (not (any (lambda (l)
|
|
|
|
|
|
(memq c (cdr l)))
|
|
|
|
|
|
inputs))
|
|
|
|
|
|
c)))
|
|
|
|
|
|
(candidate-car (lambda (l)
|
|
|
|
|
|
(and (not (null? l))
|
|
|
|
|
|
(candidate (car l)))))
|
|
|
|
|
|
(next (any candidate-car inputs)))
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(unless next
|
|
|
|
|
|
(goops-error "merge-lists: Inconsistent precedence graph"))
|
<class> accessors implemented in Scheme
* libguile/goops.c (scm_class_p): New internal helper, exported to
goops.scm.
(scm_class_name, scm_class_direct_supers, scm_class_direct_slots):
(scm_class_direct_subclasses, scm_class_direct_methods):
(scm_class_precedence_list, scm_class_slots): Dispatch to Scheme.
(scm_sys_goops_early_init): Capture <class> accessors.
* module/oop/goops.scm (define-class-accessor): New helper.
(class-name, class-direct-supers, class-direct-slots):
(class-direct-subclasses, class-direct-methods)
(class-precedence-list, class-slots): Define in Scheme.
(compute-std-cpl, compute-cpl): Move lower.
2015-01-09 21:01:03 +01:00
|
|
|
|
(let ((remove-next (lambda (l)
|
|
|
|
|
|
(if (eq? (car l) next)
|
|
|
|
|
|
(cdr l)
|
|
|
|
|
|
l))))
|
|
|
|
|
|
(merge-lists (cons next reversed-partial-result)
|
|
|
|
|
|
(only-non-null (map remove-next inputs))))))))
|
|
|
|
|
|
(let ((c-direct-supers (get-direct-supers c)))
|
|
|
|
|
|
(merge-lists (list c)
|
|
|
|
|
|
(only-non-null (append (map class-precedence-list
|
|
|
|
|
|
c-direct-supers)
|
|
|
|
|
|
(list c-direct-supers))))))
|
|
|
|
|
|
|
2015-01-13 21:07:42 +01:00
|
|
|
|
;; This version of compute-cpl is replaced with a generic function once
|
|
|
|
|
|
;; GOOPS has booted.
|
<class> accessors implemented in Scheme
* libguile/goops.c (scm_class_p): New internal helper, exported to
goops.scm.
(scm_class_name, scm_class_direct_supers, scm_class_direct_slots):
(scm_class_direct_subclasses, scm_class_direct_methods):
(scm_class_precedence_list, scm_class_slots): Dispatch to Scheme.
(scm_sys_goops_early_init): Capture <class> accessors.
* module/oop/goops.scm (define-class-accessor): New helper.
(class-name, class-direct-supers, class-direct-slots):
(class-direct-subclasses, class-direct-methods)
(class-precedence-list, class-slots): Define in Scheme.
(compute-std-cpl, compute-cpl): Move lower.
2015-01-09 21:01:03 +01:00
|
|
|
|
(define (compute-cpl class)
|
|
|
|
|
|
(compute-std-cpl class class-direct-supers))
|
|
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define (effective-slot-definition-class class slot)
|
|
|
|
|
|
(class-of slot))
|
|
|
|
|
|
|
|
|
|
|
|
(define (compute-effective-slot-definition class slot)
|
|
|
|
|
|
;; FIXME: Support slot being a list of slots, as in CLOS.
|
|
|
|
|
|
(apply make
|
|
|
|
|
|
(effective-slot-definition-class class slot)
|
|
|
|
|
|
(slot-definition-options slot)))
|
|
|
|
|
|
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define (build-slots-list dslots cpl)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define (slot-memq slot slots)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(let ((name (%slot-definition-name slot)))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(let lp ((slots slots))
|
|
|
|
|
|
(match slots
|
|
|
|
|
|
(() #f)
|
|
|
|
|
|
((slot . slots)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(or (eq? (%slot-definition-name slot) name) (lp slots)))))))
|
2015-01-18 21:01:31 +01:00
|
|
|
|
(define (check-cpl slots static-slots)
|
|
|
|
|
|
(when (or-map (lambda (slot) (slot-memq slot slots)) static-slots)
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(scm-error 'misc-error #f
|
2015-01-18 21:01:31 +01:00
|
|
|
|
"a predefined static inherited field cannot be redefined"
|
2015-01-04 15:52:12 -05:00
|
|
|
|
'() '())))
|
|
|
|
|
|
(define (remove-duplicate-slots slots)
|
|
|
|
|
|
(let lp ((slots (reverse slots)) (res '()) (seen '()))
|
2015-01-14 20:15:53 +01:00
|
|
|
|
(match slots
|
|
|
|
|
|
(() res)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
((slot . slots)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(let ((name (%slot-definition-name slot)))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(if (memq name seen)
|
|
|
|
|
|
(lp slots res seen)
|
|
|
|
|
|
(lp slots (cons slot res) (cons name seen))))))))
|
2015-01-18 21:01:31 +01:00
|
|
|
|
;; For subclases of <class> and <slot>, we need to ensure that the
|
|
|
|
|
|
;; <class> or <slot> slots come first.
|
|
|
|
|
|
(let* ((static-slots (cond
|
|
|
|
|
|
((memq <class> cpl)
|
|
|
|
|
|
(when (memq <slot> cpl) (error "invalid class"))
|
|
|
|
|
|
(struct-ref <class> class-index-slots))
|
|
|
|
|
|
((memq <slot> cpl)
|
|
|
|
|
|
(struct-ref <slot> class-index-slots))
|
|
|
|
|
|
(else #f))))
|
|
|
|
|
|
(when static-slots
|
|
|
|
|
|
(check-cpl dslots static-slots))
|
|
|
|
|
|
(let lp ((cpl (cdr cpl)) (res dslots) (static-slots '()))
|
2015-01-14 20:15:53 +01:00
|
|
|
|
(match cpl
|
2015-01-18 21:01:31 +01:00
|
|
|
|
(() (remove-duplicate-slots (append static-slots res)))
|
2015-01-14 20:15:53 +01:00
|
|
|
|
((head . cpl)
|
|
|
|
|
|
(let ((new-slots (struct-ref head class-index-direct-slots)))
|
|
|
|
|
|
(cond
|
2015-01-18 21:01:31 +01:00
|
|
|
|
((not static-slots)
|
|
|
|
|
|
(lp cpl (append new-slots res) static-slots))
|
|
|
|
|
|
((or (eq? head <class>) (eq? head <slot>))
|
|
|
|
|
|
;; Move static slots to the head of the list.
|
2015-01-14 20:15:53 +01:00
|
|
|
|
(lp cpl res new-slots))
|
|
|
|
|
|
(else
|
2015-01-18 21:01:31 +01:00
|
|
|
|
(check-cpl new-slots static-slots)
|
|
|
|
|
|
(lp cpl (append new-slots res) static-slots)))))))))
|
Move GOOPS boot to Scheme
* module/oop/goops.scm (build-<class>-slots): New helper, replacing
build_class_class_slots.
(build-slots-list, %compute-getters-n-setters, %compute-layout): New
private helpers, moved here from C.
(%prep-layout!): Reimplement in Scheme.
(make-standard-class): New private helper, replacing
scm_basic_make_class.
(<class>, <top>, <object>): Define in Scheme.
(<foreign-slot>, <protected-slot>, <hidden-slot>, <opaque-slot>,
<read-only-slot>, <self-slot>, <protected-opaque-slot>,
<protected-hidden-slot>, <protected-read-only-slot>, <scm-slot>,
<int-slot>, <float-slot>, <double-slot>, <procedure-class>,
<applicable-struct-class>, <method>, <accessor-method>, <applicable>,
<applicable-struct>, <generic>, <extended-generic>,
<generic-with-setter>, <accessor>, <extended-generic-with-setter>,
<extended-accessor>): Define in Scheme.
(<boolean>, <char>, <list>, <pair>, <null>, <string>, <symbol>,
<vector>, <foreign>, <hashtable>, <fluid>, <dynamic-state>, <frame>,
<vm-continuation>, <bytevector>, <uvec>, <array>, <bitvector>,
<number>, <complex>, <real>, <integer>, <fraction>, <keyword>,
<unknown>, <procedure>, <primitive-generic>, <port>, <input-port>,
<output-port>, <input-output-port>): Define in Scheme.
(compute-slots): Use build-slots-list helper.
* libguile/goops.h:
* libguile/goops.c (scm_basic_basic_make_class, scm_sys_compute_slots)
(scm_sys_prep_layout_x): Remove. These were available to C, but were
undocumented internals that were dangerous, confusing, and
unnecessary.
* libguile/goops.c: Add note about variable versus value references.
Remove internal C routines that were just used during boot, as they
have been moved to Scheme.
(scm_basic_make_class): Change to call out to make-standard-class in
Scheme.
(scm_sys_make_root_class, scm_sys_bless_applicable_struct_vtable_x)
(scm_sys_bless_pure_generic_vtable_x, scm_sys_init_layout_x): New
private helpers.
(scm_sys_goops_early_init): Change to capture values defined in
Scheme.
2015-01-04 13:41:09 -05:00
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
;; Boot definition.
|
|
|
|
|
|
(define (compute-get-n-set class slot)
|
|
|
|
|
|
(let ((index (struct-ref class class-index-nfields)))
|
|
|
|
|
|
(struct-set! class class-index-nfields (1+ index))
|
|
|
|
|
|
index))
|
|
|
|
|
|
|
|
|
|
|
|
(define (allocate-slots class slots)
|
|
|
|
|
|
"Transform the computed list of direct slot definitions @var{slots}
|
|
|
|
|
|
into a corresponding list of effective slot definitions, allocating
|
|
|
|
|
|
slots as we go."
|
|
|
|
|
|
(define (make-effective-slot-definition slot)
|
|
|
|
|
|
;; `compute-get-n-set' is expected to mutate `nfields' if it
|
|
|
|
|
|
;; allocates a field to the object. Pretty strange, but we preserve
|
|
|
|
|
|
;; the behavior for backward compatibility.
|
|
|
|
|
|
(let* ((slot (compute-effective-slot-definition class slot))
|
|
|
|
|
|
(index (struct-ref class class-index-nfields))
|
|
|
|
|
|
(g-n-s (compute-get-n-set class slot))
|
|
|
|
|
|
(size (- (struct-ref class class-index-nfields) index)))
|
|
|
|
|
|
(call-with-values
|
|
|
|
|
|
(lambda ()
|
|
|
|
|
|
(match g-n-s
|
|
|
|
|
|
((? integer?)
|
|
|
|
|
|
(unless (= size 1)
|
|
|
|
|
|
(error "unexpected return from compute-get-n-set"))
|
|
|
|
|
|
(values #f #f))
|
|
|
|
|
|
(((? procedure? get) (? procedure? set))
|
|
|
|
|
|
(values get set))))
|
|
|
|
|
|
(lambda (get set)
|
|
|
|
|
|
(struct-set! slot slot-index-index index)
|
|
|
|
|
|
(struct-set! slot slot-index-size size)
|
|
|
|
|
|
(struct-set! slot slot-index-slot-ref get)
|
|
|
|
|
|
(struct-set! slot slot-index-slot-set! set)))
|
|
|
|
|
|
slot))
|
|
|
|
|
|
(struct-set! class class-index-nfields 0)
|
|
|
|
|
|
(map-in-order make-effective-slot-definition slots))
|
|
|
|
|
|
|
|
|
|
|
|
(define (%compute-layout slots nfields is-class?)
|
|
|
|
|
|
(define (slot-protection-and-kind slot)
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define (subclass? class parent)
|
|
|
|
|
|
(memq parent (class-precedence-list class)))
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(let ((type (kw-arg-ref (%slot-definition-options slot) #:class)))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(if (and type (subclass? type <foreign-slot>))
|
|
|
|
|
|
(values (cond
|
|
|
|
|
|
((subclass? type <self-slot>) #\s)
|
|
|
|
|
|
((subclass? type <protected-slot>) #\p)
|
|
|
|
|
|
(else #\u))
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((subclass? type <opaque-slot>) #\o)
|
|
|
|
|
|
((subclass? type <read-only-slot>) #\r)
|
|
|
|
|
|
((subclass? type <hidden-slot>) #\h)
|
|
|
|
|
|
(else #\w)))
|
|
|
|
|
|
(values #\p #\w))))
|
|
|
|
|
|
(let ((layout (make-string (* nfields 2))))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(let lp ((n 0) (slots slots))
|
|
|
|
|
|
(match slots
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(()
|
|
|
|
|
|
(unless (= n nfields) (error "bad nfields"))
|
|
|
|
|
|
(when is-class?
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(let ((class-layout (struct-ref <class> class-index-layout)))
|
|
|
|
|
|
(unless (string-prefix? (symbol->string class-layout) layout)
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(error "bad layout for class"))))
|
|
|
|
|
|
layout)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
((slot . slots)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(unless (= n (%slot-definition-index slot)) (error "bad allocation"))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(call-with-values (lambda () (slot-protection-and-kind slot))
|
|
|
|
|
|
(lambda (protection kind)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(let init ((n n) (size (%slot-definition-size slot)))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(cond
|
|
|
|
|
|
((zero? size) (lp n slots))
|
|
|
|
|
|
(else
|
|
|
|
|
|
(unless (< n nfields) (error "bad nfields"))
|
|
|
|
|
|
(string-set! layout (* n 2) protection)
|
|
|
|
|
|
(string-set! layout (1+ (* n 2)) kind)
|
|
|
|
|
|
(init (1+ n) (1- size))))))))))))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
|
2015-01-13 23:04:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; With all of this, we are now able to define subclasses of <class>.
|
|
|
|
|
|
;;;
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define (%prep-layout! class)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(let* ((is-class? (and (memq <class> (struct-ref class class-index-cpl)) #t))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(layout (%compute-layout (struct-ref class class-index-slots)
|
|
|
|
|
|
(struct-ref class class-index-nfields)
|
|
|
|
|
|
is-class?)))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(%init-layout! class layout)))
|
|
|
|
|
|
|
|
|
|
|
|
(define (make-standard-class class name dsupers dslots)
|
|
|
|
|
|
(let ((z (make-struct/no-tail class)))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define (make-direct-slot-definition dslot)
|
|
|
|
|
|
(let ((initargs (compute-direct-slot-definition-initargs z dslot)))
|
|
|
|
|
|
(compute-direct-slot-definition z initargs)))
|
|
|
|
|
|
|
|
|
|
|
|
(struct-set! z class-index-name name)
|
|
|
|
|
|
(struct-set! z class-index-nfields 0)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(struct-set! z class-index-direct-supers dsupers)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(struct-set! z class-index-direct-subclasses '())
|
|
|
|
|
|
(struct-set! z class-index-direct-methods '())
|
|
|
|
|
|
(struct-set! z class-index-redefined #f)
|
|
|
|
|
|
(let ((cpl (compute-cpl z)))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(struct-set! z class-index-cpl cpl)
|
2015-01-18 21:01:31 +01:00
|
|
|
|
(when (memq <slot> cpl)
|
|
|
|
|
|
(class-add-flags! z vtable-flag-goops-slot))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(let* ((dslots (map make-direct-slot-definition dslots))
|
|
|
|
|
|
(slots (allocate-slots z (build-slots-list dslots cpl))))
|
|
|
|
|
|
(struct-set! z class-index-direct-slots dslots)
|
|
|
|
|
|
(struct-set! z class-index-slots slots)))
|
|
|
|
|
|
(for-each
|
|
|
|
|
|
(lambda (super)
|
|
|
|
|
|
(let ((subclasses (struct-ref super class-index-direct-subclasses)))
|
|
|
|
|
|
(struct-set! super class-index-direct-subclasses
|
|
|
|
|
|
(cons z subclasses))))
|
|
|
|
|
|
dsupers)
|
|
|
|
|
|
(%prep-layout! z)
|
|
|
|
|
|
z))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
|
|
|
|
|
|
(define-syntax define-standard-class
|
|
|
|
|
|
(syntax-rules ()
|
|
|
|
|
|
((define-standard-class name (super ...) #:metaclass meta slot ...)
|
|
|
|
|
|
(define name
|
|
|
|
|
|
(make-standard-class meta 'name (list super ...) '(slot ...))))
|
|
|
|
|
|
((define-standard-class name (super ...) slot ...)
|
|
|
|
|
|
(define-standard-class name (super ...) #:metaclass <class> slot ...))))
|
|
|
|
|
|
|
2015-01-13 23:04:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Sweet! Now we can define <top> and <object>, and finish
|
|
|
|
|
|
;;; initializing the `direct-subclasses', `direct-supers', and `cpl'
|
|
|
|
|
|
;;; slots of <class>.
|
|
|
|
|
|
;;;
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define-standard-class <top> ())
|
|
|
|
|
|
(define-standard-class <object> (<top>))
|
|
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
;; The inheritance links for <top>, <object>, <class>, and <slot> were
|
|
|
|
|
|
;; partially initialized. Correct them here.
|
|
|
|
|
|
(struct-set! <object> class-index-direct-subclasses (list <slot> <class>))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(struct-set! <class> class-index-direct-supers (list <object>))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(struct-set! <slot> class-index-direct-supers (list <object>))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(struct-set! <class> class-index-cpl (list <class> <object> <top>))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(struct-set! <slot> class-index-cpl (list <slot> <object> <top>))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
|
2015-01-13 23:04:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; We can also define the various slot types, and finish initializing
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
;;; `direct-slots' and `slots' on <class> and <slot>.
|
2015-01-13 23:04:57 +01:00
|
|
|
|
;;;
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-standard-class <foreign-slot> (<slot>))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define-standard-class <protected-slot> (<foreign-slot>))
|
|
|
|
|
|
(define-standard-class <hidden-slot> (<foreign-slot>))
|
|
|
|
|
|
(define-standard-class <opaque-slot> (<foreign-slot>))
|
|
|
|
|
|
(define-standard-class <read-only-slot> (<foreign-slot>))
|
|
|
|
|
|
(define-standard-class <self-slot> (<read-only-slot>))
|
|
|
|
|
|
(define-standard-class <protected-opaque-slot> (<protected-slot>
|
|
|
|
|
|
<opaque-slot>))
|
|
|
|
|
|
(define-standard-class <protected-hidden-slot> (<protected-slot>
|
|
|
|
|
|
<hidden-slot>))
|
|
|
|
|
|
(define-standard-class <protected-read-only-slot> (<protected-slot>
|
|
|
|
|
|
<read-only-slot>))
|
|
|
|
|
|
(define-standard-class <scm-slot> (<protected-slot>))
|
|
|
|
|
|
(define-standard-class <int-slot> (<foreign-slot>))
|
|
|
|
|
|
(define-standard-class <float-slot> (<foreign-slot>))
|
|
|
|
|
|
(define-standard-class <double-slot> (<foreign-slot>))
|
|
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Finally! Initialize `direct-slots' and `slots' on <class>, and
|
|
|
|
|
|
;;; `slots' on <slot>.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
(let ()
|
|
|
|
|
|
(define-syntax-rule (cons-slot (name . initargs) tail)
|
|
|
|
|
|
(cons (list 'name . initargs) tail))
|
|
|
|
|
|
(define-syntax-rule (initialize-direct-slots! class fold-slots)
|
|
|
|
|
|
(let ((specs (fold-slots macro-fold-right cons-slot '())))
|
|
|
|
|
|
(define (make-direct-slot-definition spec)
|
|
|
|
|
|
(let ((initargs (compute-direct-slot-definition-initargs class spec)))
|
|
|
|
|
|
(compute-direct-slot-definition class initargs)))
|
|
|
|
|
|
(struct-set! class class-index-direct-slots
|
|
|
|
|
|
(map make-direct-slot-definition specs))))
|
|
|
|
|
|
(define (initialize-slots! class)
|
|
|
|
|
|
(let ((slots (build-slots-list (class-direct-slots class)
|
|
|
|
|
|
(class-precedence-list class))))
|
|
|
|
|
|
(struct-set! class class-index-slots (allocate-slots class slots))))
|
|
|
|
|
|
|
|
|
|
|
|
;; Finish initializing <class> with the specialized slot kinds.
|
|
|
|
|
|
(initialize-direct-slots! <class> fold-class-slots)
|
|
|
|
|
|
|
|
|
|
|
|
(initialize-slots! <class>)
|
|
|
|
|
|
(initialize-slots! <slot>))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
|
2015-01-13 23:04:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Now, to build out the class hierarchy.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define-standard-class <procedure-class> (<class>))
|
Manipulate GOOPS vtable flags from Scheme, for speed
* libguile/goops.h: Remove unimplemented declarations of
scm_make_next_method, scm_sys_invalidate_method_cache_x, and
stklos_version.
(scm_sys_invalidate_class_x): Remove helper definition. This was
exported in the past but shouldn't have been.
* libguile/goops.c (scm_sys_make_vtable_vtable): Rename from
scm_sys_make_root_class, and don't do anything about flags.
(scm_sys_bless_applicable_struct_vtables_x, scm_class_p)
(scm_sys_invalidate_class_x): Remove; we do these in Scheme now.
(scm_init_goops_builtins): Define Scheme values for vtable flags.
* module/oop/goops.scm (vtable-flag-goops-metaclass)
(class-add-flags!, class-clear-flags!, class-has-flags?)
(class?, instance?): New definitions.
(<class>): Add GOOPS metaclass flags from Scheme.
(<applicable-struct-class>, <applicable-struct-with-setter-class>):
Add flags from Scheme.
(make, initialize): Add class flags as appropriate.
(class-redefinition): Clear the "valid" flag on the old class.
(check-slot-args): Use instance? instead of a CPL check.
2015-01-16 11:26:25 +01:00
|
|
|
|
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
(define-standard-class <applicable-struct-class>
|
|
|
|
|
|
(<procedure-class>))
|
Manipulate GOOPS vtable flags from Scheme, for speed
* libguile/goops.h: Remove unimplemented declarations of
scm_make_next_method, scm_sys_invalidate_method_cache_x, and
stklos_version.
(scm_sys_invalidate_class_x): Remove helper definition. This was
exported in the past but shouldn't have been.
* libguile/goops.c (scm_sys_make_vtable_vtable): Rename from
scm_sys_make_root_class, and don't do anything about flags.
(scm_sys_bless_applicable_struct_vtables_x, scm_class_p)
(scm_sys_invalidate_class_x): Remove; we do these in Scheme now.
(scm_init_goops_builtins): Define Scheme values for vtable flags.
* module/oop/goops.scm (vtable-flag-goops-metaclass)
(class-add-flags!, class-clear-flags!, class-has-flags?)
(class?, instance?): New definitions.
(<class>): Add GOOPS metaclass flags from Scheme.
(<applicable-struct-class>, <applicable-struct-with-setter-class>):
Add flags from Scheme.
(make, initialize): Add class flags as appropriate.
(class-redefinition): Clear the "valid" flag on the old class.
(check-slot-args): Use instance? instead of a CPL check.
2015-01-16 11:26:25 +01:00
|
|
|
|
(class-add-flags! <applicable-struct-class>
|
|
|
|
|
|
vtable-flag-applicable-vtable)
|
|
|
|
|
|
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
(define-standard-class <applicable-struct-with-setter-class>
|
|
|
|
|
|
(<applicable-struct-class>))
|
Manipulate GOOPS vtable flags from Scheme, for speed
* libguile/goops.h: Remove unimplemented declarations of
scm_make_next_method, scm_sys_invalidate_method_cache_x, and
stklos_version.
(scm_sys_invalidate_class_x): Remove helper definition. This was
exported in the past but shouldn't have been.
* libguile/goops.c (scm_sys_make_vtable_vtable): Rename from
scm_sys_make_root_class, and don't do anything about flags.
(scm_sys_bless_applicable_struct_vtables_x, scm_class_p)
(scm_sys_invalidate_class_x): Remove; we do these in Scheme now.
(scm_init_goops_builtins): Define Scheme values for vtable flags.
* module/oop/goops.scm (vtable-flag-goops-metaclass)
(class-add-flags!, class-clear-flags!, class-has-flags?)
(class?, instance?): New definitions.
(<class>): Add GOOPS metaclass flags from Scheme.
(<applicable-struct-class>, <applicable-struct-with-setter-class>):
Add flags from Scheme.
(make, initialize): Add class flags as appropriate.
(class-redefinition): Clear the "valid" flag on the old class.
(check-slot-args): Use instance? instead of a CPL check.
2015-01-16 11:26:25 +01:00
|
|
|
|
(class-add-flags! <applicable-struct-with-setter-class>
|
|
|
|
|
|
vtable-flag-setter-vtable)
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define-standard-class <applicable> (<top>))
|
|
|
|
|
|
(define-standard-class <applicable-struct> (<object> <applicable>)
|
|
|
|
|
|
#:metaclass <applicable-struct-class>
|
|
|
|
|
|
procedure)
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
(define-standard-class <applicable-struct-with-setter> (<applicable-struct>)
|
|
|
|
|
|
#:metaclass <applicable-struct-with-setter-class>
|
|
|
|
|
|
setter)
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define-standard-class <generic> (<applicable-struct>)
|
|
|
|
|
|
#:metaclass <applicable-struct-class>
|
|
|
|
|
|
methods
|
|
|
|
|
|
(n-specialized #:init-value 0)
|
|
|
|
|
|
(extended-by #:init-value ())
|
|
|
|
|
|
effective-methods)
|
|
|
|
|
|
(define-standard-class <extended-generic> (<generic>)
|
|
|
|
|
|
#:metaclass <applicable-struct-class>
|
|
|
|
|
|
(extends #:init-value ()))
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
(define-standard-class <generic-with-setter> (<generic>
|
|
|
|
|
|
<applicable-struct-with-setter>)
|
|
|
|
|
|
#:metaclass <applicable-struct-with-setter-class>)
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define-standard-class <accessor> (<generic-with-setter>)
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
#:metaclass <applicable-struct-with-setter-class>)
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define-standard-class <extended-generic-with-setter> (<extended-generic>
|
|
|
|
|
|
<generic-with-setter>)
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
#:metaclass <applicable-struct-with-setter-class>)
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define-standard-class <extended-accessor> (<accessor>
|
|
|
|
|
|
<extended-generic-with-setter>)
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
#:metaclass <applicable-struct-with-setter-class>)
|
2015-01-04 15:52:12 -05:00
|
|
|
|
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
(define-standard-class <method> (<object>)
|
|
|
|
|
|
generic-function
|
|
|
|
|
|
specializers
|
|
|
|
|
|
procedure
|
|
|
|
|
|
formals
|
|
|
|
|
|
body
|
|
|
|
|
|
make-procedure)
|
|
|
|
|
|
(define-standard-class <accessor-method> (<method>)
|
|
|
|
|
|
(slot-definition #:init-keyword #:slot-definition))
|
|
|
|
|
|
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define-standard-class <boolean> (<top>))
|
|
|
|
|
|
(define-standard-class <char> (<top>))
|
|
|
|
|
|
(define-standard-class <list> (<top>))
|
2015-01-21 15:16:56 +01:00
|
|
|
|
;; Not all pairs are lists, but there is code out there that relies on
|
|
|
|
|
|
;; (is-a? '(1 2 3) <list>) to work. Terrible. How to fix?
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define-standard-class <pair> (<list>))
|
|
|
|
|
|
(define-standard-class <null> (<list>))
|
|
|
|
|
|
(define-standard-class <string> (<top>))
|
|
|
|
|
|
(define-standard-class <symbol> (<top>))
|
|
|
|
|
|
(define-standard-class <vector> (<top>))
|
|
|
|
|
|
(define-standard-class <foreign> (<top>))
|
|
|
|
|
|
(define-standard-class <hashtable> (<top>))
|
|
|
|
|
|
(define-standard-class <fluid> (<top>))
|
|
|
|
|
|
(define-standard-class <dynamic-state> (<top>))
|
|
|
|
|
|
(define-standard-class <frame> (<top>))
|
|
|
|
|
|
(define-standard-class <vm-continuation> (<top>))
|
|
|
|
|
|
(define-standard-class <bytevector> (<top>))
|
|
|
|
|
|
(define-standard-class <uvec> (<bytevector>))
|
|
|
|
|
|
(define-standard-class <array> (<top>))
|
|
|
|
|
|
(define-standard-class <bitvector> (<top>))
|
|
|
|
|
|
(define-standard-class <number> (<top>))
|
|
|
|
|
|
(define-standard-class <complex> (<number>))
|
|
|
|
|
|
(define-standard-class <real> (<complex>))
|
|
|
|
|
|
(define-standard-class <integer> (<real>))
|
|
|
|
|
|
(define-standard-class <fraction> (<real>))
|
|
|
|
|
|
(define-standard-class <keyword> (<top>))
|
|
|
|
|
|
(define-standard-class <unknown> (<top>))
|
|
|
|
|
|
(define-standard-class <procedure> (<applicable>)
|
|
|
|
|
|
#:metaclass <procedure-class>)
|
|
|
|
|
|
(define-standard-class <primitive-generic> (<procedure>)
|
|
|
|
|
|
#:metaclass <procedure-class>)
|
|
|
|
|
|
(define-standard-class <port> (<top>))
|
|
|
|
|
|
(define-standard-class <input-port> (<port>))
|
|
|
|
|
|
(define-standard-class <output-port> (<port>))
|
|
|
|
|
|
(define-standard-class <input-output-port> (<input-port> <output-port>))
|
|
|
|
|
|
|
2015-01-11 20:49:16 +01:00
|
|
|
|
(define (inherit-applicable! class)
|
|
|
|
|
|
"An internal routine to redefine a SMOB class that was added after
|
|
|
|
|
|
GOOPS was loaded, and on which scm_set_smob_apply installed an apply
|
|
|
|
|
|
function."
|
|
|
|
|
|
;; Why not use class-redefinition? We would, except that loading the
|
|
|
|
|
|
;; compiler to compile effective methods can happen while GOOPS has
|
|
|
|
|
|
;; only been partially loaded, and loading the compiler might cause
|
|
|
|
|
|
;; SMOB types to be defined that need this facility. Instead we make
|
|
|
|
|
|
;; a very specific hack, not a general solution. Probably the right
|
|
|
|
|
|
;; solution is to avoid using the compiler, but that is another kettle
|
|
|
|
|
|
;; of fish.
|
|
|
|
|
|
(unless (memq <applicable> (class-precedence-list class))
|
|
|
|
|
|
(unless (null? (class-slots class))
|
|
|
|
|
|
(error "SMOB object has slots?"))
|
|
|
|
|
|
(for-each
|
|
|
|
|
|
(lambda (super)
|
|
|
|
|
|
(let ((subclasses (struct-ref super class-index-direct-subclasses)))
|
|
|
|
|
|
(struct-set! super class-index-direct-subclasses
|
|
|
|
|
|
(delq class subclasses))))
|
|
|
|
|
|
(struct-ref class class-index-direct-supers))
|
|
|
|
|
|
(struct-set! class class-index-direct-supers (list <applicable>))
|
|
|
|
|
|
(struct-set! class class-index-cpl (compute-cpl class))
|
|
|
|
|
|
(let ((subclasses (struct-ref <applicable> class-index-direct-subclasses)))
|
|
|
|
|
|
(struct-set! <applicable> class-index-direct-subclasses
|
|
|
|
|
|
(cons class subclasses)))))
|
|
|
|
|
|
|
2015-01-13 23:16:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; At this point we have defined the class hierarchy, and it's time to
|
|
|
|
|
|
;;; move on to instance allocation and generics. Once we have generics,
|
|
|
|
|
|
;;; we'll fill out the metaobject protocol.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Here we define a limited version of `make', so that we can allocate
|
|
|
|
|
|
;;; instances of specific classes. This definition will be replaced
|
|
|
|
|
|
;;; later.
|
|
|
|
|
|
;;;
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define (%invalidate-method-cache! gf)
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(slot-set! gf 'effective-methods '())
|
|
|
|
|
|
(recompute-generic-function-dispatch-procedure! gf))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
|
|
|
|
|
|
;; Boot definition.
|
|
|
|
|
|
(define (invalidate-method-cache! gf)
|
|
|
|
|
|
(%invalidate-method-cache! gf))
|
|
|
|
|
|
|
|
|
|
|
|
(define (make class . args)
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((or (eq? class <generic>) (eq? class <accessor>))
|
|
|
|
|
|
(let ((z (make-struct/no-tail class #f '() 0 '())))
|
|
|
|
|
|
(set-procedure-property! z 'name (get-keyword #:name args #f))
|
|
|
|
|
|
(invalidate-method-cache! z)
|
|
|
|
|
|
(when (eq? class <accessor>)
|
|
|
|
|
|
(let ((setter (get-keyword #:setter args #f)))
|
|
|
|
|
|
(when setter
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
(slot-set! z 'setter setter))))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
z))
|
|
|
|
|
|
(else
|
2015-01-11 19:11:41 +01:00
|
|
|
|
(let ((z (%allocate-instance class)))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(cond
|
|
|
|
|
|
((or (eq? class <method>) (eq? class <accessor-method>))
|
|
|
|
|
|
(for-each (match-lambda
|
|
|
|
|
|
((kw slot default)
|
|
|
|
|
|
(slot-set! z slot (get-keyword kw args default))))
|
|
|
|
|
|
'((#:generic-function generic-function #f)
|
|
|
|
|
|
(#:specializers specializers ())
|
|
|
|
|
|
(#:procedure procedure #f)
|
|
|
|
|
|
(#:formals formals ())
|
|
|
|
|
|
(#:body body ())
|
|
|
|
|
|
(#:make-procedure make-procedure #f))))
|
|
|
|
|
|
((memq <class> (class-precedence-list class))
|
Manipulate GOOPS vtable flags from Scheme, for speed
* libguile/goops.h: Remove unimplemented declarations of
scm_make_next_method, scm_sys_invalidate_method_cache_x, and
stklos_version.
(scm_sys_invalidate_class_x): Remove helper definition. This was
exported in the past but shouldn't have been.
* libguile/goops.c (scm_sys_make_vtable_vtable): Rename from
scm_sys_make_root_class, and don't do anything about flags.
(scm_sys_bless_applicable_struct_vtables_x, scm_class_p)
(scm_sys_invalidate_class_x): Remove; we do these in Scheme now.
(scm_init_goops_builtins): Define Scheme values for vtable flags.
* module/oop/goops.scm (vtable-flag-goops-metaclass)
(class-add-flags!, class-clear-flags!, class-has-flags?)
(class?, instance?): New definitions.
(<class>): Add GOOPS metaclass flags from Scheme.
(<applicable-struct-class>, <applicable-struct-with-setter-class>):
Add flags from Scheme.
(make, initialize): Add class flags as appropriate.
(class-redefinition): Clear the "valid" flag on the old class.
(check-slot-args): Use instance? instead of a CPL check.
2015-01-16 11:26:25 +01:00
|
|
|
|
(class-add-flags! z (logior vtable-flag-goops-class
|
|
|
|
|
|
vtable-flag-goops-valid))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(for-each (match-lambda
|
|
|
|
|
|
((kw slot default)
|
|
|
|
|
|
(slot-set! z slot (get-keyword kw args default))))
|
|
|
|
|
|
'((#:name name ???)
|
|
|
|
|
|
(#:dsupers direct-supers ())
|
2015-01-14 20:15:53 +01:00
|
|
|
|
(#:slots direct-slots ()))))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(else
|
|
|
|
|
|
(error "boot `make' does not support this class" class)))
|
|
|
|
|
|
z))))
|
|
|
|
|
|
|
2015-01-13 23:16:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
;;; Slot access.
|
2015-01-14 00:01:51 +01:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; Before we go on, some notes about class redefinition. In GOOPS,
|
|
|
|
|
|
;;; classes can be redefined. Redefinition of a class marks the class
|
|
|
|
|
|
;;; as invalid, and instances will be lazily migrated over to the new
|
|
|
|
|
|
;;; representation as they are accessed. Migration happens when
|
|
|
|
|
|
;;; `class-of' is called on an instance. For more technical details on
|
|
|
|
|
|
;;; object redefinition, see struct.h.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; In the following interfaces, class-of handles the redefinition
|
|
|
|
|
|
;;; protocol. I would think though that there is some thread-unsafety
|
|
|
|
|
|
;;; here though as the { class, object data } pair needs to be accessed
|
|
|
|
|
|
;;; atomically, not the { class, object } pair.
|
|
|
|
|
|
;;;
|
2015-01-18 21:02:51 +01:00
|
|
|
|
(define-inlinable (%class-slot-definition class slot-name kt kf)
|
|
|
|
|
|
(let lp ((slots (struct-ref class class-index-slots)))
|
|
|
|
|
|
(match slots
|
|
|
|
|
|
((slot . slots)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(if (eq? (%slot-definition-name slot) slot-name)
|
2015-01-18 21:02:51 +01:00
|
|
|
|
(kt slot)
|
|
|
|
|
|
(lp slots)))
|
|
|
|
|
|
(_ (kf)))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (class-slot-definition class slot-name)
|
|
|
|
|
|
(unless (class? class)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a class: ~S" (list class) #f))
|
|
|
|
|
|
(%class-slot-definition class slot-name
|
|
|
|
|
|
(lambda (slot) slot)
|
|
|
|
|
|
(lambda () #f)))
|
2015-01-10 00:50:33 +01:00
|
|
|
|
|
|
|
|
|
|
(define (slot-ref obj slot-name)
|
|
|
|
|
|
"Return the value from @var{obj}'s slot with the nam var{slot_name}."
|
2015-01-18 21:02:51 +01:00
|
|
|
|
(let ((class (class-of obj)))
|
|
|
|
|
|
(define (slot-value slot)
|
|
|
|
|
|
(cond
|
2015-01-19 12:20:50 +01:00
|
|
|
|
((%slot-definition-slot-ref slot)
|
2015-01-18 21:02:51 +01:00
|
|
|
|
=> (lambda (slot-ref) (slot-ref obj)))
|
|
|
|
|
|
(else
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(struct-ref obj (%slot-definition-index slot)))))
|
2015-01-18 21:02:51 +01:00
|
|
|
|
(define (have-slot slot)
|
|
|
|
|
|
(let ((val (slot-value slot)))
|
|
|
|
|
|
(if (unbound? val)
|
|
|
|
|
|
(slot-unbound class obj slot-name)
|
|
|
|
|
|
val)))
|
|
|
|
|
|
(define (no-slot)
|
|
|
|
|
|
(unless (symbol? slot-name)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a symbol: ~S"
|
|
|
|
|
|
(list slot-name) #f))
|
|
|
|
|
|
(let ((val (slot-missing class obj slot-name)))
|
|
|
|
|
|
(if (unbound? val)
|
|
|
|
|
|
(slot-unbound class obj slot-name)
|
|
|
|
|
|
val)))
|
|
|
|
|
|
(%class-slot-definition class slot-name have-slot no-slot)))
|
2015-01-10 00:50:33 +01:00
|
|
|
|
|
|
|
|
|
|
(define (slot-set! obj slot-name value)
|
|
|
|
|
|
"Set the slot named @var{slot_name} of @var{obj} to @var{value}."
|
2015-01-18 21:02:51 +01:00
|
|
|
|
(let ((class (class-of obj)))
|
|
|
|
|
|
(define (have-slot slot)
|
|
|
|
|
|
(cond
|
2015-01-19 12:20:50 +01:00
|
|
|
|
((%slot-definition-slot-set! slot)
|
2015-01-18 21:02:51 +01:00
|
|
|
|
=> (lambda (slot-set!) (slot-set! obj value)))
|
|
|
|
|
|
(else
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(struct-set! obj (%slot-definition-index slot) value))))
|
2015-01-18 21:02:51 +01:00
|
|
|
|
(define (no-slot)
|
|
|
|
|
|
(unless (symbol? slot-name)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a symbol: ~S"
|
|
|
|
|
|
(list slot-name) #f))
|
|
|
|
|
|
(slot-missing class obj slot-name value))
|
|
|
|
|
|
|
|
|
|
|
|
(%class-slot-definition class slot-name have-slot no-slot)))
|
2015-01-10 00:50:33 +01:00
|
|
|
|
|
|
|
|
|
|
(define (slot-bound? obj slot-name)
|
|
|
|
|
|
"Return the value from @var{obj}'s slot with the nam var{slot_name}."
|
2015-01-18 21:02:51 +01:00
|
|
|
|
(let ((class (class-of obj)))
|
|
|
|
|
|
(define (slot-value slot)
|
|
|
|
|
|
(cond
|
2015-01-19 12:20:50 +01:00
|
|
|
|
((%slot-definition-slot-ref slot)
|
2015-01-18 21:02:51 +01:00
|
|
|
|
=> (lambda (slot-ref) (slot-ref obj)))
|
|
|
|
|
|
(else
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(struct-ref obj (%slot-definition-index slot)))))
|
2015-01-18 21:02:51 +01:00
|
|
|
|
(define (have-slot slot)
|
|
|
|
|
|
(not (unbound? (slot-value slot))))
|
|
|
|
|
|
(define (no-slot)
|
|
|
|
|
|
(unless (symbol? slot-name)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a symbol: ~S"
|
|
|
|
|
|
(list slot-name) #f))
|
|
|
|
|
|
(let ((val (slot-missing class obj slot-name)))
|
|
|
|
|
|
(if (unbound? val)
|
|
|
|
|
|
(slot-unbound class obj slot-name)
|
|
|
|
|
|
val)))
|
|
|
|
|
|
(%class-slot-definition class slot-name have-slot no-slot)))
|
2015-01-10 00:50:33 +01:00
|
|
|
|
|
|
|
|
|
|
(define (slot-exists? obj slot-name)
|
|
|
|
|
|
"Return @code{#t} if @var{obj} has a slot named @var{slot_name}."
|
2015-01-18 21:02:51 +01:00
|
|
|
|
(define (have-slot slot) #t)
|
|
|
|
|
|
(define (no-slot)
|
|
|
|
|
|
(unless (symbol? slot-name)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a symbol: ~S"
|
|
|
|
|
|
(list slot-name) #f))
|
|
|
|
|
|
#f)
|
|
|
|
|
|
(%class-slot-definition (class-of obj) slot-name have-slot no-slot))
|
2015-01-10 00:50:33 +01:00
|
|
|
|
|
2015-01-16 13:18:05 +01:00
|
|
|
|
(begin-deprecated
|
|
|
|
|
|
(define (check-slot-args class obj slot-name)
|
|
|
|
|
|
(unless (eq? class (class-of obj))
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "~S is not the class of ~S"
|
|
|
|
|
|
(list class obj) #f))
|
|
|
|
|
|
(unless (symbol? slot-name)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a symbol: ~S"
|
|
|
|
|
|
(list slot-name) #f)))
|
|
|
|
|
|
|
|
|
|
|
|
(define (slot-ref-using-class class obj slot-name)
|
|
|
|
|
|
(issue-deprecation-warning "slot-ref-using-class is deprecated. "
|
|
|
|
|
|
"Use slot-ref instead.")
|
|
|
|
|
|
(check-slot-args class obj slot-name)
|
|
|
|
|
|
(slot-ref obj slot-name))
|
|
|
|
|
|
|
|
|
|
|
|
(define (slot-set-using-class! class obj slot-name value)
|
|
|
|
|
|
(issue-deprecation-warning "slot-set-using-class! is deprecated. "
|
|
|
|
|
|
"Use slot-set! instead.")
|
|
|
|
|
|
(check-slot-args class obj slot-name)
|
|
|
|
|
|
(slot-set! obj slot-name value))
|
|
|
|
|
|
|
|
|
|
|
|
(define (slot-bound-using-class? class obj slot-name)
|
|
|
|
|
|
(issue-deprecation-warning "slot-bound-using-class? is deprecated. "
|
|
|
|
|
|
"Use slot-bound? instead.")
|
|
|
|
|
|
(check-slot-args class obj slot-name)
|
|
|
|
|
|
(slot-bound? obj slot-name))
|
|
|
|
|
|
|
|
|
|
|
|
(define (slot-exists-using-class? class obj slot-name)
|
|
|
|
|
|
(issue-deprecation-warning "slot-exists-using-class? is deprecated. "
|
|
|
|
|
|
"Use slot-exists? instead.")
|
|
|
|
|
|
(check-slot-args class obj slot-name)
|
|
|
|
|
|
(slot-exists? obj slot-name)))
|
|
|
|
|
|
|
2015-01-14 00:01:51 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Method accessors.
|
|
|
|
|
|
;;;
|
2015-01-09 22:05:01 +01:00
|
|
|
|
(define (method-generic-function obj)
|
|
|
|
|
|
"Return the generic function for the method @var{obj}."
|
|
|
|
|
|
(unless (is-a? obj <method>)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a method: ~S"
|
|
|
|
|
|
(list obj) #f))
|
|
|
|
|
|
(slot-ref obj 'generic-function))
|
|
|
|
|
|
|
|
|
|
|
|
(define (method-specializers obj)
|
|
|
|
|
|
"Return specializers of the method @var{obj}."
|
|
|
|
|
|
(unless (is-a? obj <method>)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a method: ~S"
|
|
|
|
|
|
(list obj) #f))
|
|
|
|
|
|
(slot-ref obj 'specializers))
|
|
|
|
|
|
|
|
|
|
|
|
(define (method-procedure obj)
|
|
|
|
|
|
"Return the procedure of the method @var{obj}."
|
|
|
|
|
|
(unless (is-a? obj <method>)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a method: ~S"
|
|
|
|
|
|
(list obj) #f))
|
|
|
|
|
|
(slot-ref obj 'procedure))
|
|
|
|
|
|
|
2015-01-14 00:01:51 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Generic functions!
|
2015-01-04 15:52:12 -05:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; Generic functions have an applicable-methods cache associated with
|
|
|
|
|
|
;;; them. Every distinct set of types that is dispatched through a
|
2015-01-21 15:16:56 +01:00
|
|
|
|
;;; generic adds an entry to the cache. A composite dispatch procedure
|
|
|
|
|
|
;;; is recomputed every time an entry gets added to the cache, or when
|
|
|
|
|
|
;;; the cache is invalidated.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; In steady-state, this dispatch procedure is never regenerated; but
|
|
|
|
|
|
;;; during warm-up there is some churn.
|
2015-01-04 15:52:12 -05:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; So what is the deal if warm-up happens in a multithreaded context?
|
|
|
|
|
|
;;; There is indeed a window between missing the cache for a certain set
|
|
|
|
|
|
;;; of arguments, and then updating the cache with the newly computed
|
|
|
|
|
|
;;; applicable methods. One of the updaters is liable to lose their new
|
|
|
|
|
|
;;; entry.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; This is actually OK though, because a subsequent cache miss for the
|
|
|
|
|
|
;;; race loser will just cause memoization to try again. The cache will
|
2015-01-21 15:16:56 +01:00
|
|
|
|
;;; eventually be consistent. We're not mutating the old part of the
|
2015-01-04 15:52:12 -05:00
|
|
|
|
;;; cache, just consing on the new entry.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; It doesn't even matter if the dispatch procedure and the cache are
|
|
|
|
|
|
;;; inconsistent -- most likely the type-set that lost the dispatch
|
|
|
|
|
|
;;; procedure race will simply re-trigger a memoization, but since the
|
|
|
|
|
|
;;; winner isn't in the effective-methods cache, it will likely also
|
|
|
|
|
|
;;; re-trigger a memoization, and the cache will finally be consistent.
|
|
|
|
|
|
;;; As you can see there is a possibility for ping-pong effects, but
|
|
|
|
|
|
;;; it's unlikely given the shortness of the window between slot-set!
|
2015-01-21 15:16:56 +01:00
|
|
|
|
;;; invocations.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; We probably do need to use atomic access primitives to correctly
|
|
|
|
|
|
;;; handle concurrency, but that's a more general Guile concern.
|
|
|
|
|
|
;;;
|
2015-01-04 15:52:12 -05:00
|
|
|
|
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(define-syntax arity-case
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
;; (arity-case n 2 foo bar)
|
|
|
|
|
|
;; => (case n
|
|
|
|
|
|
;; ((0) (foo))
|
|
|
|
|
|
;; ((1) (foo a))
|
|
|
|
|
|
;; ((2) (foo a b))
|
|
|
|
|
|
;; (else bar))
|
|
|
|
|
|
((arity-case n max form alternate)
|
|
|
|
|
|
(let ((max (syntax->datum #'max)))
|
|
|
|
|
|
#`(case n
|
|
|
|
|
|
#,@(let lp ((n 0))
|
|
|
|
|
|
(let ((ids (map (lambda (n)
|
|
|
|
|
|
(let* ((n (+ (char->integer #\a) n))
|
|
|
|
|
|
(c (integer->char n)))
|
|
|
|
|
|
(datum->syntax #'here (symbol c))))
|
|
|
|
|
|
(iota n))))
|
|
|
|
|
|
#`(((#,n) (form #,@ids))
|
|
|
|
|
|
. #,(if (< n max)
|
|
|
|
|
|
(lp (1+ n))
|
|
|
|
|
|
#'()))))
|
|
|
|
|
|
(else alternate)))))))
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; These dispatchers are set as the "procedure" field of <generic>
|
|
|
|
|
|
;;; instances. Unlike CLOS, in GOOPS a generic function can have
|
|
|
|
|
|
;;; multiple arities.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; We pre-generate fast dispatchers for applications of up to 20
|
|
|
|
|
|
;;; arguments. More arguments than that will go through slower generic
|
|
|
|
|
|
;;; routines that cons arguments into a rest list.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
(define (multiple-arity-dispatcher fv miss)
|
|
|
|
|
|
(define-syntax dispatch
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(define (build-clauses args)
|
|
|
|
|
|
(let ((len (length (syntax->datum args))))
|
|
|
|
|
|
#`((#,args ((vector-ref fv #,len) . #,args))
|
|
|
|
|
|
. #,(syntax-case args ()
|
|
|
|
|
|
(() #'())
|
|
|
|
|
|
((arg ... _) (build-clauses #'(arg ...)))))))
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
((dispatch arg ...)
|
|
|
|
|
|
#`(case-lambda
|
|
|
|
|
|
#,@(build-clauses #'(arg ...))
|
|
|
|
|
|
(args (apply miss args)))))))
|
|
|
|
|
|
(arity-case (vector-length fv) 20 dispatch
|
|
|
|
|
|
(lambda args
|
|
|
|
|
|
(let ((nargs (length args)))
|
|
|
|
|
|
(if (< nargs (vector-length fv))
|
|
|
|
|
|
(apply (vector-ref fv nargs) args)
|
|
|
|
|
|
(apply miss args))))))
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; The above multiple-arity-dispatcher is entirely sufficient, and
|
|
|
|
|
|
;;; should be fast enough. Still, for no good reason we also have an
|
|
|
|
|
|
;;; arity dispatcher for generics that are only called with one arity.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
(define (single-arity-dispatcher f nargs miss)
|
|
|
|
|
|
(define-syntax-rule (dispatch arg ...)
|
|
|
|
|
|
(case-lambda
|
|
|
|
|
|
((arg ...) (f arg ...))
|
|
|
|
|
|
(args (apply miss args))))
|
|
|
|
|
|
(arity-case nargs 20 dispatch
|
|
|
|
|
|
(lambda args
|
|
|
|
|
|
(if (eqv? (length args) nargs)
|
|
|
|
|
|
(apply f args)
|
|
|
|
|
|
(apply miss args)))))
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; The guts of generic function dispatch are here. Once we've selected
|
|
|
|
|
|
;;; an arity, we need to map from arguments to effective method. Until
|
|
|
|
|
|
;;; we have `eqv?' specializers, this map is entirely a function of the
|
|
|
|
|
|
;;; types (classes) of the arguments. So, we look in the cache to see
|
|
|
|
|
|
;;; if we have seen this set of concrete types, and if so we apply the
|
|
|
|
|
|
;;; previously computed effective method. Otherwise we miss the cache,
|
|
|
|
|
|
;;; so we'll have to compute the right answer for this set of types, add
|
|
|
|
|
|
;;; the mapping to the cache, and apply the newly computed method.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; The cached mapping is invalidated whenever a new method is defined
|
|
|
|
|
|
;;; on this generic, or whenever the class hierarchy of any method
|
|
|
|
|
|
;;; specializer changes.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
(define (single-arity-cache-dispatch cache nargs cache-miss)
|
|
|
|
|
|
(match cache
|
|
|
|
|
|
(() cache-miss)
|
2015-01-21 15:53:53 +01:00
|
|
|
|
(((typev . cmethod) . cache)
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(cond
|
2015-01-21 15:53:53 +01:00
|
|
|
|
((eqv? nargs (vector-length typev))
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(let ((cache-miss (single-arity-cache-dispatch cache nargs cache-miss)))
|
2015-01-21 15:53:53 +01:00
|
|
|
|
(define (type-ref n)
|
|
|
|
|
|
(and (< n nargs) (vector-ref typev n)))
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(define-syntax args-match?
|
|
|
|
|
|
(syntax-rules ()
|
|
|
|
|
|
((args-match?) #t)
|
|
|
|
|
|
((args-match? (arg type) (arg* type*) ...)
|
|
|
|
|
|
;; Check that the arg has the exact type that we saw. It
|
|
|
|
|
|
;; could be that `type' is #f, which indicates the end of
|
|
|
|
|
|
;; the specializers list. Once all specializers have been
|
|
|
|
|
|
;; examined, we don't need to look at any more arguments
|
|
|
|
|
|
;; to know that this is a cache hit.
|
|
|
|
|
|
(or (not type)
|
|
|
|
|
|
(and (eq? (class-of arg) type)
|
|
|
|
|
|
(args-match? (arg* type*) ...))))))
|
|
|
|
|
|
(define-syntax dispatch
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(define (bind-types types k)
|
|
|
|
|
|
(let lp ((types types) (n 0))
|
|
|
|
|
|
(syntax-case types ()
|
|
|
|
|
|
(() (k))
|
|
|
|
|
|
((type . types)
|
|
|
|
|
|
#`(let ((type (type-ref #,n)))
|
|
|
|
|
|
#,(lp #'types (1+ n)))))))
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
((dispatch arg ...)
|
|
|
|
|
|
(with-syntax (((type ...) (generate-temporaries #'(arg ...))))
|
|
|
|
|
|
(bind-types
|
|
|
|
|
|
#'(type ...)
|
|
|
|
|
|
(lambda ()
|
|
|
|
|
|
#'(lambda (arg ...)
|
|
|
|
|
|
(if (args-match? (arg type) ...)
|
|
|
|
|
|
(cmethod arg ...)
|
|
|
|
|
|
(cache-miss arg ...))))))))))
|
|
|
|
|
|
(arity-case nargs 20 dispatch
|
|
|
|
|
|
(lambda args
|
|
|
|
|
|
(define (args-match? args)
|
2015-01-21 15:53:53 +01:00
|
|
|
|
(let lp ((args args) (n 0))
|
|
|
|
|
|
(match args
|
|
|
|
|
|
((arg . args)
|
|
|
|
|
|
(or (not (vector-ref typev n))
|
|
|
|
|
|
(and (eq? (vector-ref typev n) (class-of arg))
|
|
|
|
|
|
(lp args (1+ n)))))
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(_ #t))))
|
|
|
|
|
|
(if (args-match? args)
|
|
|
|
|
|
(apply cmethod args)
|
|
|
|
|
|
(apply cache-miss args))))))
|
|
|
|
|
|
(else
|
|
|
|
|
|
(single-arity-cache-dispatch cache nargs cache-miss))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (compute-generic-function-dispatch-procedure gf)
|
|
|
|
|
|
(define (seen-arities cache)
|
|
|
|
|
|
(let lp ((arities 0) (cache cache))
|
|
|
|
|
|
(match cache
|
|
|
|
|
|
(() arities)
|
2015-01-21 15:53:53 +01:00
|
|
|
|
(((typev . cmethod) . cache)
|
|
|
|
|
|
(lp (logior arities (ash 1 (vector-length typev)))
|
|
|
|
|
|
cache)))))
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(define (cache-miss . args)
|
|
|
|
|
|
(memoize-generic-function-application! gf args)
|
|
|
|
|
|
(apply gf args))
|
|
|
|
|
|
(let* ((cache (slot-ref gf 'effective-methods))
|
|
|
|
|
|
(arities (seen-arities cache))
|
|
|
|
|
|
(max-arity (let lp ((max -1))
|
|
|
|
|
|
(if (< arities (ash 1 (1+ max)))
|
|
|
|
|
|
max
|
|
|
|
|
|
(lp (1+ max))))))
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((= max-arity -1)
|
|
|
|
|
|
;; Nothing in the cache.
|
|
|
|
|
|
cache-miss)
|
|
|
|
|
|
((= arities (ash 1 max-arity))
|
|
|
|
|
|
;; Only one arity in the cache.
|
2015-01-21 15:53:53 +01:00
|
|
|
|
(let* ((nargs max-arity)
|
|
|
|
|
|
(f (single-arity-cache-dispatch cache nargs cache-miss)))
|
|
|
|
|
|
(single-arity-dispatcher f nargs cache-miss)))
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(else
|
|
|
|
|
|
;; Multiple arities.
|
|
|
|
|
|
(let ((fv (make-vector (1+ max-arity) #f)))
|
|
|
|
|
|
(let lp ((n 0))
|
|
|
|
|
|
(when (<= n max-arity)
|
|
|
|
|
|
(let ((f (single-arity-cache-dispatch cache n cache-miss)))
|
|
|
|
|
|
(vector-set! fv n f)
|
|
|
|
|
|
(lp (1+ n)))))
|
|
|
|
|
|
(multiple-arity-dispatcher fv cache-miss))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (recompute-generic-function-dispatch-procedure! gf)
|
|
|
|
|
|
(slot-set! gf 'procedure
|
|
|
|
|
|
(compute-generic-function-dispatch-procedure gf)))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
|
|
|
|
|
|
(define (memoize-effective-method! gf args applicable)
|
2015-01-21 15:53:53 +01:00
|
|
|
|
(define (record-types args)
|
|
|
|
|
|
(let ((typev (make-vector (length args) #f)))
|
|
|
|
|
|
(let lp ((n 0) (args args))
|
|
|
|
|
|
(when (and (< n (slot-ref gf 'n-specialized))
|
|
|
|
|
|
(pair? args))
|
|
|
|
|
|
(match args
|
|
|
|
|
|
((arg . args)
|
|
|
|
|
|
(vector-set! typev n (class-of arg))
|
|
|
|
|
|
(lp (1+ n) args)))))
|
|
|
|
|
|
typev))
|
|
|
|
|
|
(let* ((typev (record-types args))
|
|
|
|
|
|
(cmethod (compute-cmethod applicable typev))
|
|
|
|
|
|
(cache (acons typev cmethod (slot-ref gf 'effective-methods))))
|
|
|
|
|
|
(slot-set! gf 'effective-methods cache)
|
|
|
|
|
|
(recompute-generic-function-dispatch-procedure! gf)
|
|
|
|
|
|
cmethod))
|
Move GOOPS boot to Scheme
* module/oop/goops.scm (build-<class>-slots): New helper, replacing
build_class_class_slots.
(build-slots-list, %compute-getters-n-setters, %compute-layout): New
private helpers, moved here from C.
(%prep-layout!): Reimplement in Scheme.
(make-standard-class): New private helper, replacing
scm_basic_make_class.
(<class>, <top>, <object>): Define in Scheme.
(<foreign-slot>, <protected-slot>, <hidden-slot>, <opaque-slot>,
<read-only-slot>, <self-slot>, <protected-opaque-slot>,
<protected-hidden-slot>, <protected-read-only-slot>, <scm-slot>,
<int-slot>, <float-slot>, <double-slot>, <procedure-class>,
<applicable-struct-class>, <method>, <accessor-method>, <applicable>,
<applicable-struct>, <generic>, <extended-generic>,
<generic-with-setter>, <accessor>, <extended-generic-with-setter>,
<extended-accessor>): Define in Scheme.
(<boolean>, <char>, <list>, <pair>, <null>, <string>, <symbol>,
<vector>, <foreign>, <hashtable>, <fluid>, <dynamic-state>, <frame>,
<vm-continuation>, <bytevector>, <uvec>, <array>, <bitvector>,
<number>, <complex>, <real>, <integer>, <fraction>, <keyword>,
<unknown>, <procedure>, <primitive-generic>, <port>, <input-port>,
<output-port>, <input-output-port>): Define in Scheme.
(compute-slots): Use build-slots-list helper.
* libguile/goops.h:
* libguile/goops.c (scm_basic_basic_make_class, scm_sys_compute_slots)
(scm_sys_prep_layout_x): Remove. These were available to C, but were
undocumented internals that were dangerous, confusing, and
unnecessary.
* libguile/goops.c: Add note about variable versus value references.
Remove internal C routines that were just used during boot, as they
have been moved to Scheme.
(scm_basic_make_class): Change to call out to make-standard-class in
Scheme.
(scm_sys_make_root_class, scm_sys_bless_applicable_struct_vtable_x)
(scm_sys_bless_pure_generic_vtable_x, scm_sys_init_layout_x): New
private helpers.
(scm_sys_goops_early_init): Change to capture values defined in
Scheme.
2015-01-04 13:41:09 -05:00
|
|
|
|
|
2015-01-04 15:52:12 -05:00
|
|
|
|
;;;
|
2015-01-21 15:16:56 +01:00
|
|
|
|
;;; If a method refers to `next-method' in its body, that method will be
|
|
|
|
|
|
;;; able to dispatch to the next most specific method. The exact
|
|
|
|
|
|
;;; `next-method' implementation is only known at runtime, as it is a
|
|
|
|
|
|
;;; function of which precise argument types are being dispatched, which
|
|
|
|
|
|
;;; might be subclasses of the method's declared specializers.
|
2015-01-04 15:52:12 -05:00
|
|
|
|
;;;
|
2015-01-21 15:16:56 +01:00
|
|
|
|
;;; Guile implements `next-method' by binding it as a closure variable.
|
|
|
|
|
|
;;; An effective method is bound to a specific `next-method' by the
|
|
|
|
|
|
;;; `make-procedure' slot of a <method>, which returns the new closure.
|
2015-01-04 15:52:12 -05:00
|
|
|
|
;;;
|
|
|
|
|
|
(define (compute-cmethod methods types)
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(match methods
|
|
|
|
|
|
((method . methods)
|
|
|
|
|
|
(match (slot-ref method 'make-procedure)
|
|
|
|
|
|
(#f (method-procedure method))
|
|
|
|
|
|
(make-procedure
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(make-procedure
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(match methods
|
|
|
|
|
|
(()
|
|
|
|
|
|
(lambda args
|
|
|
|
|
|
(no-next-method (method-generic-function method) args)))
|
|
|
|
|
|
(methods
|
|
|
|
|
|
(compute-cmethod methods types)))))))))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Memoization
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(define (memoize-generic-function-application! gf args)
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(let ((applicable ((if (eq? gf compute-applicable-methods)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
%compute-applicable-methods
|
|
|
|
|
|
compute-applicable-methods)
|
|
|
|
|
|
gf args)))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(cond (applicable
|
|
|
|
|
|
(memoize-effective-method! gf args applicable))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(else
|
|
|
|
|
|
(no-applicable-method gf args)))))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
|
|
|
|
|
|
(define no-applicable-method
|
|
|
|
|
|
(make <generic> #:name 'no-applicable-method))
|
|
|
|
|
|
|
|
|
|
|
|
(%goops-early-init)
|
2014-12-24 11:29:45 -05:00
|
|
|
|
|
2001-05-19 00:19:25 +00:00
|
|
|
|
;; Then load the rest of GOOPS
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
2011-04-29 16:34:35 +02:00
|
|
|
|
;; FIXME: deprecate.
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(define min-fixnum (- (expt 2 29)))
|
|
|
|
|
|
(define max-fixnum (- (expt 2 29) 1))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
|
;; goops-error
|
|
|
|
|
|
;;
|
|
|
|
|
|
(define (goops-error format-string . args)
|
|
|
|
|
|
(scm-error 'goops-error #f format-string args '()))
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Meta classes}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define ensure-metaclass-with-supers
|
|
|
|
|
|
(let ((table-of-metas '()))
|
|
|
|
|
|
(lambda (meta-supers)
|
|
|
|
|
|
(let ((entry (assoc meta-supers table-of-metas)))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(if entry
|
|
|
|
|
|
;; Found a previously created metaclass
|
|
|
|
|
|
(cdr entry)
|
|
|
|
|
|
;; Create a new meta-class which inherit from "meta-supers"
|
|
|
|
|
|
(let ((new (make <class> #:dsupers meta-supers
|
|
|
|
|
|
#:slots '()
|
|
|
|
|
|
#:name (gensym "metaclass"))))
|
|
|
|
|
|
(set! table-of-metas (cons (cons meta-supers new) table-of-metas))
|
|
|
|
|
|
new))))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2009-11-27 20:50:40 +01:00
|
|
|
|
(define (ensure-metaclass supers)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(if (null? supers)
|
|
|
|
|
|
<class>
|
|
|
|
|
|
(let* ((all-metas (map (lambda (x) (class-of x)) supers))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(all-cpls (append-map (lambda (m)
|
|
|
|
|
|
(cdr (class-precedence-list m)))
|
2009-02-05 00:31:38 +01:00
|
|
|
|
all-metas))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(needed-metas '()))
|
|
|
|
|
|
;; Find the most specific metaclasses. The new metaclass will be
|
|
|
|
|
|
;; a subclass of these.
|
|
|
|
|
|
(for-each
|
|
|
|
|
|
(lambda (meta)
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (and (not (member meta all-cpls))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(not (member meta needed-metas)))
|
|
|
|
|
|
(set! needed-metas (append needed-metas (list meta)))))
|
|
|
|
|
|
all-metas)
|
|
|
|
|
|
;; Now return a subclass of the metaclasses we found.
|
|
|
|
|
|
(if (null? (cdr needed-metas))
|
|
|
|
|
|
(car needed-metas) ; If there's only one, just use it.
|
|
|
|
|
|
(ensure-metaclass-with-supers needed-metas)))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Classes}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
;;; (define-class NAME (SUPER ...) SLOT-DEFINITION ... OPTION ...)
|
|
|
|
|
|
;;;
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
;;; SLOT-DEFINITION ::= INSTANCE-OF-<SLOT> | (SLOT-NAME OPTION ...)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;; OPTION ::= KEYWORD VALUE
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2009-04-25 14:10:08 +02:00
|
|
|
|
(define (make-class supers slots . options)
|
2015-01-12 21:40:29 +01:00
|
|
|
|
(define (find-duplicate l)
|
|
|
|
|
|
(match l
|
|
|
|
|
|
(() #f)
|
|
|
|
|
|
((head . tail)
|
|
|
|
|
|
(if (memq head tail)
|
|
|
|
|
|
head
|
|
|
|
|
|
(find-duplicate tail)))))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define (slot-spec->name slot-spec)
|
|
|
|
|
|
(match slot-spec
|
|
|
|
|
|
(((? symbol? name) . args) name)
|
|
|
|
|
|
;; We can get here when redefining classes.
|
2015-01-19 12:20:50 +01:00
|
|
|
|
((? slot? slot) (%slot-definition-name slot))))
|
2015-01-12 21:40:29 +01:00
|
|
|
|
|
2015-01-16 13:50:21 +01:00
|
|
|
|
(let* ((name (get-keyword #:name options *unbound*))
|
2009-11-27 20:50:40 +01:00
|
|
|
|
(supers (if (not (or-map (lambda (class)
|
|
|
|
|
|
(memq <object>
|
|
|
|
|
|
(class-precedence-list class)))
|
|
|
|
|
|
supers))
|
|
|
|
|
|
(append supers (list <object>))
|
|
|
|
|
|
supers))
|
|
|
|
|
|
(metaclass (or (get-keyword #:metaclass options #f)
|
|
|
|
|
|
(ensure-metaclass supers))))
|
|
|
|
|
|
|
|
|
|
|
|
;; Verify that all direct slots are different and that we don't inherit
|
|
|
|
|
|
;; several time from the same class
|
|
|
|
|
|
(let ((tmp1 (find-duplicate supers))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(tmp2 (find-duplicate (map slot-spec->name slots))))
|
2009-11-27 20:50:40 +01:00
|
|
|
|
(if tmp1
|
|
|
|
|
|
(goops-error "make-class: super class ~S is duplicate in class ~S"
|
|
|
|
|
|
tmp1 name))
|
|
|
|
|
|
(if tmp2
|
|
|
|
|
|
(goops-error "make-class: slot ~S is duplicate in class ~S"
|
|
|
|
|
|
tmp2 name)))
|
|
|
|
|
|
|
|
|
|
|
|
;; Everything seems correct, build the class
|
|
|
|
|
|
(apply make metaclass
|
|
|
|
|
|
#:dsupers supers
|
2015-01-09 20:07:06 +01:00
|
|
|
|
#:slots slots
|
2009-11-27 20:50:40 +01:00
|
|
|
|
#:name name
|
|
|
|
|
|
options)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;; (class (SUPER ...) SLOT-DEFINITION ... OPTION ...)
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; SLOT-DEFINITION ::= SLOT-NAME | (SLOT-NAME OPTION ...)
|
|
|
|
|
|
;;; OPTION ::= KEYWORD VALUE
|
|
|
|
|
|
;;;
|
2015-01-04 15:18:39 -05:00
|
|
|
|
(define-syntax class
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(define (parse-options options)
|
|
|
|
|
|
(syntax-case options ()
|
|
|
|
|
|
(() #'())
|
|
|
|
|
|
((kw arg . options) (keyword? (syntax->datum #'kw))
|
|
|
|
|
|
(with-syntax ((options (parse-options #'options)))
|
|
|
|
|
|
(syntax-case #'kw ()
|
|
|
|
|
|
(#:init-form
|
|
|
|
|
|
#'(kw 'arg #:init-thunk (lambda () arg) . options))
|
|
|
|
|
|
(_
|
|
|
|
|
|
#'(kw arg . options)))))))
|
|
|
|
|
|
(define (check-valid-kwargs args)
|
|
|
|
|
|
(syntax-case args ()
|
|
|
|
|
|
(() #'())
|
|
|
|
|
|
((kw arg . args) (keyword? (syntax->datum #'kw))
|
|
|
|
|
|
#`(kw arg . #,(check-valid-kwargs #'args)))))
|
|
|
|
|
|
(define (parse-slots-and-kwargs args)
|
|
|
|
|
|
(syntax-case args ()
|
|
|
|
|
|
(()
|
|
|
|
|
|
#'(() ()))
|
|
|
|
|
|
((kw . _) (keyword? (syntax->datum #'kw))
|
|
|
|
|
|
#`(() #,(check-valid-kwargs args)))
|
|
|
|
|
|
(((name option ...) args ...)
|
|
|
|
|
|
(with-syntax (((slots kwargs) (parse-slots-and-kwargs #'(args ...)))
|
|
|
|
|
|
((option ...) (parse-options #'(option ...))))
|
|
|
|
|
|
#'(((list 'name option ...) . slots) kwargs)))
|
|
|
|
|
|
((name args ...) (symbol? (syntax->datum #'name))
|
|
|
|
|
|
(with-syntax (((slots kwargs) (parse-slots-and-kwargs #'(args ...))))
|
|
|
|
|
|
#'(('(name) . slots) kwargs)))))
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
((class (super ...) arg ...)
|
|
|
|
|
|
(with-syntax ((((slot-def ...) (option ...))
|
|
|
|
|
|
(parse-slots-and-kwargs #'(arg ...))))
|
|
|
|
|
|
#'(make-class (list super ...)
|
|
|
|
|
|
(list slot-def ...)
|
|
|
|
|
|
option ...))))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2009-04-25 14:10:08 +02:00
|
|
|
|
(define-syntax define-class-pre-definition
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
((_ (k arg rest ...) out ...)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(keyword? (syntax->datum #'k))
|
|
|
|
|
|
(case (syntax->datum #'k)
|
2009-04-25 14:10:08 +02:00
|
|
|
|
((#:getter #:setter)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
#'(define-class-pre-definition (rest ...)
|
|
|
|
|
|
out ...
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (or (not (defined? 'arg))
|
|
|
|
|
|
(not (is-a? arg <generic>)))
|
|
|
|
|
|
(toplevel-define!
|
|
|
|
|
|
'arg
|
|
|
|
|
|
(ensure-generic (if (defined? 'arg) arg #f) 'arg)))))
|
2009-04-25 14:10:08 +02:00
|
|
|
|
((#:accessor)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
#'(define-class-pre-definition (rest ...)
|
|
|
|
|
|
out ...
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (or (not (defined? 'arg))
|
|
|
|
|
|
(not (is-a? arg <accessor>)))
|
|
|
|
|
|
(toplevel-define!
|
|
|
|
|
|
'arg
|
|
|
|
|
|
(ensure-accessor (if (defined? 'arg) arg #f) 'arg)))))
|
2009-04-25 14:10:08 +02:00
|
|
|
|
(else
|
2011-05-21 13:12:44 +02:00
|
|
|
|
#'(define-class-pre-definition (rest ...) out ...))))
|
2009-04-25 14:10:08 +02:00
|
|
|
|
((_ () out ...)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
#'(begin out ...)))))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
|
2009-04-25 14:10:08 +02:00
|
|
|
|
;; Some slot options require extra definitions to be made. In
|
|
|
|
|
|
;; particular, we want to make sure that the generic function objects
|
|
|
|
|
|
;; which represent accessors exist before `make-class' tries to add
|
|
|
|
|
|
;; methods to them.
|
|
|
|
|
|
(define-syntax define-class-pre-definitions
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
((_ () out ...)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
#'(begin out ...))
|
2009-04-25 14:10:08 +02:00
|
|
|
|
((_ (slot rest ...) out ...)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(keyword? (syntax->datum #'slot))
|
|
|
|
|
|
#'(begin out ...))
|
2009-04-25 14:10:08 +02:00
|
|
|
|
((_ (slot rest ...) out ...)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(identifier? #'slot)
|
|
|
|
|
|
#'(define-class-pre-definitions (rest ...)
|
|
|
|
|
|
out ...))
|
2009-04-25 14:10:08 +02:00
|
|
|
|
((_ ((slotname slotopt ...) rest ...) out ...)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
#'(define-class-pre-definitions (rest ...)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
out ... (define-class-pre-definition (slotopt ...)))))))
|
2009-04-25 14:10:08 +02:00
|
|
|
|
|
2011-09-02 11:36:14 +02:00
|
|
|
|
(define-syntax-rule (define-class name supers slot ...)
|
|
|
|
|
|
(begin
|
|
|
|
|
|
(define-class-pre-definitions (slot ...))
|
|
|
|
|
|
(if (and (defined? 'name)
|
|
|
|
|
|
(is-a? name <class>)
|
|
|
|
|
|
(memq <object> (class-precedence-list name)))
|
|
|
|
|
|
(class-redefinition name
|
|
|
|
|
|
(class supers slot ... #:name 'name))
|
|
|
|
|
|
(toplevel-define! 'name (class supers slot ... #:name 'name)))))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
|
2011-09-02 11:36:14 +02:00
|
|
|
|
(define-syntax-rule (standard-define-class arg ...)
|
|
|
|
|
|
(define-class arg ...))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Generic functions and accessors}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2008-10-23 14:24:57 +02:00
|
|
|
|
;; Apparently the desired semantics are that we extend previous
|
|
|
|
|
|
;; procedural definitions, but that if `name' was already a generic, we
|
|
|
|
|
|
;; overwrite its definition.
|
2015-01-04 15:35:25 -05:00
|
|
|
|
(define-syntax define-generic
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
((define-generic name) (symbol? (syntax->datum #'name))
|
|
|
|
|
|
#'(define name
|
|
|
|
|
|
(if (and (defined? 'name) (is-a? name <generic>))
|
|
|
|
|
|
(make <generic> #:name 'name)
|
|
|
|
|
|
(ensure-generic (if (defined? 'name) name #f) 'name)))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define-syntax define-extended-generic
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
((define-extended-generic name val) (symbol? (syntax->datum #'name))
|
|
|
|
|
|
#'(define name (make-extended-generic val 'name))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define-syntax define-extended-generics
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
(define (id-append ctx a b)
|
|
|
|
|
|
(datum->syntax ctx (symbol-append (syntax->datum a) (syntax->datum b))))
|
|
|
|
|
|
(syntax-case x ()
|
|
|
|
|
|
((define-extended-generic (name ...) #:prefix (prefix ...))
|
|
|
|
|
|
(and (and-map symbol? (syntax->datum #'(name ...)))
|
|
|
|
|
|
(and-map symbol? (syntax->datum #'(prefix ...))))
|
|
|
|
|
|
(with-syntax ((((val ...)) (map (lambda (name)
|
|
|
|
|
|
(map (lambda (prefix)
|
|
|
|
|
|
(id-append name prefix name))
|
|
|
|
|
|
#'(prefix ...)))
|
|
|
|
|
|
#'(name ...))))
|
|
|
|
|
|
#'(begin
|
|
|
|
|
|
(define-extended-generic name (list val ...))
|
|
|
|
|
|
...))))))
|
2003-01-08 13:24:41 +00:00
|
|
|
|
|
2011-07-07 12:17:08 +02:00
|
|
|
|
(define* (make-generic #:optional name)
|
|
|
|
|
|
(make <generic> #:name name))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2011-07-07 12:17:08 +02:00
|
|
|
|
(define* (make-extended-generic gfs #:optional name)
|
|
|
|
|
|
(let* ((gfs (if (list? gfs) gfs (list gfs)))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(gws? (any (lambda (gf) (is-a? gf <generic-with-setter>)) gfs)))
|
2003-01-08 13:24:41 +00:00
|
|
|
|
(let ((ans (if gws?
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(let* ((sname (and name (make-setter-name name)))
|
|
|
|
|
|
(setters
|
|
|
|
|
|
(append-map (lambda (gf)
|
|
|
|
|
|
(if (is-a? gf <generic-with-setter>)
|
|
|
|
|
|
(list (ensure-generic (setter gf)
|
|
|
|
|
|
sname))
|
|
|
|
|
|
'()))
|
|
|
|
|
|
gfs))
|
|
|
|
|
|
(es (make <extended-generic-with-setter>
|
|
|
|
|
|
#:name name
|
|
|
|
|
|
#:extends gfs
|
|
|
|
|
|
#:setter (make <extended-generic>
|
|
|
|
|
|
#:name sname
|
|
|
|
|
|
#:extends setters))))
|
|
|
|
|
|
(extended-by! setters (setter es))
|
|
|
|
|
|
es)
|
|
|
|
|
|
(make <extended-generic>
|
|
|
|
|
|
#:name name
|
|
|
|
|
|
#:extends gfs))))
|
2003-01-08 13:24:41 +00:00
|
|
|
|
(extended-by! gfs ans)
|
|
|
|
|
|
ans)))
|
|
|
|
|
|
|
|
|
|
|
|
(define (extended-by! gfs eg)
|
|
|
|
|
|
(for-each (lambda (gf)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(slot-set! gf 'extended-by
|
|
|
|
|
|
(cons eg (slot-ref gf 'extended-by))))
|
|
|
|
|
|
gfs)
|
2011-09-02 13:17:19 +02:00
|
|
|
|
(invalidate-method-cache! eg))
|
2003-01-08 13:24:41 +00:00
|
|
|
|
|
|
|
|
|
|
(define (not-extended-by! gfs eg)
|
|
|
|
|
|
(for-each (lambda (gf)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(slot-set! gf 'extended-by
|
|
|
|
|
|
(delq! eg (slot-ref gf 'extended-by))))
|
|
|
|
|
|
gfs)
|
2011-09-02 13:17:19 +02:00
|
|
|
|
(invalidate-method-cache! eg))
|
2003-01-08 13:24:41 +00:00
|
|
|
|
|
2011-07-07 12:17:08 +02:00
|
|
|
|
(define* (ensure-generic old-definition #:optional name)
|
|
|
|
|
|
(cond ((is-a? old-definition <generic>) old-definition)
|
|
|
|
|
|
((procedure-with-setter? old-definition)
|
|
|
|
|
|
(make <generic-with-setter>
|
|
|
|
|
|
#:name name
|
|
|
|
|
|
#:default (procedure old-definition)
|
|
|
|
|
|
#:setter (setter old-definition)))
|
|
|
|
|
|
((procedure? old-definition)
|
|
|
|
|
|
(if (generic-capability? old-definition) old-definition
|
|
|
|
|
|
(make <generic> #:name name #:default old-definition)))
|
|
|
|
|
|
(else (make <generic> #:name name))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2008-10-23 14:24:57 +02:00
|
|
|
|
;; same semantics as <generic>
|
2011-09-02 11:36:14 +02:00
|
|
|
|
(define-syntax-rule (define-accessor name)
|
|
|
|
|
|
(define name
|
|
|
|
|
|
(cond ((not (defined? 'name)) (ensure-accessor #f 'name))
|
|
|
|
|
|
((is-a? name <accessor>) (make <accessor> #:name 'name))
|
|
|
|
|
|
(else (ensure-accessor name 'name)))))
|
2003-03-17 13:53:58 +00:00
|
|
|
|
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(define (make-setter-name name)
|
|
|
|
|
|
(string->symbol (string-append "setter:" (symbol->string name))))
|
|
|
|
|
|
|
2011-07-07 12:17:08 +02:00
|
|
|
|
(define* (make-accessor #:optional name)
|
|
|
|
|
|
(make <accessor>
|
|
|
|
|
|
#:name name
|
|
|
|
|
|
#:setter (make <generic>
|
|
|
|
|
|
#:name (and name (make-setter-name name)))))
|
|
|
|
|
|
|
|
|
|
|
|
(define* (ensure-accessor proc #:optional name)
|
|
|
|
|
|
(cond ((and (is-a? proc <accessor>)
|
|
|
|
|
|
(is-a? (setter proc) <generic>))
|
|
|
|
|
|
proc)
|
|
|
|
|
|
((is-a? proc <generic-with-setter>)
|
|
|
|
|
|
(upgrade-accessor proc (setter proc)))
|
|
|
|
|
|
((is-a? proc <generic>)
|
|
|
|
|
|
(upgrade-accessor proc (make-generic name)))
|
|
|
|
|
|
((procedure-with-setter? proc)
|
|
|
|
|
|
(make <accessor>
|
|
|
|
|
|
#:name name
|
|
|
|
|
|
#:default (procedure proc)
|
|
|
|
|
|
#:setter (ensure-generic (setter proc) name)))
|
|
|
|
|
|
((procedure? proc)
|
|
|
|
|
|
(ensure-accessor (if (generic-capability? proc)
|
|
|
|
|
|
(make <generic> #:name name #:default proc)
|
|
|
|
|
|
(ensure-generic proc name))
|
|
|
|
|
|
name))
|
|
|
|
|
|
(else
|
|
|
|
|
|
(make-accessor name))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2003-03-11 14:50:08 +00:00
|
|
|
|
(define (upgrade-accessor generic setter)
|
2003-01-08 13:24:41 +00:00
|
|
|
|
(let ((methods (slot-ref generic 'methods))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(gws (make (if (is-a? generic <extended-generic>)
|
|
|
|
|
|
<extended-generic-with-setter>
|
|
|
|
|
|
<accessor>)
|
|
|
|
|
|
#:name (generic-function-name generic)
|
|
|
|
|
|
#:extended-by (slot-ref generic 'extended-by)
|
|
|
|
|
|
#:setter setter)))
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (is-a? generic <extended-generic>)
|
|
|
|
|
|
(let ((gfs (slot-ref generic 'extends)))
|
|
|
|
|
|
(not-extended-by! gfs generic)
|
|
|
|
|
|
(slot-set! gws 'extends gfs)
|
|
|
|
|
|
(extended-by! gfs gws)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;; Steal old methods
|
|
|
|
|
|
(for-each (lambda (method)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(slot-set! method 'generic-function gws))
|
|
|
|
|
|
methods)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(slot-set! gws 'methods methods)
|
2011-09-02 13:17:19 +02:00
|
|
|
|
(invalidate-method-cache! gws)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
gws))
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Methods}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2014-12-18 21:57:24 +01:00
|
|
|
|
;; Note: `a' and `b' can have unequal lengths (i.e. one can be one
|
|
|
|
|
|
;; element longer than the other when we have a dotted parameter
|
|
|
|
|
|
;; list). For instance, with the call
|
|
|
|
|
|
;;
|
|
|
|
|
|
;; (M 1)
|
|
|
|
|
|
;;
|
|
|
|
|
|
;; with
|
|
|
|
|
|
;;
|
|
|
|
|
|
;; (define-method M (a . l) ....)
|
|
|
|
|
|
;; (define-method M (a) ....)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
;;
|
2014-12-18 21:57:24 +01:00
|
|
|
|
;; we consider that the second method is more specific.
|
2015-01-09 20:07:06 +01:00
|
|
|
|
;;
|
2014-12-18 21:57:24 +01:00
|
|
|
|
;; Precondition: `a' and `b' are methods and are applicable to `types'.
|
|
|
|
|
|
(define (%method-more-specific? a b types)
|
|
|
|
|
|
(let lp ((a-specializers (method-specializers a))
|
|
|
|
|
|
(b-specializers (method-specializers b))
|
|
|
|
|
|
(types types))
|
|
|
|
|
|
(cond
|
|
|
|
|
|
;; (a) less specific than (a b ...) or (a . b)
|
|
|
|
|
|
((null? a-specializers) #t)
|
|
|
|
|
|
;; (a b ...) or (a . b) less specific than (a)
|
|
|
|
|
|
((null? b-specializers) #f)
|
|
|
|
|
|
;; (a . b) less specific than (a b ...)
|
|
|
|
|
|
((not (pair? a-specializers)) #f)
|
|
|
|
|
|
;; (a b ...) more specific than (a . b)
|
|
|
|
|
|
((not (pair? b-specializers)) #t)
|
|
|
|
|
|
(else
|
|
|
|
|
|
(let ((a-specializer (car a-specializers))
|
|
|
|
|
|
(b-specializer (car b-specializers))
|
|
|
|
|
|
(a-specializers (cdr a-specializers))
|
|
|
|
|
|
(b-specializers (cdr b-specializers))
|
|
|
|
|
|
(type (car types))
|
|
|
|
|
|
(types (cdr types)))
|
|
|
|
|
|
(if (eq? a-specializer b-specializer)
|
|
|
|
|
|
(lp a-specializers b-specializers types)
|
|
|
|
|
|
(let lp ((cpl (class-precedence-list type)))
|
|
|
|
|
|
(let ((elt (car cpl)))
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((eq? a-specializer elt) #t)
|
|
|
|
|
|
((eq? b-specializer elt) #f)
|
|
|
|
|
|
(else (lp (cdr cpl))))))))))))
|
|
|
|
|
|
|
2014-12-18 12:51:11 +01:00
|
|
|
|
(define (%sort-applicable-methods methods types)
|
|
|
|
|
|
(sort methods (lambda (a b) (%method-more-specific? a b types))))
|
|
|
|
|
|
|
2015-01-09 22:05:01 +01:00
|
|
|
|
(define (generic-function-methods obj)
|
|
|
|
|
|
"Return the methods of the generic function @var{obj}."
|
|
|
|
|
|
(define (fold-upward method-lists gf)
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((is-a? gf <extended-generic>)
|
|
|
|
|
|
(let lp ((method-lists method-lists) (gfs (slot-ref gf 'extends)))
|
|
|
|
|
|
(match gfs
|
|
|
|
|
|
(() method-lists)
|
|
|
|
|
|
((gf . gfs)
|
|
|
|
|
|
(lp (fold-upward (cons (slot-ref gf 'methods) method-lists) gf)
|
|
|
|
|
|
gfs)))))
|
|
|
|
|
|
(else method-lists)))
|
|
|
|
|
|
(define (fold-downward method-lists gf)
|
|
|
|
|
|
(let lp ((method-lists (cons (slot-ref gf 'methods) method-lists))
|
|
|
|
|
|
(gfs (slot-ref gf 'extended-by)))
|
|
|
|
|
|
(match gfs
|
|
|
|
|
|
(() method-lists)
|
|
|
|
|
|
((gf . gfs)
|
|
|
|
|
|
(lp (fold-downward method-lists gf) gfs)))))
|
|
|
|
|
|
(unless (is-a? obj <generic>)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not a generic: ~S"
|
|
|
|
|
|
(list obj) #f))
|
|
|
|
|
|
(concatenate (fold-downward (fold-upward '() obj) obj)))
|
|
|
|
|
|
|
2014-12-18 12:51:11 +01:00
|
|
|
|
(define (%compute-applicable-methods gf args)
|
|
|
|
|
|
(define (method-applicable? m types)
|
|
|
|
|
|
(let lp ((specs (method-specializers m)) (types types))
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((null? specs) (null? types))
|
|
|
|
|
|
((not (pair? specs)) #t)
|
|
|
|
|
|
((null? types) #f)
|
|
|
|
|
|
(else
|
|
|
|
|
|
(and (memq (car specs) (class-precedence-list (car types)))
|
|
|
|
|
|
(lp (cdr specs) (cdr types)))))))
|
|
|
|
|
|
(let ((n (length args))
|
|
|
|
|
|
(types (map class-of args)))
|
|
|
|
|
|
(let lp ((methods (generic-function-methods gf))
|
|
|
|
|
|
(applicable '()))
|
|
|
|
|
|
(if (null? methods)
|
|
|
|
|
|
(and (not (null? applicable))
|
|
|
|
|
|
(%sort-applicable-methods applicable types))
|
|
|
|
|
|
(let ((m (car methods)))
|
|
|
|
|
|
(lp (cdr methods)
|
|
|
|
|
|
(if (method-applicable? m types)
|
|
|
|
|
|
(cons m applicable)
|
|
|
|
|
|
applicable)))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define compute-applicable-methods %compute-applicable-methods)
|
|
|
|
|
|
|
2009-04-25 12:50:53 +02:00
|
|
|
|
(define (toplevel-define! name val)
|
|
|
|
|
|
(module-define! (current-module) name val))
|
|
|
|
|
|
|
|
|
|
|
|
(define-syntax define-method
|
|
|
|
|
|
(syntax-rules (setter)
|
|
|
|
|
|
((_ ((setter name) . args) body ...)
|
|
|
|
|
|
(begin
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (or (not (defined? 'name))
|
|
|
|
|
|
(not (is-a? name <accessor>)))
|
|
|
|
|
|
(toplevel-define! 'name
|
|
|
|
|
|
(ensure-accessor
|
|
|
|
|
|
(if (defined? 'name) name #f) 'name)))
|
2009-04-25 12:50:53 +02:00
|
|
|
|
(add-method! (setter name) (method args body ...))))
|
|
|
|
|
|
((_ (name . args) body ...)
|
|
|
|
|
|
(begin
|
|
|
|
|
|
;; FIXME: this code is how it always was, but it's quite cracky:
|
|
|
|
|
|
;; it will only define the generic function if it was undefined
|
|
|
|
|
|
;; before (ok), or *was defined to #f*. The latter is crack. But
|
|
|
|
|
|
;; there are bootstrap issues about fixing this -- change it to
|
|
|
|
|
|
;; (is-a? name <generic>) and see.
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (or (not (defined? 'name))
|
|
|
|
|
|
(not name))
|
|
|
|
|
|
(toplevel-define! 'name (make <generic> #:name 'name)))
|
2009-04-25 12:50:53 +02:00
|
|
|
|
(add-method! name (method args body ...))))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2009-05-21 13:49:00 +02:00
|
|
|
|
(define-syntax method
|
|
|
|
|
|
(lambda (x)
|
2009-05-21 15:34:29 +02:00
|
|
|
|
(define (parse-args args)
|
|
|
|
|
|
(let lp ((ls args) (formals '()) (specializers '()))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
(syntax-case ls ()
|
2009-05-21 15:34:29 +02:00
|
|
|
|
(((f s) . rest)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(and (identifier? #'f) (identifier? #'s))
|
|
|
|
|
|
(lp #'rest
|
|
|
|
|
|
(cons #'f formals)
|
|
|
|
|
|
(cons #'s specializers)))
|
2009-05-21 15:34:29 +02:00
|
|
|
|
((f . rest)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(identifier? #'f)
|
|
|
|
|
|
(lp #'rest
|
|
|
|
|
|
(cons #'f formals)
|
|
|
|
|
|
(cons #'<top> specializers)))
|
2009-05-21 15:34:29 +02:00
|
|
|
|
(()
|
|
|
|
|
|
(list (reverse formals)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(reverse (cons #''() specializers))))
|
2009-05-21 15:34:29 +02:00
|
|
|
|
(tail
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(identifier? #'tail)
|
|
|
|
|
|
(list (append (reverse formals) #'tail)
|
|
|
|
|
|
(reverse (cons #'<top> specializers)))))))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
|
|
|
|
|
|
(define (find-free-id exp referent)
|
|
|
|
|
|
(syntax-case exp ()
|
|
|
|
|
|
((x . y)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(or (find-free-id #'x referent)
|
|
|
|
|
|
(find-free-id #'y referent)))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
(x
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(identifier? #'x)
|
|
|
|
|
|
(let ((id (datum->syntax #'x referent)))
|
|
|
|
|
|
(and (free-identifier=? #'x id) id)))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
(_ #f)))
|
|
|
|
|
|
|
|
|
|
|
|
(define (compute-procedure formals body)
|
|
|
|
|
|
(syntax-case body ()
|
|
|
|
|
|
((body0 ...)
|
|
|
|
|
|
(with-syntax ((formals formals))
|
2011-05-21 13:12:44 +02:00
|
|
|
|
#'(lambda formals body0 ...)))))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
|
|
|
|
|
|
(define (->proper args)
|
|
|
|
|
|
(let lp ((ls args) (out '()))
|
|
|
|
|
|
(syntax-case ls ()
|
2011-05-21 13:12:44 +02:00
|
|
|
|
((x . xs) (lp #'xs (cons #'x out)))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
(() (reverse out))
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(tail (reverse (cons #'tail out))))))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
|
|
|
|
|
|
(define (compute-make-procedure formals body next-method)
|
|
|
|
|
|
(syntax-case body ()
|
|
|
|
|
|
((body ...)
|
|
|
|
|
|
(with-syntax ((next-method next-method))
|
|
|
|
|
|
(syntax-case formals ()
|
|
|
|
|
|
((formal ...)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
#'(lambda (real-next-method)
|
|
|
|
|
|
(lambda (formal ...)
|
|
|
|
|
|
(let ((next-method (lambda args
|
|
|
|
|
|
(if (null? args)
|
|
|
|
|
|
(real-next-method formal ...)
|
|
|
|
|
|
(apply real-next-method args)))))
|
|
|
|
|
|
body ...))))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
(formals
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(with-syntax (((formal ...) (->proper #'formals)))
|
|
|
|
|
|
#'(lambda (real-next-method)
|
|
|
|
|
|
(lambda formals
|
|
|
|
|
|
(let ((next-method (lambda args
|
|
|
|
|
|
(if (null? args)
|
|
|
|
|
|
(apply real-next-method formal ...)
|
|
|
|
|
|
(apply real-next-method args)))))
|
|
|
|
|
|
body ...))))))))))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
|
|
|
|
|
|
(define (compute-procedures formals body)
|
|
|
|
|
|
;; So, our use of this is broken, because it operates on the
|
|
|
|
|
|
;; pre-expansion source code. It's equivalent to just searching
|
|
|
|
|
|
;; for referent in the datums. Ah well.
|
|
|
|
|
|
(let ((id (find-free-id body 'next-method)))
|
|
|
|
|
|
(if id
|
|
|
|
|
|
;; return a make-procedure
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(values #'#f
|
2009-05-21 13:49:00 +02:00
|
|
|
|
(compute-make-procedure formals body id))
|
|
|
|
|
|
(values (compute-procedure formals body)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
#'#f))))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
|
|
|
|
|
|
(syntax-case x ()
|
2011-05-21 13:12:44 +02:00
|
|
|
|
((_ args) #'(method args (if #f #f)))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
((_ args body0 body1 ...)
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(with-syntax (((formals (specializer ...)) (parse-args #'args)))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
(call-with-values
|
|
|
|
|
|
(lambda ()
|
2011-05-21 13:12:44 +02:00
|
|
|
|
(compute-procedures #'formals #'(body0 body1 ...)))
|
2009-05-21 13:49:00 +02:00
|
|
|
|
(lambda (procedure make-procedure)
|
|
|
|
|
|
(with-syntax ((procedure procedure)
|
|
|
|
|
|
(make-procedure make-procedure))
|
2011-05-21 13:12:44 +02:00
|
|
|
|
#'(make <method>
|
|
|
|
|
|
#:specializers (cons* specializer ...)
|
|
|
|
|
|
#:formals 'formals
|
|
|
|
|
|
#:body '(body0 body1 ...)
|
|
|
|
|
|
#:make-procedure make-procedure
|
|
|
|
|
|
#:procedure procedure)))))))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2015-01-12 21:43:48 +01:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Utilities}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; These are useful when dealing with method specializers, which might
|
|
|
|
|
|
;;; have a rest argument.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define (map* fn . l) ; A map which accepts dotted lists (arg lists
|
|
|
|
|
|
(cond ; must be "isomorph"
|
|
|
|
|
|
((null? (car l)) '())
|
|
|
|
|
|
((pair? (car l)) (cons (apply fn (map car l))
|
|
|
|
|
|
(apply map* fn (map cdr l))))
|
|
|
|
|
|
(else (apply fn l))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (for-each* fn . l) ; A for-each which accepts dotted lists (arg lists
|
|
|
|
|
|
(cond ; must be "isomorph"
|
|
|
|
|
|
((null? (car l)) '())
|
|
|
|
|
|
((pair? (car l)) (apply fn (map car l)) (apply for-each* fn (map cdr l)))
|
|
|
|
|
|
(else (apply fn l))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (length* ls)
|
|
|
|
|
|
(do ((n 0 (+ 1 n))
|
|
|
|
|
|
(ls ls (cdr ls)))
|
|
|
|
|
|
((not (pair? ls)) n)))
|
|
|
|
|
|
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; {add-method!}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define (add-method-in-classes! m)
|
|
|
|
|
|
;; Add method in all the classes which appears in its specializers list
|
|
|
|
|
|
(for-each* (lambda (x)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(let ((dm (class-direct-methods x)))
|
|
|
|
|
|
(unless (memq m dm)
|
|
|
|
|
|
(struct-set! x class-index-direct-methods (cons m dm)))))
|
|
|
|
|
|
(method-specializers m)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
(define (remove-method-in-classes! m)
|
|
|
|
|
|
;; Remove method in all the classes which appears in its specializers list
|
|
|
|
|
|
(for-each* (lambda (x)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(struct-set! x
|
|
|
|
|
|
class-index-direct-methods
|
|
|
|
|
|
(delv! m (class-direct-methods x))))
|
|
|
|
|
|
(method-specializers m)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
(define (compute-new-list-of-methods gf new)
|
|
|
|
|
|
(let ((new-spec (method-specializers new))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(methods (slot-ref gf 'methods)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let loop ((l methods))
|
|
|
|
|
|
(if (null? l)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(cons new methods)
|
|
|
|
|
|
(if (equal? (method-specializers (car l)) new-spec)
|
|
|
|
|
|
(begin
|
|
|
|
|
|
;; This spec. list already exists. Remove old method from dependents
|
|
|
|
|
|
(remove-method-in-classes! (car l))
|
|
|
|
|
|
(set-car! l new)
|
|
|
|
|
|
methods)
|
|
|
|
|
|
(loop (cdr l)))))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2011-09-02 13:17:19 +02:00
|
|
|
|
(define (method-n-specializers m)
|
|
|
|
|
|
(length* (slot-ref m 'specializers)))
|
|
|
|
|
|
|
|
|
|
|
|
(define (calculate-n-specialized gf)
|
|
|
|
|
|
(fold (lambda (m n) (max n (method-n-specializers m)))
|
|
|
|
|
|
0
|
|
|
|
|
|
(generic-function-methods gf)))
|
|
|
|
|
|
|
|
|
|
|
|
(define (invalidate-method-cache! gf)
|
|
|
|
|
|
(slot-set! gf 'n-specialized (calculate-n-specialized gf))
|
2015-01-21 15:16:56 +01:00
|
|
|
|
(%invalidate-method-cache! gf)
|
2011-09-02 13:17:19 +02:00
|
|
|
|
(for-each (lambda (gf) (invalidate-method-cache! gf))
|
|
|
|
|
|
(slot-ref gf 'extended-by)))
|
|
|
|
|
|
|
2008-10-31 00:07:04 +01:00
|
|
|
|
(define internal-add-method!
|
|
|
|
|
|
(method ((gf <generic>) (m <method>))
|
|
|
|
|
|
(slot-set! m 'generic-function gf)
|
|
|
|
|
|
(slot-set! gf 'methods (compute-new-list-of-methods gf m))
|
2011-09-02 13:17:19 +02:00
|
|
|
|
(invalidate-method-cache! gf)
|
2008-10-31 00:07:04 +01:00
|
|
|
|
(add-method-in-classes! m)
|
|
|
|
|
|
*unspecified*))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
(define-generic add-method!)
|
|
|
|
|
|
|
2008-10-31 00:07:04 +01:00
|
|
|
|
((method-procedure internal-add-method!) add-method! internal-add-method!)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (add-method! (proc <procedure>) (m <method>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(if (generic-capability? proc)
|
|
|
|
|
|
(begin
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(enable-primitive-generic! proc)
|
|
|
|
|
|
(add-method! proc m))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(next-method)))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (add-method! (pg <primitive-generic>) (m <method>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(add-method! (primitive-generic-generic pg) m))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (add-method! obj (m <method>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(goops-error "~S is not a valid generic function" obj))
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Access to meta objects}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Methods
|
|
|
|
|
|
;;;
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (method-source (m <method>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let* ((spec (map* class-name (slot-ref m 'specializers)))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(src (procedure-source (slot-ref m 'procedure))))
|
2009-03-20 12:06:10 +01:00
|
|
|
|
(and src
|
|
|
|
|
|
(let ((args (cadr src))
|
|
|
|
|
|
(body (cddr src)))
|
|
|
|
|
|
(cons 'method
|
|
|
|
|
|
(cons (map* list args spec)
|
|
|
|
|
|
body))))))
|
|
|
|
|
|
|
|
|
|
|
|
(define-method (method-formals (m <method>))
|
|
|
|
|
|
(slot-ref m 'formals))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Slots
|
|
|
|
|
|
;;;
|
|
|
|
|
|
(define (slot-init-function class slot-name)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(%slot-definition-init-thunk (or (class-slot-definition class slot-name)
|
|
|
|
|
|
(error "slot not found" slot-name))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
limn goops flags, remove foreign objs, rename entity to applicable-struct
* libguile/goops.c (scm_class_applicable_struct)
(scm_class_applicable_struct_with_setter)
(scm_class_applicable_struct_class): Rename from
scm_class_entity, scm_class_entity_with_setter, and
scm_class_entity_class.
(scm_class_simple_method): Removed; this abstraction is not used.
(scm_class_foreign_class, scm_class_foreign_object): Remove these,
they are undocumented and unused. They might come back later.
(scm_sys_inherit_magic_x): Simply inherit the vtable flags from the
class's class. Flags are about layout, and it is the class that
determines the layout of the instance.
(scm_basic_basic_make_class): Don't bother setting GOOPS_OR_VALID,
inherit-magic will do that.
(scm_basic_make_class): Inherit magic after setting the layout. Allows
the struct magic checker to do its job.
(scm_accessor_method_slot_definition): Move implementation to Scheme.
Removes the need for the accessor flag.
(scm_sys_allocate_instance): Adapt to scm_i_alloc_struct name change,
and that alloc-struct will handle finalization.
(scm_compute_applicable_methods): Remove accessor check, as it's
unnecessary.
(scm_make): Adapt to new generic slot order, and no more
simple-method.
(create_standard_classes): What was the GF slot "dispatch-procedure"
is now the applicable-struct slot "procedure". No more foreign class,
foreign object, or simple method. Rename <entity> and friends to
<applicable-struct> and friends. No more entity-with-setter -- though
perhaps it will come back too. Instead generic-with-setter is its own
thing.
* libguile/goops.h (SCM_CLASSF_METACLASS): "A goops class that is a
vtable" -- no need for a separate flag.
(SCM_CLASSF_FOREIGN, SCM_CLASSF_SIMPLE_METHOD)
(SCM_CLASSF_ACCESSOR_METHOD): Removed these unused flags.
(SCM_ACCESSORP): Removed.
Renumber generic slots, rename entity classes, and remove the foreign
class, foreign object, and simple method classes.
* libguile/struct.c (scm_i_struct_inherit_vtable_magic): New function,
called when making new vtables.applicable structs
(scm_i_alloc_struct): Remove 8-bit alignment check, as libGC
guarantees this for us. Handle finalizer registration here.
(scm_make_struct): Factor some things to scm_i_alloc_struct and
scm_i_struct_inherit_vtable_magic.
(scm_make_vtable_vtable): Adapt to scm_i_alloc_struct name change.
* libguile/struct.h (scm_i_alloc_struct): Change name from
scm_alloc_struct, and make internal.
* module/oop/goops.scm (oop): Don't declare #:replace <class> et al,
because <class> isn't defined in the core any more.
(accessor-method-slot-definition): Defined in Scheme now.
Remove <foreign-object> methods.
(initialize on <class>): Prep layout before inheriting magic, as in
scm_basic_make_class.
* module/oop/goops/dispatch.scm (delayed-compile)
(memoize-effective-method!): Adapt to 'procedure slot name change.
2009-11-08 11:24:23 +01:00
|
|
|
|
(define (accessor-method-slot-definition obj)
|
|
|
|
|
|
"Return the slot definition of the accessor @var{obj}."
|
|
|
|
|
|
(slot-ref obj 'slot-definition))
|
|
|
|
|
|
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Standard methods used by the C runtime}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
;;; Methods to compare objects
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2009-11-08 11:49:06 +01:00
|
|
|
|
;; Have to do this in a strange order because equal? is used in the
|
|
|
|
|
|
;; add-method! implementation; we need to make sure that when the
|
|
|
|
|
|
;; primitive is extended, that the generic has a method. =
|
|
|
|
|
|
(define g-equal? (make-generic 'equal?))
|
|
|
|
|
|
;; When this generic gets called, we will have already checked eq? and
|
|
|
|
|
|
;; eqv? -- the purpose of this generic is to extend equality. So by
|
|
|
|
|
|
;; default, there is no extension, thus the #f return.
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(add-method! g-equal? (method (x y) #f))
|
2009-11-08 11:49:06 +01:00
|
|
|
|
(set-primitive-generic! equal? g-equal?)
|
2003-03-06 12:51:57 +00:00
|
|
|
|
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; methods to display/write an object
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
; Code for writing objects must test that the slots they use are
|
2015-01-09 20:07:06 +01:00
|
|
|
|
; bound. Otherwise a slot-unbound method will be called and will
|
2000-10-25 14:51:33 +00:00
|
|
|
|
; conduct to an infinite loop.
|
|
|
|
|
|
|
|
|
|
|
|
;; Write
|
|
|
|
|
|
(define (display-address o file)
|
|
|
|
|
|
(display (number->string (object-address o) 16) file))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (write o file)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(display "#<instance " file)
|
|
|
|
|
|
(display-address o file)
|
|
|
|
|
|
(display #\> file))
|
|
|
|
|
|
|
|
|
|
|
|
(define write-object (primitive-generic-generic write))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (write (o <object>) file)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let ((class (class-of o)))
|
|
|
|
|
|
(if (slot-bound? class 'name)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(begin
|
|
|
|
|
|
(display "#<" file)
|
|
|
|
|
|
(display (class-name class) file)
|
|
|
|
|
|
(display #\space file)
|
|
|
|
|
|
(display-address o file)
|
|
|
|
|
|
(display #\> file))
|
|
|
|
|
|
(next-method))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-method (write (slot <slot>) file)
|
|
|
|
|
|
(let ((class (class-of slot)))
|
|
|
|
|
|
(if (and (slot-bound? class 'name)
|
|
|
|
|
|
(slot-bound? slot 'name))
|
|
|
|
|
|
(begin
|
|
|
|
|
|
(display "#<" file)
|
|
|
|
|
|
(display (class-name class) file)
|
|
|
|
|
|
(display #\space file)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(display (%slot-definition-name slot) file)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(display #\space file)
|
|
|
|
|
|
(display-address slot file)
|
|
|
|
|
|
(display #\> file))
|
|
|
|
|
|
(next-method))))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (write (class <class>) file)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let ((meta (class-of class)))
|
|
|
|
|
|
(if (and (slot-bound? class 'name)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(slot-bound? meta 'name))
|
|
|
|
|
|
(begin
|
|
|
|
|
|
(display "#<" file)
|
|
|
|
|
|
(display (class-name meta) file)
|
|
|
|
|
|
(display #\space file)
|
|
|
|
|
|
(display (class-name class) file)
|
|
|
|
|
|
(display #\space file)
|
|
|
|
|
|
(display-address class file)
|
|
|
|
|
|
(display #\> file))
|
|
|
|
|
|
(next-method))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (write (gf <generic>) file)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let ((meta (class-of gf)))
|
|
|
|
|
|
(if (and (slot-bound? meta 'name)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(slot-bound? gf 'methods))
|
|
|
|
|
|
(begin
|
|
|
|
|
|
(display "#<" file)
|
|
|
|
|
|
(display (class-name meta) file)
|
|
|
|
|
|
(let ((name (generic-function-name gf)))
|
|
|
|
|
|
(if name
|
|
|
|
|
|
(begin
|
|
|
|
|
|
(display #\space file)
|
|
|
|
|
|
(display name file))))
|
|
|
|
|
|
(display " (" file)
|
|
|
|
|
|
(display (length (generic-function-methods gf)) file)
|
|
|
|
|
|
(display ")>" file))
|
|
|
|
|
|
(next-method))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (write (o <method>) file)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let ((meta (class-of o)))
|
|
|
|
|
|
(if (and (slot-bound? meta 'name)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(slot-bound? o 'specializers))
|
|
|
|
|
|
(begin
|
|
|
|
|
|
(display "#<" file)
|
|
|
|
|
|
(display (class-name meta) file)
|
|
|
|
|
|
(display #\space file)
|
|
|
|
|
|
(display (map* (lambda (spec)
|
|
|
|
|
|
(if (slot-bound? spec 'name)
|
|
|
|
|
|
(slot-ref spec 'name)
|
|
|
|
|
|
spec))
|
|
|
|
|
|
(method-specializers o))
|
|
|
|
|
|
file)
|
|
|
|
|
|
(display #\space file)
|
|
|
|
|
|
(display-address o file)
|
|
|
|
|
|
(display #\> file))
|
|
|
|
|
|
(next-method))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;; Display (do the same thing as write by default)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(define-method (display o file)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(write-object o file))
|
|
|
|
|
|
|
2003-03-07 13:12:47 +00:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; Handling of duplicate bindings in the module system
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
(define (find-subclass super name)
|
|
|
|
|
|
(let lp ((classes (class-direct-subclasses super)))
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((null? classes)
|
|
|
|
|
|
(error "class not found" name))
|
|
|
|
|
|
((and (slot-bound? (car classes) 'name)
|
|
|
|
|
|
(eq? (class-name (car classes)) name))
|
|
|
|
|
|
(car classes))
|
|
|
|
|
|
(else
|
|
|
|
|
|
(lp (cdr classes))))))
|
|
|
|
|
|
|
|
|
|
|
|
;; A record type.
|
|
|
|
|
|
(define <module> (find-subclass <top> '<module>))
|
|
|
|
|
|
|
2003-03-07 13:12:47 +00:00
|
|
|
|
(define-method (merge-generics (module <module>)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(name <symbol>)
|
|
|
|
|
|
(int1 <module>)
|
|
|
|
|
|
(val1 <top>)
|
|
|
|
|
|
(int2 <module>)
|
|
|
|
|
|
(val2 <top>)
|
|
|
|
|
|
(var <top>)
|
|
|
|
|
|
(val <top>))
|
2003-03-07 13:12:47 +00:00
|
|
|
|
#f)
|
|
|
|
|
|
|
|
|
|
|
|
(define-method (merge-generics (module <module>)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(name <symbol>)
|
|
|
|
|
|
(int1 <module>)
|
|
|
|
|
|
(val1 <generic>)
|
|
|
|
|
|
(int2 <module>)
|
|
|
|
|
|
(val2 <generic>)
|
|
|
|
|
|
(var <top>)
|
|
|
|
|
|
(val <boolean>))
|
2003-03-12 18:41:44 +00:00
|
|
|
|
(and (not (eq? val1 val2))
|
|
|
|
|
|
(make-variable (make-extended-generic (list val2 val1) name))))
|
2003-03-07 13:12:47 +00:00
|
|
|
|
|
|
|
|
|
|
(define-method (merge-generics (module <module>)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(name <symbol>)
|
|
|
|
|
|
(int1 <module>)
|
|
|
|
|
|
(val1 <generic>)
|
|
|
|
|
|
(int2 <module>)
|
|
|
|
|
|
(val2 <generic>)
|
|
|
|
|
|
(var <top>)
|
|
|
|
|
|
(gf <extended-generic>))
|
2003-03-12 18:41:44 +00:00
|
|
|
|
(and (not (memq val2 (slot-ref gf 'extends)))
|
|
|
|
|
|
(begin
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(slot-set! gf
|
|
|
|
|
|
'extends
|
|
|
|
|
|
(cons val2 (delq! val2 (slot-ref gf 'extends))))
|
|
|
|
|
|
(slot-set! val2
|
|
|
|
|
|
'extended-by
|
|
|
|
|
|
(cons gf (delq! gf (slot-ref val2 'extended-by))))
|
2011-09-02 13:17:19 +02:00
|
|
|
|
(invalidate-method-cache! gf)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
var)))
|
2003-03-07 13:12:47 +00:00
|
|
|
|
|
|
|
|
|
|
(module-define! duplicate-handlers 'merge-generics merge-generics)
|
|
|
|
|
|
|
2003-03-11 14:50:08 +00:00
|
|
|
|
(define-method (merge-accessors (module <module>)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(name <symbol>)
|
|
|
|
|
|
(int1 <module>)
|
|
|
|
|
|
(val1 <top>)
|
|
|
|
|
|
(int2 <module>)
|
|
|
|
|
|
(val2 <top>)
|
|
|
|
|
|
(var <top>)
|
|
|
|
|
|
(val <top>))
|
2003-03-11 14:50:08 +00:00
|
|
|
|
#f)
|
|
|
|
|
|
|
|
|
|
|
|
(define-method (merge-accessors (module <module>)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(name <symbol>)
|
|
|
|
|
|
(int1 <module>)
|
|
|
|
|
|
(val1 <accessor>)
|
|
|
|
|
|
(int2 <module>)
|
|
|
|
|
|
(val2 <accessor>)
|
|
|
|
|
|
(var <top>)
|
|
|
|
|
|
(val <top>))
|
2003-03-11 14:50:08 +00:00
|
|
|
|
(merge-generics module name int1 val1 int2 val2 var val))
|
|
|
|
|
|
|
|
|
|
|
|
(module-define! duplicate-handlers 'merge-accessors merge-accessors)
|
|
|
|
|
|
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; slot access
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define (class-slot-ref class slot-name)
|
|
|
|
|
|
(let ((slot (class-slot-definition class slot-name)))
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(unless (memq (%slot-definition-allocation slot) '(#:class #:each-subclass))
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(slot-missing class slot-name))
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(let ((x ((%slot-definition-slot-ref slot) #f)))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(if (unbound? x)
|
|
|
|
|
|
(slot-unbound class slot-name)
|
|
|
|
|
|
x))))
|
|
|
|
|
|
|
|
|
|
|
|
(define (class-slot-set! class slot-name value)
|
|
|
|
|
|
(let ((slot (class-slot-definition class slot-name)))
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(unless (memq (%slot-definition-allocation slot) '(#:class #:each-subclass))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(slot-missing class slot-name))
|
2015-01-19 12:20:50 +01:00
|
|
|
|
((%slot-definition-slot-set! slot) #f value)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (slot-unbound (c <class>) (o <object>) s)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(goops-error "Slot `~S' is unbound in object ~S" s o))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (slot-unbound (c <class>) s)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(goops-error "Slot `~S' is unbound in class ~S" s c))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (slot-unbound (o <object>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(goops-error "Unbound slot in object ~S" o))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (slot-missing (c <class>) (o <object>) s)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(goops-error "No slot with name `~S' in object ~S" s o))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (slot-missing (c <class>) s)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(goops-error "No class slot with name `~S' in class ~S" s c))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (slot-missing (c <class>) (o <object>) s value)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(slot-missing c o s))
|
|
|
|
|
|
|
|
|
|
|
|
;;; Methods for the possible error we can encounter when calling a gf
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (no-next-method (gf <generic>) args)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(goops-error "No next method when calling ~S\nwith arguments ~S" gf args))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (no-applicable-method (gf <generic>) args)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(goops-error "No applicable method for ~S in call ~S"
|
2015-01-09 20:07:06 +01:00
|
|
|
|
gf (cons (generic-function-name gf) args)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (no-method (gf <generic>) args)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(goops-error "No method defined for ~S" gf))
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Cloning functions (from rdeline@CS.CMU.EDU)}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (shallow-clone (self <object>))
|
2015-01-11 19:11:41 +01:00
|
|
|
|
(let* ((class (class-of self))
|
|
|
|
|
|
(clone (%allocate-instance class))
|
|
|
|
|
|
(slots (map slot-definition-name (class-slots class))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(for-each (lambda (slot)
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (slot-bound? self slot)
|
|
|
|
|
|
(slot-set! clone slot (slot-ref self slot))))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
slots)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
clone))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (deep-clone (self <object>))
|
2015-01-11 19:11:41 +01:00
|
|
|
|
(let* ((class (class-of self))
|
|
|
|
|
|
(clone (%allocate-instance class))
|
|
|
|
|
|
(slots (map slot-definition-name (class-slots class))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(for-each (lambda (slot)
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (slot-bound? self slot)
|
|
|
|
|
|
(slot-set! clone slot
|
|
|
|
|
|
(let ((value (slot-ref self slot)))
|
|
|
|
|
|
(if (instance? value)
|
|
|
|
|
|
(deep-clone value)
|
|
|
|
|
|
value)))))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
slots)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
clone))
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Class redefinition utilities}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
;;; (class-redefinition OLD NEW)
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
;;; Has correct the following conditions:
|
|
|
|
|
|
|
|
|
|
|
|
;;; Methods
|
2015-01-09 20:07:06 +01:00
|
|
|
|
;;;
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;; 1. New accessor specializers refer to new header
|
2015-01-09 20:07:06 +01:00
|
|
|
|
;;;
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;; Classes
|
2015-01-09 20:07:06 +01:00
|
|
|
|
;;;
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;; 1. New class cpl refers to the new class header
|
|
|
|
|
|
;;; 2. Old class header exists on old super classes direct-subclass lists
|
|
|
|
|
|
;;; 3. New class header exists on new super classes direct-subclass lists
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (class-redefinition (old <class>) (new <class>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;; Work on direct methods:
|
2015-01-09 20:07:06 +01:00
|
|
|
|
;; 1. Remove accessor methods from the old class
|
|
|
|
|
|
;; 2. Patch the occurences of new in the specializers by old
|
|
|
|
|
|
;; 3. Displace the methods from old to new
|
|
|
|
|
|
(remove-class-accessors! old) ;; -1-
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let ((methods (class-direct-methods new)))
|
|
|
|
|
|
(for-each (lambda (m)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(update-direct-method! m new old)) ;; -2-
|
2000-10-25 14:51:33 +00:00
|
|
|
|
methods)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(struct-set! new
|
|
|
|
|
|
class-index-direct-methods
|
|
|
|
|
|
(append methods (class-direct-methods old))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;; Substitute old for new in new cpl
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(set-car! (struct-ref new class-index-cpl) old)
|
|
|
|
|
|
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;; Remove the old class from the direct-subclasses list of its super classes
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(for-each (lambda (c) (struct-set! c class-index-direct-subclasses
|
|
|
|
|
|
(delv! old (class-direct-subclasses c))))
|
|
|
|
|
|
(class-direct-supers old))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;; Replace the new class with the old in the direct-subclasses of the supers
|
|
|
|
|
|
(for-each (lambda (c)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(struct-set! c class-index-direct-subclasses
|
|
|
|
|
|
(cons old (delv! new (class-direct-subclasses c)))))
|
|
|
|
|
|
(class-direct-supers new))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;; Swap object headers
|
|
|
|
|
|
(%modify-class old new)
|
|
|
|
|
|
|
|
|
|
|
|
;; Now old is NEW!
|
|
|
|
|
|
|
|
|
|
|
|
;; Redefine all the subclasses of old to take into account modification
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(for-each
|
|
|
|
|
|
(lambda (c)
|
|
|
|
|
|
(update-direct-subclass! c new old))
|
|
|
|
|
|
(class-direct-subclasses new))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;; Invalidate class so that subsequent instances slot accesses invoke
|
|
|
|
|
|
;; change-object-class
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(struct-set! new class-index-redefined old)
|
Manipulate GOOPS vtable flags from Scheme, for speed
* libguile/goops.h: Remove unimplemented declarations of
scm_make_next_method, scm_sys_invalidate_method_cache_x, and
stklos_version.
(scm_sys_invalidate_class_x): Remove helper definition. This was
exported in the past but shouldn't have been.
* libguile/goops.c (scm_sys_make_vtable_vtable): Rename from
scm_sys_make_root_class, and don't do anything about flags.
(scm_sys_bless_applicable_struct_vtables_x, scm_class_p)
(scm_sys_invalidate_class_x): Remove; we do these in Scheme now.
(scm_init_goops_builtins): Define Scheme values for vtable flags.
* module/oop/goops.scm (vtable-flag-goops-metaclass)
(class-add-flags!, class-clear-flags!, class-has-flags?)
(class?, instance?): New definitions.
(<class>): Add GOOPS metaclass flags from Scheme.
(<applicable-struct-class>, <applicable-struct-with-setter-class>):
Add flags from Scheme.
(make, initialize): Add class flags as appropriate.
(class-redefinition): Clear the "valid" flag on the old class.
(check-slot-args): Use instance? instead of a CPL check.
2015-01-16 11:26:25 +01:00
|
|
|
|
(class-clear-flags! new vtable-flag-goops-valid) ;must come after slot-set!
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
old)
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; remove-class-accessors!
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (remove-class-accessors! (c <class>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(for-each (lambda (m)
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (is-a? m <accessor-method>)
|
|
|
|
|
|
(let ((gf (slot-ref m 'generic-function)))
|
|
|
|
|
|
;; remove the method from its GF
|
|
|
|
|
|
(slot-set! gf 'methods
|
|
|
|
|
|
(delq1! m (slot-ref gf 'methods)))
|
|
|
|
|
|
(invalidate-method-cache! gf)
|
|
|
|
|
|
;; remove the method from its specializers
|
|
|
|
|
|
(remove-method-in-classes! m))))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(class-direct-methods c)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; update-direct-method!
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (update-direct-method! (m <method>)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(old <class>)
|
|
|
|
|
|
(new <class>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let loop ((l (method-specializers m)))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
;; Note: the <top> in dotted list is never used.
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;; So we can work as if we had only proper lists.
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (pair? l)
|
|
|
|
|
|
(when (eqv? (car l) old)
|
|
|
|
|
|
(set-car! l new))
|
|
|
|
|
|
(loop (cdr l)))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; update-direct-subclass!
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (update-direct-subclass! (c <class>)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(old <class>)
|
|
|
|
|
|
(new <class>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(class-redefinition c
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(make-class (class-direct-supers c)
|
|
|
|
|
|
(class-direct-slots c)
|
|
|
|
|
|
#:name (class-name c)
|
|
|
|
|
|
#:metaclass (class-of c))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Utilities for INITIALIZE methods}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
;;; compute-slot-accessors
|
|
|
|
|
|
;;;
|
2009-11-27 20:50:40 +01:00
|
|
|
|
(define (compute-slot-accessors class slots)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(for-each
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(lambda (slot)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(let ((getter (%slot-definition-getter slot))
|
|
|
|
|
|
(setter (%slot-definition-setter slot))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(accessor-setter setter)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(accessor (%slot-definition-accessor slot)))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(when getter
|
|
|
|
|
|
(add-method! getter (compute-getter-method class slot)))
|
|
|
|
|
|
(when setter
|
|
|
|
|
|
(add-method! setter (compute-setter-method class slot)))
|
|
|
|
|
|
(when accessor
|
|
|
|
|
|
(add-method! accessor (compute-getter-method class slot))
|
|
|
|
|
|
(add-method! (accessor-setter accessor)
|
|
|
|
|
|
(compute-setter-method class slot)))))
|
|
|
|
|
|
slots))
|
|
|
|
|
|
|
|
|
|
|
|
(define-method (compute-getter-method (class <class>) slot)
|
|
|
|
|
|
(let ((init-thunk (slot-definition-init-thunk slot))
|
|
|
|
|
|
(slot-ref (slot-definition-slot-ref slot))
|
|
|
|
|
|
(index (slot-definition-index slot)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(make <accessor-method>
|
|
|
|
|
|
#:specializers (list class)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
#:procedure (cond
|
|
|
|
|
|
(slot-ref (make-generic-bound-check-getter slot-ref))
|
|
|
|
|
|
(init-thunk (standard-get index))
|
|
|
|
|
|
(else (bound-check-get index)))
|
|
|
|
|
|
#:slot-definition slot)))
|
|
|
|
|
|
|
|
|
|
|
|
(define-method (compute-setter-method (class <class>) slot)
|
|
|
|
|
|
(let ((slot-set! (slot-definition-slot-set! slot))
|
|
|
|
|
|
(index (slot-definition-index slot)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(make <accessor-method>
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
#:specializers (list class <top>)
|
|
|
|
|
|
#:procedure (cond
|
|
|
|
|
|
(slot-set! slot-set!)
|
|
|
|
|
|
(else (standard-set index)))
|
|
|
|
|
|
#:slot-definition slot)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
(define (make-generic-bound-check-getter proc)
|
2015-01-06 14:54:44 -05:00
|
|
|
|
(lambda (o)
|
|
|
|
|
|
(let ((val (proc o)))
|
|
|
|
|
|
(if (unbound? val)
|
|
|
|
|
|
(slot-unbound o)
|
|
|
|
|
|
val))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2013-11-30 16:40:17 +01:00
|
|
|
|
;;; Pre-generate getters and setters for the first 20 slots.
|
|
|
|
|
|
(define-syntax define-standard-accessor-method
|
|
|
|
|
|
(lambda (stx)
|
|
|
|
|
|
(define num-standard-pre-cache 20)
|
|
|
|
|
|
(syntax-case stx ()
|
|
|
|
|
|
((_ ((proc n) arg ...) body)
|
|
|
|
|
|
#`(define proc
|
|
|
|
|
|
(let ((cache (vector #,@(map (lambda (n*)
|
|
|
|
|
|
#`(lambda (arg ...)
|
|
|
|
|
|
(let ((n #,n*))
|
|
|
|
|
|
body)))
|
|
|
|
|
|
(iota num-standard-pre-cache)))))
|
|
|
|
|
|
(lambda (n)
|
|
|
|
|
|
(if (< n #,num-standard-pre-cache)
|
|
|
|
|
|
(vector-ref cache n)
|
|
|
|
|
|
(lambda (arg ...) body)))))))))
|
2009-02-14 00:24:32 +01:00
|
|
|
|
|
|
|
|
|
|
(define-standard-accessor-method ((bound-check-get n) o)
|
2013-11-30 16:40:17 +01:00
|
|
|
|
(let ((x (struct-ref o n)))
|
2009-02-14 00:24:32 +01:00
|
|
|
|
(if (unbound? x)
|
2009-10-22 22:42:45 +02:00
|
|
|
|
(slot-unbound o)
|
2009-02-14 00:24:32 +01:00
|
|
|
|
x)))
|
|
|
|
|
|
|
|
|
|
|
|
(define-standard-accessor-method ((standard-get n) o)
|
2013-11-30 16:40:17 +01:00
|
|
|
|
(struct-ref o n))
|
2009-02-14 00:24:32 +01:00
|
|
|
|
|
|
|
|
|
|
(define-standard-accessor-method ((standard-set n) o v)
|
2013-11-30 16:40:17 +01:00
|
|
|
|
(struct-set! o n v))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;; compute-cpl
|
|
|
|
|
|
;;;
|
compute-cpl implementation only in Scheme
* libguile/goops.c (build_class_class_slots, create_basic_classes):
Instead of creating <class> with uninitialized `direct-slots',
`slots', and `getters-n-setters' fields and initializing them later,
create <class> with a "boot" version of unspecialized slots and later
replace the fields with specialized slot classes. This allows
slot-ref to work during early boot, which is necessary to move
compute-cpl to Scheme.
(create_standard_classes): Finish initializing <class> here.
(map, filter_cpl, compute_cpl): Remove the boot-time compute-cpl in C
and its helpers.
(scm_basic_basic_make_class): Call compute-cpl in Scheme.
(fix_cpl): Remove; since we use the correct compute-cpl from the
beginning, there's no need to correct for the deficiencies of the C
implementation any more.
(build_slots_list): Adapt to build_class_class_slots change.
* module/oop/goops.scm (compute-std-cpl, compute-cpl): Move these up to
the top, so they can be called by the boot process.
(compute-clos-cpl, top-sort, std-tie-breaker, build-transitive-closure)
(build-constraints): Remove unused private code.
2014-12-24 09:37:14 -05:00
|
|
|
|
|
|
|
|
|
|
;; Replace the bootstrap compute-cpl with this definition.
|
|
|
|
|
|
(define compute-cpl
|
|
|
|
|
|
(make <generic> #:name 'compute-cpl))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (compute-cpl (class <class>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(compute-std-cpl class class-direct-supers))
|
|
|
|
|
|
|
|
|
|
|
|
;;; compute-get-n-set
|
|
|
|
|
|
;;;
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define compute-get-n-set
|
|
|
|
|
|
(make <generic> #:name 'compute-get-n-set))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (compute-get-n-set (class <class>) s)
|
2015-01-22 12:40:43 +01:00
|
|
|
|
(define (class-slot-init-value)
|
|
|
|
|
|
(let ((thunk (slot-definition-init-thunk s)))
|
|
|
|
|
|
(if thunk
|
|
|
|
|
|
(thunk)
|
|
|
|
|
|
(slot-definition-init-value s))))
|
|
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define (make-closure-variable class value)
|
|
|
|
|
|
(list (lambda (o) value)
|
|
|
|
|
|
(lambda (o v) (set! value v))))
|
|
|
|
|
|
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(case (slot-definition-allocation s)
|
|
|
|
|
|
((#:instance) ;; Instance slot
|
|
|
|
|
|
;; get-n-set is just its offset
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(let ((already-allocated (struct-ref class class-index-nfields)))
|
|
|
|
|
|
(struct-set! class class-index-nfields (+ already-allocated 1))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
already-allocated))
|
|
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
((#:class) ;; Class slot
|
2015-01-09 20:07:06 +01:00
|
|
|
|
;; Class-slots accessors are implemented as 2 closures around
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;; a Scheme variable. As instance slots, class slots must be
|
|
|
|
|
|
;; unbound at init time.
|
|
|
|
|
|
(let ((name (slot-definition-name s)))
|
|
|
|
|
|
(if (memq name (map slot-definition-name (class-direct-slots class)))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
;; This slot is direct; create a new shared variable
|
|
|
|
|
|
(make-closure-variable class (class-slot-init-value))
|
|
|
|
|
|
;; Slot is inherited. Find its definition in superclass
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(let lp ((cpl (cdr (class-precedence-list class))))
|
|
|
|
|
|
(match cpl
|
|
|
|
|
|
((super . cpl)
|
|
|
|
|
|
(let ((s (class-slot-definition super name)))
|
|
|
|
|
|
(if s
|
|
|
|
|
|
(list (slot-definition-slot-ref s)
|
|
|
|
|
|
(slot-definition-slot-set! s))
|
|
|
|
|
|
;; Multiple inheritance means that we might have
|
|
|
|
|
|
;; to look deeper in the CPL.
|
|
|
|
|
|
(lp cpl)))))))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
((#:each-subclass) ;; slot shared by instances of direct subclass.
|
|
|
|
|
|
;; (Thomas Buerger, April 1998)
|
2015-01-22 12:40:43 +01:00
|
|
|
|
(make-closure-variable class (class-slot-init-value)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
((#:virtual) ;; No allocation
|
|
|
|
|
|
;; slot-ref and slot-set! function must be given by the user
|
|
|
|
|
|
(let ((get (get-keyword #:slot-ref (slot-definition-options s) #f))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(set (get-keyword #:slot-set! (slot-definition-options s) #f)))
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(unless (and get set)
|
|
|
|
|
|
(goops-error "You must supply a #:slot-ref and a #:slot-set! in ~S" s))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(list get set)))
|
|
|
|
|
|
(else (next-method))))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (compute-get-n-set (o <object>) s)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(goops-error "Allocation \"~S\" is unknown" (slot-definition-allocation s)))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (compute-slots (class <class>))
|
Move GOOPS boot to Scheme
* module/oop/goops.scm (build-<class>-slots): New helper, replacing
build_class_class_slots.
(build-slots-list, %compute-getters-n-setters, %compute-layout): New
private helpers, moved here from C.
(%prep-layout!): Reimplement in Scheme.
(make-standard-class): New private helper, replacing
scm_basic_make_class.
(<class>, <top>, <object>): Define in Scheme.
(<foreign-slot>, <protected-slot>, <hidden-slot>, <opaque-slot>,
<read-only-slot>, <self-slot>, <protected-opaque-slot>,
<protected-hidden-slot>, <protected-read-only-slot>, <scm-slot>,
<int-slot>, <float-slot>, <double-slot>, <procedure-class>,
<applicable-struct-class>, <method>, <accessor-method>, <applicable>,
<applicable-struct>, <generic>, <extended-generic>,
<generic-with-setter>, <accessor>, <extended-generic-with-setter>,
<extended-accessor>): Define in Scheme.
(<boolean>, <char>, <list>, <pair>, <null>, <string>, <symbol>,
<vector>, <foreign>, <hashtable>, <fluid>, <dynamic-state>, <frame>,
<vm-continuation>, <bytevector>, <uvec>, <array>, <bitvector>,
<number>, <complex>, <real>, <integer>, <fraction>, <keyword>,
<unknown>, <procedure>, <primitive-generic>, <port>, <input-port>,
<output-port>, <input-output-port>): Define in Scheme.
(compute-slots): Use build-slots-list helper.
* libguile/goops.h:
* libguile/goops.c (scm_basic_basic_make_class, scm_sys_compute_slots)
(scm_sys_prep_layout_x): Remove. These were available to C, but were
undocumented internals that were dangerous, confusing, and
unnecessary.
* libguile/goops.c: Add note about variable versus value references.
Remove internal C routines that were just used during boot, as they
have been moved to Scheme.
(scm_basic_make_class): Change to call out to make-standard-class in
Scheme.
(scm_sys_make_root_class, scm_sys_bless_applicable_struct_vtable_x)
(scm_sys_bless_pure_generic_vtable_x, scm_sys_init_layout_x): New
private helpers.
(scm_sys_goops_early_init): Change to capture values defined in
Scheme.
2015-01-04 13:41:09 -05:00
|
|
|
|
(build-slots-list (class-direct-slots class)
|
|
|
|
|
|
(class-precedence-list class)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Initialize}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2015-01-11 00:17:22 +01:00
|
|
|
|
;; FIXME: This could be much more efficient.
|
|
|
|
|
|
(define (%initialize-object obj initargs)
|
|
|
|
|
|
"Initialize the object @var{obj} with the given arguments
|
|
|
|
|
|
var{initargs}."
|
2015-01-19 13:06:44 +01:00
|
|
|
|
(define (valid-initargs? initargs)
|
|
|
|
|
|
(match initargs
|
|
|
|
|
|
(() #t)
|
|
|
|
|
|
(((? keyword?) _ . initargs) (valid-initargs? initargs))
|
|
|
|
|
|
(_ #f)))
|
2015-01-11 00:17:22 +01:00
|
|
|
|
(unless (instance? obj)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Not an object: ~S"
|
|
|
|
|
|
(list obj) #f))
|
2015-01-19 13:06:44 +01:00
|
|
|
|
(unless (valid-initargs? initargs)
|
|
|
|
|
|
(scm-error 'wrong-type-arg #f "Invalid initargs: ~S"
|
2015-01-11 00:17:22 +01:00
|
|
|
|
(list initargs) #f))
|
|
|
|
|
|
(let ((class (class-of obj)))
|
|
|
|
|
|
(define (get-initarg kw)
|
|
|
|
|
|
(if kw
|
2015-01-19 13:06:44 +01:00
|
|
|
|
;; Inlined get-keyword to avoid checking initargs for validity
|
|
|
|
|
|
;; each time.
|
|
|
|
|
|
(let lp ((initargs initargs))
|
|
|
|
|
|
(match initargs
|
|
|
|
|
|
((kw* val . initargs)
|
|
|
|
|
|
(if (eq? kw* kw)
|
|
|
|
|
|
val
|
|
|
|
|
|
(lp initargs)))
|
|
|
|
|
|
(_ *unbound*)))
|
2015-01-11 00:17:22 +01:00
|
|
|
|
*unbound*))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(let lp ((slots (struct-ref class class-index-slots)))
|
2015-01-11 00:17:22 +01:00
|
|
|
|
(match slots
|
|
|
|
|
|
(() obj)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
((slot . slots)
|
2015-01-19 13:06:44 +01:00
|
|
|
|
(define (initialize-slot! value)
|
|
|
|
|
|
(cond
|
|
|
|
|
|
((%slot-definition-slot-set! slot)
|
|
|
|
|
|
=> (lambda (slot-set!) (slot-set! obj value)))
|
|
|
|
|
|
(else
|
|
|
|
|
|
(struct-set! obj (%slot-definition-index slot) value))))
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(let ((initarg (get-initarg (%slot-definition-init-keyword slot))))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(cond
|
|
|
|
|
|
((not (unbound? initarg))
|
2015-01-19 13:06:44 +01:00
|
|
|
|
(initialize-slot! initarg))
|
2015-01-19 12:20:50 +01:00
|
|
|
|
((%slot-definition-init-thunk slot)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
=> (lambda (init-thunk)
|
|
|
|
|
|
(unless (memq (slot-definition-allocation slot)
|
|
|
|
|
|
'(#:class #:each-subclass))
|
2015-01-19 13:06:44 +01:00
|
|
|
|
(initialize-slot! (init-thunk)))))))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(lp slots))))))
|
2015-01-11 00:17:22 +01:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (initialize (object <object>) initargs)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(%initialize-object object initargs))
|
|
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define-method (initialize (slot <slot>) initargs)
|
|
|
|
|
|
(next-method)
|
|
|
|
|
|
(struct-set! slot slot-index-options initargs)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(let ((init-thunk (%slot-definition-init-thunk slot)))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(when init-thunk
|
|
|
|
|
|
(unless (thunk? init-thunk)
|
|
|
|
|
|
(goops-error "Bad init-thunk for slot `~S': ~S"
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(%slot-definition-name slot) init-thunk)))))
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (initialize (class <class>) initargs)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(define (make-direct-slot-definition dslot)
|
|
|
|
|
|
(let ((initargs (compute-direct-slot-definition-initargs class dslot)))
|
|
|
|
|
|
(compute-direct-slot-definition class initargs)))
|
|
|
|
|
|
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(next-method)
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
(class-add-flags! class (logior vtable-flag-goops-class
|
|
|
|
|
|
vtable-flag-goops-valid))
|
|
|
|
|
|
(struct-set! class class-index-name (get-keyword #:name initargs '???))
|
|
|
|
|
|
(struct-set! class class-index-nfields 0)
|
|
|
|
|
|
(struct-set! class class-index-direct-supers
|
|
|
|
|
|
(get-keyword #:dsupers initargs '()))
|
|
|
|
|
|
(struct-set! class class-index-direct-subclasses '())
|
|
|
|
|
|
(struct-set! class class-index-direct-methods '())
|
|
|
|
|
|
(struct-set! class class-index-redefined #f)
|
|
|
|
|
|
(struct-set! class class-index-cpl (compute-cpl class))
|
|
|
|
|
|
(struct-set! class class-index-direct-slots
|
|
|
|
|
|
(map (lambda (slot)
|
|
|
|
|
|
(if (slot? slot)
|
|
|
|
|
|
slot
|
|
|
|
|
|
(make-direct-slot-definition slot)))
|
|
|
|
|
|
(get-keyword #:slots initargs '())))
|
|
|
|
|
|
(struct-set! class class-index-slots
|
|
|
|
|
|
(allocate-slots class (compute-slots class)))
|
|
|
|
|
|
|
2015-01-18 21:01:31 +01:00
|
|
|
|
;; This is a hack.
|
|
|
|
|
|
(when (memq <slot> (struct-ref class class-index-cpl))
|
|
|
|
|
|
(class-add-flags! class vtable-flag-goops-slot))
|
|
|
|
|
|
|
Introduce <slot> objects in GOOPS
* module/oop/goops.scm (fold-class-slots): Change format to use proper
slot specifications.
(fold-slot-slots): Flesh out with all needed slots.
(<class>): Update cons-layout to deal with new fold-class-slots form.
Don't create slots; we do that later.
(is-a?, get-keyword, *unbound, unbound?, %allocate-instance): Move
definitions up.
(<slot>, slot?): New definitions.
(slot-definition-name, slot-definition-allocation)
(slot-definition-init-keyword, slot-definition-init-form)
(slot-definition-init-value, slot-definition-init-thunk)
(slot-definition-options, slot-definition-getter)
(slot-definition-setter, slot-definition-accessor)
(slot-definition-slot-ref, slot-definition-slot-set!)
(slot-definition-index, slot-definition-size): New definitions as
accessors on <slot> objects.
(class-slot-definition): Adapt to class-slots change.
(direct-slot-definition-class, make-slot): New definitions.
(make): Define a boot version that can allocate <slot> instances.
(compute-direct-slot-definition)
(compute-direct-slot-definition-initargs)
(effective-slot-definition-class, compute-effective-slot-definition):
New definitions.
(build-slots-list): Adapt to slots being <slot> objects.
(compute-get-n-set): New boot definition.
(allocate-slots): New definition. Replaces
compute-getters-n-setters.
(%compute-layout, %prep-layout): Adapt to changes.
(make-standard-class): Make <slot> objects for direct-slots, and
handle the allocate-slots protocol.
(<foreign-slot>): Inherit from <slot>.
(get-slot-value-using-name, set-slot-value-using-name!)
(test-slot-existence): Adapt to using slot definition objects.
(make-class): Allow slot specs or <slot> objects as the `slots'
argument.
(write): New method on <slot>.
(class-slot-ref, class-slot-set!): Reimplement.
(compute-slot-accessors, compute-getter-method)
(compute-setter-method): Adapt to changes.
(compute-getters-n-setters): Remove. Yay!
(compute-get-n-set): Adapt to use effective slot definitions instead
of the getters-n-setters for #:class / #:each-subclass allocation.
(%initialize-object): Adapt.
(initialize): New method for <slot>. Adapt method for <class>.
* module/oop/goops/active-slot.scm (compute-get-n-set):
* module/oop/goops/composite-slot.scm (compute-propagated-get-n-set):
Use slot-definition-options to access options of slot.
* test-suite/tests/goops.test ("bad init-thunk"): Fix to be a "pass-if"
instead of an "expect-fail".
2015-01-18 20:53:19 +01:00
|
|
|
|
;; Build getters - setters - accessors
|
|
|
|
|
|
(compute-slot-accessors class (struct-ref class class-index-slots))
|
|
|
|
|
|
|
|
|
|
|
|
;; Update the "direct-subclasses" of each inherited classes
|
|
|
|
|
|
(for-each (lambda (x)
|
|
|
|
|
|
(let ((dsubs (struct-ref x class-index-direct-subclasses)))
|
|
|
|
|
|
(struct-set! x class-index-direct-subclasses
|
|
|
|
|
|
(cons class dsubs))))
|
|
|
|
|
|
(struct-ref class class-index-direct-supers))
|
|
|
|
|
|
|
|
|
|
|
|
;; Compute struct layout of instances, set the `layout' slot, and
|
|
|
|
|
|
;; update class flags.
|
|
|
|
|
|
(%prep-layout! class))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
(define (initialize-object-procedure object initargs)
|
|
|
|
|
|
(let ((proc (get-keyword #:procedure initargs #f)))
|
|
|
|
|
|
(cond ((not proc))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
((pair? proc)
|
|
|
|
|
|
(apply slot-set! object 'procedure proc))
|
|
|
|
|
|
(else
|
2010-06-29 09:14:33 +01:00
|
|
|
|
(slot-set! object 'procedure proc)))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
limn goops flags, remove foreign objs, rename entity to applicable-struct
* libguile/goops.c (scm_class_applicable_struct)
(scm_class_applicable_struct_with_setter)
(scm_class_applicable_struct_class): Rename from
scm_class_entity, scm_class_entity_with_setter, and
scm_class_entity_class.
(scm_class_simple_method): Removed; this abstraction is not used.
(scm_class_foreign_class, scm_class_foreign_object): Remove these,
they are undocumented and unused. They might come back later.
(scm_sys_inherit_magic_x): Simply inherit the vtable flags from the
class's class. Flags are about layout, and it is the class that
determines the layout of the instance.
(scm_basic_basic_make_class): Don't bother setting GOOPS_OR_VALID,
inherit-magic will do that.
(scm_basic_make_class): Inherit magic after setting the layout. Allows
the struct magic checker to do its job.
(scm_accessor_method_slot_definition): Move implementation to Scheme.
Removes the need for the accessor flag.
(scm_sys_allocate_instance): Adapt to scm_i_alloc_struct name change,
and that alloc-struct will handle finalization.
(scm_compute_applicable_methods): Remove accessor check, as it's
unnecessary.
(scm_make): Adapt to new generic slot order, and no more
simple-method.
(create_standard_classes): What was the GF slot "dispatch-procedure"
is now the applicable-struct slot "procedure". No more foreign class,
foreign object, or simple method. Rename <entity> and friends to
<applicable-struct> and friends. No more entity-with-setter -- though
perhaps it will come back too. Instead generic-with-setter is its own
thing.
* libguile/goops.h (SCM_CLASSF_METACLASS): "A goops class that is a
vtable" -- no need for a separate flag.
(SCM_CLASSF_FOREIGN, SCM_CLASSF_SIMPLE_METHOD)
(SCM_CLASSF_ACCESSOR_METHOD): Removed these unused flags.
(SCM_ACCESSORP): Removed.
Renumber generic slots, rename entity classes, and remove the foreign
class, foreign object, and simple method classes.
* libguile/struct.c (scm_i_struct_inherit_vtable_magic): New function,
called when making new vtables.applicable structs
(scm_i_alloc_struct): Remove 8-bit alignment check, as libGC
guarantees this for us. Handle finalizer registration here.
(scm_make_struct): Factor some things to scm_i_alloc_struct and
scm_i_struct_inherit_vtable_magic.
(scm_make_vtable_vtable): Adapt to scm_i_alloc_struct name change.
* libguile/struct.h (scm_i_alloc_struct): Change name from
scm_alloc_struct, and make internal.
* module/oop/goops.scm (oop): Don't declare #:replace <class> et al,
because <class> isn't defined in the core any more.
(accessor-method-slot-definition): Defined in Scheme now.
Remove <foreign-object> methods.
(initialize on <class>): Prep layout before inheriting magic, as in
scm_basic_make_class.
* module/oop/goops/dispatch.scm (delayed-compile)
(memoize-effective-method!): Adapt to 'procedure slot name change.
2009-11-08 11:24:23 +01:00
|
|
|
|
(define-method (initialize (applicable-struct <applicable-struct>) initargs)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(next-method)
|
limn goops flags, remove foreign objs, rename entity to applicable-struct
* libguile/goops.c (scm_class_applicable_struct)
(scm_class_applicable_struct_with_setter)
(scm_class_applicable_struct_class): Rename from
scm_class_entity, scm_class_entity_with_setter, and
scm_class_entity_class.
(scm_class_simple_method): Removed; this abstraction is not used.
(scm_class_foreign_class, scm_class_foreign_object): Remove these,
they are undocumented and unused. They might come back later.
(scm_sys_inherit_magic_x): Simply inherit the vtable flags from the
class's class. Flags are about layout, and it is the class that
determines the layout of the instance.
(scm_basic_basic_make_class): Don't bother setting GOOPS_OR_VALID,
inherit-magic will do that.
(scm_basic_make_class): Inherit magic after setting the layout. Allows
the struct magic checker to do its job.
(scm_accessor_method_slot_definition): Move implementation to Scheme.
Removes the need for the accessor flag.
(scm_sys_allocate_instance): Adapt to scm_i_alloc_struct name change,
and that alloc-struct will handle finalization.
(scm_compute_applicable_methods): Remove accessor check, as it's
unnecessary.
(scm_make): Adapt to new generic slot order, and no more
simple-method.
(create_standard_classes): What was the GF slot "dispatch-procedure"
is now the applicable-struct slot "procedure". No more foreign class,
foreign object, or simple method. Rename <entity> and friends to
<applicable-struct> and friends. No more entity-with-setter -- though
perhaps it will come back too. Instead generic-with-setter is its own
thing.
* libguile/goops.h (SCM_CLASSF_METACLASS): "A goops class that is a
vtable" -- no need for a separate flag.
(SCM_CLASSF_FOREIGN, SCM_CLASSF_SIMPLE_METHOD)
(SCM_CLASSF_ACCESSOR_METHOD): Removed these unused flags.
(SCM_ACCESSORP): Removed.
Renumber generic slots, rename entity classes, and remove the foreign
class, foreign object, and simple method classes.
* libguile/struct.c (scm_i_struct_inherit_vtable_magic): New function,
called when making new vtables.applicable structs
(scm_i_alloc_struct): Remove 8-bit alignment check, as libGC
guarantees this for us. Handle finalizer registration here.
(scm_make_struct): Factor some things to scm_i_alloc_struct and
scm_i_struct_inherit_vtable_magic.
(scm_make_vtable_vtable): Adapt to scm_i_alloc_struct name change.
* libguile/struct.h (scm_i_alloc_struct): Change name from
scm_alloc_struct, and make internal.
* module/oop/goops.scm (oop): Don't declare #:replace <class> et al,
because <class> isn't defined in the core any more.
(accessor-method-slot-definition): Defined in Scheme now.
Remove <foreign-object> methods.
(initialize on <class>): Prep layout before inheriting magic, as in
scm_basic_make_class.
* module/oop/goops/dispatch.scm (delayed-compile)
(memoize-effective-method!): Adapt to 'procedure slot name change.
2009-11-08 11:24:23 +01:00
|
|
|
|
(initialize-object-procedure applicable-struct initargs))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
Generics with setters have <applicable-struct-with-setter> layout
* libguile/goops.c (scm_sys_set_object_setter_x): Remove. Instead, we
use slot-set! of 'setter.
(scm_i_define_class_for_vtable): Move lower in the file, and fold in
scm_make_extended_class_from_symbol and make_class_from_symbol.
Properly handle applicable structs with setters.
(scm_class_applicable_struct_with_setter_class): New private capture.
(scm_sys_bless_applicable_struct_vtables_x): Rename to take two
arguments, and bless the second argument as an applicable struct with
setter vtable.
(scm_sys_goops_early_init): Capture setter classes.
* libguile/deprecated.c (SPEC_OF, CPL_OF): Access slots by name, not by
index.
(applicablep, more_specificp): Adapt to use CPL_OF.
(scm_find_method): Access "methods" slot by name.
* libguile/procs.c (scm_setter): Remove special case for generics; if
it's a setter, it will be a normal applicable struct.
* module/oop/goops.scm (<applicable-struct-with-setter-class>)
(<applicable-struct-with-setter>): New classes.
(<generic-with-setter>): Now an instance of the setter metaclass and a
child of the setter class, so that the "setter" slot ends up in the
right place.
(<accessor>, <extended-generic-with-setter>, <extended-accessor>): Be
instances of the setter metaclass.
(<method>, <accessor-method>): Move definitions farther down.
(make): Use slot-set! when initializing setters here.
(initialize): Likewise for <applicable-struct-with-setter>. Remove
specialization for <generic-with-setter>.
2015-01-06 13:41:56 -05:00
|
|
|
|
(define-method (initialize (applicable-struct <applicable-struct-with-setter>)
|
|
|
|
|
|
initargs)
|
|
|
|
|
|
(next-method)
|
|
|
|
|
|
(slot-set! applicable-struct 'setter (get-keyword #:setter initargs #f)))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (initialize (generic <generic>) initargs)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let ((previous-definition (get-keyword #:default initargs #f))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(name (get-keyword #:name initargs #f)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(next-method)
|
|
|
|
|
|
(slot-set! generic 'methods (if (is-a? previous-definition <procedure>)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(list (method args
|
2008-10-31 00:07:04 +01:00
|
|
|
|
(apply previous-definition args)))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
'()))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(if name
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(set-procedure-property! generic 'name name))
|
2015-01-04 15:52:12 -05:00
|
|
|
|
(invalidate-method-cache! generic)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2003-01-08 13:24:41 +00:00
|
|
|
|
(define-method (initialize (eg <extended-generic>) initargs)
|
|
|
|
|
|
(next-method)
|
|
|
|
|
|
(slot-set! eg 'extends (get-keyword #:extends initargs '())))
|
|
|
|
|
|
|
2001-03-04 20:46:34 +00:00
|
|
|
|
(define dummy-procedure (lambda args *unspecified*))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (initialize (method <method>) initargs)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(next-method)
|
|
|
|
|
|
(slot-set! method 'generic-function (get-keyword #:generic-function initargs #f))
|
|
|
|
|
|
(slot-set! method 'specializers (get-keyword #:specializers initargs '()))
|
2001-03-04 20:46:34 +00:00
|
|
|
|
(slot-set! method 'procedure
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(get-keyword #:procedure initargs #f))
|
2008-10-24 11:56:31 +02:00
|
|
|
|
(slot-set! method 'formals (get-keyword #:formals initargs '()))
|
|
|
|
|
|
(slot-set! method 'body (get-keyword #:body initargs '()))
|
don't re-enter the compiler during method dispatch
* libguile/goops.c (scm_make): In the pre-inst `make', default
`procedure' to #f, and read a `make-procedure' instead of
`compile-env'.
* libguile/goops.h (scm_si_make_procedure): This instead of
scm_si_compile_env.
* module/oop/goops.scm (make-method): Remove this unused function. Users
should use (make <method> ...) directly.
(method): Capture `make-procedure' instead of `procedure' in the case
that the body calls a next-method. Allows for the kind of
"recompilation" that we were using before, but with closures instead of
re-entering the compiler. Type-specific compilation is still
interesting, but probably should be implemented in another way.
(initialize): Default #:procedure to #f, and
s/compile-env/make-procedure/.
* module/oop/goops/compile.scm (code-table-lookup): Just return the
cmethod, not the entry -- since the entry is now just (append types
cmethod).
(compile-make-procedure): New procedure, returns a form that, when
evaluated/compiled, will yield a procedure of one argument, the
next-method. When called with a next-method, the procedure returns an
actual method implementation. compile-make-procedure returns #f if the
body doesn't call next-method.
(compile-method): Unify to always return procedures. Much cleaner and
*much* faster in the compiled case. In the interpreted case, there
might be a slight slowdown, but if there is one it should be slight.
* module/oop/goops/dispatch.scm (method-cache-install!): Adapt to removal
of compute-entry-with-cmethod.
2009-02-13 23:30:20 +01:00
|
|
|
|
(slot-set! method 'make-procedure (get-keyword #:make-procedure initargs #f)))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Change-class}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define (change-object-class old-instance old-class new-class)
|
2001-03-04 05:28:21 +00:00
|
|
|
|
(let ((new-instance (allocate-instance new-class '())))
|
2005-04-24 12:29:14 +00:00
|
|
|
|
;; Initialize the slots of the new instance
|
2015-01-16 13:02:31 +01:00
|
|
|
|
(for-each
|
|
|
|
|
|
(lambda (slot)
|
|
|
|
|
|
(if (and (slot-exists? old-instance slot)
|
2015-01-19 12:20:50 +01:00
|
|
|
|
(eq? (%slot-definition-allocation
|
2015-01-16 13:02:31 +01:00
|
|
|
|
(class-slot-definition old-class slot))
|
|
|
|
|
|
#:instance)
|
|
|
|
|
|
(slot-bound? old-instance slot))
|
|
|
|
|
|
;; Slot was present and allocated in old instance; copy it
|
|
|
|
|
|
(slot-set! new-instance slot (slot-ref old-instance slot))
|
|
|
|
|
|
;; slot was absent; initialize it with its default value
|
|
|
|
|
|
(let ((init (slot-init-function new-class slot)))
|
|
|
|
|
|
(when init
|
|
|
|
|
|
(slot-set! new-instance slot (init))))))
|
|
|
|
|
|
(map slot-definition-name (class-slots new-class)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;; Exchange old and new instance in place to keep pointers valid
|
|
|
|
|
|
(%modify-instance old-instance new-instance)
|
|
|
|
|
|
;; Allow class specific updates of instances (which now are swapped)
|
|
|
|
|
|
(update-instance-for-different-class new-instance old-instance)
|
|
|
|
|
|
old-instance))
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (update-instance-for-different-class (old-instance <object>)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(new-instance
|
|
|
|
|
|
<object>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;not really important what we do, we just need a default method
|
|
|
|
|
|
new-instance)
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (change-class (old-instance <object>) (new-class <class>))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(change-object-class old-instance (class-of old-instance) new-class))
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {make}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; A new definition which overwrites the previous one which was built-in
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (allocate-instance (class <class>) initargs)
|
2015-01-11 19:11:41 +01:00
|
|
|
|
(%allocate-instance class))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (make-instance (class <class>) . initargs)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let ((instance (allocate-instance class initargs)))
|
|
|
|
|
|
(initialize instance initargs)
|
|
|
|
|
|
instance))
|
|
|
|
|
|
|
|
|
|
|
|
(define make make-instance)
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {apply-generic}
|
|
|
|
|
|
;;;
|
2015-01-11 22:23:51 +01:00
|
|
|
|
;;; Protocol for calling generic functions, intended to be used when
|
|
|
|
|
|
;;; applying subclasses of <generic> and <generic-with-setter>. The
|
|
|
|
|
|
;;; code below is similar to the first MOP described in AMOP.
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; Note that standard generic functions dispatch only on the classes of
|
|
|
|
|
|
;;; the arguments, and the result of such dispatch can be memoized. The
|
2015-01-21 15:16:56 +01:00
|
|
|
|
;;; `dispatch-generic-function-application-from-cache' routine
|
|
|
|
|
|
;;; implements this. `apply-generic' isn't called currently; the
|
|
|
|
|
|
;;; generic function MOP was never fully implemented in GOOPS. However
|
|
|
|
|
|
;;; now that GOOPS is implemented entirely in Scheme (2015) it's much
|
|
|
|
|
|
;;; easier to complete this work. Contributions gladly accepted!
|
|
|
|
|
|
;;; Please read the AMOP first though :)
|
2015-01-11 22:23:51 +01:00
|
|
|
|
;;;
|
|
|
|
|
|
;;; The protocol is:
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; + apply-generic (gf args)
|
|
|
|
|
|
;;; + compute-applicable-methods (gf args ...)
|
|
|
|
|
|
;;; + sort-applicable-methods (gf methods args)
|
|
|
|
|
|
;;; + apply-methods (gf methods args)
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; apply-methods calls make-next-method to build the "continuation" of
|
|
|
|
|
|
;;; a method. Applying a next-method will call apply-next-method which
|
|
|
|
|
|
;;; in turn will call apply again to call effectively the following
|
|
|
|
|
|
;;; method. (This paragraph is out of date but is kept so that maybe it
|
|
|
|
|
|
;;; illuminates some future hack.)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
;;;
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (apply-generic (gf <generic>) args)
|
2015-01-14 20:06:35 +01:00
|
|
|
|
(when (null? (slot-ref gf 'methods))
|
|
|
|
|
|
(no-method gf args))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(let ((methods (compute-applicable-methods gf args)))
|
|
|
|
|
|
(if methods
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(apply-methods gf (sort-applicable-methods gf methods args) args)
|
|
|
|
|
|
(no-applicable-method gf args))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;; compute-applicable-methods is bound to %compute-applicable-methods.
|
|
|
|
|
|
;; *fixme* use let
|
|
|
|
|
|
(define %%compute-applicable-methods
|
|
|
|
|
|
(make <generic> #:name 'compute-applicable-methods))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (%%compute-applicable-methods (gf <generic>) args)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(%compute-applicable-methods gf args))
|
|
|
|
|
|
|
|
|
|
|
|
(set! compute-applicable-methods %%compute-applicable-methods)
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (sort-applicable-methods (gf <generic>) methods args)
|
2014-12-18 12:51:11 +01:00
|
|
|
|
(%sort-applicable-methods methods (map class-of args)))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (method-more-specific? (m1 <method>) (m2 <method>) targs)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(%method-more-specific? m1 m2 targs))
|
|
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (apply-method (gf <generic>) methods build-next args)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(apply (method-procedure (car methods))
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(build-next (cdr methods) args)
|
|
|
|
|
|
args))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
2001-03-10 03:09:50 +00:00
|
|
|
|
(define-method (apply-methods (gf <generic>) (l <list>) args)
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(letrec ((next (lambda (procs args)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(lambda new-args
|
|
|
|
|
|
(let ((a (if (null? new-args) args new-args)))
|
|
|
|
|
|
(if (null? procs)
|
|
|
|
|
|
(no-next-method gf a)
|
|
|
|
|
|
(apply-method gf procs next a)))))))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
(apply-method gf l next args)))
|
|
|
|
|
|
|
|
|
|
|
|
;; We don't want the following procedure to turn up in backtraces:
|
|
|
|
|
|
(for-each (lambda (proc)
|
2015-01-09 20:07:06 +01:00
|
|
|
|
(set-procedure-property! proc 'system-procedure #t))
|
|
|
|
|
|
(list slot-unbound
|
|
|
|
|
|
slot-missing
|
|
|
|
|
|
no-next-method
|
|
|
|
|
|
no-applicable-method
|
|
|
|
|
|
no-method
|
|
|
|
|
|
))
|
2000-10-25 14:51:33 +00:00
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {Final initialization}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
;; Tell C code that the main bulk of Goops has been loaded
|
|
|
|
|
|
(%goops-loaded)
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
|
;;; {SMOB and port classes}
|
|
|
|
|
|
;;;
|
|
|
|
|
|
|
|
|
|
|
|
(define <arbiter> (find-subclass <top> '<arbiter>))
|
|
|
|
|
|
(define <promise> (find-subclass <top> '<promise>))
|
|
|
|
|
|
(define <thread> (find-subclass <top> '<thread>))
|
|
|
|
|
|
(define <mutex> (find-subclass <top> '<mutex>))
|
|
|
|
|
|
(define <condition-variable> (find-subclass <top> '<condition-variable>))
|
|
|
|
|
|
(define <regexp> (find-subclass <top> '<regexp>))
|
|
|
|
|
|
(define <hook> (find-subclass <top> '<hook>))
|
|
|
|
|
|
(define <bitvector> (find-subclass <top> '<bitvector>))
|
|
|
|
|
|
(define <random-state> (find-subclass <top> '<random-state>))
|
|
|
|
|
|
(define <async> (find-subclass <top> '<async>))
|
|
|
|
|
|
(define <directory> (find-subclass <top> '<directory>))
|
|
|
|
|
|
(define <array> (find-subclass <top> '<array>))
|
|
|
|
|
|
(define <character-set> (find-subclass <top> '<character-set>))
|
|
|
|
|
|
(define <dynamic-object> (find-subclass <top> '<dynamic-object>))
|
|
|
|
|
|
(define <guardian> (find-subclass <applicable> '<guardian>))
|
2011-07-26 11:48:37 +02:00
|
|
|
|
(define <macro> (find-subclass <top> '<macro>))
|
defining a smob or port type no longer mucks exports of (oop goops)
* libguile/goops.c (DEFVAR): Remove this helper macro, replacing its
uses with scm_module_define, but without scm_module_export.
(create_basic_classes, scm_init_goops_builtins): Update callers.
(make_class_from_template, make_class_from_symbol): Change to not
define variables for classes. This affects ports, struct classes, and
smob classes.
* module/oop/goops.scm: Explicitly list our exports, so there is no more
trickery happening in C.
(find-subclass): Private helper to grub the class hierarchy, so we can
define bindings for smobs, ports, etc. Use to define the classes that
goops.c used to define -- probably a subset, but it's better to have
them listed.
2011-07-01 11:46:32 +02:00
|
|
|
|
|
|
|
|
|
|
(define (define-class-subtree class)
|
|
|
|
|
|
(define! (class-name class) class)
|
|
|
|
|
|
(for-each define-class-subtree (class-direct-subclasses class)))
|
|
|
|
|
|
|
|
|
|
|
|
(define-class-subtree (find-subclass <port> '<file-port>))
|