-
Notifications
You must be signed in to change notification settings - Fork 0
/
sort-list.cl
executable file
·146 lines (106 loc) · 2.93 KB
/
sort-list.cl
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
(*
This file presents a fairly large example of Cool programming. The
class List defines the names of standard list operations ala Scheme:
car, cdr, cons, isNil, rev, sort, rcons (add an element to the end of
the list), and print_list. In the List class most of these functions
are just stubs that abort if ever called. The classes Nil and Cons
inherit from List and define the same operations, but now as
appropriate to the empty list (for the Nil class) and for cons cells (for
the Cons class).
The Main class puts all of this code through the following silly
test exercise:
1. prompt for a number N
2. generate a list of numbers 0..N-1
3. reverse the list
4. sort the list
5. print the sorted list
Because the sort used is a quadratic space insertion sort, sorting
moderately large lists can be quite slow.
*)
Class List inherits IO {
(* Since abort() returns Object, we need something of
type Bool at the end of the block to satisfy the typechecker.
This code is unreachable, since abort() halts the program. *)
isNil() : Bool { { abort(); true; } };
cons(hd : Int) : Cons {
(let new_cell : Cons <- new Cons in
new_cell.init(hd,self)
)
};
(*
Since abort "returns" type Object, we have to add
an expression of type Int here to satisfy the typechecker.
This code is, of course, unreachable.
*)
car() : Int { { abort(); new Int; } };
cdr() : List { { abort(); new List; } };
rev() : List { cdr() };
sort() : List { cdr() };
insert(i : Int) : List { cdr() };
rcons(i : Int) : List { cdr() };
print_list() : Object { abort() };
};
Class Cons inherits List {
xcar : Int; -- We keep the car in cdr in attributes.
xcdr : List;
isNil() : Bool { false };
init(hd : Int, tl : List) : Cons {
{
xcar <- hd;
xcdr <- tl;
self;
}
};
car() : Int { xcar };
cdr() : List { xcdr };
rev() : List { (xcdr.rev()).rcons(xcar) };
sort() : List { (xcdr.sort()).insert(xcar) };
insert(i : Int) : List {
if i < xcar then
(new Cons).init(i,self)
else
(new Cons).init(xcar,xcdr.insert(i))
fi
};
rcons(i : Int) : List { (new Cons).init(xcar, xcdr.rcons(i)) };
print_list() : Object {
{
out_int(xcar);
out_string("\n");
xcdr.print_list();
}
};
};
Class Nil inherits List {
isNil() : Bool { true };
rev() : List { self };
sort() : List { self };
insert(i : Int) : List { rcons(i) };
rcons(i : Int) : List { (new Cons).init(i,self) };
print_list() : Object { true };
};
Class Main inherits IO {
l : List;
(* iota maps its integer argument n into the list 0..n-1 *)
iota(i : Int) : List {
{
l <- new Nil;
(let j : Int <- 0 in
while j < i
loop
{
l <- (new Cons).init(j,l);
j <- j + 1;
}
pool
);
l;
}
};
main() : Object {
{
out_string("How many numbers to sort? ");
iota(in_int()).rev().sort().print_list();
}
};
};