Skip to content

Commit ec81f5b

Browse files
committed
zpy: Creates metaobject classes.
Signed-off-by: Amy Ringo <me@remexre.com>
1 parent 9a6b9bf commit ec81f5b

File tree

3 files changed

+170
-75
lines changed

3 files changed

+170
-75
lines changed

doc/z/stdlib.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ Every class is an instance of `Z:CLASS`.
2626
- `Z:CLASS/NAME` (has reader, type [`Z:SYMBOL`](#zsymbol))
2727
- `Z:CLASS/FINALIZED?` (has reader, type [`Z:BOOLEAN`](#zboolean))
2828
- `Z:CLASS/DIRECT-SLOTS` (has accessor)
29-
- `Z:CLASS/EFFECTIVE-SLOTS` (has reader)
3029
- `Z:CLASS/DIRECT-SUPERCLASSES` (has accessor)
31-
- `Z:CLASS/EFFECTIVE-SUPERCLASSES` (has reader)
3230
- `Z:CLASS/DIRECT-SUBCLASSES` (has accessor)
31+
- `Z:CLASS/EFFECTIVE-SLOTS` (has reader)
32+
- `Z:CLASS/EFFECTIVE-SUPERCLASSES` (has reader)
3333
- `Z:CLASS/EFFECTIVE-SUBCLASSES` (has reader)
3434

3535
**Summary:**
@@ -38,7 +38,7 @@ Every class is an instance of `Z:CLASS`.
3838

3939
### `Z:DIRECT-SLOT-DEFINITION`
4040

41-
**Superclasses:** [`Z:T`](#zt)
41+
**Superclasses:** [`Z:SLOT-DEFINITION`](#zslot-definition)
4242

4343
**Slots:**
4444

@@ -50,7 +50,7 @@ TODO
5050

5151
### `Z:EFFECTIVE-SLOT-DEFINITION`
5252

53-
**Superclasses:** [`Z:T`](#zt)
53+
**Superclasses:** [`Z:SLOT-DEFINITION`](#zslot-definition)
5454

5555
**Slots:**
5656

@@ -95,6 +95,18 @@ TODO
9595

9696
TODO
9797

98+
### `Z:SLOT-DEFINITION`
99+
100+
**Superclasses:** [`Z:T`](#zt)
101+
102+
**Slots:**
103+
104+
- TODO
105+
106+
**Summary:**
107+
108+
TODO
109+
98110
### `Z:STREAM`
99111

100112
**Superclasses:** [`Z:T`](#zt)

src/zpy/zval.py

Lines changed: 151 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# SPDX-License-Identifier: GPL-3.0-or-later
44

55
from dataclasses import dataclass
6-
from typing import Self
6+
from typing import Optional, Self
77

88
"""
99
The basic object model.
@@ -59,7 +59,7 @@ class ZStructObj:
5959
| ZSimpleArrayT
6060
| ZStructObj
6161
)
62-
ZNil: ZVal = ()
62+
Nil: ZVal = ()
6363

6464
### Define some builtin objects that need extra data associated with them that's not in slots.
6565

@@ -154,86 +154,172 @@ def make_vec(*elems: ZVal) -> ZSimpleArrayT:
154154
### names of the form PackageFoo, symbols in Z have names of the form SymbolFoo.
155155

156156
## Define Z:BUILTIN-CLASS, but don't define its slots.
157-
ClassBuiltinClass = ZSlottedObj(ZNil)
158-
ClassBuiltinClass.klass = ClassBuiltinClass
157+
ClassBuiltInClass = ZSlottedObj(Nil)
158+
ClassBuiltInClass.klass = ClassBuiltInClass
159159

160160
## Define objects we need to make symbols.
161-
ClassPackage = ZSlottedObj(ClassBuiltinClass)
162-
ClassSymbol = ZSlottedObj(ClassBuiltinClass)
161+
ClassPackage = ZSlottedObj(ClassBuiltInClass)
162+
ClassSymbol = ZSlottedObj(ClassBuiltInClass)
163163
PackageZ = ZPackage("Z")
164164
SymbolPackageName = PackageZ.intern("PACKAGE/NAME")
165165
SymbolSymbolName = PackageZ.intern("SYMBOL/NAME")
166166
SymbolSymbolPackage = PackageZ.intern("SYMBOL/PACKAGE")
167167

168-
## Define objects we need to define slots.
169-
ClassDirectSlotDefinition = ZSlottedObj(ClassBuiltinClass)
170-
ClassEffectiveSlotDefinition = ZSlottedObj(ClassBuiltinClass)
171-
172-
## Define the names of the slots of class objects.
173-
SymbolClassName = PackageZ.intern("CLASS/NAME")
174-
SymbolClassFinalized = PackageZ.intern("CLASS/FINALIZED?")
175-
SymbolClassDirectSlots = PackageZ.intern("CLASS/DIRECT-SLOTS")
176-
SymbolClassDirectSuperclasses = PackageZ.intern("CLASS/DIRECT-SUPERCLASSES")
177-
SymbolClassDirectSubclasses = PackageZ.intern("CLASS/DIRECT-SUBCLASSES")
178-
SymbolClassEffectiveSlots = PackageZ.intern("CLASS/EFFECTIVE-SLOTS")
179-
SymbolClassEffectiveSuperclasses = PackageZ.intern("CLASS/EFFECTIVE-SUPERCLASSES")
180-
SymbolClassEffectiveSubclasses = PackageZ.intern("CLASS/EFFECTIVE-SUBCLASSES")
181-
168+
## Define T.
169+
T = PackageZ.intern("T")
170+
171+
## Define slot definitions.
172+
ClassStandardDirectSlotDefinition = ZSlottedObj(ClassBuiltInClass)
173+
174+
175+
def make_direct_slot_definition(
176+
name: str,
177+
*,
178+
initform: Optional[ZVal] = None,
179+
initargs: list[ZVal] = [],
180+
reader: Optional[str] = None,
181+
writer: Optional[str] = None,
182+
# allocation: Optional[str] = None,
183+
) -> ZVal:
184+
slot = ZSlottedObj(ClassStandardDirectSlotDefinition)
185+
slot.set_slot(PackageZ.intern("SLOT-DEFINITION/NAME"), PackageZ.intern(name))
186+
if initform is not None:
187+
slot.set_slot(PackageZ.intern("SLOT-DEFINITION/INITFORM"), initform)
188+
# TODO: initfunction
189+
slot.set_slot(PackageZ.intern("SLOT-DEFINITION/INITARGS"), make_list(*initargs))
190+
slot.set_slot(
191+
PackageZ.intern("SLOT-DEFINITION/READERS"),
192+
make_list(PackageZ.intern(reader) if reader is not None else Nil),
193+
)
194+
slot.set_slot(
195+
PackageZ.intern("SLOT-DEFINITION/WRITERS"),
196+
make_list(PackageZ.intern(writer) if writer is not None else Nil),
197+
)
198+
# slot.set_slot(PackageZ.intern("ALLOCATION"), PackageZ.intern(name))
199+
# slot.set_slot(PackageZ.intern("ALLOCATION-CLASS"), PackageZ.intern(name))
200+
# TODO
201+
return slot
202+
203+
204+
## Define helpers for defining classes.
205+
206+
207+
def add_direct_subclass(child: ZSlottedObj, parent: ZSlottedObj):
208+
SymbolClassDirectSuperclasses = PackageZ.intern("CLASS/DIRECT-SUPERCLASSES")
209+
SymbolClassDirectSubclasses = PackageZ.intern("CLASS/DIRECT-SUBCLASSES")
210+
child.set_slot(
211+
SymbolClassDirectSuperclasses,
212+
(parent, child.get_slot(SymbolClassDirectSubclasses)),
213+
)
214+
parent.set_slot(
215+
SymbolClassDirectSubclasses,
216+
(child, parent.get_slot(SymbolClassDirectSubclasses)),
217+
)
218+
219+
220+
def init_class(
221+
klass: ZSlottedObj,
222+
name: str,
223+
*direct_slots: ZVal,
224+
direct_superclasses: list[ZSlottedObj] = [],
225+
):
226+
klass.set_slot(PackageZ.intern("CLASS/NAME"), PackageZ.intern(name))
227+
klass.set_slot(PackageZ.intern("CLASS/FINALIZED?"), Nil)
228+
klass.set_slot(PackageZ.intern("CLASS/DIRECT-SLOTS"), make_list(*direct_slots))
229+
klass.set_slot(PackageZ.intern("CLASS/DIRECT-SUPERCLASSES"), Nil)
230+
klass.set_slot(PackageZ.intern("CLASS/DIRECT-SUBCLASSES"), Nil)
231+
for parent in direct_superclasses:
232+
add_direct_subclass(klass, parent)
233+
234+
235+
def defclass(
236+
name: str,
237+
*direct_slots: ZVal,
238+
sup: Optional[list[ZSlottedObj]] = None,
239+
metaclass: Optional[ZVal] = None,
240+
) -> ZSlottedObj:
241+
if sup is None:
242+
sup = [ClassStandardObject]
243+
if metaclass is None:
244+
metaclass = ClassStandardClass
245+
klass = ZSlottedObj(metaclass)
246+
init_class(klass, name, *direct_slots, direct_superclasses=sup)
247+
return klass
248+
249+
250+
### Define the rest of the metaobjects and fill out the fields on the classes
251+
### we've already defined.
252+
253+
ClassStandardClass = defclass("STANDARD-CLASS", sup=[], metaclass=Nil)
254+
ClassStandardClass.klass = ClassStandardClass
255+
256+
ClassT = defclass("T", sup=[], metaclass=ClassBuiltInClass)
257+
ClassStandardObject = defclass("STANDARD-OBJECT", sup=[ClassT])
258+
259+
ClassSpecializer = defclass("SPECIALIZER")
260+
ClassEqlSpecializer = defclass("EQL-SPECIALIZER", sup=[ClassSpecializer])
261+
ClassClass = defclass("CLASS", sup=[ClassSpecializer])
262+
init_class(ClassBuiltInClass, "BUILT-IN-CLASS", direct_superclasses=[ClassClass])
263+
add_direct_subclass(ClassStandardClass, ClassClass)
264+
ClassForwardReferencedClass = defclass("FORWARD-REFERENCED-CLASS")
265+
ClassFuncallableStandardClass = defclass("FUNCALLABLE-STANDARD-CLASS", sup=[ClassClass])
266+
267+
ClassSlotDefinition = defclass("SLOT-DEFINITION")
268+
ClassDirectSlotDefinition = defclass(
269+
"DIRECT-SLOT-DEFINITION", sup=[ClassSlotDefinition]
270+
)
271+
ClassEffectiveSlotDefinition = defclass(
272+
"EFFECTIVE-SLOT-DEFINITION", sup=[ClassSlotDefinition]
273+
)
274+
ClassStandardSlotDefinition = defclass(
275+
"STANDARD-SLOT-DEFINITION", sup=[ClassSlotDefinition]
276+
)
277+
init_class(
278+
ClassStandardDirectSlotDefinition,
279+
"STANDARD-DIRECT-SLOT-DEFINITION",
280+
direct_superclasses=[ClassStandardSlotDefinition, ClassDirectSlotDefinition],
281+
)
282+
ClassStandardEffectiveSlotDefinition = defclass(
283+
"STANDARD-EFFECTIVE-SLOT-DEFINITION",
284+
sup=[ClassStandardSlotDefinition, ClassEffectiveSlotDefinition],
285+
)
182286

183-
## Set the direct slots of the classes we've defined so far.
287+
ClassMethodCombination = defclass("METHOD-COMBINATION")
184288

289+
ClassMethod = defclass("METHOD")
290+
ClassStandardMethod = defclass("STANDARD-METHOD", sup=[ClassMethod])
291+
ClassStandardAccessorMethod = defclass(
292+
"STANDARD-ACCESSOR-METHOD", sup=[ClassStandardMethod]
293+
)
294+
ClassStandardReaderMethod = defclass(
295+
"STANDARD-READER-METHOD", sup=[ClassStandardAccessorMethod]
296+
)
297+
ClassStandardWriterMethod = defclass(
298+
"STANDARD-WRITER-METHOD", sup=[ClassStandardAccessorMethod]
299+
)
185300

186-
def make_direct_slot_definition():
187-
# TODO
188-
pass
301+
ClassFuncallableStandardObject = defclass("FUNCALLABLE-STANDARD-OBJECT")
302+
ClassGenericFunction = defclass(
303+
"GENERIC-FUNCTION", sup=[ClassFuncallableStandardObject]
304+
)
305+
ClassStandardGenericFunction = defclass(
306+
"STANDARD-GENERIC-FUNCTION", sup=[ClassGenericFunction]
307+
)
189308

309+
### Implement class finalization and finalize the metaobject classes.
190310

191-
ClassBuiltinClass.set_slot(SymbolClassName, PackageZ.intern("BUILTIN-CLASS"))
192-
ClassBuiltinClass.set_slot(SymbolClassFinalized, ZNil)
193-
ClassBuiltinClass.set_slot(SymbolClassDirectSlots, make_vec())
194-
ClassBuiltinClass.set_slot(SymbolClassDirectSuperclasses, make_vec())
195-
ClassBuiltinClass.set_slot(SymbolClassDirectSubclasses, make_vec())
196311

197-
ClassDirectSlotDefinition.set_slot(
198-
SymbolClassName, PackageZ.intern("DIRECT-SLOT-DEFINITION")
199-
)
200-
ClassDirectSlotDefinition.set_slot(SymbolClassFinalized, ZNil)
201-
ClassDirectSlotDefinition.set_slot(SymbolClassDirectSlots, make_vec())
202-
ClassDirectSlotDefinition.set_slot(SymbolClassDirectSuperclasses, make_vec())
203-
ClassDirectSlotDefinition.set_slot(SymbolClassDirectSubclasses, make_vec())
312+
def finalize_inheritance(klass: ZSlottedObj):
313+
pass
204314

205-
ClassEffectiveSlotDefinition.set_slot(
206-
SymbolClassName, PackageZ.intern("EFFECTIVE-SLOT-DEFINITION")
207-
)
208-
ClassEffectiveSlotDefinition.set_slot(SymbolClassFinalized, ZNil)
209-
ClassEffectiveSlotDefinition.set_slot(SymbolClassDirectSlots, make_vec())
210-
ClassEffectiveSlotDefinition.set_slot(SymbolClassDirectSuperclasses, make_vec())
211-
ClassEffectiveSlotDefinition.set_slot(SymbolClassDirectSubclasses, make_vec())
212-
213-
ClassPackage.set_slot(SymbolClassName, PackageZ.intern("PACKAGE"))
214-
ClassPackage.set_slot(SymbolClassFinalized, ZNil)
215-
ClassPackage.set_slot(SymbolClassDirectSlots, make_vec()) # TODO
216-
ClassPackage.set_slot(SymbolClassDirectSuperclasses, make_vec())
217-
ClassPackage.set_slot(SymbolClassDirectSubclasses, make_vec())
218-
219-
ClassSymbol.set_slot(SymbolClassName, PackageZ.intern("SYMBOL"))
220-
ClassSymbol.set_slot(SymbolClassFinalized, ZNil)
221-
ClassSymbol.set_slot(SymbolClassDirectSlots, make_vec()) # TODO
222-
ClassSymbol.set_slot(SymbolClassDirectSuperclasses, make_vec())
223-
ClassSymbol.set_slot(SymbolClassDirectSubclasses, make_vec())
224-
225-
## TODO
226-
SymbolClass = PackageZ.intern("CLASS")
227-
SymbolPackageName = PackageZ.intern("PACKAGE/NAME")
228-
SymbolString = PackageZ.intern("STRING")
229315

230316
### Define some other primitive classes.
231317

232-
# ClassClass = ZObj(ClassBuiltinClass)
233-
# ClassString = ZObj(ClassBuiltinClass)
234-
# ClassCons = ZObj(ClassBuiltinClass)
235-
# ClassInt = ZObj(ClassBuiltinClass)
236-
# ClassNull = ZObj(ClassBuiltinClass)
318+
# ClassClass = ZObj(ClassBuiltInClass)
319+
# ClassString = ZObj(ClassBuiltInClass)
320+
# ClassCons = ZObj(ClassBuiltInClass)
321+
# ClassInt = ZObj(ClassBuiltInClass)
322+
# ClassNull = ZObj(ClassBuiltInClass)
237323

238324
### Bootstrap Z:CLASS-OF.
239325
###

src/zz/main.z

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
;;
33
;; SPDX-License-Identifier: GPL-3.0-or-later
44

5-
(defun main ()
6-
(+ 40 2))
7-
8-
(1+ (* 2 (+ 19 (main))))
9-
10-
;; vi: set ft=lisp :
5+
; TODO: Hello, world!
6+
; TODO: Fizzbuzz
7+
; TODO: Metacircular eval

0 commit comments

Comments
 (0)