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