Skip to content

Commit ca7d597

Browse files
committed
more collection related stuff
1 parent 9d0b4df commit ca7d597

File tree

5 files changed

+221
-11
lines changed

5 files changed

+221
-11
lines changed

PLATFORM/C/LIB/collections.lsts

Lines changed: 164 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,30 @@ interface Iterator<t> {
99
};
1010

1111
interface Iterable<t> {
12-
let .iter(): Iterator<t>;
13-
let .unsafe-iter(): Iterator<t>;
12+
let .iter(self: Iterable<t>): Iterator<t>;
13+
let .unsafe-iter(self: Iterable<t>): Iterator<t>;
1414
};
1515

16+
interface IteratorRemaining {
17+
let .remaining(self: IteratorRemaining+Iterator<t>): U64;
18+
};
19+
20+
let remaining-or-zero(from: Iterator<t>): U64 = (
21+
0
22+
);
23+
24+
let remaining-or-zero(from: Iterator<t>+IteratorRemaining): U64 = (
25+
from.remaining()
26+
);
27+
28+
let .last(self: Collection<t>): t = (
29+
let ln = self.length();
30+
if ln == 0 {
31+
fail("cannot get .last() from empty element");
32+
};
33+
self[(ln-1)]
34+
);
35+
1636
let length-or-zero(from: Iterable<t>): U64 = (
1737
0_u64
1838
);
@@ -41,9 +61,32 @@ let .skip(self: Iterator<t>, num: U64): Iterator<t> = (
4161
self
4262
);
4363

64+
type RangeIter = RangeIter { let i: U64, len: U64, step: U64 };
65+
66+
let .next(vp: RangeIter[]): Maybe<U64> = (
67+
let v = open(vp);
68+
let res = if vp.i < vp.length {
69+
let idx = vp.i;
70+
vp.i = vp.i + vp.step;
71+
Some { idx }
72+
} else {
73+
None :: Maybe<U64>
74+
};
75+
vp[0] = v;
76+
res
77+
);
78+
79+
let range(len: U64, step: U64): RangeIter = (
80+
RangeIter { 0, len, step }
81+
);
82+
83+
let range(len: U64): RangeIter = (
84+
range(len, 1)
85+
);
86+
4487
type SkipIterator<i+Iterator<t>> = SkipIterator { ii: i, to_skip: U64 };
4588

