History

fix issue 9, add preliminary lists module

Charles.Forsyth committed 19 years ago

Commit 331b25a1 parent 6f2213610 files · +370 −6Browse files

Unified · Split

10 files
  1. CHANGES +9 −0
  2. appl/lib/libc.b +9 −2
  3. appl/lib/libc0.b +14 −6
  4. appl/lib/lists.b +131 −0
  5. dis/lib/libc.dis +0 −0
  6. dis/lib/libc0.dis +0 −0
  7. dis/lib/lists.dis +0 −0
  8. include/version.h +1 −1
  9. man/2/lists +185 −0
  10. module/lists.m +24 −0
CHANGES+9−0
@@ -1,3 +1,12 @@
1+20070217
2+ repair /appl/lib/libc.b and /appl/lib/libc0.b strncmp implementations (used only by c2l output) [inferno-os issue 9]
3+20070216
4+ add /module/lists.m, /appl/lib/lists.b, and lists(2)
5+20070209
6+ remove debugging -d option to exportfs call in emu/Plan9/devsrv9.c(!)
7+20070206
8+ /appl/svc/auth.sh: replace exit by raise
9+ /man/2/styxservers: document replychan and replydirect
110 20070201
211 update US timezone files to save energy
312 20070131
appl/lib/libc.b+9−2
@@ -113,9 +113,16 @@ strncmp(s1: string, s2: string, n: int): int · 112 unmodified lines
113113 {
114114 l1 := len s1;
115115 l2 := len s2;
116− for(i := 0; i < l1 && i < l2 && i < n; i++)
116+ m := n;
117+ if(m > l1)
118+ m = l1;
119+ if(m > l2)
120+ m = l2;
121+ for(i := 0; i < m; i++)
117122 if(s1[i] != s2[i])
118− return s1[i]-int s2[i];
123+ return s1[i]-s2[i];
124+ if(i == n)
125+ return 0;
119126 return l1-l2;
120127 }
121128
appl/lib/libc0.b+14−6
@@ -170,12 +170,20 @@ strcmp(s1: array of byte, s2: array of byte): int · 169 unmodified lines
170170
171171 strncmp(s1: array of byte, s2: array of byte, n: int): int
172172 {
173− l1 := strlen(s1);
174− l2 := strlen(s2);
175− for(i := 0; i < l1 && i < l2 && i < n; i++)
176− if(s1[i] != s2[i])
177− return int s1[i]-int s2[i];
178− return l1-l2;
173+ i1 := i2 := 0;
174+ while(n > 0){
175+ c1 := int s1[i1++];
176+ c2 := int s2[i2++];
177+ n--;
178+ if(c1 != c2){
179+ if(c1 > c2)
180+ return 1;
181+ return -1;
182+ }
183+ if(c1 == 0)
184+ break;
185+ }
186+ return 0;
179187 }
180188
181189 strchr(s: array of byte, n: int): array of byte
appl/lib/lists.b+131−0
@@ -0,0 +1,131 @@
1+implement Lists;
2+
3+include "lists.m";
4+
5+# these will be more useful when p is a closure
6+allsat[T](p: ref fn(x: T): int, l: list of T): int
7+{
8+ for(; l != nil; l = tl l)
9+ if(!p(hd l))
10+ return 0;
11+ return 1;
12+}
13+
14+anysat[T](p: ref fn(x: T): int, l: list of T): int
15+{
16+ for(; l != nil; l = tl l)
17+ if(p(hd l))
18+ return 1;
19+ return 0;
20+}
21+
22+map[T](f: ref fn(x: T): T, l: list of T): list of T
23+{
24+ if(l == nil)
25+ return nil;
26+ return f(hd l) :: map(f, tl l);
27+}
28+
29+filter[T](p: ref fn(x: T): int, l: list of T): list of T
30+{
31+ if(l == nil)
32+ return nil;
33+ if(p(hd l))
34+ return hd l :: filter(p, tl l);
35+ return filter(p, tl l);
36+}
37+
38+partition[T](p: ref fn(x: T): int, l: list of T): (list of T, list of T)
39+{
40+ l1: list of T;
41+ l2: list of T;
42+ for(; l != nil; l = tl l)
43+ if(p(hd l))
44+ l1 = hd l :: l1;
45+ else
46+ l2 = hd l :: l2;
47+ return (reverse(l1), reverse(l2));
48+}
49+
50+append[T](l: list of T, x: T): list of T
51+{
52+ # could use the reversing loops instead if this is ever a bottleneck
53+ if(l == nil)
54+ return x :: nil;
55+ return hd l :: append(tl l, x);
56+}
57+
58+concat[T](l: list of T, l2: list of T): list of T
59+{
60+ if(l2 == nil)
61+ return l;
62+ for(l = reverse(l); l2 != nil; l2 = tl l2)
63+ l = hd l2 :: l;
64+ return reverse(l);
65+}
66+
67+combine[T](l: list of T, l2: list of T): list of T
68+{
69+ for(; l != nil; l = tl l)
70+ l2 = hd l :: l2;
71+ return l2;
72+}
73+
74+reverse[T](l: list of T): list of T
75+{
76+ rl: list of T;
77+ for(; l != nil; l = tl l)
78+ rl = hd l :: rl;
79+ return rl;
80+}
81+
82+last[T](l: list of T): T
83+{
84+ # l must not be nil
85+ while(tl l != nil)
86+ l = tl l;
87+ return hd l;
88+}
89+
90+# delete the first instance of x in l
91+delete[T](x: T, l: list of T): list of T
92+ for { T => eq: fn(a, b: T): int; }
93+{
94+ o: list of T;
95+ for(; l != nil; l = tl l)
96+ if(T.eq(x, hd l)){
97+ l = tl l;
98+ for(; o != nil; o = tl o)
99+ l = hd o :: l;
100+ break;
101+ }
102+ return l;
103+}
104+
105+pair[T1, T2](l1: list of T1, l2: list of T2): list of (T1, T2)
106+{
107+ if(l1 == nil && l2 == nil)
108+ return nil;
109+ return (hd l1, hd l2) :: pair(tl l1, tl l2);
110+}
111+
112+unpair[T1, T2](l: list of (T1, T2)): (list of T1, list of T2)
113+{
114+ l1: list of T1;
115+ l2: list of T2;
116+ for(; l != nil; l = tl l){
117+ (v1, v2) := hd l;
118+ l1 = v1 :: l1;
119+ l2 = v2 :: l2;
120+ }
121+ return (reverse(l1), reverse(l2));
122+}
123+
124+ismember[T](x: T, l: list of T): int
125+ for { T => eq: fn(a, b: T): int; }
126+{
127+ for(; l != nil; l = tl l)
128+ if(T.eq(x, hd l))
129+ return 1;
130+ return 0;
131+}
dis/lib/libc.dis+0−0

