/* 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