-
Notifications
You must be signed in to change notification settings - Fork 2
/
array.na
125 lines (98 loc) · 2.36 KB
/
array.na
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
inline C <<end
#include "array.h"
#define CLIP_LEN(l) ((l) & 0x0fffffff)
datum
make_array(uint len)
{
datum p;
if (len < 1) return nil;
if (len != CLIP_LEN(len)) die("make_array -- too big");
p = make_record(len, mtab, nil, nil);
for (;--len;) p[len] = (size_t) nil;
return p;
}
datum
array_get(datum arr, uint index)
{
if (!arrayp(arr)) die1("array_get -- not an array", arr);
if (index >= datum_size(arr)) die("array_get -- index out of bounds");
return (datum) arr[index];
}
datum
array_put(datum arr, uint index, datum val)
{
if (!arrayp(arr)) die1("array_put -- not an array", arr);
if (index >= datum_size(arr)) die("array_put -- index out of bounds");
return (datum) (arr[index] = (size_t) val);
}
uint
array_len(datum arr)
{
return datum_size(arr);
}
int
arrayp(datum x)
{
return !(((size_t) x) & 1) && (((datum) x[-1]) == mtab);
}
end
def array: sobj:
inline C (get i) <<end
int i;
if (!intp(n_i)) die1("array#get -- not an int", n_i);
i = datum2int(n_i);
return array_get(rcv, i);
end
inline C (put! i v) <<end
int i;
if (!intp(n_i)) die1("array#put! -- not an int", n_i);
i = datum2int(n_i);
array_put(rcv, i, n_v);
return ok_sym;
end
inline C (length.) <<end
return int2datum(datum_size(rcv));
end
(car.): self.get 0
(cdr.):
def (make-cursor i):
if i >= self.length: return '()
obj:
(car.): self.get i
(cdr.): make-cursor i + 1
make-cursor 1
(filter f):
def rest ((self.cdr).filter f)
? (f (self.car)):
cons (self.car) rest
. rest
(each f):
def (iter i):
if (i > self.length): return 'ok
if (i == self.length): return 'ok
f (self.get i)
iter (i + 1)
iter 0
. 'ok
(== p):
? ((self.car) == (p.car)):
? ((self.cdr) == (p.cdr)) true false
. false
(assq name):
? (is? (self.car.car) name) (self.car) (self.cdr.assq name)
(frozen.): tuple.from (map [x.frozen] self)
def array-factory: sobj:
(run . args):
len = args.length
new = (array.make len)
i = 0
for x in args:
if i >= len: error "internal error"
new.put! i x
i = i + 1
new
inline C (make size) <<end
if (!intp(n_size)) die1("array.make -- not an int", n_size);
return make_array(datum2int(n_size));
end
return array-factory