Dear David,
I'm trying to understand the IR of functors in Poly/ML, and I got a
few questions here:
1. I tried the following example:
signature A =
sig
type element
end
signature B =
sig
type element
end
functor myfctor(s: A) :> B =
struct
type element = s.element
end
which corresponds to the following code tree:
BLOCK(DECL #1{0 uses} =
LAMBDAONLYINLINE(
myfctor
CL=false CR=0 LEV=0 LOCALS=0
ARGS=G
ARGLIVES=
RES=G CLOS=()
BLOCK(DECL #1{0 uses} =
BLOCK(DECL #2{0 uses} = INDIRECT(0, PARAM(0,1));
RECCONSTR(INDIRECT(0, LOCAL(0,2)),
POLY_SYS_alloc_store G
$(LIT1 G,
LIT40 G,
POLY_SYS_load_word G $(INDIRECT(1, LOCAL(0,2)) G, LIT0 G) G
),
INDIRECT(2, LOCAL(0,2)),
INDIRECT(3, LOCAL(0,2))
)
);
BLOCK(RECCONSTR(LOCAL(0,1)))
)){LAMBDA};
RECCONSTR(LOCAL(0,1))
)
>From above, I understand that functor is compiled to a lambda
expression. But I don't quite see what the body of the lambda
expression does. From my understanding, here PARAM(0, 1) refers to
the input structure s which is a tuple. However, what does the values
of
INDIRECT(0, LOCAL(0,2))
INDIRECT(1, LOCAL(0,2))
INDIRECT(2, LOCAL(0,2))
INDIRECT(3, LOCAL(0,2))
represent? For example, from the printing of the IR of a structure
whose type is A is the following:
> structure foo : A =
# struct
# type element = int
# end;
BLOCK(DECL #1{0 uses} = LIT0; RECCONSTR(LOCAL(0,1)))
structure foo : A
Since the tuple returned in the last statement only contains only one
local variable whose value is LIT0, why we could use index 1, 2, 3
above to access other elements in the tuple?
And may I also ask you what does the following code in the above
codetree do, and why it does that?
POLY_SYS_alloc_store G
$(LIT1 G,
LIT40 G,
POLY_SYS_load_word G $(INDIRECT(1, LOCAL(0,2)) G, LIT0 G) G
)
2. Later I tried to add more content which is a type implemented by a list:
signature A =
sig
type element
end
signature B =
sig
type element
type set
end
functor myfctor(s: A) :> B =
struct
type element = s.element
type set = element list
end
The printed codetree looks similar to the one given in 1, except the
corresponding IR for type set = element list, which is:
DECL #3{0 uses} =
BLOCK(RECCONSTR(LIT0,
POLY_SYS_alloc_store G
$(LIT1 G,
LIT40 G,
LAMBDA(
print-list
CL=false CR=0 LEV=0 LOCALS=0
ARGS=G
ARGLIVES=
RES=G CLOS=()
POLY_SYS_load_word G
$(GLOBAL (LIT <long>, NIL ) (*GLOBAL*) G, LIT0 G) G
$(RECCONSTR(LIT0,
LAMBDA(
print-element
CL=false CR=0 LEV=0 LOCALS=0
ARGS=G
ARGLIVES=
RES=G CLOS=()
POLY_SYS_load_word G
$(INDIRECT(1, INDIRECT(0, PARAM(2,1))) G,
LIT0 G
) G $(PARAM(0,1) G)){LAMBDA},
INDIRECT(2, INDIRECT(0, PARAM(1,1))),
INDIRECT(3, INDIRECT(0, PARAM(1,1)))
) G
) G $(PARAM(0,1) G)){LAMBDA} G
),
GLOBAL (FUN "boxed-list",
LAMBDAINLINE(
boxed-list
CL=false CR=0 LEV=0 LOCALS=0
ARGS=G
ARGLIVES=
RES=G CLOS=()
LIT3){LAMBDA}
) (*GLOBAL*){early} G
$(RECCONSTR(LIT0, LIT0, INDIRECT(2, INDIRECT(0, PARAM(0,1))), LIT1)
G
),
GLOBAL (FUN "size-list",
LAMBDAINLINE(
size-list
CL=false CR=0 LEV=0 LOCALS=0
ARGS=G
ARGLIVES=
RES=G CLOS=()
LIT1){LAMBDA}
) (*GLOBAL*){early} G
$(RECCONSTR(LIT0, LIT0, LIT0, INDIRECT(3, INDIRECT(0, PARAM(0,1))))
G
)
)
);
Here why there are two more functions "size-list" and "boxed-list"
appended to the end of code tree?
Sorry for making this email too long, and thank you very much for your help!
-- Yue