Metropoli BBS
VIEWER: tree.h MODE: TEXT (ASCII)
/* 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
[ RETURN TO DIRECTORY ]