Binary file not shown.

dis/lib/libc0.dis+0−0

Binary file not shown.

dis/lib/lists.dis+0−0

Binary file not shown.

include/version.h+1−1
@@ -1 +1 @@
1−#define VERSION "Fourth Edition (20070213)"
1+#define VERSION "Fourth Edition (20070217)"
man/2/lists+185−0
@@ -0,0 +1,185 @@
1+.TH LISTS 2
2+.SH NAME
3+lists: allsat, anysat, append, combine, concat, delete, filter, ismember, last, map, pair, partition, rev, unpair\- list operations
4+.SH SYNOPSIS
5+.EX
6+include "lists.m"
7+lists := load Lists Lists->PATH;
8+
9+append: fn[T](l: list of T, x: T): list of T;
10+combine: fn[T](l1: list of T, l2: list of T): list of T;
11+concat: fn[T](l1: list of T, l2: list of T): list of T;
12+delete: fn[T](x: T, l: list of T): list of T
13+ for { T => eq: fn(a, b: T): int; };
14+ismember: fn[T](x: T, l: list of T): int
15+ for { T => eq: fn(a, b: T): int; };
16+last: fn[T](l: list of T): T;
17+pair: fn[T1, T2](l1: list of T1, l2: list of T2):
18+ list of (T1, T2);
19+reverse: fn[T](l: list of T): list of T;
20+unpair: fn[T1, T2](l: list of (T1, T2)):
21+ (list of T1, list of T2);
22+
23+allsat: fn[T](p: ref fn(x: T): int, l: list of T): int;
24+anysat: fn[T](p: ref fn(x: T): int, l: list of T): int;
25+filter: fn[T](p: ref fn(x: T): int, l: list of T): list of T;
26+map: fn[T](f: ref fn(x: T): T, l: list of T): list of T;
27+partition: fn[T](p: ref fn(x: T): int, l: list of T):
28+ (list of T, list of T);
29+.EE
30+.SH DESCRIPTION
31+The module provides operations on lists of type
32+.IR T ,
33+which may be any reference type, or
34+.BR string .
35+Reference types are
36+.BR array ,
37+.BR chan ,
38+.BR list ,
39+.BR module ,
40+and
41+.BI ref "adt".
42+None of the operations change their parameter lists: they always return a new list.
43+.PP
44+First, there is a group of common list operations.
45+.PP
46+.B Append
47+returns a new list with the elements of
48+.I l
49+followed by the element
50+.IR x .
51+.PP
52+.B Combine
53+returns a new list that has the elements of both
54+.I l1
55+and
56+.I l2
57+in no defined order.
58+.PP
59+.B Concat
60+returns a new list that has the elements of
61+.I l1
62+followed by the elements of
63+.IR l2 .
64+.PP
65+.B Delete
66+returns a new list in which the first element of
67+.I l
68+that is equal to
69+.I x
70+has been removed (all others remain).
71+.I X
72+must be an adt reference type
73+.I T
74+with an operation
75+.IB T .eq
76+that returns true (non-zero) if two values of type
77+.I T
78+are considered equal.
79+.PP
80+.B Ismember
81+returns 1 if
82+there is an element of
83+.I l
84+that is equal to
85+.IR x .
86+.PP
87+.B Last
88+returns the value of the element at the end of list
89+.IR l .
90+A run-time error occurs if
91+.I l
92+is nil.
93+.PP
94+.B Pair
95+takes two lists
96+.I l1
97+and
98+.IR l2 ,
99+and returns a new list of tuples
100+.BI ( v1,\ v2 )
101+in which each element of
102+.I l1
103+has been paired with the corresponding element of
104+.IR l2 .
105+A run-time error occurs if the lists are not equal in length.
106+.PP
107+.B Reverse
108+returns a new list containing the elements of
109+.I l
110+in reverse order.
111+.PP
112+.B Unpair
113+takes a list of tuples
114+.BI ( v1,\ v2 )
115+and returns a tuple of lists
116+.BI ( l1,\ l2 )
117+where
118+.I l1
119+contains the first element of each tuple, and
120+.I l2
121+contains the second element of each tuple.
122+.PP
123+A second group of operations applies a function
124+.I f
125+or a Boolean predicate
126+.I p
127+to each element of a list
128+.IR l ,
129+returning a transformed list or a Boolean value.
130+A predicate
131+.I p
132+must return non-zero if its parameter value satisfies its condition, and must return zero if it does not.
133+.PP
134+.B Allsat
135+returns 1 if all elements of
136+.I l
137+satisfy
138+.IR p ,
139+and returns 0 otherwise.
140+.PP
141+.B Anyset
142+returns 1 if any element of
143+.I l
144+satisfies
145+.IR p ,
146+and returns 0 otherwise.
147+.PP
148+.B Filter
149+returns a new list containing only the elements of
150+.I l
151+that satisfy
152+.IR p .
153+.PP
154+.B Map
155+returns a new list in which each element of
156+.I l
157+has been transformed by
158+.I f
159+(ie, if
160+.I l
161+is
162+.IB e0 :: e1 :: ...
163+then the result is
164+.IB f(e0) :: f(e1) :: ... ).
165+.PP
166+.B Partition
167+returns a tuple of lists
168+.BI ( l1,\ l2 )
169+of lists where
170+.I l1
171+contains all elements of
172+.I l
173+that satisfy
174+.I p
175+and
176+.I l2
177+contains all elements of
178+.I l
179+that do not satisfy
180+.IR p .
181+.SH SOURCE
182+.B /appl/lib/lists.b
183+.SH BUGS
184+The current implementation of polymorphism is limited to reference types and strings,
185+which in turn limits use of this module.
module/lists.m+24−0
@@ -0,0 +1,24 @@
1+Lists: module
2+{
3+ map: fn[T](f: ref fn(x: T): T, l: list of T): list of T;
4+ allsat: fn[T](p: ref fn(x: T): int, l: list of T): int;
5+ anysat: fn[T](p: ref fn(x: T): int, l: list of T): int;
6+ filter: fn[T](p: ref fn(x: T): int, l: list of T): list of T;
7+ partition: fn[T](p: ref fn(x: T): int, l: list of T): (list of T, list of T);
8+
9+ append: fn[T](l: list of T, x: T): list of T;
10+ concat: fn[T](l: list of T, l2: list of T): list of T;
11+ combine: fn[T](l: list of T, l2: list of T): list of T;
12+ reverse: fn[T](l: list of T): list of T;
13+ last: fn[T](l: list of T): T;
14+ delete: fn[T](x: T, l: list of T): list of T
15+ for { T => eq: fn(a, b: T): int; };
16+ pair: fn[T1, T2](l1: list of T1, l2: list of T2): list of (T1, T2);
17+ unpair: fn[T1, T2](l: list of (T1, T2)): (list of T1, list of T2);
18+ ismember: fn[T](x: T, l: list of T): int
19+ for { T => eq: fn(a, b: T): int; };
20+};
21+
22+#sort?
23+#join
24+#split