blob: c2bc394f866659f8df0d29fecaad4f7c449e4ffa (
plain)
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
|
// -*- mode: java; -*-
// 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;
};
// Write to aryu8
val str = { ->
// TODO: clunky default constructor syntax
var str = new aryu8(new u8[1]).add('[');
for( int i=0; i<len; i++ )
str.num(buf[i]).add(',').add(' ');
str.undo(2).add(']');
};
// Comma-separated form used by command-line examples.
val csv = { ->
var str = new aryu8(new u8[1]);
for( int i=0; i<len; i++ )
str.num(buf[i]).add(',').add(' ');
str.undo(2).add('\n');
};
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;
};
|