-
Notifications
You must be signed in to change notification settings - Fork 45
/
runtime-meta.frt
158 lines (123 loc) · 3.68 KB
/
runtime-meta.frt
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
( What we want to do here is to create a system that allows us writing
structures on steroids. They should have the following functionality:
- declaring fields
- implicitly creating a meta-information common chunk using ALLOT
- creating a 'tostring'-kind of method
- creating a word that accepts a word and applies it to each field address /used by GC /
' word set-printer typename
typename is an alias for its metainformation
adt lisp-expr
mconstructor lisp-number
int ::
mend
mconstructor
endadt
)
struct
cell% field >meta-name
cell% field >meta-printer
cell% field >meta-collected
cell% field >meta-is-value
cell% field >meta-size
end-struct meta-entry%
: meta-default-print chunk-header% - >chunk-meta @ >meta-name @ ." obj:" prints ;
( : constant inbuf word drop 0 inbuf create ' docol @ , ' lit , , ' exit , ; )
: mtype inbuf word drop
inbuf string-allot
meta-entry% allot >r
r@ >meta-name !
0 r@ >meta-collected !
0 r@ >meta-is-value !
( creating 'typename' word to return its metainformation address )
0 inbuf create ' docol @ , ' lit , r@ , ' exit ,
' meta-default-print r@ >meta-printer !
r> 0
;
( parent-metainf offset field-metainf -- parent-metainf newoffset )
: ::
cell% allot !
( parent-metainf offset -- )
inbuf word drop
dup 0 inbuf create ' docol @ , ' lit , , ' + , ' exit ,
cell% +
;
( metainf size - )
: mend swap >meta-size ! 0 cell% allot ! ;
( fixme: raw cell is not printing correctly )
: meta-show
." --- " cr
dup ." type name: " >meta-name @ prints cr
dup ." printer: " >meta-printer @ ? cr
( dup ." is value? " >meta-is-value @ . cr )
dup ." size: " >meta-size @ dup if . ." bytes" else ." UNK" drop then cr
." fields:" cr
dup >meta-size @ cell% /
swap meta-entry% + swap dup if 0
( fields-count 0 -- )
do
dup @ >meta-name @ prints cr cell% +
loop
then
drop
." --- " cr
;
( chunk-contents *metainf )
: meta-execute-printer >meta-printer @ execute ;
' meta-execute-printer heap-meta-printer !
( addr meta - )
: manage swap chunk-header% - >chunk-meta ! ;
( metainf - addr )
: meta-alloc dup >meta-size @ heap-alloc ( metainf addr ) >r r@ swap manage r> ;
( addr metainf - 0/1 )
: of-type
over addr-is-chunk-start if
swap chunk-header% - >chunk-meta @ =
else 2drop 0
then ;
mtype raw-cell mend
cell% raw-cell >meta-size !
mtype int
raw-cell :: >value
mend
1 int >meta-is-value !
: int-show ." int " >value @ . ;
' int-show int >meta-printer !
( value )
( : new-int int _new >r r@ ! r> ; )
: meta-fields-count >meta-size @ cell% / ;
( fieldN ... field2 field1 meta -- addr )
: new
dup meta-alloc dup >r swap
( fieldN ... field2 field1 addr count )
meta-fields-count 0 do
2dup !
swap drop
cell% +
loop
drop r>
;
: addr-is-managed dup addr-is-chunk-start if
chunk-header% - >chunk-meta @ 0 <>
else drop 0 then ;
( addr -- meta )
: addr-get-meta dup addr-is-managed if chunk-header% - >chunk-meta @ else drop 0 then ;
: delete rec
dup addr-get-meta dup if ( addr meta )
dup >meta-is-value @ not if
>meta-size @ over + over ( addr limit curaddr )
repeat
2dup = if 2drop 1 else
dup @ recurse
cell% + 0
then
until
heap-free
else drop
heap-free then
else drop heap-free then ;
( addr -- )
: .
dup addr-get-meta dup if ( addr meta )
over . ." " >meta-printer @ ." [" execute ." ]"
else drop . then
;