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