/* Copyright 1993, 1994 by Thomas Glen Smith. All rights reserved. */
/* tree.h APL2 V1.0.0 **************************************************
* Included text to define structures in building AVL-balanced trees. *
***********************************************************************/
#if !defined(TREE_INCL)
#define TREE_INCL
#define SUSPNDED 1 /* 1=suspended, 0=pendent */
#define NOT_WHOLE_ARRAY 2 /* see explanation below */
#define SELSPEC 4 /* Selective specification operation is taking
place. All references to variable names
are resolved to arrays of indices.
See routines ? */
typedef struct treelist *Treelist;
typedef struct avlnode *Avlnode;
typedef struct execstk *Execstk;
struct treelist {
Treelist treenext; /* next treelist element */
Avlnode avlhdr; /* AVL-balanced tree */
Aplfunc avlfun; /* Suspended function */
char *avlfname; /* Suspended function name */
int avlstmt; /* Suspended stmt */
int indxsave; /* 1 if indxorg localized */
int indxhold; /* Old indxorg to restore */
int fuzzsave; /* 1 if fuzz localized */
double fuzzhold; /* Old fuzz to restore */
Execstk avlexec; /* Execution stack */
Apltoken avltokhd; /* Input token stack */
int lastfun; /* 1=last was assignment */
/* 2=last user defined func. */
/* Notes on lastfun:
-> Compute pushes a new treelist element on the avlhdr stack, calls
executf to process an APL statement, saves lastfun before
popping the treelist element, and assigns the saved value to
lastfun in the new top-of-stack.
-> Execalt calls executg to execute an APL statement, then tests
for a NULL return value, indicating a niladic defined function,
and sets lastfun to 2 in top-of-stack if so.
-> Execdyan, which is called to do dyadic functions, sets lastfun to
2 in top-of-stack if it's a user defined function.
-> Execexec pushes a new element on execstk, initializes treehdr->
lastfun to 0, then calls execexed to process an APL expression.
-> Execexed, before processing each function/operator token, if it's
not BASE-NULL (compute), sets treehdr->lastfun to its token_code
before calling execspec to do monadics and assignment.
-> Execexeg saves treehdr->lastfun before processing bracketed
and parenthesized expressions. Then it restores the saved value
to treehdr->lastfun.
-> Execexeh tests treehdr->lastfun for 2, and if so, resets it to 0.
-> Execnext passes the value of treehdr->lastfun, saved before calling
execexee to get the next operand, to execnexs, who tests it for
LEFT_ARROW, and if so creates a list of names to its left in the
expression being evaluated.
-> Execspec sets treehdr->lastfun to LEFT_ARROW after handling
selective assignment.
-> Execspex saves treehdr->lastfun, sets it to 0, then processes
a selective specification, and restores the saved value.
-> Execute initializes treehdr->lastfun to 0, calls executf to
process and APL expression, then tests treehdr->lastfun, and calls
quadout to print the result if the last thing done was not LEFT_ARROW.
-> Funcexee initializes treehdr->lastfun to 0.
-> Funcexef calls quadout if the last thing done in the most recently
executed APL statement was not LEFT_ARROW.
-> Functrac calls quadout if the last thing done in the most recently
executed APL statement was not LEFT_ARROW.
-> Slashtra initializes treehdr->lastfun to 0.
-> Treeroot initializes lastfun to 0 in the new treelist element.
*/
int avloff; /* offset in stmt where error */
int treeflag; /* 1 = suspended (SUSPNDED) */
/* Notes on SUSPNDED:
-> Referenced in APLSI, FUNCEXEF, FUNCSUSP, and FUNCSUSQ.
-> APLSI, which displays the state indicator stack, displays a star (*)
next to any suspended function (treeflag == SUSPNDED) in the stack.
-> FUNCEXEF, if aplerr == 997, indicating the state indicator stack is
to be cleared to the next most recently suspended function, tests for
treeflag & SUSPNDED to determine if it's found the next most recently
suspended function.
-> FUNCSUSP turns on SUSPNDED if, at initial entry, treehdr->avlfun is not
NULL, which means it's being called to handle terminal interaction until
the user enters a right arrow to resume execution of the function being
suspended. The SUSPNDED flag is turned off by FUNCSUSP and it exits
under any one of three conditions:
1) aplerr == 998, indicating EOF or )off.
2) aplerr == 997, indicating the state stack is being cleared
up to the most recently suspended function.
3) FUNCSUSQ returns a 0, indicating the current function is
finished.
-> FUNCSUSQ, if the current statement is a right arrow, turns off
SUSPNDED in the current treeflag. If the current function is suspended,
it means the terminal user no longer wants it to be. He either wants
the state indicator stack cleared to the next most recently suspended
function, if the right arrow stands alone, or he wants execution of the
suspended function to resume at the specified statement, if the right
arrow doesn't stand alone.
If the arrow stands alone, FUNCSUSQ also sets aplerr to 997 to indicate
the state indicator is to be cleared to the next most recently
suspended function.
*/
/* 2 = NOT_WHOLE_ARRAY */
/* Notes on NOT_WHOLE_ARRAY:
-> Set on in execdyad if the current operation is assignment.
-> Set on in execmonh if the current operation is not UP_ARROW.
-> Referenced in execspeg, and indirectly in execspef, as follows:
Execspef is called by execspez, passing an argument (nwa),
which is set in execspeg to (treeflag & NOT_WHOLE_ARRAY). Execspef
sets the fifth argument passed to execspeh to 1 if nwa is zero, and
to indices->aplcount otherwise. Execspeh expects the fifth
argument to be the count of indices in a selective specification
operation. If the count is greater than 1 and matches the count of
items in rite, the variable from which elements are assigned,
then the individual items of rite are assigned to individual items
of left. Otherwise, rite itself is assigned as an element in left,
which is converted to type APLAPL if necessary.
*/
};
struct avlnode {
Avlnode left_child; /* left child pointer */
Avlnode rite_child; /* right child pointer */
void *avlleaf; /* value pointer - may be NULL */
int avlbf; /* avl balance factor */
char *avlname; /* name of node */
};
struct execstk {
Execstk execnxt; /* next on stack */
Apltoken avlfunst; /* operator stack */
Apltoken avloprst; /* operand stack */
};
#endif