diff options
author | Joe Hunkeler <jhunkeler@gmail.com> | 2015-08-11 16:51:37 -0400 |
---|---|---|
committer | Joe Hunkeler <jhunkeler@gmail.com> | 2015-08-11 16:51:37 -0400 |
commit | 40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch) | |
tree | 4464880c571602d54f6ae114729bf62a89518057 /pkg/utilities/nttools/stxtools/vexstack.x | |
download | iraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz |
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'pkg/utilities/nttools/stxtools/vexstack.x')
-rw-r--r-- | pkg/utilities/nttools/stxtools/vexstack.x | 585 |
1 files changed, 585 insertions, 0 deletions
diff --git a/pkg/utilities/nttools/stxtools/vexstack.x b/pkg/utilities/nttools/stxtools/vexstack.x new file mode 100644 index 00000000..8f51b2bb --- /dev/null +++ b/pkg/utilities/nttools/stxtools/vexstack.x @@ -0,0 +1,585 @@ +include "vex.h" + +# VEX_STACK -- Procedures which manipulate the vex stack +# +# The expression evaluator, vex_eval, uses a stack to hold intermediate +# results, constants, and variable names in the expression. There are +# actually two stacks, a type stack wich contains the data types of the +# elements on the stack, and a value stack, which contains pointers to +# the stack elements. Constants and variable names are stored in two +# buffers which are part of the stack structure and pointers to their +# locations are placed on the stack. Intermediate results are stored in +# malloc'ed arrays and their pointers are also placed on the stack. The +# stack structure contains three indices, bottom, an index one greater +# than the last constant or variable name, top, an index that is one +# greater than the current top of stack, and high, an index that is one +# greater than the last valid pointer on the stack. Valid pointers exist +# beyond the top of stack because the arrays which store intermediate +# results are not mfree'd when the stack is popped, instead, they are +# kept in case they may be needed for a future intermediate result. The +# only user callable procedure in this file is stk_alloc, which should +# be called by getvar, the user's function which fills an array when +# passed the name of a variable. +# +# B.Simon 24-Apr-91 Original +# B.Simon 15-Oct-98 Store strings in pseudocode, not on stack + +# STK_ALLOC -- Allocate an array of the specified length and type + +pointer procedure stk_alloc (stack, len, type) + +pointer stack # i: Stack structure +int len # i: Length of array to allocate +int type # i: Data type of array (spp type) +#-- +int index, stype, top +pointer var, svar + +string badstack "stk_alloc: illegal type on stack" +string badsize "Requested array size does not match previous requests" + +errchk stk_find + +begin + # Check to see if array length is being defined for the first time + + if (STK_LENVAL(stack) == 0 && len != 0) { + + # Store length in stack structure + + STK_LENVAL(stack) = len + + # Free all stack arrays not currently being used + + index = STK_TOP(stack) + while (index < STK_HIGH(stack)) { + svar = STK_VALUE(stack,index) + stype = STK_TYPE(stack,index) + call mfree (svar, stype) + index = index + 1 + } + STK_HIGH(stack) = STK_TOP(stack) + + # Reallocate the null buffer + + if (STK_NULLARY(stack) != NULL) { + call stk_freenull (stack) + call stk_initnull (stack, true) + } + + # Convert length one arrays to their full length + + index = 0 + while (index < STK_TOP(stack)) { + svar = STK_VALUE(stack,index) + stype = STK_TYPE(stack,index) + + call malloc (var, len, stype) + STK_VALUE(stack,index) = var + switch (stype) { + case TY_INT,TY_LONG: + call amovki (Memi[svar], Memi[var], len) + call mfree (svar, TY_INT) + case TY_REAL: + call amovkr (Memr[svar], Memr[var], len) + call mfree (svar, TY_REAL) + case TY_DOUBLE: + call amovkd (Memd[svar], Memd[var], len) + call mfree (svar, TY_DOUBLE) + default: + call error (1, badstack) + } + index = index + 1 + } + } + + # Check requested size + + if (len != 0 && len != STK_LENVAL(stack)) + call error (1, badsize) + + # Look for an existing array of the same type + + call stk_find (stack, type, index) + + # Increment top of stack pointer + + top = STK_TOP(stack) + STK_TOP(stack) = top + 1 + + # Swap array with one currently at top of stack + + if (top != index) { + stype = STK_TYPE(stack,top) + STK_TYPE(stack,top) = STK_TYPE(stack,index) + STK_TYPE(stack,index) = stype + + svar = STK_VALUE(stack,top) + STK_VALUE(stack,top) = STK_VALUE(stack,index) + STK_VALUE(stack,index) = svar + } + + var = STK_VALUE(stack,top) + return (var) +end + +# STK_CLEAR -- Clear all stack elements above the bottom + +procedure stk_clear (stack) + +pointer stack # u: Stack pointer +#-- +int index + +begin + # Free all value arrays above the bottom of stack + + index = 0 + while (index < STK_HIGH(stack)) { + call mfree (STK_VALUE(stack,index), STK_TYPE(stack,index)) + index = index + 1 + } + + # Free null array + + call stk_freenull (stack) + + # Reset scalars + + STK_TOP(stack) = 0 + STK_HIGH(stack) = 0 + STK_LENVAL(stack) = 0 +end + +# STK_COERCE -- Coerce an array in the stack to the specified type + +procedure stk_coerce (stack, pos, type, var) + +pointer stack # i: Stack descriptor +int pos # i: Position of array in stack +int type # i: New type for array +pointer var # o: New pointer to array +#-- +int index, last, stype, len, i +pointer svar + +string underflow "stk_coerce: underflow in expression evaluator" + +errchk stk_find + +begin + # Convert relative to absolute position + + if (pos == TOP) { + index = STK_TOP(stack) - 1 + if (index < 0) + call error (1, underflow) + } else { + index = pos + } + + # If type of array matches requested type, return pointer to array + # Otherwise, get new array and copy old array to it + + if (type == STK_TYPE(stack,index)) { + var = STK_VALUE(stack,index) + + } else { + # Find array of correct type + + last = index + call stk_find (stack, type, index) + + # Copy array, converting to new type + + len = max (1, STK_LENVAL(stack)) + var = STK_VALUE(stack,index) + + stype = STK_TYPE(stack,last) + svar = STK_VALUE(stack,last) + + switch (type) { + case TY_INT,TY_LONG: + switch (stype) { + case TY_INT,TY_LONG: + ; # can't happen + case TY_REAL: + do i = 0, len-1 { + if (IS_INDEFR(Memr[svar+i])) { + Memi[var+i] = INDEFI + } else { + Memi[var+i] = Memr[svar+i] + } + } + case TY_DOUBLE: + do i = 0, len-1 { + if (IS_INDEFD(Memd[svar+i])) { + Memi[var+i] = INDEFI + } else { + Memi[var+i] = Memd[svar+i] + } + } + } + case TY_REAL: + switch (stype) { + case TY_INT,TY_LONG: + do i = 0, len-1 { + if (IS_INDEFI(Memi[svar+i])) { + Memr[var+i] = INDEFR + } else { + Memr[var+i] = Memi[svar+i] + } + } + case TY_REAL: + ; # can't happen + case TY_DOUBLE: + do i = 0, len-1 { + if (IS_INDEFD(Memd[svar+i])) { + Memr[var+i] = INDEFR + } else { + Memr[var+i] = Memd[svar+i] + } + } + } + case TY_DOUBLE: + switch (stype) { + case TY_INT,TY_LONG: + do i = 0, len-1 { + if (IS_INDEFI(Memi[svar+i])) { + Memd[var+i] = INDEFD + } else { + Memd[var+i] = Memi[svar+i] + } + } + case TY_REAL: + do i = 0, len-1 { + if (IS_INDEFR(Memr[svar+i])) { + Memd[var+i] = INDEFD + } else { + Memd[var+i] = Memr[svar+i] + } + } + case TY_DOUBLE: + ; # can't happen + } + } + + # Swap position of new and old arrays on stack + + STK_TYPE(stack,last) = STK_TYPE(stack,index) + STK_TYPE(stack,index) = stype + + STK_VALUE(stack,last) = STK_VALUE(stack,index) + STK_VALUE(stack,index) = svar + } + +end + +# STK_FETCH -- Fetch the specified number of arrays from the stack + +procedure stk_fetch (stack, nvar, var, len, type) + +pointer stack # i: Stack descriptor +int nvar # i: Number of pointers requested +pointer var[ARB] # o: Array pointers +int len # o: Length of arrays +int type # o: Type of arrays +#-- +int one, two, index, ivar + +string underflow "stk_fetch: underflow in expression evaluator" + +errchk stk_coerce + +begin + # If length is not yet defined, STK_LENVAL equals zero + + len = STK_LENVAL(stack) + + # Find the highest type in the pointers to be returned + + one = STK_TOP(stack) - 1 + two = STK_TOP(stack) - 2 + + type = STK_TYPE(stack,one) + if (nvar > 1) { + switch (STK_TYPE(stack,two)) { + case TY_INT, TY_LONG: + ; + case TY_REAL: + if (type == TY_INT) + type = TY_REAL + case TY_DOUBLE: + type = TY_DOUBLE + } + } + + # Retrieve pointers to arrays from stack. var[nvar] is top of stack + # Convert arrays to output type when the type differs + + index = STK_TOP(stack) - nvar + do ivar = 1, nvar { + if (index < 0) + call error (1, underflow) + + if (type == STK_TYPE(stack,index) || index < two) { + var[ivar] = STK_VALUE(stack,index) + } else { + call stk_coerce (stack, index, type, var[ivar]) + } + index = index + 1 + } + +end + +# STK_FIND -- Find a free array of the proper type on the stack + +procedure stk_find (stack, type, index) + +pointer stack # i: Stack descriptor +int type # i: Required type +int index # o: Position on the stack +#-- +int len +pointer var + +string overflow "Expression too complex to be evaluated" + +begin + # Try to find an array of the proper type already on the stack + + index = STK_TOP(stack) + while (index < STK_HIGH(stack)) { + if (type == STK_TYPE(stack,index)) + break + + index = index + 1 + } + + # If not found, allocate a new array + + if (index == MAX_STACK) { + call error (1, overflow) + + } else if (index == STK_HIGH(stack)) { + len = max (1, STK_LENVAL(stack)) + call malloc (var, len, type) + + STK_TYPE(stack,index) = type + STK_VALUE(stack,index) = var + STK_HIGH(stack) = STK_HIGH(stack) + 1 + } + +end + +# STK_FREE -- Free memory used by the stack + +procedure stk_free (stack) + +pointer stack # u: Stack pointer +#-- + +begin + # Free all values above the stack bottom + + call stk_clear (stack) + + # Free substructures in stack + + if (STK_NULLARY(stack) != NULL) + call mfree (STK_NULLARY(stack), TY_BOOL) + + call mfree (STK_VALARY(stack), TY_INT) + call mfree (STK_TYPARY(stack), TY_INT) + + # Free the stack structure + call mfree (stack, TY_INT) +end + +# STK_FREENULL -- Free the null array in the stack + +procedure stk_freenull (stack) + +pointer stack # u: Stack structure +#-- + +begin + if (STK_NULLARY(stack) != NULL) + call mfree (STK_NULLARY(stack), TY_BOOL) + + STK_NULLARY(stack) = NULL +end + +# STK_GET -- Get a single array from the stack + +procedure stk_get (stack, pos, var, len, type) + +pointer stack # i: Stack descriptor +int pos # i: Position on the stack +pointer var # o: Pointer to array +int len # o: Length of array +int type # o: Type of the array +#-- +int index + +string underflow "stk_get: underflow in expression evaluator" + +begin + # Convert relative to absolute position + + if (pos == TOP) { + index = STK_TOP(stack) - 1 + if (index < 0) + call error (1, underflow) + } else { + index = pos + } + + var = STK_VALUE(stack,index) + len = STK_LENVAL(stack) + type = STK_TYPE(stack,index) +end + +# STK_GETNULL -- Get the null array from the stack + +procedure stk_getnull (stack, nullvec) + +pointer stack # i: Stack structure +pointer nullvec # o: Null array +#-- + +begin + nullvec = STK_NULLARY(stack) +end + +# STK_INIT -- Initialize the stack + +procedure stk_init (stack) + +pointer stack # o: Stack pointer +#-- + +begin + # Allocate stack and initialize members to zero + + call calloc (stack, SZ_STKSTRUCT, TY_INT) + + # Allocate substructures in stack + + call malloc (STK_VALARY(stack), MAX_STACK, TY_INT) + call malloc (STK_TYPARY(stack), MAX_STACK, TY_INT) + +end + +# STK_INITNULL -- Initialize the null array on the stack + +procedure stk_initnull (stack, value) + +pointer stack # u: Stack structure +bool value # i: Value used in initialization +#-- +int len, i +pointer nullvec + +begin + # Only initialize if array doesn't exist + + if (STK_NULLARY(stack) == NULL) { + len = STK_LENVAL(stack) + + # Allocate array + call malloc (nullvec, len, TY_BOOL) + STK_NULLARY(stack) = nullvec + + # Initialize to value + do i = 0, len-1 + Memb[nullvec+i] = value + } + +end + +# STK_ORNULL -- Update null array by doing a logical or + +procedure stk_ornull (stack, newvec, newlen) + +pointer stack # u: Stack structure +bool newvec[ARB] # i: Array of new values +int newlen # i: Length of new array +#-- +int len, i +pointer nullvec + +string badlength "stk_ornull: length of array does not match null array" + +begin + len = STK_LENVAL(stack) + if (len != newlen) + call error (1, badlength) + + call stk_initnull (stack, false) + nullvec = STK_NULLARY(stack) + + do i = 1, len { + Memb[nullvec] = Memb[nullvec] || newvec[i] + nullvec = nullvec + 1 + } + +end + +# STK_POP -- Remove the specified number of arrays from the stack + +procedure stk_pop (stack, npop) + +pointer stack # u: Stack structure +int npop # i: Number of arrays to pop +#-- +int top, index, type +pointer var + +string underflow "stk_pop: underflow in expression evaluator" + +begin + + top = STK_TOP(stack) - 1 + index = top - npop + + if (index < 0) { + call error (1, underflow) + } else { + STK_TOP(stack) = index + 1 + } + + var = STK_VALUE(stack,index) + STK_VALUE(stack,index) = STK_VALUE(stack,top) + STK_VALUE(stack,top) = var + + type = STK_TYPE(stack,index) + STK_TYPE(stack,index) = STK_TYPE(stack,top) + STK_TYPE(stack,top) = type + +end + +# STK_POS -- Compute absolute position on stack + +int procedure stk_pos (stack, pos) + +pointer stack # i: Stack structure +int pos # i: Position relative to top of stack +#-- + +begin + return (STK_TOP(stack) - pos) +end + +# STK_SETNULL -- Set a single value in the null array to true + +procedure stk_setnull (stack, index) + +pointer stack # u: Stack structure +int index # i: Index into null array +#-- + +begin + STK_NULL(stack,index) = true +end + |