46-
let .skip(iter: SkipIterator<i>, amount: U64): SkipIterator<i> = (
89+
let .skip(iter: i+Iterator<t>, amount: U64): SkipIterator<i> = (
4790
SkipIterator { iter.ii, iter.to_skip + amount }
4891
);
4992

@@ -58,6 +101,25 @@ let .next(vp: SkipIterator<i+Iterator<t>>[]): Maybe<t> = (
58101
val
59102
);
60103

104+
type LimitIterator<i+Iterator<t>> = LimitIterator { ii: i, idx: U64, limit: U64 };
105+
106+
let .next(vp: LimitIterator<i+Iterator<t>>[]): Maybe<t> = (
107+
let v = open(vp);
108+
let val = if v.idx < v.limit {
109+
v.idx = v.idx + 1;
110+
(&v.ii).next()
111+
} else {
112+
None :: Maybe<t>
113+
};
114+
vp[0] = v;
115+
val
116+
);
117+
118+
# the resulting iter has at most <amount> elements
119+
let .limit(iter: i+Iterator<t>, amount: U64): LimitIterator<i> = (
120+
LimitIterator { iter, 0, amount }
121+
);
122+
61123
type ZipIterator<ai+Iterator<at>, bi+Iterator<bt>> = ZipIterator { aii: ai, bii: bi };
62124

63125
let .next(p: ZipIterator<ai+Iterator<at>, bi+Iterator<bt>>[]): Maybe<Tuple<at,bt>> = (
@@ -213,7 +275,7 @@ let to-smart-string(ls: Iterable<t>): String = (
213275
ls.join(", ", "[", "]")
214276
);
215277

216-
# TODO: use iterators in the following two functions
278+
# TODO: use iterators in the following 3 functions
217279

218280
let .find-first(list: Collection<t>, elem: e): Maybe<U64> = (
219281
let found = false;
@@ -238,6 +300,104 @@ let .find-first(list: Collection<t>, elem: e): Maybe<U64> = (
238300
}
239301
);
240302

303+
let .find-first-with-indent(list: Collection<t>, elem: e, up: Collection<uv>, down: Collection<dv>): Maybe<U64> = (
304+
let found = false;
305+
306+
let ind = 0_u64;
307+
let i = 0_u64;
308+
let where = 0_u64;
309+
let len = list.length();
310+
while i < len {
311+
if up.contains(list[i]) {
312+
ind = ind + 1;
313+
i = i + 1;
314+
} else {
315+
if down.contains(list[i]) {
316+
if ind == 0 {
317+
fail("unopened parentheses");
318+
};
319+
ind = ind - 1;
320+
i = i + 1;
321+
} else {
322+
match list[i] {
323+
elem => (
324+
if ind == 0 {
325+
found = true;
326+
where = i;
327+
i = len; # break
328+
} else {
329+
i = i + 1;
330+
};
331+
);
332+
333+
other => (
334+
i = i + 1;
335+
);
336+
};
337+
};
338+
};
339+
};
340+
341+
if ind != 0_u64 {
342+
fail("unclosed parentheses");
343+
};
344+
345+
if found {
346+
Some{where}
347+
} else {
348+
None{} :: Maybe<U64>
349+
}
350+
);
351+
352+
let .collect(x: Iterator<t>, to: Vector<t>): Vector<t> = (
353+
let rem = remaining-or-zero(x);
354+
if rem != 0 {
355+
to = to.reserve-additional(rem);
356+
};
357+
358+
for item in x {
359+
to = to.push(item);
360+
};
361+
to
362+
);
363+
364+
let .collect(x: Iterator<t>): Vector<t> = (
365+
let to = mk-vector(type(t), 0);
366+
to = x.collect(to);
367+
to
368+
);
369+
370+
type SplitWithIndentIter<t,sp,uv,dv> = SplitWithIndentIter { data: Vector<t>, split: sp, up: Vector<uv>, down: Vector<dv> };
371+
372+
let .next(vp: SplitWithIndentIter<t,sp,uv,dv>[]): Maybe<Vector<t>> => (
373+
let v = open(vp);
374+
375+
if v.data.length() > 0 {
376+
let idx-of-sep = v.data.find-first-with-indent(v.split, v.up, v.down);
377+
let val = match idx-of-sep {
378+
Some { content=content } => (
379+
let r = vp.data.unsafe-iter().limit(content).collect();
380+
vp.data = vp.data.remove-front(content+1);
381+
r
382+
);
383+
384+
None {} => (
385+
let t = vp.data;
386+
vp.data = mk-vector(type(t), 0);
387+
t
388+
);
389+
};
390+
vp[0] = v;
391+
val
392+
} else {
393+
None {} :: Maybe<Vector<t>>
394+
}
395+
);
396+
397+
let split-with-indent(self: Collection<t>, split: sp, up: Collection<uv>, down: Collection<dv>): SplitWithIndentIter<t,sp,uv,dv> = (
398+
SplitWithIndentIter { self.unsafe-iter().collect(), split, up.unsafe-iter().collect(), down.unsafe-iter().collect() }
399+
);
400+
241401
let .find-last(list: Collection<t>, elem: e): Maybe<U64> = (
242402
let found = false;
243403
let found_idx = 0_u64;

PLATFORM/C/LIB/serial.lsts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ let deserialize(vali: SerialVal, ty: Type<ot+FromVector<eltt+Deserializable>>):
121121
match vali {
122122
SerialVec { val=val } => (
123123
let out = mk-vector(type(eltt), val.length());
124-
for x in val {
124+
for x in val.unsafe-iter() {
125125
out = out.push(deserialize(x,type(eltt)));
126126
};
127127
out.move-to(ty)
@@ -138,7 +138,20 @@ let serialize(self: Iterable<t+Serializable>): SerialVal = (
138138
SerialVec { out }
139139
);
140140

141-
# TODO: deserialize for dict
141+
let deserialize(val: SerialVal, ty: Type<HashtableEq<k+Deserializable,v+Deserializable>>): HashtableEq<k,v> = (
142+
let out = {} :: HashtableEq<k,v>;
143+
match val {
144+
SerialDict { val=val } => (
145+
for kv in val.unsafe-iter() {
146+
let k = deserialize(open(kv.first), type(k));
147+
let v = deserialize(open(kv.second), type(v));
148+
out = out.bind(k, v);
149+
};
150+
);
151+
r => ( fail("can only deserialize map from serialdict") );
152+
};
153+
out
154+
);
142155

143156
let serialize(self: HashtableEq<k+Serializable,v+Serializable>): SerialVal = (
144157
let out = {} :: HashtableEq<SerialVal, SerialVal>;

PLATFORM/C/LIB/smart-string.lsts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,45 @@ let print(io: IO::File, x: SmartString): Nil = (
5353
);
5454

5555
let .pad-left-str(self: String, value: U8, minlen: U64): String = (
56-
self.pad-left(self, value, minlen).move-to(type(String))
56+
self.pad-left(self, value, minlen).move-to(type(String))
5757
);
5858

5959
let .pad-right-str(self: String, value: U8, minlen: U64): String = (
60-
self.pad-right(self, value, minlen).move-to(type(String))
60+
self.pad-right(self, value, minlen).move-to(type(String))
61+
);
62+
63+
let .count-left-spaces(self: String): U64 = (
64+
let num = 0_u64;
65+
66+
let i = 0_u64;
67+
while i < self.length() {
68+
if self[i].is-space() {
69+
num = num + 1;
70+
} else {
71+
i = self.length(); # break
72+
};
73+
i = i + 1;
74+
};
75+
76+
num
77+
);
78+
79+
let .count-right-spaces(self: String): U64 = (
80+
self.length() - self.trim-right().length()
81+
);
82+
83+
let .trim-right(self: String): String = (
84+
while self.length() > 0 && self.last().is-space() {
85+
self = self[:(self.length()-1)];
86+
};
87+
self
88+
);
89+
90+
let .trim-left(self: String): String = (
91+
let n = self.count-left-spaces();
92+
self[n:]
93+
);
94+
95+
let .trim(self: String): String = (
96+
self.trim-left().trim-right()
6197
);

PLATFORM/C/LIB/u8.lsts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,6 @@ let to-smart-string(i: U8): String = (
3737
intern(to-string(i as U64))
3838
);
3939

40+
let .is-space(self: U8): U64 = (
41+
(self >= 1) && (self <= 40)) || (self == 177)
42+
);

PLATFORM/C/LIB/vector.lsts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,7 @@ let .push-all(self: Vector<t>, val: Iterable<t>): Vector<t> = (
175175
if ln != 0 {
176176
self = self.reserve-additional(ln);
177177
};
178-
for x in val {
179-
self = self.push(x);
180-
};
178+
self = val.unsafe-iter().collect(self);
181179
self
182180
);
183181

0 commit comments

Comments
 (0)