DataMuseum.dk

Presents historical artifacts from the history of:

CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦1338f0d3d⟧ TextFile

    Length: 8832 (0x2280)
    Types: TextFile
    Names: »MC-MOD04.INC«

Derivation

└─⟦d482c3728⟧ Bits:30005987 Turbo Pascal v2.00A (Jet80)
    └─ ⟦this⟧ »MC-MOD04.INC« 

TextFile

æ.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»