home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 229.lha / Calc_v1.01 / sources / CalcBrains.mod < prev    next >
Text File  |  1989-04-04  |  4KB  |  197 lines

  1. IMPLEMENTATION MODULE CalcBrains;
  2.  
  3.  
  4. FROM SYSTEM      IMPORT TERMPROC;
  5. FROM Stacks      IMPORT CreateStack, DisposeStack, PushB, PopB, PushL, PopL,
  6.                          ClearStack, Stack;
  7. FROM CalcGadgets  IMPORT resetValue;
  8. FROM CalcValidate IMPORT Addition, Subtraction, Multiplication, Division,
  9.                          errorString;
  10. FROM CalcDisplay  IMPORT DoLCDStr;
  11.  
  12.  
  13. TYPE
  14.   OpSet = SET OF OpType;
  15.  
  16.  
  17. CONST
  18.   HiPriorityOps = OpSet{OpTimes,OpDivide,OpAnd,OpOr,OpXor};
  19.  
  20.  
  21. VAR
  22.   opStack   : Stack;
  23.   numStack  : Stack;
  24.   openCount : CARDINAL;
  25.  
  26.  
  27. (*$L+*)
  28. PROCEDURE PushOp(op:OpType);
  29. BEGIN
  30.   PushB(opStack,op);
  31. END PushOp;
  32.  
  33.  
  34. PROCEDURE PopOp(): OpType;
  35. BEGIN
  36.   RETURN OpType(PopB(opStack));
  37. END PopOp;
  38.  
  39.  
  40. PROCEDURE PushNum(num:LONGCARD);
  41. BEGIN
  42.   PushL(numStack,num);
  43. END PushNum;
  44.  
  45.  
  46. PROCEDURE PopNum(): LONGCARD;
  47. BEGIN
  48.   RETURN LONGCARD(PopL(numStack));
  49. END PopNum;
  50.  
  51.  
  52. (*$L-*)
  53. PROCEDURE ProcessParenthesis();
  54. VAR
  55.   tos       : OpType;
  56.   val1,val2 : LONGCARD;
  57. BEGIN
  58.   tos:=PopOp();
  59.   IF tos=OpLeftParen THEN
  60.     value:=PopNum();
  61.     RETURN;
  62.   END;
  63.  
  64.   LOOP
  65.     val1:=PopNum();
  66.     val2:=PopNum();
  67.     CASE tos OF
  68.       |OpPlus  : IF NOT Addition(val1,val2) THEN
  69.                    EXIT;
  70.                  END;
  71.                  value:=val1+val2;
  72.       |OpMinus : IF NOT Subtraction(val2,val1) THEN
  73.                    EXIT;
  74.                  END;
  75.                  value:=val2-val1;
  76.       |OpTimes : IF NOT Multiplication(val1,val2) THEN
  77.                    EXIT;
  78.                  END;
  79.                  value:=val1*val2;
  80.       |OpDivide: IF NOT Division(val2,val1) THEN
  81.                    EXIT;
  82.                  END;
  83.                  value:=val2 DIV val1;
  84.       |OpAnd   : value:=LONGCARD(LONGBITSET(val1) * LONGBITSET(val2));
  85.       |OpOr    : value:=LONGCARD(LONGBITSET(val1) + LONGBITSET(val2));
  86.       |OpXor   : value:=LONGCARD(LONGBITSET(val1) / LONGBITSET(val2));
  87.     ELSE
  88.     END;
  89.  
  90.     tos:=PopOp();
  91.     IF tos=OpLeftParen THEN
  92.       RETURN;
  93.     END;
  94.     PushNum(value);
  95.   END;
  96.  
  97.   DoLCDStr(errorString^);
  98. END ProcessParenthesis;
  99.  
  100.  
  101. PROCEDURE EnterOperation(op:OpType);
  102. VAR
  103.   tos      : OpType;        (* Top Of Stack *)
  104.   tosValue : LONGCARD;
  105.   backup   : LONGCARD;
  106. BEGIN
  107.   resetValue:=TRUE;
  108.  
  109.   IF (op # OpLeftParen) & (op # OpRightParen) & (op # OpClearAll) THEN
  110.     LOOP
  111.       tos:=PopOp();
  112.       IF NOT (tos IN HiPriorityOps) THEN
  113.         PushOp(tos);
  114.         EXIT;
  115.       END;
  116.     
  117.       tosValue:=PopNum();
  118.       CASE tos OF
  119.         |OpTimes : IF NOT Multiplication(value,tosValue) THEN
  120.                      DoLCDStr(errorString^);
  121.                      EXIT;
  122.                    END;
  123.                    value:=value*tosValue;
  124.         |OpDivide: IF NOT Division(tosValue,value) THEN
  125.                      DoLCDStr(errorString^);
  126.                      EXIT;
  127.                    END;
  128.                    value:=tosValue DIV value;
  129.         |OpAnd   : value:=LONGCARD(LONGBITSET(tosValue) * LONGBITSET(value));
  130.         |OpOr    : value:=LONGCARD(LONGBITSET(tosValue) + LONGBITSET(value));
  131.         |OpXor   : value:=LONGCARD(LONGBITSET(tosValue) / LONGBITSET(value));
  132.       END;
  133.     END;
  134.   END;
  135.  
  136.   CASE op OF
  137.     |OpLeftParen : PushOp(OpLeftParen);
  138.                    INC(openCount);
  139.  
  140.     |OpRightParen: DEC(openCount);
  141.                    PushNum(value);
  142.                    ProcessParenthesis();
  143.  
  144.     |OpEqual     : WHILE openCount>0 DO
  145.                      EnterOperation(OpRightParen); (* will decrement openCount *)
  146.            END;
  147.                    EnterOperation(OpClearAll);
  148.     |OpPlus,
  149.      OpMinus     : PushNum(value);
  150.                    ProcessParenthesis();
  151.                    PushOp(OpLeftParen);
  152.                    PushNum(value);
  153.                    PushOp(op);
  154.  
  155.     |OpTimes,
  156.      OpDivide,
  157.      OpAnd,
  158.      OpOr,
  159.      OpXor     : PushOp(op);
  160.                    PushNum(value);
  161.  
  162.     |OpClearAll     : ClearStack(opStack);
  163.                    ClearStack(numStack);
  164.                    PushOp(OpLeftParen);
  165.                    openCount:=1;
  166.   ELSE
  167.   END;
  168. END EnterOperation;
  169.  
  170.  
  171. PROCEDURE TerminateCalcBrains;
  172. BEGIN
  173.   DisposeStack(opStack);
  174.   DisposeStack(numStack);
  175. END TerminateCalcBrains;
  176.  
  177.  
  178. PROCEDURE InitBrains(): BOOLEAN;
  179. BEGIN
  180.   IF CreateStack(opStack,2000) THEN
  181.     IF CreateStack(numStack,4000) THEN
  182.       EnterOperation(OpClearAll);
  183.       TERMPROC(TerminateCalcBrains);
  184.       RETURN TRUE;
  185.     END;
  186.     DisposeStack(opStack);
  187.   END;
  188.  
  189.   RETURN FALSE;
  190. END InitBrains;
  191.  
  192.  
  193. BEGIN
  194.   value:=0;
  195.   stoValue:=0;
  196. END CalcBrains.
  197.