forked from yak-labs/chirp-lang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
class.go
84 lines (73 loc) · 1.46 KB
/
class.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package chirp
import (
. "fmt"
R "reflect"
)
type Obj struct {
Class *Obj
Super *Obj
Slots Scope
}
func cmdSubclass(fr *Frame, argv []T) T {
super := Arg1(argv)
var sup *Obj
if !super.IsEmpty() {
sup = super.Raw().(*Obj)
}
z := &Obj{
Super: sup,
Slots: make(Scope),
}
return MkValue(R.ValueOf(z))
}
var methSerial = 100
func cmdMeth(fr *Frame, argv []T) T {
cls, name, arglist, body := Arg4(argv)
super := cls.Raw().(*Obj).Super
slots := cls.Raw().(*Obj).Slots
methSerial++
tmpName := Sprintf("%s_%d", name, methSerial)
procArgs := []T{MkString("proc"), MkString(tmpName), arglist, body}
procOrYProc(fr, procArgs, false, super)
node := fr.G.Cmds[tmpName]
slot := new(Slot)
slot.Set(MkValue(R.ValueOf(node.Fn)))
slots[name.String()] = slot
return Empty
}
func cmdNew(fr *Frame, argv []T) T {
class := Arg1(argv)
cls := class.Raw().(*Obj)
z := &Obj{
Class: cls,
Slots: make(Scope),
}
return MkValue(R.ValueOf(z))
}
func cmdOn(fr *Frame, argv []T) T {
rcvr, msg, _ := Arg2v(argv)
cls := rcvr.Raw().(*Obj).Class
var loc Loc
var ok bool
for cls != nil {
loc, ok = cls.Slots[msg.String()]
if ok {
break
}
cls = cls.Super
}
if !ok {
panic(Sprintf("Cannot find message: %q", msg.String()))
}
cmd := loc.Get().Raw().(Command)
return cmd(fr, argv[1:])
}
func init() {
if Safes == nil {
Safes = make(map[string]Command, 333)
}
Safes["subclass"] = cmdSubclass
Safes["meth"] = cmdMeth
Safes["new"] = cmdNew
Safes["on"] = cmdOn
}