
of a supertype and subtype, where the subtype was not yet added to the tenv. Had to hack to get around that one. Also little problems like the fact that list can be captured by the user program, so we can't use that -- used list* (with a null at the end) and null (for empty lists) instead. Since the power was down and I couldn't get the earlier stuff committed, I have even more changes. Bug-fixes, mostly, though now top-level functions that are defined consecutively are mutually recursive as they should be. svn: r300
178 lines
3.5 KiB
Plaintext
178 lines
3.5 KiB
Plaintext
type List {
|
|
|
|
List addToFront(Any);
|
|
List addToEnd(Any);
|
|
|
|
Any first();
|
|
Any atIndex(int);
|
|
Any last();
|
|
|
|
List rest();
|
|
List drop(int);
|
|
List take(int);
|
|
|
|
List appendToEnd(List);
|
|
List appendToFront(List);
|
|
|
|
List reverse();
|
|
|
|
int length();
|
|
bool empty();
|
|
|
|
List map(Any -> Any);
|
|
Any foldl(<Any, Any> -> Any, Any);
|
|
Any foldr(<Any, Any> -> Any, Any);
|
|
List filter(Any -> bool);
|
|
|
|
}
|
|
|
|
class MTList() : List impl List {
|
|
|
|
List add(Any elt) {
|
|
return new ConsList(car = elt, cdr = (this : List));
|
|
}
|
|
|
|
Any no_elts(int n) {
|
|
error("The empty list has no elements!");
|
|
}
|
|
|
|
Any no_elt() {
|
|
error("The empty list has no elements!");
|
|
}
|
|
|
|
List rest() {
|
|
error("Cannot get the rest of an empty list!");
|
|
}
|
|
|
|
List drop(int n) {
|
|
if n == 0 {
|
|
this : List;
|
|
} else {
|
|
error("Attempt to drop elements from an empty list!");
|
|
};
|
|
}
|
|
|
|
List take(int n) {
|
|
if n == 0 {
|
|
this : List;
|
|
} else {
|
|
error("Attempt to take elements from an empty list!");
|
|
};
|
|
}
|
|
|
|
List ret_other(List l) { return l; }
|
|
|
|
List reverse() { return (this : List); }
|
|
|
|
int length() { return 0; }
|
|
|
|
bool empty() { return true; }
|
|
|
|
List map(Any -> Any f) { return (this : List); }
|
|
|
|
Any fold(<Any, Any> -> Any f, Any i) { return i; }
|
|
|
|
List filter(Any -> bool f) { return (this : List); }
|
|
|
|
export List : add as addToFront, add as addToEnd,
|
|
no_elt as first, no_elts as atIndex, no_elt as last,
|
|
rest, drop, take, reverse,
|
|
ret_other as appendToEnd, ret_other as appendToFront,
|
|
length, empty,
|
|
map, fold as foldl, fold as foldr, filter;
|
|
}
|
|
|
|
// Since init slots get translated to init fields by need, we can put
|
|
// car and cdr here, and then use them appropriately inside the methods
|
|
// which will make them fields.
|
|
class ConsList(Any car, List cdr) : List impl List {
|
|
|
|
Any first() { return car; }
|
|
|
|
Any atIndex(int n) {
|
|
if n == 0 {
|
|
car;
|
|
} else {
|
|
cdr.atIndex(n - 1);
|
|
};
|
|
}
|
|
|
|
Any last() {
|
|
if cdr.empty() {
|
|
car;
|
|
} else {
|
|
cdr.last();
|
|
};
|
|
}
|
|
|
|
List rest() { return cdr; }
|
|
|
|
List drop(int n) {
|
|
if n == 0 {
|
|
this : List;
|
|
} else {
|
|
cdr.drop(n - 1);
|
|
};
|
|
}
|
|
|
|
List take(int n) {
|
|
if n == 0 {
|
|
new MTList();
|
|
} else {
|
|
new ConsList(car = car, cdr = cdr.take(n - 1));
|
|
};
|
|
}
|
|
|
|
List addToFront(Any x) {
|
|
return new ConsList(car = x, cdr = (this : List));
|
|
}
|
|
|
|
List addToEnd(Any x) {
|
|
return new ConsList(car = car, cdr = cdr.addToEnd(x));
|
|
}
|
|
|
|
List appendToFront(List other) {
|
|
if other.empty() {
|
|
this : List;
|
|
} else {
|
|
new ConsList(car = other.first(), cdr = other.drop(1));
|
|
};
|
|
}
|
|
|
|
List appendToEnd(List other) {
|
|
return new ConsList(car = car, cdr = cdr.appendToEnd(other));
|
|
}
|
|
|
|
List reverse() {
|
|
return cdr.reverse().addToEnd(car);
|
|
}
|
|
|
|
int length() { return 1 + cdr.length(); }
|
|
|
|
bool empty() { return false; }
|
|
|
|
List map(Any -> Any f) {
|
|
return new ConsList(car = f(car), cdr = cdr.map(f));
|
|
}
|
|
|
|
Any foldl(<Any, Any> -> Any f, Any i) {
|
|
return f(car, cdr.foldl(f, i));
|
|
}
|
|
|
|
Any foldr(<Any, Any> -> Any f, Any i) {
|
|
return cdr.foldr(f, f(car, i));
|
|
}
|
|
|
|
List filter(Any -> bool f) {
|
|
if f(car) {
|
|
new ConsList(car = car, cdr = cdr.filter(f));
|
|
} else {
|
|
cdr.filter(f);
|
|
};
|
|
}
|
|
|
|
export List : addToFront, addToEnd, first, atIndex, last, reverse,
|
|
rest, drop, take, appendToEnd, appendToFront, length, empty,
|
|
map, foldl, foldr, filter;
|
|
}
|