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
|
// Ary/Vector of i64s
struct aryi64 {
u32 !len = 0;
i64[] !buf;
new aryi64 = { i64[] b ->
buf = b;
};
// Grow as needed
val _grow = { int len2 ->
if( len+len2 < buf# ) return self;
int newlen = buf# * 2;
while( len+len2 >= newlen ) newlen *= 2;
i64[] !buf2 = new i64[newlen];
for( int i=0; i<buf#; i++ )
buf2[i] = buf[i];
buf = buf2;
self;
};
// Add a i64 to aryu8
val add = { i64 c ->
_grow(1).buf[len++] = c;
self;
};
val get = { int index -> return buf[index]; };
// Write the bracketed array-list form to aryu8.
val str = { ->
// TODO: clunky default constructor syntax
var str = new aryu8().add('[');
for( int i=0; i<len; i++ )
str.num(buf[i]).add(',').add(' ');
if( len ) str.undo(2);
return str.add(']');
};
val swap = { int i, int j ->
i64 tmp = buf[i];
buf[i] = buf[j];
buf[j] = tmp;
self;
};
};
// Parse a comma-separated list of numbers, wrapped with square brackets,
// with optional whitespace e.g. "[ -17, 0,99,12456789 ] ".
// parseAryI64 & aryi64.str are bijections modulo whitespace.
// Returns null if the parse failed, without giving a clue as to why.
val parseAryI64 = { u8[~] str ->
!scan !s = new scan(str);
if( !s.match('[') ) return null;
// Array of parsed results
var nums = new aryi64(new i64[1]);
// Parse a list of numbers
if( s.match(']') ) // Handle the empty list
return nums;
// Parse number commas "123, " until something else
while( s.x < s.buf# ) {
nums.add(s.number());
if( s.bad ) return null;
if( !s.match(',') )
break;
};
// Close the list
if( !s.match(']') ) return null;
s.skip();
return s.x == s.buf# ? nums : null;
};
val copy = { i64[] dst, int doff, i64[~] src, int soff, int len ->
for( int i=0; i<len; i++ )
dst[i+doff] = src[i+soff];
return dst;
};
|