
		LOAD		'Macros.dump'

		INCLUDE	'SS.equ'

		INCLUDE	'Driver.equ'
		INCLUDE	'Heap.aii.i'
		INCLUDE	'Eval.aii.i'

;-----------------------------------------------
;
;	Imported addresses
;
;-----------------------------------------------

		IMPORT	D_AlertBox
		IMPORT	D_BitMapChanged
		IMPORT	D_BitMapPtr
		IMPORT	D_SetCursor

		IMPORT	S_AddCellToRecalcList
		IMPORT	S_ColLab2Text
		IMPORT	S_CurHeap
		IMPORT	S_GetCellPtr
		IMPORT	S_InsertDependency
		IMPORT	S_RecalcMemError
		IMPORT	S_RemoveDependency
		IMPORT	S_SetCircularBits
		IMPORT	S_UpdatePriorities

;---------------------------------------------------------------------
;
;

S_FormulaData	PROC		EXPORT

		EXPORT	S_ErrorFormulaLength
		EXPORT	S_NAFormulaLength
		EXPORT	S_INFFormulaLength
		EXPORT	S_NegINFFormulaLength

		EXPORT	S_ErrorFormula
		EXPORT	S_NAFormula
		EXPORT	S_INFFormula
		EXPORT	S_NegINFFormula

S_ErrorFormulaLength	equ 	6
S_NAFormulaLength		equ 	6
S_INFFormulaLength		equ 	6
S_NegINFFormulaLength	equ 	8

S_ErrorFormula		DC.B	$4,0,$4,0,E_ERRORfToken,0
S_NAFormula		DC.B	$4,0,$4,0,E_NAfToken,0
S_INFFormula		DC.B	$4,0,$4,0,E_INFfToken,0
S_NegINFFormula	DC.B	$4,0,$4,0,E_NegToken,E_InfFToken,E_CalcToken,0

			ENDP

;----------------------------------------------------------------------
S_EvalFormula	PROC		EXPORT
			;Using	S_CurrentData
			;Using	S_ErrorData
			;Using	SANEequs
			;Using	D_GlobalData

			input	CellIndex:l
			local	CellPtr:l
			local	FormulaPtr:l,ValueStack:l
			local	TypeStack:l,CellFormat:w
			local	StrLen:l,StrPtr:l,Index:l,LookUpFlag:w
			local	Cell:l,ContentIndex:l,OldFormat:w,OldValue:l
			error	ErrFlag
			BEGIN

			stz		ErrFlag

	;	Set up calculation stacks	;

			MoveWord	#1,>D_BitMapChanged
			MoveLong	>D_BitMapPtr,ValueStack
			AddLong	#$7000,ValueStack,TypeStack

	;	Get formula	;

			H_GetBlockPtr	CellIndex,CellPtr

			MoveLong		[CellPtr]:#S_CellID,Cell

			H_GetBlockPtr	[CellPtr]:#S_CellContent,FormulaPtr

	;	Evaluate formula	;

			in		FormulaPtr:l,ValueStack:l,TypeStack:l
			in		Cell:l
			XCall	E_EvalExpr

			stx		LookUpFlag



	;	Save the old value	;

			MoveLong	[CellPtr]:#S_CellValue,OldValue

			MoveWord	[CellPtr]:#S_CellFormat,x
			and		#S_CellType
			sta		OldFormat

	;	Move final result and type into the cell	;

			txa
			and		#-1-S_CellTypeValue-S_CellError-S_CellInvalid
			MoveWord	a,CellFormat

			lda		[TypeStack]
			cmp		#E_NumType
			jeq		storeNum
			cmp		#E_StrType
			jeq		storeStr
			cmp		#E_EmptyType
;			jeq		storeEmpty				; store as 0
			jeq		storeStr					; store as null string
			cmp		#E_NAType
			beq		storeNA
;			bra		storeErr

storeErr
			lda		CellFormat
			ora		#S_CellInvalid+S_CellError+S_CellTypeValue
			brl		doneEval

storeNA
			lda		CellFormat
			ora		#S_CellInvalid+S_CellTypeValue
			brl		doneEval

