	.TITLE	SYMBOL
	.IDENT	"V1.0"
;
;   Author:	D. Mischler	14-JUN-87
;
;   This module contains the symbol table management routines.
;   Notice that symbols are linked in order of increasing value.
;

	.ASECT
;
;   Symbol table entry offset definitions.
;
	.=0
S.NEXT::.BLKW	1	; Link to next symbol (must be at offset 0).
S.NAME::.BLKW	2	; Symbol name (RAD50).
S.VALU::.BLKW	1	; Symbol value.
S.LEN::
	.PAGE
	.PSECT	CODE,I,RO
;
;   Subroutine to define a symbol.
;
;   On entry:	R0 must point to the symbol table head.
;		R1 must contain the symbol value.
;		R2 & R3 must contain the symbol name.
;
;   On exit:	R0 points to symbol entry. If an allocation
;		failure occurs then the carry will be set.
;		R2 & R3 are destroyed by this routine.
;
S$DEFN::
	MOV	R0,-(SP)	; Save symbol table head address.
	CALL	S$LNAM		; Is this a duplicate definition?
	BCC	10$		; Yes, redefine it.
	MOV	#S.LEN,R0	; Get symbol block length.
	CALL	U$RQCB		; Allocate a new symbol table entry, OK?
	BCS	60$		; No, allocation failure.
	MOV	R2,S.NAME(R0)	; Save symbol name.
	MOV	R3,S.NAME+2(R0)
	BR	30$		; Save value and link symbol into list.
;   Unlink symbol table entry from table.
10$:	MOV	SP,R2		; Point to symbol table head pointer.
20$:	MOV	(R2),R2		; Point to next symbol table entry.
	CMP	(R2),R0		; Found correct symbol yet?
	BNE	20$		; No, keep looking.
	MOV	(R0),(R2)	; Unlink symbol table entry.
;   Save value in symbol table entry and link into list.
30$:	MOV	R1,S.VALU(R0)	; Save symbol value.
	MOV	(SP)+,R2	; Pop symbol table head address.
40$:	MOV	(R2),R3		; Point to next symbol table entry, zero?
	BEQ	50$		; Yes, append entry to end of list.
	CMP	R1,S.VALU(R3)	; Does symbol entry belong ahead of this one?
	BLO	50$		; Yes, link it in.
	MOV	R3,R2		; Point to current entry.
	BR	40$		; Try next one.
;   Link symbol entry into table at current point.
50$:	MOV	R3,(R0)		; Set up link to next.
	MOV	R0,(R2)		; Link in symbol table entry.
	CLC			; Indicate success.
	RETURN
;   Allocation failure prevents symbol definition.
60$:	TST	(SP)+		; Clean up stack.
	SEC			; Indicate failure.
	RETURN
	.PAGE
;
;   Subroutine to look up a symbol by name.
;
;   On entry:	R0 must point to the symbol table head.
;		R2 & R3 must contain the symbol name.
;   On exit:	R0 points to desired entry, or carry set if no entry.
;
S$LNAM::
	MOV	(R0),R0		; Point to next symbol entry, zero?
	BEQ	10$		; Yes, forget about it.
	CMP	S.NAME(R0),R2	; Is first name word OK?
	BNE	S$LNAM		; No, try next entry.
	CMP	S.NAME+2(R0),R3	; Is second name word OK?
	BNE	S$LNAM		; No, try next entry.
	CLC			; Indicate success.
	RETURN
;   Here if an appropriate symbol cannot be found.
10$:	SEC			; Indicate failure.
	RETURN

;
;   Subroutine to look up a symbol by value. The highest value
;   lower than or equal to R1 will be accepted.
;
;   On entry:	R0 must point to the symbol table head.
;   On exit:	R0 points to desired entry, or carry set if no entry.
;
S$LVAL::
	MOV	R2,-(SP)	; Save R2.
	CLR	R2		; Indicate no legal value has been found.
	BR	20$		; Point to first symbol entry.
;   Loop to find appropriate symbol.
10$:	MOV	R0,R2		; Save symbol entry pointer.
20$:	MOV	(R0),R0		; Point to next symbol entry, zero?
	BEQ	30$		; Yes, terminate search.
	CMP	S.VALU(R0),R1	; Is this value acceptable?
	BLOS	10$		; Yes, drop a pointer to it.
;   Here when search is terminated.
30$:	MOV	R2,R0		; Get resulting symbol pointer.
	MOV	(SP)+,R2	; Recover saved R2.
	TST	R0		; Was an appropriate symbol found?
	BNE	40$		; Yes, indicate success.
	SEC			; Indicate failure.
40$:	RETURN
	.END
