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
|
/*
Implementation of optimally compiled list comprehensions using Wadler's algorithm from
Peyton-Jones "Implementation of Functional Programming Languages", 1987
TQ transforms a list of qualifiers (either boolean expressions or generators) into a
single expression which implements the list comprehension.
TE << [E || Q] >> = TQ << [E || Q] ++ [] >>
TQ << [E || p <- L1, Q] ++ L2 >> =
h ( TE << L1 >> ) where
h = us -> case us in
[] -> TE << L2 >>
(u : us') ->
(TE << p >> -> ( TQ << [E || Q] ++ (h us') >> )) u
*/
tree TQ(quals,l2)
list quals, l2;
{
tree qualh;
list rest;
if(tlist(quals) == lnil)
return(mkcons(zfexpr,l2));
qualh = (tree) lhd(quals);
rest = ltl(quals);
if(ttree(qualh) != qual)
return(mkif(qualh,TQ(rest,l2),l2));
{
tree h = mkident(uniqueident("Zh%d")),
u = mkident(uniqueident("Iu%d")),
us = mkident(uniqueident("Ius%d")),
pat = gqpat(qualh);
pbinding tq = mkppat(gqpat(qualh),TQ(rest,mkap(h,us)));
return(
mkletv(
mkrbind(
mkpbind(
lsing(
mkppat(h,
mklam(us,
mkcasee(us,
ldub(
mkppat(niltree,l2),
mkppat(
mkcons(u,us),
mkcasee(u,lsing(tq))
/*
replaces the following code which elides patterns in list comprehensions a la M*****a
mkcasee(u,
ttree(pat) == ident && !isconstr(gident(pat))?
lsing(tq):
ldub(tq,mkppat(mkident("_"),mkap(h,us))))
*/
)))))))),
mkap(h,gqexp(qualh))));
}
}
|