|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 8832 (0x2280)
Types: TextFile
Names: »MC-MOD04.INC«
└─⟦d482c3728⟧ Bits:30005987 Turbo Pascal v2.00A (Jet80)
└─⟦this⟧ »MC-MOD04.INC«
æ.PAå
æ*******************************************************************å
æ* SOURCE CODE MODULE: MC-MOD04 *å
æ* PURPOSE: Evaluate formulas. *å
æ* Recalculate spread sheet. *å
æ* *å
æ* NOTE: This module contains recursive procedures *å
æ* and is for computer scientists only. *å
æ*******************************************************************å
var
Form: Boolean;
æ$A-å
procedure Evaluate(var IsFormula: Boolean; æ True if formulaå
var Formula: AnyString; æ Fomula to evaluateå
var Value: Real; æ Result of formula å
var ErrPos: Integer);æ Position of error å
const
Numbers: set of Char = Æ'0'..'9'Å;
EofLine = ^M;
var
Pos: Integer; æ Current position in formula å
Ch: Char; æ Current character being scanned å
EXY: stringÆ3Å; æ Intermidiate string for conversion å
æ Procedure NextCh returns the next character in the formula å
æ The variable Pos contains the position ann Ch the character å
procedure NextCh;
begin
repeat
Pos:=Pos+1;
if Pos<=Length(Formula) then
Ch:=FormulaÆPosÅ else Ch:=eofline;
until Ch<>' ';
end æ NextCh å;
function Expression: Real;
var
E: Real;
Opr: Char;
function SimpleExpression: Real;
var
S: Real;
Opr: Char;
function Term: Real;
var
T: Real;
function SignedFactor: Real;
function Factor: Real;
type
StandardFunction = (fabs,fsqrt,fsqr,fsin,fcos,
farctan,fln,flog,fexp,ffact);
StandardFunctionList = arrayÆStandardFunctionÅ of stringÆ6Å;
const
StandardFunctionNames: StandardFunctionList =('ABS','SQRT','SQR','SIN','COS',
'ARCTAN','LN','LOG','EXP','FACT');
var
E,EE,L: Integer; æ intermidiate variables å
Found:Boolean;
F: Real;
Sf:StandardFunction;
OldEFY, æ Current cell å
EFY,
SumFY,
Start:Integer;
OldEFX,
EFX,
SumFX:ScreenIndex;
CellSum: Real;
function Fact(I: Integer): Real;
begin
if I > 0 then begin Fact:=I*Fact(I-1); end
else Fact:=1;
end æ Fact å;
æ.PAå
begin æ Function Factor å
if Ch in Numbers then
begin
Start:=Pos;
repeat NextCh until not (Ch in Numbers);
if Ch='.' then repeat NextCh until not (Ch in Numbers);
if Ch='E' then
begin
NextCh;
repeat NextCh until not (Ch in Numbers);
end;
Val(Copy(Formula,Start,Pos-Start),F,ErrPos);
end else
if Ch='(' then
begin
NextCh;
F:=Expression;
if Ch=')' then NextCh else ErrPos:=Pos;
end else
if Ch in Æ'A'..'G'Å then æ Maybe a cell reference å
begin
EFX:=Ch;
NextCh;
if Ch in Numbers then
begin
F:=0;
EXY:=Ch; NextCh;
if Ch in Numbers then
begin
EXY:=EXY+Ch;
NextCh;
end;
Val(EXY,EFY,ErrPos);
IsFormula:=true;
if (Constant in ScreenÆEFX,EFYÅ.CellStatus) and
not (Calculated in ScreenÆEFX,EFYÅ.CellStatus) then
begin
Evaluate(Form,screenÆEFX,EFYÅ.contents,f,ErrPos);
ScreenÆEFX,EFYÅ.CellStatus:=ScreenÆEFX,EFYÅ.CellStatus+ÆCalculatedÅ
end else if not (Txt in ScreenÆEFX,EFYÅ.CellStatus) then
F:=ScreenÆEFX,EFYÅ.Value;
if Ch='>' then
begin
OldEFX:=EFX; OldEFY:=EFY;
NextCh;
EFX:=Ch;
NextCh;
if Ch in Numbers then
begin
EXY:=Ch;
NextCh;
if Ch in Numbers then
begin
EXY:=EXY+Ch;
NextCh;
end;
val(EXY,EFY,ErrPos);
Cellsum:=0;
for SumFY:=OldEFY to EFY do
begin
for SumFX:=OldEFX to EFX do
begin
F:=0;
if (Constant in ScreenÆSumFX,SumFYÅ.CellStatus) and
not (Calculated in ScreenÆSumFX,SumFYÅ.CellStatus) then
begin
Evaluate(Form,ScreenÆSumFX,SumFYÅ.contents,f,errPos);
ScreenÆSumFX,SumFYÅ.CellStatus:=
ScreenÆSumFX,SumFYÅ.CellStatus+ÆCalculatedÅ;
end else if not (Txt in ScreenÆSumFX,SumFYÅ.CellStatus) then
F:=ScrEEnÆSumFX,SumFYÅ.Value;
Cellsum:=Cellsum+f;
f:=Cellsum;
end;
end;
end;
end;
end;
end else
begin
found:=false;
for sf:=fabs to ffact do
if not found then
begin
l:=Length(StandardFunctionNamesÆsfÅ);
if copy(Formula,Pos,l)=StandardFunctionNamesÆsfÅ then
begin
Pos:=Pos+l-1; NextCh;
F:=Factor;
case sf of
fabs: f:=abs(f);
fsqrt: f:=sqrt(f);
fsqr: f:=sqr(f);
fsin: f:=sin(f);
fcos: f:=cos(f);
farctan: f:=arctan(f);
fln : f:=ln(f);
flog: f:=ln(f)/ln(10);
fexp: f:=exp(f);
ffact: f:=fact(trunc(f));
end;
Found:=true;
end;
end;
if not Found then ErrPos:=Pos;
end;
Factor:=F;
end æ function Factorå;
æ.PAå
begin æ SignedFactor å
if Ch='-' then
begin
NextCh; SignedFactor:=-Factor;
end else SignedFactor:=Factor;
end æ SignedFactor å;
begin æ Term å
T:=SignedFactor;
while Ch='^' do
begin
NextCh; t:=exp(ln(t)*SignedFactor);
end;
Term:=t;
end æ Term å;
begin æ SimpleExpression å
s:=term;
while Ch in Æ'*','/'Å do
begin
Opr:=Ch; NextCh;
case Opr of
'*': s:=s*term;
'/': s:=s/term;
end;
end;
SimpleExpression:=s;
end æ SimpleExpression å;
begin æ Expression å
E:=SimpleExpression;
while Ch in Æ'+','-'Å do
begin
Opr:=Ch; NextCh;
case Opr of
'+': e:=e+SimpleExpression;
'-': e:=e-SimpleExpression;
end;
end;
Expression:=E;
end æ Expression å;
begin æ procedure Evaluate å
if FormulaÆ1Å='.' then Formula:='0'+Formula;
if FormulaÆ1Å='+' then delete(Formula,1,1);
IsFormula:=false;
Pos:=0; NextCh;
Value:=Expression;
if Ch=EofLine then ErrPos:=0 else ErrPos:=Pos;
end æ Evaluate å;
æ.PAå
procedure Recalculate;
var
RFX: ScreenIndex;
RFY:integer;
OldValue: real;
Err: integer;
begin
LowVideo;
GotoXY(1,24); ClrEol;
Write('Calculating..');
for RFY:=1 to FYMax do
begin
for RFX:='A' to FXMax do
begin
with ScreenÆRFX,RFYÅ do
begin
if (Formula in CellStatus) then
begin
CellStatus:=CellStatus+ÆCalculatedÅ;
OldValue:=Value;
Evaluate(Form,Contents,Value,Err);
if OldValue<>Value then
begin
GotoXY(XPosÆRFXÅ,RFY+1);
if (DEC>=0) then Write(Value:FW:DEC)
else Write(Value:FW);
end;
end;
end;
end;
end;
GotoCell(FX,FY);
end;
«eof»