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