;storeEmpty									; store as 0
;			PushLong	#ZeroValue
;			AddLong	CellPtr,#S_CellValue,s
;			Tool		FX2X,in=(:l,:l)
;			lda		CellFormat
;			ora		#S_CellTypeValue
;			brl		doneEval

storeNum
			Tool		FCLASSX,in=(ValueStack:l)
			FBSNAN	storeErr
			FBQNAN	storeErr
			PushLong	ValueStack
			AddLong	CellPtr,#S_CellValue,s
			Tool		FX2X,in=(:l,:l)
			lda		CellFormat
			ora		#S_CellTypeValue
			brl		doneEval

storeStr
			stz		StrLen+2
			MoveWord	[TypeStack]:#2,StrLen

			inc		StrLen					; allocate space for str + len

			H_NewBlock	StrLen,Index,StrPtr,err=ErrFlag
			bcc			contStoreStr

	;	Cant allocate enough memory to Save the result, so we'll
	;	pretend that we haven't calculated it and return error.

memError
			Call		D_SetCursor,in=(#ArrowCursor:w)
			Call		D_AlertBox,in=(#OKBox:w,#S_RecalcMemError:l),out=(a:w)

			Call		S_AddCellToRecalcList,in=(Cell:l)
			brl		Exit

contStoreStr
			H_GetBlockPtr	CellIndex,CellPtr

			MoveLong	Index,[CellPtr]:#S_CellValue

			dec		StrLen
			MoveWord	StrLen,[StrPtr]
			IncL		StrPtr

			Tool		_BlockMove,in=(ValueStack:l,StrPtr:l,StrLen:l)
			lda		CellFormat

doneEval
			MoveWord	a,[CellPtr]:#S_CellFormat

	;	If previous result was a string, free allocated space	;

			lda		OldFormat
			and		#S_CellTypeValue
			bne		disposed

			H_DisposeBlock	OldValue
disposed

			lda		LookUpFlag
			beq		Exit


	;	This is for the LookUp functions.	Circularity may come and
	;	go with evaluation.	(Dynamic Circularity!)

			MoveLong	[CellPtr]:#S_CellContent,ContentIndex

			Call		S_RemoveDependency,in=(Cell:l,ContentIndex:l)

			H_GetBlockPtr	ContentIndex,FormulaPtr

			Call		E_FixCellList,in=(TypeStack:l,FormulaPtr:l)

			in		Cell:l,ContentIndex:l
			XCall	S_InsertDependency,err=ErrFlag
			jcs		memError

			Call		S_SetCircularBits,in=(Cell:l)
			Call		S_UpdatePriorities,in=(Cell:l)

Exit
			RETURN
			ENDP

;---------------------------------------------------------------------------
; S_GetMinMax( first:l, last:l, which:w): loc:l
;
;	first and last are the endpoints of a range, which = 1 for MIN and 0 for MAX
;

S_GetMinMax	PROC		EXPORT
			;Using	D_GlobalData

			input	first:l,last:l,which:w
			output	loc:l
			local	TypeStack:l
			BEGIN	+b

			lda		which
			bne		DoMax

			lda		#E_MINfToken<<8
			bra		DoStore

DoMax		lda		#E_MAXfToken<<8

DoStore		sta		S_MMOp

			MoveLong	first,S_MM1st
			MoveLong	last,S_MMLast

			MoveWord	#1,>D_BitMapChanged
			AddLong	#$7000,>D_BitMapPtr,TypeStack

			in		#S_MinMax:l,>D_BitMapPtr:l,TypeStack:l,#$10001:l
			XCall	E_EvalExpr

			MoveLong	>D_BitMapPtr,loc
			RETURN

S_MinMax		DC.B		$E,0,$E,0,$8A
S_MM1st		DS.B 	4
			DC.B		$A
S_MMlast		DS.B 	3							;<- really 4, but...
S_MMOp		DS.B		2							;<- upper byte
			DC.B		E_RangeToken,4,0,E_EndFUNCToken,0

			ENDP
			END

