In article <34d63708.0@rcfnews.cs.umass.edu>,
pop@cs.umass.edu ( Robin Popplestone ) wrote:
>I'd be interested in exchanging ideas re. JVM representations of
>procedure-objects, bignums etc. For my POP200O project I'm planning to
>translate from POP2000 to the JVM, optionally producing Java source.
So would I, although it sounds like you are intending something which
is well-formulated, rather than the crude hack I'm currently playing
with.
Procedure Objects
=================
My reply got a bit long, so I've posted about procedure objects
separately.
Bignums
=======
I believe there is a bignum package in Java, so that would be the
obvious solution for bignums. (I haven't looked at it yet.) The
package name is java.math.BigInteger. (This is in JDK 1.1.4).
<Digression>
Just how do you do division in bignums arithmetic? I tried
writing my own bignums a while back (in C++), and long division
is not nearly as obvious as you'd think :-). (Multiplication
etc. is straightforward.)
I must look at the Java source code ...
</Digression>
Inferring Types
===============
Some of your earlier posts refer to work on inferring types, which
would be relevant, e.g.
define greet(n, name);
lvars surname = front(back(name));
repeat n times
[hello mr ^surname]=>
endrepeat
enddefine;
define test();
greet(1, [christopher robin]);
greet(3, [pooh bear]);
enddefine;
If the above two procedures are the whole program (I'm interested
only in a batch compiler, not an incremental compiler, at this
stage; "test" is my current entry-point, analogous to "main" in
a C program), then you could infer a signature for "greet" of
int, pair :-> void
which would allow it to be translated into something like (in
Java):
void greet(int n, Pair name) {
PopObject surname = front(name.back);
for (int i=0; i<n; i++) {
pop.printarrow(
cons(word("hello"), cons(word("mr"), surname)));
}
}
void test() {
greet(1, cons(word("christopher"), cons(word("robin"), nil)));
greet(3, cons(word("pooh"), cons(word("bear"), nil)));
}
instead of (what I do now) something like
PopObject greet(PopObject n, PopObject name) {
PopObject surname = front(back(name));
for (int i=0; i < n.getInteger(); i++) {
pop.printarrow(
cons(word("hello"), cons(word("mr"), surname)));
}
return nil;
}
PopObject test() {
greet( coerce(1),
cons(word("christopher"), cons(word("robin"), nil)));
return greet( coerce(3),
cons(word("pooh"), cons(word("bear"), nil)));
}
The two main differences in the second (almost typeless) version
being (1) that I have to construct a PopObject, and extract the
integer from it for the first argument, and (2) that an unnecessary
run-time type check is performed on the second argument. (The
return argument is intended to be the _list_ of results returned
from a pop function. So far, I'm ignoring pop's open stack, which is
both powerful and a source of bugs.)
<explanation>
A Pair has two fields: front and back. If you know name is a Pair,
then you can get the back directly: name.back. If name is a PopObject,
you have to call a function (see below). I could have made these
methods of the class PopObject, so that name.back().front() would have
been correct. As it happens, I made it a static method of a class
PopStuff, so that the correct expression is front(back(name)). The code
for back (part of the "pop" run-time system, and written by hand)
looks something like:
static PopObject back(PopObject consObj) {
try {
Pair cons = (Pair)consObj;
return cons.back;
}
catch (ClassCastException e) {
System.out.println("Attempt to take back of non-pair");
throw new PopException(consObj);
}
}
</explanation>
(continued in next message)
--
Home: jlc@sofluc.demon.co.uk |
Work: jlc@bmtech.co.uk |
|