Skip to content

Commit 2a65fbd

Browse files
committed
Sort out type Init and New so we can make built in objects too!
1 parent 35eacd5 commit 2a65fbd

File tree

2 files changed

+35
-17
lines changed

2 files changed

+35
-17
lines changed

notes.txt

+2
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,7 @@ could run the vm in a go routine - then could start new stack frames in existing
7373
BoundMethods should be run straight away in the vm not make a new vm
7474

7575
ObjectType in *Type is probably redundant
76+
- except that Base can be nil
77+
7678

7779

py/type.go

+33-17
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22

33
package py
44

5-
// FIXME If we only have two types of Init and New function pointers
6-
// we don't really need function pointers, though the ported C code
7-
// expects them to be pointers
8-
95
import (
106
"fmt"
117
)
@@ -68,6 +64,10 @@ const (
6864
TPFLAGS_DEFAULT = TPFLAGS_HAVE_VERSION_TAG
6965
)
7066

67+
type NewFunc func(metatype *Type, args Tuple, kwargs StringDict) Object
68+
69+
type InitFunc func(self Object, args Tuple, kwargs StringDict)
70+
7171
type Type struct {
7272
ObjectType *Type // Type of this object -- FIXME this is redundant in Base?
7373
Name string // For printing, in format "<module>.<name>"
@@ -83,8 +83,8 @@ type Type struct {
8383
// Cache Object
8484
// Subclasses Tuple
8585
// Weaklist Tuple
86-
New func(metatype *Type, args Tuple, kwargs StringDict) *Type
87-
Init func(self *Type, args Tuple, kwargs StringDict)
86+
New NewFunc
87+
Init InitFunc
8888
Flags int // Flags to define presence of optional/expanded features
8989
Qualname string
9090

@@ -168,17 +168,19 @@ type Type struct {
168168
*/
169169
}
170170

171-
var TypeType *Type = &Type{Name: "type", Doc: "type(object) -> the object's type\ntype(name, bases, dict) -> a new type"}
172-
var BaseObjectType = NewType("object", "The most base type")
171+
var TypeType *Type = &Type{
172+
Name: "type",
173+
Doc: "type(object) -> the object's type\ntype(name, bases, dict) -> a new type",
174+
}
175+
var BaseObjectType = NewTypeX("object", "The most base type", ObjectNew, ObjectInit)
173176

174177
func init() {
175-
TypeType.ObjectType = TypeType
176-
// FIXME put this into NewType
178+
// Initialises like this to avoid initialisation loops
177179
TypeType.New = TypeNew
178180
TypeType.Init = TypeInit
181+
TypeType.ObjectType = TypeType
182+
// FIXME put this into NewType
179183
BaseObjectType.Flags |= TPFLAGS_BASETYPE
180-
BaseObjectType.New = ObjectNew
181-
BaseObjectType.Init = ObjectInit
182184
}
183185

184186
// Type of this object
@@ -197,6 +199,19 @@ func NewType(Name string, Doc string) *Type {
197199
}
198200
}
199201

202+
// Make a new type with constructors
203+
//
204+
// For making Go types
205+
func NewTypeX(Name string, Doc string, New NewFunc, Init InitFunc) *Type {
206+
return &Type{
207+
ObjectType: TypeType,
208+
Name: Name,
209+
Doc: Doc,
210+
New: New,
211+
Init: Init,
212+
}
213+
}
214+
200215
// Determine the most derived metatype.
201216
func (metatype *Type) CalculateMetaclass(bases Tuple) *Type {
202217
// Determine the proper metatype to deal with this,
@@ -1021,7 +1036,7 @@ func (t *Type) Alloc() *Type {
10211036
}
10221037

10231038
// Create a new type
1024-
func TypeNew(metatype *Type, args Tuple, kwargs StringDict) *Type {
1039+
func TypeNew(metatype *Type, args Tuple, kwargs StringDict) Object {
10251040
fmt.Printf("TypeNew(type=%q, args=%v, kwargs=%v\n", metatype.Name, args, kwargs)
10261041
var nameObj, basesObj, orig_dictObj Object
10271042
var new_type, base, winner *Type
@@ -1365,7 +1380,7 @@ func TypeNew(metatype *Type, args Tuple, kwargs StringDict) *Type {
13651380
return new_type
13661381
}
13671382

1368-
func TypeInit(cls *Type, args Tuple, kwargs StringDict) {
1383+
func TypeInit(cls Object, args Tuple, kwargs StringDict) {
13691384
if len(kwargs) != 0 {
13701385
// FIXME TypeError
13711386
panic(fmt.Sprintf("TypeError: type.__init__() takes no keyword arguments"))
@@ -1426,7 +1441,7 @@ func excess_args(args Tuple, kwargs StringDict) bool {
14261441
return len(args) != 0 || len(kwargs) != 0
14271442
}
14281443

1429-
func ObjectInit(self *Type, args Tuple, kwargs StringDict) {
1444+
func ObjectInit(self Object, args Tuple, kwargs StringDict) {
14301445
t := self.Type()
14311446
// FIXME bodge to compare function pointers
14321447
if excess_args(args, kwargs) && (fmt.Sprintf("%x", t.New) == fmt.Sprintf("%x", ObjectNew) || fmt.Sprintf("%x", t.Init) != fmt.Sprintf("%x", ObjectInit)) {
@@ -1435,7 +1450,8 @@ func ObjectInit(self *Type, args Tuple, kwargs StringDict) {
14351450
}
14361451
// Call the __init__ method if it exists
14371452
// FIXME this isn't the way cpython does it - it adjusts the function pointers
1438-
init := self.GetAttrOrNil("__init__")
1453+
t = self.(*Type)
1454+
init := t.GetAttrOrNil("__init__")
14391455
fmt.Printf("init = %v\n", init)
14401456
if init != nil {
14411457
newArgs := make(Tuple, len(args)+1)
@@ -1445,7 +1461,7 @@ func ObjectInit(self *Type, args Tuple, kwargs StringDict) {
14451461
}
14461462
}
14471463

1448-
func ObjectNew(t *Type, args Tuple, kwargs StringDict) *Type {
1464+
func ObjectNew(t *Type, args Tuple, kwargs StringDict) Object {
14491465
// FIXME bodge to compare function pointers
14501466
if excess_args(args, kwargs) && (fmt.Sprintf("%x", t.Init) == fmt.Sprintf("%x", ObjectInit) || fmt.Sprintf("%x", t.New) != fmt.Sprintf("%x", ObjectNew)) {
14511467
// FIXME type error

0 commit comments

Comments
 (0)