Hi Lionel,
thank you for your answer.
Does it allocate the array on estack as list?
And how does the prototype for get_matrix_indices look like?
How does it behave when count >0 but < lenght of list is passed?
> get_list_indices allocates the indices array on the EStack; you have to
> clean up afterwards.
>
>
Have written my own function
/* get list of expressions
content is written to output (size of array is adjusted automatically)
returns number of elements */
unsigned short GetExpressionListArg(EStackIndex ptr,
volatile HANDLE *output) //
{
Access_AMS_Global_Variables;
// pointer to simplified list
EStackIndex topPtr;
// number of elements in list
unsigned short i = 0;
// array for elements of list
EStackIndex *array;
// expand variable name to list if necessary
push_simplify_statements (ptr);
// do not manipulate top_estack directly
topPtr = top_estack;
// wrong argument type
if (ESTACK (topPtr) != LIST_TAG) {
ER_throwVar (ER_ARGUMENT_MUST_BE_LIST);
}
// move index to first element of list
// (without decrement we start at END_TAG and are not looping)
topPtr--;
// just in case the caller has not initialized the handle
// (otherwise we will get an address error when trying to
reallocate an invalid handle)
*output = H_NULL;
// while not at end of list
while (ESTACK (topPtr) != END_TAG) {
// allocate space for additional list element
*output = HeapReallocThrow(*output, (i + 1) * sizeof
(EStackIndex));
array = HeapDeref (*output);
// store pointer to current list element in array
array[i++] = topPtr;
// so me must advance the pointer to next element explicitly
topPtr = next_expression_index (topPtr);
}
// delete simplified copy of list
delete_expression (top_estack);
// return length of list
return i;
}
Also have written function for pushing array of pointers to expression
to estack
/* push array of expressions to estack creating list */
void push_expression_list(EStackIndex input[],
short length) // ok
{
// end of list
push_quantum (END_TAG);
// loop over float array
while (--length >= 0) {
push_expression (input[length]);
}
// beginning of list
push_quantum (LIST_TAG);
}
Both seem to work.
Have tried to program some wrapper to make the interface of the
sorta/sortd commands more useable. At the moment they only accept name
of var as arg. I want them to also work when passing list as constant
(or passing func call returning list). So i tried to use VarStore to
store the constant list to variable before. That didnt work - i got the
message that VarStore is not allowed in basic extension function (it may
be allowed in basic extension program).
So i tried using code for quicksort instead of builtin sorta/sortd
static void Swap(EStackIndex v[],
int i,
int j)
{
EStackIndex temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
/* qsort: sort v[left]...v[right] into increasing order
Kernighan & Ritchie: The C programming language */
void QSort(EStackIndex v[],
short left,
short right)
{
short i, last;
// do nothing if array contains
if (left >= right) {
// fewer than two elements
return;
}
// move partition elem
Swap (v, left, (left + right) / 2);
// to v[0]
last = left;
// partition
for (i = left + 1; i <= right; i++) {
if (compare_expressions (v[i], v[left]) < 0) {
Swap (v, ++last, i);
}
}
// restore partition elem
Swap (v, left, last);
QSort (v, left, last - 1);
QSort (v, last + 1, right);
}
This doesnt work. When i pass {2,1} i get {2,2} as result.
Strangely it works when i force the list to be all float and use
comparison operator instead of compare_expressions.
Here is the function im using to call QSort
void zzz(void)
{
Access_AMS_Global_Variables;
volatile HANDLE hdl;
EStackIndex *ptr;
//double *ptr;
unsigned short length;
CheckNumArgs (1);
TRY
length = GetExpressionListArg (top_estack, &hdl);
//length = GetFloatListArg (top_estack, &hdl);
ptr = HeapDeref (hdl);
QSort (ptr, 0, length - 1);
push_expression_list (ptr, length);
//push_float_list (ptr, length);
FINALLY
HeapFreeIndir ((HANDLE *)&hdl);
ENDFINAL
}
Regards
Ralph