[net.lang.apl] Example of the APL Compiler

budd@boring.UUCP (12/09/85)

<

A while back somebody mentioned the APL compiler developed at Arizona in
this net group.  Since I was the original author of that compiler (a student of
mine, Joe Treat, later made some important contributions), I thought I
might give an example of the type of output it produces.
	I am at the moment preparing a talk I will present in Heidelberg in
January summarizing all the research I have done in the last five years
connected with the project, and thus have been reviewing in my mind all the
different aspects of the project.  If people are interested I can prepare a
short summary for the net, as well.
	The example program I include here is sort of classic APL.  i.e.,
rather cryptic.  The three letter menomics (.ro for rho, for example),
don't help.  The program is taken from a technical report by Alan Perlis of
many years ago (mid 70's, I believe).  It orders the integers in a spiral,
   50   51   52   53   54   55   56   57
   49   26   27   28   29   30   31   58
   48   25   10   11   12   13   32   59
   47   24    9    2    3   14   33   60
   46   23    8    1    4   15   34   61
   45   22    7    6    5   16   35   62
   44   21   20   19   18   17   36   63
   43   42   41   40   39   38   37   64
and then replaces the prime numbers by a *, and the non-primes by a space.
   *    
    * * 
   * * *
*  **   
 *     *
  * *   
   * *  
* *   * 
The resulting picture is somewhat interesting.  Although this is not a
typical APL application, it does have the advantage of using most of the
APL functions, and is therefore a good test case for the compiler, as well
as illustrating the type of code the compiler produces.
	Here is the program:
----------------------
scalar int n

.dl z _ spiral l
int l
vector int fun copies, linear
a _ .io n # 2
c _ 4 | a copies (| - \ a)
g _ .fl 0.5 + n % 2
e _ l [;(.ng1 + n # n) .ua c + 4 # 0 = c ]
z _ (2 .ro n) .ro .gu linear 1 1 2 .tr (2 .ro g) .so . + +\ 0 , e
.dl

.dl c _ a copies b
int vector b
vector a
c _  a [ + \ ( .io +/ b ) .ep .ng1 .da 1 + +\ 0 , b ]
.dl

.dl x _ primes a
s _ + / .ro , a
x _ a .ep (2 = + .bs 0 = (.io s) .so . | .io s)/ .io s
.dl

.dl l _ linear m
int m
l _ 1 + n .dc m - 1
.dl

int fun primes
n _ 8
.bx _ y _ spiral 2 4 .ro .ng1 0 1 0 0 1 0 .ng1
' *'[1 + primes y]
---------------
APL programmers will undoubtedly be upset at the appearance of
declarations.  In the APL compiler, declarations are treated as hints to
the code generator.  The only declarations that are absolutely required are
for forward defined functions (since otherwise the parser can't
disambiguate things).  Declarations can optionally give rank (scalar,
vector, or other), type (bit, int, real, or char), or simply just a name
(var).  Notice that most local vars aren't declared, only parameters.  This
is because at the moment the compiler performs intra- but not
inter-procedural analysis, and thus can't discover the types of parameters
unless you tell it.  Most of the declarations could be omitted, with the result
that larger (and slower) code would be produced.
	Unfortunately, you won't be able to run the resulting code, since
there is a small run-time system that must be linked with the resulting
program.  However you might have fun looking at the code and trying to
figure out how in the *ell the compiler generates THAT from the source.
--------------
# include "aplc.h"
extern struct trs_struct n;
int i_spiral[15] = {
	0, 1, 2, 4, 2, -1, 4, 0, 2, 1, 
	1, 2, 3, 2, 0} 
;
double r_spiral[1] = {
	0.5} 
;
spiral(z, _no2, l)
struct trs_struct *z, *_no2, *l;
{
	struct trs_struct e;
	struct trs_struct g;
	struct trs_struct c;
	struct trs_struct a;
	struct trs_struct trs1, trs2, trs3, trs4; 
	union mp_struct mp1, mp2, mp3, mp4, mp5, mp6, mp7, mp8, mp9, 
	mp10, mp11, mp12, mp13, mp14, mp15, mp16, mp17, mp18, mp19, 
	mp20, mp21, mp22, mp23, mp24, mp25, mp26, mp27, mp28, mp29, 
	mp30, mp31, mp32; 
	union res_struct res1, res2, res3, res4, res5, res6, res7, res8, res9, 
	res10, res11, res12, res13, res14, res15, res16, res17, res18, res19, 
	res20, res21, res22; 
	int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, 
	i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, 
	i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, 
	i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, 
	i40, i41, i42, i43, i44, i45, i46; 

	e.type = UKTYPE;
	g.type = UKTYPE;
	c.type = UKTYPE;
	a.type = UKTYPE;

	stmtno = 1;
	while (stmtno)
		switch(stmtno) {
		default: 
			stmtno = 0; 
			break;
		case 1: 
			stmtno = 1;
			trace("spiral", 1);
			valloc(&mp5, 1, INT);
			if (n.type == UKTYPE) error("undefined value used");
			mp3.ip = n.value.ip;
			*mp5.ip = (*mp3.ip * 2);
			i6 = 1;
			settrs(&trs1, INT, 1, mp5.ip);
			i1 = talloc(&trs1);
			mp1.ip = trs1.value.ip;
			for (i2 = 0; i2 < i1; i2++) {
				(*mp1.ip++  = i6++ );
			}
			assign(&a, &trs1);
			memfree(&mp5.ip);
		case 2: 
			stmtno = 2;
			trace("spiral", 2);
			if (a.type == UKTYPE) error("undefined value used");
			mp2.ip = a.value.ip;
			settrs(&trs2, INT, 1, a.shape);
			trs2.value.ip = mp2.ip;
			mp5.ip = a.value.ip;
			i8 = 1;
			i9 = *a.shape;
			i12 = *a.shape;
			valloc(&mp6, i12, INT);
			mp7 = mp6;
			for (i5 = 0; i5 < i12; i5++) {
				res5.i = 0;
				for (i6 = i5; i6 >= 0; i6--) {
					(res5.i = (*(mp5.ip + i6) - res5.i));
				}
				if (res5.i < 0)
					res5.i = - res5.i;
				(*mp6.ip++  = res5.i);
			}
			settrs(&trs3, INT, 1, a.shape);
			trs3.value.ip = mp7.ip;
			copies(&trs4, &trs2, &trs3);
			mp8.ip = trs4.value.ip;
			settrs(&trs1, INT, 1, trs4.shape);
			i1 = talloc(&trs1);
			mp1.ip = trs1.value.ip;
			for (i2 = 0; i2 < i1; i2++) {
				(*mp1.ip++  = (*mp8.ip++  % 4));
			}
			assign(&c, &trs1);
			memfree(&mp7.ip);
		case 3: 
			stmtno = 3;
			trace("spiral", 3);
			mp5.rp = &r_spiral[0];
			if (n.type == UKTYPE) error("undefined value used");
			mp3.ip = n.value.ip;
			settrs(&trs1, INT, 0, &i_spiral[1]);
			i1 = talloc(&trs1);
			mp1.ip = trs1.value.ip;
			{
				(*mp1.ip++  = ((int) floor((*mp5.rp + (((double) *mp3.ip) / ((double) 2))))));
			}
			assign(&g, &trs1);
		case 4: 
			stmtno = 4;
			trace("spiral", 4);
			if (l->type == UKTYPE) error("undefined value used");
			mp2.ip = l->value.ip;
			valloc(&mp3, 1, INT);
			*mp3.ip = *l->shape;
			if (n.type == UKTYPE) error("undefined value used");
			mp11.ip = n.value.ip;
			mp10.ip = n.value.ip;
			i17 = 1;
			valloc(&mp15, i17, INT);
			mp16 = mp15;
			{
				(*mp15.ip++  = ((*mp11.ip * *mp10.ip) - 1));
			}
			if (c.type == UKTYPE) error("undefined value used");
			mp22.ip = c.value.ip;
			mp17.ip = c.value.ip;
			i8 = 1;
			valloc(&mp9, i8, INT);
			for (i9 = i8 - 1; i9 >= 0; i9--) {
				*(mp9.ip + i9) = iabs(*(mp16.ip + i9));
			}
			i10 = qsdalloc(1, &mp5, &mp6, &mp7);
			i9 = 0;
			{
				if (*(mp16.ip + i9) < 0)
					*(mp6.ip + i9) += *(c.shape + i9) + *(mp16.ip + i9);
			}
			i7 = accessor(1, mp9.ip, 1, c.shape, &mp8, mp5.ip, mp6.ip, mp7.ip);
			outershape(&mp24, 1, mp3.ip, 1, mp9.ip);
			i24 = *mp9.ip;
			settrs(&trs1, INT, 2, mp24.ip);
			i1 = talloc(&trs1);
			mp1.ip = trs1.value.ip;
			for (i2 = 0; i2 < i1; i2++) {
				i6 = i2 % i24;
				i8 = i6;
				i11 = i7;
				for (i9 = i10 - 1; i9 >= 0; i9--) {
					i11 += i8 * *(mp8.ip + i9);
					i8 /= *(mp9.ip + i9);
				}
				i4 = i2 / i24;
				i3 = (((*(mp22.ip + i11) + ((0 == *(mp17.ip + i11)) * 4)) + (i4 * *(l->shape + 1))) - 1);
				(*mp1.ip++  = *(mp2.ip + (l->rank?i3:0)));
			}
			assign(&e, &trs1);
			memfree(&mp3.ip);
			memfree(&mp4.ip);
			memfree(&mp24.ip);
		case 5: 
			stmtno = 5;
			trace("spiral", 5);
			if (n.type == UKTYPE) error("undefined value used");
			mp5.ip = n.value.ip;
			i8 = 2;
			valloc(&mp6, i8, INT);
			mp7 = mp6;
			for (i3 = 0; i3 < i8; i3++) {
				(*mp6.ip++  = *mp5.ip);
			}
			trs2.type = UKTYPE;
			if (g.type == UKTYPE) error("undefined value used");
			mp24.ip = g.value.ip;
			i41 = 1;
			if (e.type == UKTYPE) error("undefined value used");
			mp18.ip = e.value.ip;
			catshape(&mp16, 0, &i_spiral[1], 2, e.shape);
			i28 = 1;
			i31 = *(e.shape + 1);
			i30 = i28 + i31;
			i25 = 0;
			i35 = *(mp16.ip + 1);
			i23 = 0;
			i37 = vsize(2, mp16.ip);
			valloc(&mp19, i37, INT);
			mp20 = mp19;
			for (i22 = 0; i22 < i37; i22++) {
				i36 = (i22 / i35) * i35;
				if (i22 == i36) {
					res11.i = 0;
				}
				i32 = i23 % i30;
				if (i32 < i28) {
					(res8.i = 0);
				}
				else {
					(res8.i = *mp18.ip++ );
					i25++;
				}
				res11.i += res8.i;
				i23++;
				(*mp19.ip++  = res11.i);
			}
			outershape(&mp25, 1, &i_spiral[13], 2, mp16.ip);
			i43 = vsize(2, mp16.ip);
			i20 = -1;
			dtshape(&mp12, &i_spiral[9], 3, mp25.ip);
			i16 = qsdalloc(2, &mp8, &mp9, &mp10);
			dtmerge(&i_spiral[9], 3, &mp8, &mp9, &mp10);
			i13 = accessor(2, mp12.ip, 3, mp25.ip, &mp11, mp8.ip, mp9.ip, mp10.ip);
			i45 = vsize(2, mp12.ip);
			valloc(&mp26, i45, INT);
			mp27 = mp26;
			for (i12 = 0; i12 < i45; i12++) {
				i14 = i12;
				i17 = i13;
				for (i15 = i16 - 1; i15 >= 0; i15--) {
					i17 += i14 * *(mp11.ip + i15);
					i14 /= *(mp12.ip + i15);
				}
				if ((i17 / i43) != i20) {
					i20 = i17 / i43;
					i40 = i20 % i41;
					(res16.i = *mp24.ip);
				}
				i21 = i17 % i43;
				(*mp26.ip++  = (res16.i + *(mp20.ip + i21)));
			}
			settrs(&trs3, INT, 2, mp12.ip);
			trs3.value.ip = mp27.ip;
			linear(&trs4, &trs2, &trs3);
			mp28.ip = trs4.value.ip;
			aplsort(&mp31, &mp28, *trs4.shape, INT, 1);
			i10 = *trs4.shape;
			settrs(&trs1, INT, 2, mp7.ip);
			i1 = talloc(&trs1);
			mp1.ip = trs1.value.ip;
			for (i2 = 0; i2 < i1; i2++) {
				i9 = i2 % i10;
				(*mp1.ip++  = (*(mp31.ip + i9) + 1));
			}
			assign( z, &trs1);
			memfree(&mp7.ip);
			memfree(&mp27.ip);
			memfree(&mp20.ip);
			memfree(&mp16.ip);
			memfree(&mp25.ip);
			memfree(&mp31.ip);
			stmtno = 0;
		}
}
int i_copies[5] = {
	0, 1, -1, 1, 0} 
;
copies(c, a, b)
struct trs_struct *c, *a, *b;
{
	struct trs_struct trs1; 
	union mp_struct mp1, mp2, mp3, mp4, mp5, mp6, mp7, mp8, mp9, 
	mp10, mp11, mp12, mp13, mp14, mp15, mp16, mp17, mp18, mp19, 
	mp20, mp21, mp22, mp23, mp24, mp25; 
	union res_struct res1, res2, res3, res4, res5, res6, res7, res8, res9, 
	res10, res11, res12, res13, res14, res15, res16, res17, res18, res19; 

	int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, 
	i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, 
	i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, 
	i30, i31, i32, i33, i34, i35, i36, i37, i38, i39, 
	i40; 


	stmtno = 1;
	while (stmtno)
		switch(stmtno) {
		default: 
			stmtno = 0; 
			break;
		case 1: 
			stmtno = 1;
			trace("copies", 1);
			if (a->type == UKTYPE) error("undefined value used");
			mp2 = a->value;
			valloc(&mp5, 1, INT);
			if (b->type == UKTYPE) error("undefined value used");
			mp3.ip = b->value.ip;
			i8 = *b->shape;
			res4.i = 0;
			for (i6 = 0; i6 < i8; i6++) {
				res4.i += *mp3.ip++ ;
			}
			*mp5.ip = res4.i;
			i10 = 1;
			mp16.ip = b->value.ip;
			catshape(&mp14, 0, &i_copies[1], 1, b->shape);
			i23 = 1;
			i26 = *b->shape;
			i25 = i23 + i26;
			i29 = 1;
			i30 = *mp14.ip;
			i13 = 1;
			valloc(&mp10, i13, INT);
			for (i14 = i13 - 1; i14 >= 0; i14--) {
				*(mp10.ip + i14) = *(mp14.ip + i14) - iabs(i_copies[(i14 + 2)]);
			}
			i15 = qsdalloc(1, &mp6, &mp7, &mp8);
			i14 = 0;
			{
				if (i_copies[(i14 + 2)] >= 0)
					*(mp7.ip + i14) += i_copies[(i14 + 2)];
			}
			i12 = accessor(1, mp10.ip, 1, mp14.ip, &mp9, mp6.ip, mp7.ip, mp8.ip);
			valloc(&mp19, 1, INT);
			i34 = *mp10.ip;
			*mp19.ip = i34;
			i35 = *mp19.ip;
			valloc(&mp20, i35, INT);
			mp21 = mp20;
			for (i11 = 0; i11 < i35; i11++) {
				i13 = i11;
				i16 = i12;
				for (i14 = i15 - 1; i14 >= 0; i14--) {
					i16 += i13 * *(mp9.ip + i14);
					i13 /= *(mp10.ip + i14);
				}
				res11.i = 0;
				for (i19 = i16; i19 >= 0; i19--) {
					i20 = i19 % i25;
					if (i20 < i23) {
						(res8.i = 0);
					}
					else {
						i20 -= i23;
						(res8.i = *(mp16.ip + i20));
					}
					res11.i += res8.i;
				}
				(*mp20.ip++  = (res11.i + 1));
			}
			aplsort(&mp22, &mp21, *mp19.ip, INT, 1);
			i38 = *mp5.ip;
			i4 = 0;
			settrs(&trs1, a->type, 1, mp5.ip);
			i1 = talloc(&trs1);
			mp1 = trs1.value;
			for (i2 = 0; i2 < i1; i2++) {
				i39 = (i2 / i38) * i38;
				if (i2 == i39) {
					res18.i = 0;
				}
				(res17.i = i10++ );
				res17.i = aplsearch(mp22.ip, &mp21, &res17, INT, *mp19.ip) < *mp19.ip;
				res18.i += res17.i;
				i4++;
				i3 = (res18.i - 1);
				getmp(&res2, &mp2, i3, a->type);
				setmp(&res2, &mp1, i2, trs1.type);
			}
			assign( c, &trs1);
			memfree(&mp5.ip);
			memfree(&mp21.ip);
			memfree(&mp14.ip);
			memfree(&mp19.ip);
			memfree(&mp22.ip);
			memfree(&mp25.ip);
			stmtno = 0;
		}
}
int i_primes[5] = {
	0, 1, 2, 0, 1} 
;
primes(x, _no2, a)
struct trs_struct *x, *_no2, *a;
{
	struct trs_struct s;
	struct trs_struct trs1; 
	union mp_struct mp1, mp2, mp3, mp4, mp5, mp6, mp7, mp8, mp9, 
	mp10, mp11, mp12, mp13, mp14, mp15, mp16, mp17, mp18, mp19, 
	mp20, mp21, mp22; 
	union res_struct res1, res2, res3, res4, res5, res6, res7, res8, res9, 
	res10, res11, res12, res13, res14, res15, res16, res17, res18, res19, 
	res20, res21, res22; 
	int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, 
	i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, 
	i20, i21, i22, i23, i24, i25, i26, i27; 

	s.type = UKTYPE;

	stmtno = 1;
	while (stmtno)
		switch(stmtno) {
		default: 
			stmtno = 0; 
			break;
		case 1: 
			stmtno = 1;
			trace("primes", 1);
			if (a->type == UKTYPE) error("undefined value used");
			mp2 = a->value;
			valloc(&mp3, 1, INT);
			i4 = vsize(a->rank, a->shape);
			*mp3.ip = i4;
			mp5.ip = mp3.ip;
			i6 = 1;
			i3 = 0;
			settrs(&trs1, INT, 0, &i_primes[1]);
			i1 = talloc(&trs1);
			mp1.ip = trs1.value.ip;
			i2 = 0;
			{
				res3.i = 0;
				for (i3 = 0; i3 < i6; i3++) {
					res3.i += *mp5.ip++ ;
				}
				(*mp1.ip++  = res3.i);
			}
			assign(&s, &trs1);
			memfree(&mp3.ip);
		case 2: 
			stmtno = 2;
			trace("primes", 2);
			mp2 = a->value;
			i25 = 0;
			valloc(&mp6, 1, INT);
			if (s.type == UKTYPE) error("undefined value used");
			mp5.ip = s.value.ip;
			*mp6.ip = *mp5.ip;
			valloc(&mp4, 1, INT);
			mp3.ip = s.value.ip;
			*mp4.ip = *mp3.ip;
			outershape(&mp7, 1, mp6.ip, 1, mp4.ip);
			i12 = *mp4.ip;
			i7 = -1;
			i17 = *mp7.ip;
			i16 = esubi(0, 2, mp7.ip);
			valloc(&mp14, 1, INT);
			mp13.ip = s.value.ip;
			*mp14.ip = *mp13.ip;
			i22 = 0;
			i24 = *(mp14.ip + i22);
			valloc(&mp15, i24, INT);
			for (i4 = 0; i4 < i24; i4++) {
				res12.i = 0;
				i6 = (i17 - 1) * i16 + i4 % i16;
				for (i18 = i17 - 1; i18 >= 0; i18--) {
					if ((i6 / i12) != i7) {
						i7 = i6 / i12;
						(res7.i = (i7 + 1));
					}
					i8 = i6 % i12;
					res12.i += (0 == ((i8 + 1) % res7.i));
					i6 -= i16;
				}
				if (((2 == res12.i) != 0))
					*(mp15.ip + i25++) = i4;
			}
			memfree(&mp6.ip);
			memfree(&mp4.ip);
			memfree(&mp7.ip);
			valloc(&mp16, 1, INT);
			*mp16.ip = i25;
			valloc(&mp17, 1, INT);
			i26 = *mp16.ip;
			*mp17.ip = i26;
			i27 = *mp17.ip;
			valloc(&mp18, i27, INT);
			mp19 = mp18;
			for (i3 = 0; i3 < i27; i3++) {
				i5 = *(mp15.ip + i3);
				(*mp18.ip++  = (i5 + 1));
			}
			aplsort(&mp20, &mp19, *mp17.ip, INT, 1);
			settrs(&trs1, BIT, a->rank, a->shape);
			i1 = talloc(&trs1);
			mp1.ip = trs1.value.ip;
			for (i2 = 0; i2 < i1; i2++) {
				getmp(&res2, &mp2, i2, a->type);
				cktype(&res2, INT, a->type);
				res22.i = aplsearch(mp20.ip, &mp19, &res2, INT, *mp17.ip) < *mp17.ip;
				(*mp1.ip++  = res22.i);
			}
			assign( x, &trs1);
			memfree(&mp19.ip);
			memfree(&mp16.ip);
			memfree(&mp15.ip);
			memfree(&mp14.ip);
			memfree(&mp17.ip);
			memfree(&mp20.ip);
			stmtno = 0;
		}
}
int i_linear[4] = {
	0, 1, 1, 1} 
;
linear(l, _no2, m)
struct trs_struct *l, *_no2, *m;
{
	struct trs_struct trs1; 
	union mp_struct mp1, mp2, mp3, mp4, mp5, mp6, mp7, mp8; 
	union res_struct res1, res2, res3, res4, res5, res6, res7, res8, res9, 
	res10, res11, res12, res13; 
	int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, 
	i10, i11, i12, i13, i14; 


	stmtno = 1;
	while (stmtno)
		switch(stmtno) {
		default: 
			stmtno = 0; 
			break;
		case 1: 
			stmtno = 1;
			trace("linear", 1);
			if (n.type == UKTYPE) error("undefined value used");
			mp3.ip = n.value.ip;
			if (m->type == UKTYPE) error("undefined value used");
			mp5.ip = m->value.ip;
			i4 = innershape(&mp2, 0, &i_linear[1], m->rank, m->shape);
			i5 = *m->shape;
			i12 = (m->rank?*((m->rank + m->shape) - 1):1);
			settrs(&trs1, INT, i4, mp2.ip);
			i1 = talloc(&trs1);
			mp1.ip = trs1.value.ip;
			for (i2 = 0; i2 < i1; i2++) {
				res10.i = 0;
				res2.i = 1;
				for (i6 = i5 - 1; i6 >= 0; i6--) {
					(res3.i = *mp3.ip);
					i8 = i6 * i12 + i2 % i12;
					res10.i += (res2.i * (*(mp5.ip + (m->rank?i8:0)) - 1));
					res2.i *= res3.i;
				}
				(*mp1.ip++  = (res10.i + 1));
			}
			assign( l, &trs1);
			stmtno = 0;
		}
}
extern struct trs_struct y;
struct trs_struct y;
struct trs_struct n;
int i_main[17] = {
	0, 1, 10, 2, 4, 2, -1, 0, 1, 0, 
	0, 1, 0, -1, 8, 2, 1} 
;
char c_main[] = " *";
main() {
	struct trs_struct trs1, trs2, trs3, trs4; 
	union mp_struct mp1, mp2, mp3, mp4, mp5, mp6, mp7, mp8, mp9; 

	union res_struct res1, res2, res3, res4, res5, res6, res7, res8, res9; 

	int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; 


	y.type = UKTYPE;
	n.type = UKTYPE;

	stmtno = 1;
	while (stmtno)
		switch(stmtno) {
		default: 
			stmtno = 0; 
			break;
		case 1: 
			stmtno = 1;
			trace("main", 1);
			settrs(&trs1, INT, 0, &i_main[1]);
			i1 = talloc(&trs1);
			mp1.ip = trs1.value.ip;
			{
				(*mp1.ip++  = 10);
			}
			assign(&n, &trs1);
		case 2: 
			stmtno = 2;
			trace("main", 2);
			trs2.type = UKTYPE;
			settrs(&trs3, INT, 2, &i_main[3]);
			trs3.value.ip = &i_main[6];
			spiral(&trs4, &trs2, &trs3);
			mp9 = trs4.value;
			i1 = vsize(trs4.rank, trs4.shape);
			bldrqv(&mp1, trs4.rank);
			for (i2 = 0; i2 < i1; i2++) {
				getmp(&res7, &mp9, i2, trs4.type);
				printit(&res7, trs4.type, bmprqv(mp1.ip, trs4.rank, trs4.shape));
			}
			assign(&y, &trs4);
			memfree(&mp1.ip);
		case 3: 
			stmtno = 3;
			trace("main", 3);
			mp2.cp = &c_main[0];
			trs1.type = UKTYPE;
			if (y.type == UKTYPE) error("undefined value used");
			mp3 = y.value;
			settrs(&trs2, y.type, y.rank, y.shape);
			trs2.value = mp3;
			primes(&trs3, &trs1, &trs2);
			mp6.ip = trs3.value.ip;
			i1 = vsize(trs3.rank, trs3.shape);
			bldrqv(&mp1, trs3.rank);
			for (i2 = 0; i2 < i1; i2++) {
				i3 = *mp6.ip++ ;
				(res1.c = *(mp2.cp + i3));
				printit(&res1, CHAR, bmprqv(mp1.ip, trs3.rank, trs3.shape));
			}
			memfree(&mp9.ip);
			memfree(&mp1.ip);
			stmtno = 0;
		}
}