/
classes.pir
193 lines (144 loc) · 5.32 KB
/
classes.pir
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# Since Class, Module, and Object are all kinda bound up together, this
# file handles their declaration all at once. Methods are still found
# in the appropriate places.
.sub '' :load :init :anon
# First, we'll make the parrot classes.
.local pmc obj_pclass, cls_pclass, mdl_pclass
obj_pclass = newclass 'Object'
addattribute obj_pclass, 'class'
addattribute obj_pclass, 'frozen'
mdl_pclass = subclass obj_pclass, 'Module'
addattribute mdl_pclass, '!super'
addattribute mdl_pclass, '!meta'
addattribute mdl_pclass, '!parrot_class'
# This next is actually for metaclasses to refer back to their class.
addattribute mdl_pclass, '!class'
addattribute mdl_pclass, 'name'
cls_pclass = subclass mdl_pclass, 'Class'
# Then we make the parrot classes for the metaclasses.
.local pmc obj_meta_pclass, mdl_meta_pclass, cls_meta_pclass
obj_meta_pclass = subclass cls_pclass, ['Object';'meta']
mdl_meta_pclass = subclass obj_meta_pclass, ['Module';'meta']
cls_meta_pclass = subclass mdl_meta_pclass, ['Class';'meta']
# Then we make the Ruby Classes.
.local pmc obj_rclass, cls_rclass, mdl_rclass
.local pmc obj_meta_rclass, cls_meta_rclass, mdl_meta_rclass
obj_rclass = new 'Class'
cls_rclass = new 'Class'
mdl_rclass = new 'Class'
obj_meta_rclass = new 'Class'
cls_meta_rclass = new 'Class'
mdl_meta_rclass = new 'Class'
# And fill in the parrot classes.
setattribute obj_rclass, '!parrot_class', obj_pclass
setattribute mdl_rclass, '!parrot_class', mdl_pclass
setattribute cls_rclass, '!parrot_class', cls_pclass
setattribute obj_meta_rclass, '!parrot_class', obj_meta_pclass
setattribute mdl_meta_rclass, '!parrot_class', mdl_meta_pclass
setattribute cls_meta_rclass, '!parrot_class', cls_meta_pclass
# Now they can take names
obj_rclass.'name='('Object', 1)
cls_rclass.'name='('Class', 1)
mdl_rclass.'name='('Module', 1)
# And then the super classes
setattribute mdl_rclass, '!super', obj_rclass
setattribute cls_rclass, '!super', mdl_rclass
setattribute obj_meta_rclass, '!super', cls_rclass
setattribute mdl_meta_rclass, '!super', obj_meta_rclass
setattribute cls_meta_rclass, '!super', mdl_meta_rclass
# And then the metas
setattribute obj_rclass, '!meta', obj_meta_rclass
setattribute mdl_rclass, '!meta', mdl_meta_rclass
setattribute cls_rclass, '!meta', cls_meta_rclass
# Now we populate the globals
.local pmc glbl
glbl = new obj_meta_pclass
setattribute glbl, '!class', obj_rclass
set_hll_global 'Object', glbl
glbl = new mdl_meta_pclass
setattribute glbl, '!class', mdl_rclass
set_hll_global 'Module', glbl
glbl = new cls_meta_pclass
setattribute glbl, '!class', cls_rclass
set_hll_global 'Class', glbl
# Now that these are all ready, let's make nil, which is required for !make_named_class
.local pmc nil_rclass, nil_pclass, nil_meta_rclass, nil_meta_pclass, nil
nil_rclass = new 'Class'
nil_meta_rclass = new 'Class'
nil_pclass = subclass cls_pclass, 'NilClass'
nil_meta_pclass = subclass cls_meta_pclass, ['NilClass';'meta']
setattribute nil_rclass, '!parrot_class', nil_pclass
setattribute nil_meta_rclass, '!parrot_class', nil_meta_pclass
setattribute nil_rclass, '!super', obj_rclass
setattribute nil_meta_rclass, '!super', obj_meta_rclass
setattribute nil_rclass, '!meta', nil_meta_rclass
nil_rclass.'name='('NilClass', 1)
.local pmc interp, undef
undef = '!get_parrot_class'('Undef')
addparent nil_pclass, undef
interp = getinterp
interp.'hll_map'(undef, nil_pclass)
nil = new nil_pclass
set_hll_global 'nil', nil
# Now let's go back and use nil wherever it should have been
setattribute obj_rclass, '!super', nil
setattribute obj_meta_rclass, '!meta', nil
setattribute mdl_meta_rclass, '!meta', nil
setattribute cls_meta_rclass, '!meta', nil
setattribute nil_meta_rclass, '!meta', nil
# Now things should be good to go.
.end
.sub '!get_class'
.param pmc name
$S0 = name
$P0 = get_hll_global $S0
$P0 = getattribute $P0, '!class'
.return ($P0)
.end
.sub '!get_parrot_class'
.param pmc name
$S0 = name
$P0 = get_root_namespace ['parrot';$S0]
$P0 = get_class $P0
.return ($P0)
.end
.sub '!new'
.param pmc cls
.param pmc args :slurpy
.local pmc meta
$S0 = cls
meta = get_hll_global $S0
$P0 = meta.'new'(args :flat)
.return ($P0)
.end
.sub '!make_named_class'
.param pmc name
.param pmc superclass
.param pmc parrot_super :optional
.param int psuper_flag :opt_flag
.local pmc class_meta
.local pmc new_class
class_meta = get_hll_global 'Class'
new_class = class_meta.'new'(superclass)
$P0 = getattribute new_class, '!meta'
$P0 = getattribute $P0, '!parrot_class'
$P1 = new $P0
setattribute $P1, '!class', new_class
$S0 = name
say $S0
set_hll_global $S0, $P1
new_class.'name='(name)
unless psuper_flag goto done
.local pmc interp
$P0 = getattribute new_class, '!parrot_class'
addparent $P0, parrot_super
interp = getinterp
interp.'hll_map'(parrot_super, $P0)
done:
.return (new_class)
.end
# Local Variables:
# mode: pir
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir: