4 #include "assertions.h"
7 /* Copies the enviroment vector currenv to a new vector of size
8 (currenv_size+1) starting from element #1.
9 Copies the arguments from the stack to element #0 of the new vector.
10 Returns the new env. vector.
12 @param currenv: points to the current enviroment vector
13 @param currenv_size: size of the current enviroment vector
15 int** extendEnviroment(int** currenv, int currenv_size)
17 int** newenv; /* newenv: points to the new envoriment vector */
18 int ndx; /* ndx: loop index */
20 ASSERT_ALWAYS(currenv_size>=0,"");
22 /* allocate new enviroment vector */
23 newenv = autoMalloc( sizeof(int) * (currenv_size + 1) );
25 /* copy current enviroment to new enviroment */
28 if (ndx<=0) goto LendFor1;
29 newenv[ndx] = currenv[ndx-1];
33 /* copy arguments from stack to new enviroment vector (extend env.) */
34 if (currenv_size<=0) goto LendExtend1; /* no activation frame at all */
35 if (ST_ARG_COUNT()<=0) goto LendExtend1; /* no args in act. frame */
36 newenv[0] = autoMalloc( sizeof(int) * ST_ARG_COUNT() );
39 if (ndx>=ST_ARG_COUNT()) goto LendFor2;
40 newenv[0][ndx] = ST_ARG(ndx);
49 /* Prepares the stack for a tail-call.
50 Overrides the last activation frame with the current one,
53 void shiftActFrmDown()
55 int low; /* lowest address of the activation frame (included) */
56 int high; /* highest address of the activation frame (included) */
57 int dest_low; /* lowest address where to put the activation frame */
59 int old_fp = ST_OLDFP();
61 /* Shift activation frame down the stack */
67 stack[dest_low] = stack[low];
77 /* Shifts the elements in the stack upwards.
79 @param pos: index of the first element to shift
80 @param amount: the number of elements to shift up each element by
82 Shifts up each element between `pos` and sp (inclusive) by `amount`.
84 void shiftStackUp(int pos, unsigned int amount)
88 /* shift elements upwards */
89 for (i=sp-1; i>=pos; --i) {
90 stack[i+amount] = stack[i];
98 /* Shifts the elements in the stack downwards.
100 @param pos: index of the first element to shift
101 @param amount: the number of elements to shift down each element by
103 Shifts down each element between `pos` and sp (inclusive) by `amount`.
105 void shiftStackDown(int pos, unsigned int amount)
109 /* shift elements downwards */
110 for (i=pos; i<=sp-1; ++i) {
111 stack[i-amount] = stack[i];
119 /* Prepares the stack for an application of lambda-optional.
121 @param formalParams: the number of formal parameters the lambda
122 expects, including the optional one.
124 Moves the optional parameters to a list in the heap.
126 void prepareStackForAbsOpt(int formalParams)
128 int actualParams = ST_ARG_COUNT();
129 int optionalsUsed = actualParams-(formalParams-1);
131 ASSERT_ALWAYS( optionalsUsed>=0, "" );
133 if (optionalsUsed==0) {
134 /* if the optional parameter was not used, initialize it to an
137 shiftStackUp( ST_OLDFP(), 1 ); /* make room for the optional param */
138 stack[ ST_OLDFP() ] = (int)makeSchemeNil(); /* set it to () */
141 /* if the optional parameters were used, move them to a list
144 SchemeObject* opt; /* the list of optional params */
145 int lastOptional; /* last opt. param. (lowest index) */
146 int firstOptional; /* first opt. param. (highest index) */
149 /* copy optional params to a list on the heap */
150 opt = makeSchemeNil();
151 lastOptional = ST_OLDFP();
152 firstOptional = lastOptional + (optionalsUsed-1);
154 for (i=lastOptional; i<=firstOptional; ++i) {
155 opt = makeSchemePair( (SchemeObject*)(stack[i]), opt );
158 /* override all but one optional */
159 shiftStackDown( firstOptional, optionalsUsed-1 );
161 /* the last parameter is a pointer to the new list */
162 stack[ ST_OLDFP() ] = (int)opt;
165 /* fix actual arguments number */
166 ST_ARG_COUNT() = formalParams;