home *** CD-ROM | disk | FTP | other *** search
/ Nautilus 1992 July / Nautilus-3-8 / Nautilus-3-8.bin / Tools & Utilities / Techy Stuff / Doco ƒ / CSMP ƒ / CSMP-V1-073.TXT < prev    next >
Encoding:
Text File  |  1992-06-04  |  41.9 KB  |  1,380 lines

  1. C.S.M.P. Digest             Wed, 06 May 92       Volume 1 : Issue 73
  2.  
  3. Today's Topics:
  4.  
  5.     How to program algebraic expression interpretation
  6.     Copyright and Freeware
  7.     code overflow
  8.     Beginner C question (char or Boolean)
  9.     Application icons (attatching to existing apps)
  10.  
  11.  
  12. The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
  13.  
  14. These digests are available (by using FTP, account anonymous, your email
  15. address as password) in the pub/mac/csmp-digest directory on ftp.cs.uoregon.
  16. edu.  This is also the home of the comp.sys.mac.programmer Frequently Asked
  17. Questions list.  The last several issues of the digest are available from
  18. sumex-aim.stanford.edu as well.
  19.  
  20. These digests are also available via email.  Just send a note saying that you
  21. want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
  22. automatically receive each new digest as it is created.
  23.  
  24. The digest is a collection of articles from the internet newsgroup comp.sys.
  25. mac.programmer.  It is designed for people who read c.s.m.p. semi-regularly
  26. and want an archive of the discussions.  If you don't know what a newsgroup
  27. is, you probably don't have access to it.  Ask your systems administrator(s)
  28. for details.  (This means you can't post questions to the digest.)
  29.  
  30. The articles in these digests are taken directly from comp.sys.mac.programmer.
  31. They are not edited; all articles included in this digest are in their original
  32. posted form.  The only articles that are -not- included in these digests are
  33. those which didn't receive any replies (except those that give information
  34. rather than ask a question).  All replies to each article are concatenated
  35. onto the original article in the order in which they were received.  Article
  36. threads are not added to the digests until the last article added to the
  37. thread is at least one month old (this is to ensure that the thread is dead
  38. before adding it to the digests).
  39.  
  40. Send administrative mail to mkelly@cs.uoregon.edu.
  41.  
  42. -------------------------------------------------------
  43.  
  44. From: jess@gn.ecn.purdue.edu (Jess M Holle)
  45. Subject: How to program algebraic expression interpretation
  46. Date: 25 Mar 92 18:39:19 GMT
  47. Organization: Purdue University Engineering Computer Network
  48.  
  49. I was giving some thought to summer programming projects and found that
  50. many would need to take a user entered algebraic expression, parse it, 
  51. store it, and then QUICKLY calculate the result of the expression.
  52.  
  53. Basically, I guess I would like a little clue as to how spreadsheets work
  54. their magic.  How do you take this user entry and run calculations with it
  55. quickly?
  56.  
  57. Thanks to all who reply,
  58.  
  59. Jess Holle
  60.  
  61. +++++++++++++++++++++++++++
  62.  
  63. From: orpheus@reed.edu (P. Hawthorne)
  64. Date: 25 Mar 92 22:56:18 GMT
  65. Organization: Reed College, Portland OR
  66.  
  67.  
  68.   jess@gn.ecn.purdue.edu (Jess M Holle) writes:
  69. . I was giving some thought to summer programming projects and found that
  70. . many would need to take a user entered algebraic expression, parse it, 
  71. . store it, and then QUICKLY calculate the result of the expression.
  72.  
  73.   Well, I needed to write the same thing a couple of months ago. For the
  74. first implementation, I was mostly concerned with getting it done than with
  75. making it fast. So the object is not a fast one, but it is correct.
  76.   Since this particular object is not a crucial as some of the others in
  77. the class library I have written, perhaps it could benefit from being exposed
  78. to the world at large. Maybe you have some time...
  79.  
  80.  
  81. unit Evaluator;
  82.  
  83. interface
  84.  
  85. uses
  86.  Script, SANE, Picker, Types, Routines;
  87.  
  88. const
  89.  maxOperands = 12;
  90.  maxFunctions = 12;
  91.  
  92.  lesserPrecedence = -1;
  93.  equivalentPrecedence = 0;
  94.  higherPrecedence = 1;
  95.  
  96.  dynamicParameters = -1;
  97.  
  98. type
  99.  Evaluator = object(Abstract)
  100.    numOperands: Integer;
  101.    operandList: array[1..maxOperands] of record
  102.      Name: Text;
  103.      Relative: Boolean;
  104.     end;
  105.    operandTable: array[0..maxOperands, 0..maxOperands] of Integer;
  106.  
  107.    numFunctions: Integer;
  108.    functionList: array[1..maxOperands] of record
  109.      Name: Text;
  110.      Params: Integer;
  111.     end;
  112.  
  113.    TermStack: array[0..255] of Number;
  114.    StackIndex: Integer;
  115.  
  116.    infix, postfix, solution: Str255;
  117.  
  118.    function Evaluator.Construct: Boolean;
  119.    procedure Evaluator.Destruct;
  120.  
  121.    procedure Evaluator.OperandInit;
  122.    function Evaluator.GetOperandIndex (anOperand: Text): Integer;
  123.    procedure Evaluator.MarkPrecedence (a: Text; prec: Integer; b: Text);
  124.    procedure Evaluator.UniversalPrecedence (a: Text; prec, start, finish:
  125. Integer);
  126.    procedure Evaluator.IncludeOperand (anOperand: Text);
  127.    procedure Evaluator.RelativeOperand (anOperand: Text);
  128.    function Evaluator.RelativeOperator (anOperand: Text): Boolean;
  129.    function Evaluator.PrecedenceHigher (a, b: Integer): Boolean;
  130.  
  131.    procedure Evaluator.FunctionInit;
  132.    function Evaluator.GetFunctionIndex (aFunction: Text): Integer;
  133.    procedure Evaluator.IncludeFunction (aFunction: Text; aParameterCount:
  134. Integer);
  135.  
  136.    function Evaluator.LetterOrDigit (aTestCase: Str255): Boolean;
  137.    function Evaluator.JoinParts (partOne, partTwo: Str255): Str255;
  138.    function Evaluator.LexicalCheck (var aStr: Str255): Boolean;
  139.    function Evaluator.InfixToPostfix (aStr: Str255): Str255;
  140.    function Evaluator.Evaluate (aStr: Str255): Number;
  141.   end;
  142.  
  143. var
  144.  theEvaluator: Evaluator;
  145.  
  146. procedure InitEvaluator;
  147. procedure ExitEvaluator;
  148.  
  149. implementation
  150.  
  151. procedure InitEvaluator;
  152.  begin
  153.  New(theEvaluator);
  154.  if theEvaluator = nil then
  155.   Danger('Not enough memory to create an evaluator.');
  156.  if not theEvaluator.Construct then
  157.   Danger('Not enough memory to construct an evaluator.');
  158.  end;
  159.  
  160. procedure ExitEvaluator;
  161.  begin
  162.  theEvaluator.Destruct;
  163.  end;
  164.  
  165. function Evaluator.Construct: Boolean;
  166.  begin
  167.  Construct := false;
  168.  
  169.  Lock;
  170.  
  171.  OperandInit;
  172.  FunctionInit;
  173.  
  174.  Construct := true;
  175.  end;
  176.  
  177. procedure Evaluator.Destruct;
  178.  begin
  179.  Dispose;
  180.  end;
  181.  
  182. function Evaluator.GetOperandIndex (anOperand: Text): Integer;
  183.  var
  184.   a: Integer;
  185.  begin
  186.  GetOperandIndex := 0;
  187.  for a := 1 to numOperands do
  188.   if operandList[a].Name = anOperand then
  189.    begin
  190.    GetOperandIndex := a;
  191.    Leave;
  192.    end;
  193.  end;
  194.  
  195. procedure Evaluator.MarkPrecedence (a: Text; prec: Integer; b: Text);
  196.  var
  197.   aPos, bPos: Integer;
  198.  begin
  199.  aPos := GetOperandIndex(a);
  200.  bPos := GetOperandIndex(b);
  201.  if ((aPos > 0) and (bPos > 0)) then
  202.   begin
  203.   operandTable[aPos, bPos] := prec;
  204.   operandTable[bPos, aPos] := -prec;
  205.   end
  206.  else
  207.   Danger('Invalid operator for precedence declaration.');
  208.  end;
  209.  
  210. procedure Evaluator.UniversalPrecedence (a: Text; prec, start, finish:
  211. Integer);
  212.  var
  213.   aPos, bPos, e: Integer;
  214.  begin
  215.  aPos := GetOperandIndex(a);
  216.  if finish > numOperands then
  217.   finish := numOperands;
  218.  if (aPos > 0) then
  219.   begin
  220.   for e := start to finish do
  221.    begin
  222.    operandTable[aPos, e] := prec;
  223.    operandTable[e, aPos] := -prec;
  224.    end;
  225.   end
  226.  else
  227.   Danger('Invalid operator for precedence declaration.');
  228.  end;
  229.  
  230. procedure Evaluator.IncludeOperand (anOperand: Text);
  231.  begin
  232.  numOperands := numOperands + 1;
  233.  operandList[numOperands].Name := anOperand;
  234.  operandList[numOperands].Relative := false;
  235.  end;
  236.  
  237. procedure Evaluator.RelativeOperand (anOperand: Text);
  238.  var
  239.   anIndex: Integer;
  240.  begin
  241.  anIndex := GetOperandIndex(anOperand);
  242.  if anIndex > 0 then
  243.   operandList[numOperands].Relative := true;
  244.  end;
  245.  
  246. function Evaluator.RelativeOperator (anOperand: Text): Boolean;
  247.  var
  248.   anIndex: Integer;
  249.  begin
  250.  anIndex := GetOperandIndex(anOperand);
  251.  if anIndex > 0 then
  252.   RelativeOperator := operandList[numOperands].Relative
  253.  else
  254.   RelativeOperator := false;
  255.  end;
  256.  
  257. function Evaluator.PrecedenceHigher (a, b: Integer): Boolean;
  258.  begin
  259.  PrecedenceHigher := false;
  260.  if a > 0 then
  261.   PrecedenceHigher := (operandTable[a, b] = higherPrecedence)
  262.  end;
  263.  
  264. procedure Evaluator.OperandInit;
  265.  var
  266.   a, e: Integer;
  267.  begin
  268.  for a := 0 to maxOperands do
  269.   for e := 0 to maxOperands do
  270.    operandTable[a, e] := equivalentPrecedence;
  271.  
  272.  numOperands := 0;
  273.  IncludeOperand('^');
  274.  IncludeOperand('/');
  275.  IncludeOperand('*');
  276.  IncludeOperand('+');
  277.  IncludeOperand('-');
  278.  IncludeOperand('=');
  279.  IncludeOperand('<>');
  280.  IncludeOperand('<');
  281.  IncludeOperand('>');
  282.  IncludeOperand('<=');
  283.  IncludeOperand('>=');
  284.  
  285.  RelativeOperand('=');
  286.  RelativeOperand('<>');
  287.  RelativeOperand('<');
  288.  RelativeOperand('>');
  289.  RelativeOperand('<=');
  290.  RelativeOperand('>=');
  291.  
  292.  MarkPrecedence('^', higherPrecedence, '/');
  293.  MarkPrecedence('^', higherPrecedence, '*');
  294.  MarkPrecedence('^', higherPrecedence, '+');
  295.  MarkPrecedence('^', higherPrecedence, '-');
  296.  
  297.  MarkPrecedence('/', higherPrecedence, '*');
  298.  MarkPrecedence('/', higherPrecedence, '+');
  299.  MarkPrecedence('/', higherPrecedence, '-');
  300.  
  301.  MarkPrecedence('*', higherPrecedence, '+');
  302.  MarkPrecedence('*', higherPrecedence, '-');
  303.  
  304.  UniversalPrecedence('=', lesserPrecedence, 1, 5);
  305.  UniversalPrecedence('<>', lesserPrecedence, 1, 5);
  306.  UniversalPrecedence('<', lesserPrecedence, 1, 5);
  307.  UniversalPrecedence('>', lesserPrecedence, 1, 5);
  308.  UniversalPrecedence('<=', lesserPrecedence, 1, 5);
  309.  UniversalPrecedence('>=', lesserPrecedence, 1, 5);
  310.  end;
  311.  
  312. function Evaluator.GetFunctionIndex (aFunction: Text): Integer;
  313.  var
  314.   a: Integer;
  315.  begin
  316.  GetFunctionIndex := 0;
  317.  aFunction := Caseless(aFunction);
  318.  for a := 1 to numFunctions do
  319.   if functionList[a].Name = aFunction then
  320.    begin
  321.    GetFunctionIndex := a;
  322.    Leave;
  323.    end;
  324.  end;
  325.  
  326. procedure Evaluator.IncludeFunction (aFunction: Text; aParameterCount:
  327. Integer);
  328.  begin
  329.  numFunctions := numFunctions + 1;
  330.  aFunction := Caseless(aFunction);
  331.  with functionList[numFunctions] do
  332.   begin
  333.   Name := aFunction;
  334.   LwrText(@Name[1], Length(Name));
  335.   Params := aParameterCount;
  336.   end;
  337.  end;
  338.  
  339. procedure Evaluator.FunctionInit;
  340.  begin
  341.  numFunctions := 0;
  342.  IncludeFunction('sum', dynamicParameters);
  343.  IncludeFunction('average', dynamicParameters);
  344.  IncludeFunction('max', dynamicParameters);
  345.  IncludeFunction('min', dynamicParameters);
  346.  IncludeFunction('if', 3);
  347.  IncludeFunction('percentage', 2);
  348.  end;
  349.  
  350. function Evaluator.LetterOrDigit (aTestCase: Str255): Boolean;
  351.  var
  352.   c: Char;
  353.  begin
  354.  c := aTestCase[1];
  355.  LetterOrDigit := ((c >= 'a') and (c <= 'z')) or ((c >= 'A') and (c <= 'Z'))
  356. or ((c >= 
  357. '0') and (c <= '9')) or (c = '.');
  358.  end;
  359.  
  360. function Evaluator.JoinParts (partOne, partTwo: Str255): Str255;
  361.  begin
  362.  if partOne <> '' then
  363.   if partOne[Length(partOne)] <> ' ' then
  364.    partOne := Concat(partOne, ' ');
  365.  if partOne = ' ' then
  366.   partOne := '';
  367.  if partTwo = ' ' then
  368.   partTwo := '';
  369.  JoinParts := Concat(partOne, partTwo);
  370.  end;
  371.  
  372. function Evaluator.LexicalCheck (var aStr: Str255): Boolean;
  373.  var
  374.   a, e, i, parenCount: Integer;
  375.   c: Char;
  376.   outString: Str255;
  377.   tempTerm: Str255;
  378.   errorCondition: Boolean;
  379.  begin
  380.  parenCount := 0;
  381.  outString := '';
  382.  a := 1;
  383.  errorCondition := ((Length(aStr) = 0) or (Length(aStr) > 254));
  384.  if not errorCondition then
  385.   repeat
  386.    c := aStr[a];
  387.    a := a + 1;
  388.    if (c = '(') then
  389.     parenCount := parenCount + 1
  390.    else if (c = ')') then
  391.     parenCount := parenCount - 1;
  392.    if ((c >= '0') and (c <= '9')) or (c = '.') then
  393.     begin
  394.     i := 1;
  395.     for e := a to Length(aStr) do
  396.      if ((aStr[e] >= '0') and (aStr[e] <= '9')) or (aStr[e] = '.') then
  397.       i := i + 1
  398.      else
  399.       e := Length(aStr);
  400.     outString := Concat(outstring, Copy(aStr, a - 1, i));
  401.     a := a + i - 1;
  402.     end
  403.    else if ((c >= 'A') and (c <= 'Z')) or ((c >= 'a') and (c <= 'z')) or (c =
  404. ':') 
  405. then
  406.     begin
  407.     i := 1;
  408.     for e := a to Length(aStr) do
  409.      if ((aStr[e] >= 'A') and (aStr[e] <= 'Z')) or ((aStr[e] >= 'a') and
  410. (aStr[e] <= 
  411. 'z')) or (aStr[e] = ':') then
  412.       i := i + 1
  413.      else
  414.       e := Length(aStr);
  415.     tempTerm := Copy(aStr, a - 1, i);
  416.     outString := Concat(outstring, tempTerm);
  417.     a := a + i - 1;
  418.     end
  419.    else if ((c >= '<') and (c <= '>')) then
  420.     begin
  421.     i := 1;
  422.     for e := a to Length(aStr) do
  423.      if ((aStr[e] >= '<') and (aStr[e] <= '>')) then
  424.       i := i + 1
  425.      else
  426.       e := Length(aStr);
  427.     tempTerm := Copy(aStr, a - 1, i);
  428.     LwrText(@tempTerm[1], Length(tempTerm));
  429.     outString := Concat(outstring, tempTerm);
  430.     a := a + i - 1;
  431.     end
  432.    else if c <> ' ' then
  433.     outString := Concat(outString, c);
  434.    if outString[Length(outString)] <> ' ' then
  435.     outString := Concat(outString, ' ');
  436.   until a > Length(aStr);
  437.  aStr := outString;
  438.  if not errorCondition then
  439.   errorCondition := (parenCount <> 0);
  440.  LexicalCheck := (not errorCondition)
  441.  end;
  442.  
  443. function Evaluator.InfixToPostfix (aStr: Str255): Str255;
  444.  var
  445.   aNumeric: Number;
  446.   aLookahead: Str255;
  447.  
  448.  procedure UnexpectedEnd;
  449.   begin
  450.   Caution('Unexpected end.');
  451.   Exit(InfixToPostfix);
  452.   end;
  453.  
  454.  procedure OutOfRange;
  455.   begin
  456.   Caution('Out of range.');
  457.   Exit(InfixToPostfix);
  458.   end;
  459.  
  460.  procedure ParameterDeficit;
  461.   begin
  462.   Caution('Not enough parameters.');
  463.   Exit(InfixToPostfix);
  464.   end;
  465.  
  466.  procedure ParameterSurplus;
  467.   begin
  468.   Caution('Too many parameters.');
  469.   Exit(InfixToPostfix);
  470.   end;
  471.  
  472.  procedure PopNext;
  473.   begin
  474.   if not BreakTerm(aStr, aLookahead) then
  475.    Nothing;
  476.   end;
  477.  
  478.  function Expression: Str255;
  479.  forward;
  480.  
  481.  function Term: Str255;
  482.  forward;
  483.  
  484.  function Rest: Str255;
  485.  forward;
  486.  
  487.  function Parameters (var aResult: Str255): Integer;
  488.  forward;
  489.  
  490.  function Expression: Str255;
  491.   begin
  492.   Expression := JoinParts(Term, Rest);
  493.   if (aLookahead = ')') then
  494.    PopNext;
  495.   end;
  496.  
  497.  function Parameters (var aResult: Str255): Integer;
  498.   var
  499.    parameterCount: Integer;
  500.   begin
  501.   parameterCount := 1;
  502.   aResult := '';
  503.   if aLookahead = '(' then
  504.    PopNext
  505.   else
  506.    ParameterDeficit;
  507.   while (aLookahead <> ')') and (aLookahead <> '') do
  508.    begin
  509.    aResult := JoinParts(aResult, Rest);
  510.    if aLookahead = ',' then
  511.     begin
  512.     parameterCount := parameterCount + 1;
  513.     PopNext;
  514.     end
  515.    else if (aLookahead <> ')') and (aLookahead <> '') then
  516.     if not RelativeOperator(aLookahead) then
  517.      ParameterSurplus;
  518.    end;
  519.   Parameters := parameterCount;
  520.   end;
  521.  
  522.  function Term: Str255;
  523.   var
  524.    anOperand: Str255;
  525.    aResult, aParameterSet: Str255;
  526.    functionIndex, parameterCount: Integer;
  527.   begin
  528.   if LetterOrDigit(aLookahead) then
  529.    begin
  530.    functionIndex := GetFunctionIndex(aLookahead);
  531.    if functionIndex > 0 then
  532.     begin
  533.     aResult := aLookahead;
  534.     PopNext;
  535.     parameterCount := Parameters(aParameterSet);
  536.     if functionList[functionIndex].Params = dynamicParameters then
  537.      aParameterSet := JoinParts(aParameterSet, IntegerToText(parameterCount))
  538.     else if parameterCount < functionList[functionIndex].Params then
  539.      ParameterDeficit
  540.     else if parameterCount > functionList[functionIndex].Params then
  541.      ParameterSurplus;
  542.     aResult := JoinParts(aParameterSet, aResult);
  543.     if aLookahead = ')' then
  544.      PopNext;
  545.     end
  546.    else
  547.     begin
  548.     aResult := aLookahead;
  549.     PopNext;
  550.     end;
  551.    end
  552.   else if aLookahead = '(' then
  553.    begin
  554.    PopNext;
  555.  
  556.    if aLookahead = '-' then
  557.     begin
  558.     anOperand := aLookahead;
  559.     PopNext;
  560.     end
  561.    else
  562.     anOperand := '';
  563.  
  564.    aResult := Expression;
  565.  
  566.    if anOperand = '-' then
  567.     aResult := JoinParts(aResult, '-1 *');
  568.    if aLookahead = ')' then
  569.     PopNext;
  570.    end
  571.   else
  572.    aResult := '';
  573.   Term := aResult;
  574.   end;
  575.  
  576.  function Rest: Str255;
  577.   var
  578.    cumulative, right, operand, storedOperand: Str255;
  579.    operandIndex: Integer;
  580.  
  581.   begin
  582.   cumulative := '';
  583.   repeat
  584.    operandIndex := GetOperandIndex(aLookahead);
  585.    if operandIndex > 0 then
  586.     begin
  587.     operand := aLookahead;
  588.     PopNext;
  589.     right := Term;
  590.     while PrecedenceHigher(GetOperandIndex(aLookahead), operandIndex) do
  591.      begin
  592.      storedOperand := aLookahead;
  593.      PopNext;
  594.      right := JoinParts(right, JoinParts(Term, storedOperand));
  595.      end;
  596.     cumulative := JoinParts(cumulative, JoinParts(right, operand))
  597.     end
  598.    else if ((aLookahead <> ')') or (aLookahead <> ',')) and (aStr <> '') then
  599.     cumulative := JoinParts(cumulative, Term);
  600.   until (aStr = '') or (aLookahead = ')') or (aLookahead = ',') or (not 
  601. RelativeOperator(aLookahead));
  602. {IF (aLookahead = ')') THEN}
  603. {PopNext;}
  604.   Rest := cumulative;
  605.   end;
  606.  
  607.  procedure Main;
  608.   begin
  609.   if not LexicalCheck(aStr) then
  610.    Danger('Unmatched parentheses.')
  611.   else
  612.    begin
  613.    if not BreakTerm(aStr, aLookahead) then
  614.     UnexpectedEnd;
  615.    InfixToPostfix := Expression;
  616.    end;
  617.   end;
  618.  
  619.  begin
  620.  Main;
  621.  end;
  622.  
  623. function Evaluator.Evaluate (aStr: Str255): Number;
  624.  var
  625.   aNumeric: Number;
  626.   aTerm: Str255;
  627.   aCounter: Integer;
  628.   a: Integer;
  629.  
  630.  procedure Push (var aValue: Number);
  631.   begin
  632.   TermStack[StackIndex] := aValue;
  633.   StackIndex := StackIndex + 1;
  634.   end;
  635.  
  636.  function Pop: Number;
  637.   var
  638.    aValue: Number;
  639.   begin
  640.   StackIndex := StackIndex - 1;
  641.   if StackIndex < 0 then
  642.    begin
  643.    if true then
  644.     Pop := 0;
  645.    end
  646.   else
  647.    begin
  648.    aValue := TermStack[StackIndex];
  649.    TermStack[StackIndex] := 0;
  650.    Pop := aValue;
  651.    end;
  652.   end;
  653.  
  654.  procedure Exch;
  655.   var
  656.    a, e: Number;
  657.   begin
  658.   a := Pop;
  659.   e := Pop;
  660.   Push(e);
  661.   Push(a);
  662.   end;
  663.  
  664.  function StackEmpty: Boolean;
  665.   begin
  666.   StackEmpty := (StackIndex < 0);
  667.   end;
  668.  
  669.  procedure StackInit;
  670.   var
  671.    a: Integer;
  672.   begin
  673.   StackIndex := 0;
  674.   end;
  675.  
  676.   var
  677.    eNumeric: Number;
  678.    neutralCase: Text;
  679.  begin
  680.  StackInit;
  681.  while BreakTerm(aStr, aTerm) do
  682.   begin
  683.   if aTerm = '+' then
  684.    aNumeric := Pop + Pop
  685.   else if aTerm = '-' then
  686.    begin
  687.    aNumeric := Pop;
  688.    aNumeric := Pop - aNumeric;
  689.    end
  690.   else if aTerm = '*' then
  691.    aNumeric := Pop * Pop
  692.   else if aTerm = '/' then
  693.    begin
  694.    aNumeric := Pop;
  695.    aNumeric := Pop / aNumeric;
  696.    end
  697.   else if aTerm = '^' then
  698.    begin
  699.    aNumeric := Pop;
  700.    aNumeric := xPwrY(Pop, aNumeric);
  701.    end
  702.   else if aTerm = '=' then
  703.    begin
  704.    if (Pop = Pop) then
  705.     aNumeric := 1
  706.    else
  707.     aNumeric := 0;
  708.    end
  709.   else if aTerm = '<>' then
  710.    begin
  711.    if (Pop <> Pop) then
  712.     aNumeric := 1
  713.    else
  714.     aNumeric := 0;
  715.    end
  716.   else if aTerm = '<' then
  717.    begin
  718.    aNumeric := Pop;
  719.    eNumeric := Pop;
  720.    if (eNumeric < aNumeric) then
  721.     aNumeric := 1
  722.    else
  723.     aNumeric := 0;
  724.    end
  725.   else if aTerm = '>' then
  726.    begin
  727.    aNumeric := Pop;
  728.    eNumeric := Pop;
  729.    if (eNumeric > aNumeric) then
  730.     aNumeric := 1
  731.    else
  732.     aNumeric := 0;
  733.    end
  734.   else if aTerm = '<=' then
  735.    begin
  736.    aNumeric := Pop;
  737.    eNumeric := Pop;
  738.    if (eNumeric <= aNumeric) then
  739.     aNumeric := 1
  740.    else
  741.     aNumeric := 0;
  742.    end
  743.   else if aTerm = '>=' then
  744.    begin
  745.    aNumeric := Pop;
  746.    eNumeric := Pop;
  747.    if (eNumeric >= aNumeric) then
  748.     aNumeric := 1
  749.    else
  750.     aNumeric := 0;
  751.    end
  752.   else
  753.    begin
  754.    neutralCase := aTerm;
  755.    LwrText(@neutralCase[1], Length(neutralCase));
  756.    if neutralCase = 'percentage' then
  757.     begin
  758.     aNumeric := Pop;
  759.     aNumeric := Percentage(Pop, aNumeric);
  760.     end
  761.    else if neutralCase = 'max' then
  762.     begin
  763.     aCounter := Trunc(Pop);
  764.     if aCounter < 1 then
  765.      Danger('At least one parameter must follow this function.');
  766.     aNumeric := Pop;
  767.     for a := 2 to aCounter do
  768.      aNumeric := MaxTwo(aNumeric, Pop);
  769.     end
  770.    else if neutralCase = 'min' then
  771.     begin
  772.     aCounter := Trunc(Pop);
  773.     if aCounter < 1 then
  774.      Danger('At least one parameter must follow this function.');
  775.     aNumeric := Pop;
  776.     for a := 2 to aCounter do
  777.      aNumeric := MinTwo(aNumeric, Pop);
  778.     end
  779.    else if neutralCase = 'sum' then
  780.     begin
  781.     aCounter := Trunc(Pop);
  782.     if aCounter < 1 then
  783.      Danger('At least one parameter must follow this function.');
  784.     aNumeric := Pop;
  785.     for a := 2 to aCounter do
  786.      aNumeric := aNumeric + Pop;
  787.     end
  788.    else if neutralCase = 'if' then
  789.     begin
  790.     aNumeric := Pop;
  791.     eNumeric := Pop;
  792.     if Pop <> 0 then
  793.      aNumeric := eNumeric;
  794.     end
  795.    else if neutralCase = 'average' then
  796.     begin
  797.     aCounter := Trunc(Pop);
  798.     if aCounter < 1 then
  799.      Danger('At least one parameter must follow this function.');
  800.     aNumeric := Pop;
  801.     for a := 2 to aCounter do
  802.      aNumeric := aNumeric + Pop;
  803.     aNumeric := aNumeric / aCounter;
  804.     end
  805.    else
  806.     aNumeric := TextToNumber(aTerm);
  807.    end;
  808.   Push(aNumeric);
  809.   end;
  810.  
  811.  Evaluate := Pop;
  812.  end;
  813.  
  814. end.
  815.  
  816. +++++++++++++++++++++++++++
  817.  
  818. From: d88-jwa@byse.nada.kth.se (Jon W{tte)
  819. Date: 25 Mar 92 22:09:08 GMT
  820. Organization: Royal Institute of Technology, Stockholm, Sweden
  821.  
  822. > jess@gn.ecn.purdue.edu (Jess M Holle) writes:
  823.  
  824.    I was giving some thought to summer programming projects and found that
  825.    many would need to take a user entered algebraic expression, parse it, 
  826.    store it, and then QUICKLY calculate the result of the expression.
  827.  
  828.    Basically, I guess I would like a little clue as to how spreadsheets work
  829.    their magic.  How do you take this user entry and run calculations with it
  830.    quickly?
  831.  
  832. There are several algorithms. Using two stacks, you can run through
  833. the text as-is and achieve pretty decent performance; I believe the
  834. algorithm is called the railroad algo.
  835.  
  836. However, my favourite starts with building a tree of the expression,
  837. just like you would in a compiler. For instance:
  838.  
  839.     3 + 5 * 6
  840.  
  841. Turns into:
  842.  
  843.         +
  844.          3     *
  845.          5   6
  846.  
  847. That requires lots of small blocks of memory (you can of course use
  848. an array of "node" type and use indexes into the array. Same thing,
  849. really)
  850.  
  851. Now, this is nice and fast and easy to print and/or debug. However,
  852. it requires memory, and is hard to save to disk. The next step is
  853. flattening the tree into a byte-code stream like thus:
  854.  
  855.     + I3 * I5 I6
  856.  
  857. where "I3" of course means a special token for integer, and the
  858. actual literal.
  859.  
  860. This kind of sxpression is also easily parsed using one stack, and
  861. a recursive algorithm. However, it's a little inflexible, so you
  862. might want to emit some byte-code (I did that in a spreadsheet once,
  863. to get whizzy macro capabilities) like:
  864.  
  865.     R1=5 R2=6 R1*=R2 R2=3 R1+=3
  866.  
  867. For an interpreted pseudo-register-machine.
  868.  
  869. The nice thing about that is that you can have bytes for conditionals,
  870. jumps, loops, User Interface, ... - you can compile a script languaga
  871. down top this kind of code. Really nifty. Microsoft Word and Excel
  872. are both partly written in P-Code, and although I don't know the innards
  873. of that engine, it's clearly a powerful space-saver. If you just remember
  874. to flush the cache when needed...
  875.  
  876. HOWEVER: (Neat hack alert) now that you're emitting code for a pseudo-
  877. machine, why not go all the way and emit "real" machine code. Granted,
  878. it's a trifle more complex to keep track of MC68881/2 timing and to
  879. flush the cache after smitting machine code, but once you have, you
  880. have a really neat cell type:
  881.  
  882.     MOVEQ #5,D0
  883.     MULS  #6,D0
  884.     ADDQ  #3,D0
  885.     RTS
  886.  
  887. Evaluating this is as fast as calling a subroutine written explicitly
  888. to solve this problem... since that's what is is ! Just remember to
  889. flush the cache after emitting the instructions.
  890.  
  891. Note that your tree parser OF COURSE would recognize static constructs
  892. like these and optimize them once and for all, but substitute cell
  893. references for "3," "5" and "6" and you see what I mean.
  894.  
  895. You could even have multiple modes; one mode with the tree, and once
  896. where the cell is compiled into code, for instance. It all depends
  897. on your application.
  898.  
  899. Hope this helps,
  900.  
  901. - -- 
  902. h+@nada.kth.se; Jon W{tte, the Diplomat - NOT!
  903.  
  904. +++++++++++++++++++++++++++
  905.  
  906. From: scott@mcl.mcl.ucsb.edu (Scott Bronson)
  907. Date: 6 Apr 92 01:25:35 GMT
  908.  
  909. I've been toying around with this idea, because I think allowing the
  910. user to enter functions, then having the machine compile them would
  911. speed up many of the shareware and vertical-market applications out
  912. now to solve specific problems.  It seems awfully redundant, though,
  913. and a massive headache to have each separate application link with
  914. someone else's library, etc. etc.
  915.  
  916. I have a solution in mind.  I've been meaning to write a simple mathematical
  917. expression parser and compiler without a front end, then having other apps
  918. send this program AppleEvents with the expression they want evaluated.
  919. This program will then reply with the machine code to do this.  The
  920. calling app then locks this down and JMPs to the bottom of the block
  921. returned.  Of course, the block returned would be in the form of a Pascal
  922. function so anyone could use it.
  923.  
  924. This would also work over networks.  Concievably, you could have entire
  925. tables for variables (pi, e, user-defined), user-defined functions,
  926. and on and on.  That way, if you were to enter a function (acosh()
  927. or something arcane like that, but built upon other functions), you
  928. wouldn't have to add it to each separate program that parses these
  929. strings.  Just add it to your parser and every single program that uses
  930. your parser is able to take full advantage of it.
  931.  
  932. I've been meaning to get this project started for some time now, but other
  933. things always seem more important.  If anyone else would like to take a
  934. weekend and write it, contact me first (if you like).  I'll probably be
  935. able to save you a little time.
  936.  
  937.     - Scott
  938.  
  939. ---------------------------
  940.  
  941. From: johnsd2@jec323.its.rpi.edu (Daniel Norman Johnson)
  942. Subject: Copyright and Freeware
  943. Organization: Information Technology Services, Rennselaer Polytechnic Institute.
  944. Date: Fri, 27 Mar 1992 23:16:03 GMT
  945.  
  946. Greetings All. I have a hankering to publish some Freeware, but I do not know
  947. how to do this. Is this a FAQ? If not could somebody tell me how this is done,
  948. normally? Or give me a hint? I have asked about this before but I got no
  949. responces adressing this (or if I did I missed them somehow)
  950.  
  951. Also, last time I asked about this stuff I asked about copyrights. Symantic
  952. owns a copyright on the software I used to write my would-be freeware
  953. (its done in THINK Pascal [not C, as I misspoke previously]); They say that
  954. all ya hafta do is have a copyright that protects *THEIR* copyright.
  955.  
  956. The only responce I got adressed this. It [sorry, I do not remember who it
  957. was!] said that all I had to do was put a copyright notice on my program-
  958. I didn't have to bother registering if I did not want to! Is this right?
  959. It sounds a little fishy to me, but then what do I know?
  960.  
  961. If this is the wrong forum for these questions, could somebody direct me
  962. to the right one?
  963.  
  964. Thanks in advance.
  965. - -- 
  966.             - Dan Johnson
  967. And God said "Jeeze, this is dull"... and it *WAS* dull. Genesis 0:0
  968.  
  969. +++++++++++++++++++++++++++
  970.  
  971. From: kanderso@mabillon.ICS.UCI.EDU (Kenneth Anderson)
  972. Date: 27 Mar 92 23:50:51 GMT
  973.  
  974. In comp.sys.mac.programmer you write:
  975.  
  976. >Greetings All. I have a hankering to publish some Freeware, but I do not know
  977. >how to do this. Is this a FAQ? If not could somebody tell me how this is done,
  978. >normally? Or give me a hint? I have asked about this before but I got no
  979. >responces adressing this (or if I did I missed them somehow)
  980.  
  981. >Also, last time I asked about this stuff I asked about copyrights. Symantic
  982. >owns a copyright on the software I used to write my would-be freeware
  983. >(its done in THINK Pascal [not C, as I misspoke previously]); They say that
  984. >all ya hafta do is have a copyright that protects *THEIR* copyright.
  985.  
  986. You will need to say something like:
  987.  
  988. This software produced using the Symantic Think Pascal compiler, as such
  989. portions of this software are Copyright 1992, Symantic.
  990.  
  991. Because of the adoption by the U.S. of the Berne Convention in 1988, you
  992. no longer need to place a notice about your copyright, but the one for
  993. Symantic is required.
  994.  
  995. >The only responce I got adressed this. It [sorry, I do not remember who it
  996. >was!] said that all I had to do was put a copyright notice on my program-
  997. >I didn't have to bother registering if I did not want to! Is this right?
  998. >It sounds a little fishy to me, but then what do I know?
  999.  
  1000. Registration of your computer software is only helps if you plan on sueing
  1001. someone for copyright infringment.  It simply strenthens your case in
  1002. front of the judge.  I.E. "How can this guy say he isn't infringing on
  1003. my copyright, when I've got the damn thing registered with the Dept. of
  1004. Copyrights??!!"
  1005.  
  1006.  
  1007. >If this is the wrong forum for these questions, could somebody direct me
  1008. >to the right one?
  1009.  
  1010. You may do better in misc.int-property.
  1011.  
  1012. >Thanks in advance.
  1013. >--
  1014. >            - Dan Johnson
  1015. >And God said "Jeeze, this is dull"... and it *WAS* dull. Genesis 0:0
  1016. - --
  1017. - --------------------------------------------------------------------------------
  1018. Ken Anderson                           |  "I'd much rather live in perfection,
  1019. U.C. Irvine                            |   than deal with reality." -- Kenbod
  1020. - --------------------------------------------------------------------------------
  1021. Happy! Happy! Happy! Joy! Joy! Joy!    |  Practice random kindness and
  1022.                          -- Stimpy     |  senseless acts of beauty. -- Anonymous
  1023. - --------------------------------------------------------------------------------
  1024.  
  1025. +++++++++++++++++++++++++++
  1026.  
  1027. From: tinsel@uiuc.edu (Thomas Aaron Insel)
  1028. Date: 27 Mar 92 23:48:13 GMT
  1029. Organization: University of Illinois at Urbana
  1030.  
  1031. johnsd2@jec323.its.rpi.edu (Daniel Norman Johnson) writes:
  1032.  
  1033. >The only responce I got adressed this. It [sorry, I do not remember who it
  1034. >was!] said that all I had to do was put a copyright notice on my program-
  1035. >I didn't have to bother registering if I did not want to! Is this right?
  1036. >It sounds a little fishy to me, but then what do I know?
  1037.  
  1038. I may have been the one who said it, but it's correct.  For more information
  1039. on copyright law geared to lay-people, (including the fact that you don't need
  1040. to register a copyright in many cases), and blank forms (if you do want to 
  1041. register), write to the Library of Congress in Washington, DC.
  1042. - -- 
  1043. Thomas Aaron Insel (tinsel@uiuc.edu)
  1044.   I speak for myself, and not for the State or University of Illinois.
  1045.   "We must not confuse dissent with disloyalty." -- Edward R. Murrow
  1046.  
  1047. +++++++++++++++++++++++++++
  1048.  
  1049. From: peter@cujo.curtin.edu.au (Peter N Lewis)
  1050. Date: 28 Mar 92 06:18:39 GMT
  1051. Organization: NCRPDA, Curtin University
  1052.  
  1053. In article <45ptn8j@rpi.edu>, johnsd2@jec323.its.rpi.edu (Daniel Norman Johnson) writes:
  1054. >From: peter@cujo.curtin.edu.au (Peter N Lewis)
  1055. To: johnsd2@jec323.its.rpi.edu 
  1056. Subject: Re: Copyright and Freeware
  1057. References: <45ptn8j@rpi.edu>
  1058. Organization: NCRPDA, Curtin University
  1059.  
  1060. In article <45ptn8j@rpi.edu>, johnsd2@jec323.its.rpi.edu (Daniel Norman Johnson) writes:
  1061. > Greetings All. I have a hankering to publish some Freeware, but I do not know
  1062. > how to do this. Is this a FAQ? If not could somebody tell me how this is done,
  1063. > normally? Or give me a hint? I have asked about this before but I got no
  1064. > responces adressing this (or if I did I missed them somehow)
  1065.  
  1066. I would certainly have replied if I'd seen it, perhaps your posting 
  1067. got eaten by a cruel and nasty net.god?
  1068.  
  1069. Anyway, all you do is this:  Package all the relevent files, including
  1070. a docs file if at all possible, encode it in an archive (You can use
  1071. StuffIt Classic to make a StuffIt 1.5.1 archive - everyone can decode 
  1072. StuffIt 1.5.1 files), BinHex it (StuffIt will do that too), edit the BinHex, 
  1073. and right at the start before the (This file...) line, add it a short 
  1074. description of your file (here is one I used:
  1075.  
  1076. *****
  1077. Finger v1.3.5 & Fingerd v1.3.5 is an implementation of the UNIX Finger
  1078. protocol for Macs with MacTCP.  Fingerd is a background only application
  1079. that allows you to be fingered, while Finger is a finger client, allowing
  1080. you to finger other machines, as well as allowing others to finger you.
  1081. Both are System 7 friendly (but hopefully not dependent).
  1082.  
  1083. They are Povertyware, which basically means you get to send me five
  1084. dollars if you can.  If you use these programs, drop me a note and say hello! 
  1085.  
  1086. Hope you like them,
  1087.    Peter <peter@cujo.curtin.edu.au>.
  1088.  
  1089. Finger 1.3.5 & Fingerd 1.3.5 Copyright 1991-1992, Peter N Lewis 
  1090. ******
  1091.  
  1092. (Note: You must keep your signiture at the bottom to one line according to
  1093. the posting guidelines for sumex-aim)
  1094.  
  1095. Then mail that file to macgifts@rascal.ics.utexas.edu and it will be
  1096. resent to all the major archives (umich, sumex, rascal...), as well
  1097. as to comp.binaries.mac.
  1098. >
  1099. > Also, last time I asked about this stuff I asked about copyrights. Symantic
  1100. > owns a copyright on the software I used to write my would-be freeware
  1101. > (its done in THINK Pascal [not C, as I misspoke previously]); They say that
  1102. > all ya hafta do is have a copyright that protects *THEIR* copyright.
  1103.  
  1104. Just put:
  1105. Prograname copyright 1992 Your Name
  1106. Portions of this code are copyright by Symantec
  1107.  
  1108. Your code is automatically copyrighted to you as soon as you write it, there
  1109. is no need to register it, or even to put the above messages on, but the 
  1110. above messages are a GOOD idea, and will give you a much better legal
  1111. standing if it were ever necessary to do anything legal about it.
  1112. (Disclaimer: I am not a laywer!).  Also put the fact that the program
  1113. is free in the about box, otherwise people won't know and should assume
  1114. that it is not free...
  1115.  
  1116. HTH,
  1117.    Peter.
  1118.  
  1119. ______________________________________________________________________
  1120. Peter N Lewis, NCRPDA, Curtin University      peter@cujo.curtin.edu.au
  1121. GPO Box U1987, Perth WA 6001, AUSTRALIA            FAX: +61 9 367 8141
  1122.  
  1123. +++++++++++++++++++++++++++
  1124.  
  1125. From: jahnke@joplin.biosci.arizona.edu (Jerome Jahnke)
  1126. Date: 29 Mar 92 18:25:01 GMT
  1127. Organization: Biology Learning Center
  1128.  
  1129. In article <9203271550.aa20554@Paris.ics.uci.edu>, kanderso@mabillon.ICS.UCI.EDU (Kenneth Anderson) writes:
  1130. > You will need to say something like:
  1131. > This software produced using the Symantic Think Pascal compiler, as such
  1132. > portions of this software are Copyright 1992, Symantic.
  1133. > Because of the adoption by the U.S. of the Berne Convention in 1988, you
  1134. > no longer need to place a notice about your copyright, but the one for
  1135. > Symantic is required.
  1136.  
  1137. Nope, the license agreement in the Manual states CLEARLY:
  1138. "you also have the right to use, distribute, and license such programs to 
  1139. third parties without payment of any further license fees, so long as a 
  1140. copyright notice sufficent to protect YOUR copyright in the software in 
  1141. United States or any other coutry is included in the graphic display of
  1142. your software and on the labels affixed to the media on which your software
  1143. is distriuted."
  1144.  
  1145. See it does not say a THING about Symantec needing to be referenced in the
  1146. about. They are granting you rights to the software. I assume that if you 
  1147. release the software are public domain that you will then have to put a
  1148. copyright to Symantec on it.
  1149.  
  1150. When in doubt read the licensing agreement. With MacApp you have to pay 
  1151. Apple to distribute a program which uses MacApp. I don't remember if you have
  1152. to include an Apple Copyright. But in Thinks product you only have to include
  1153. your own copyright.
  1154.  
  1155. Jer,
  1156. - ----
  1157. Jerome Jahnke
  1158. Biology Learning Center
  1159. University of Arizona
  1160. 'jahnke@biosci.arizona.edu' or +1 (602) 621-3820
  1161.  
  1162. +++++++++++++++++++++++++++
  1163.  
  1164. From: scott@mcl.mcl.ucsb.edu (Scott Bronson)
  1165. Date: 6 Apr 92 03:18:07 GMT
  1166.  
  1167. Now that Symantec is using Apple's libraries as include, header, and glue
  1168. doesn't that mean that portions are copyright (c) Apple Computer?
  1169.  
  1170. What if I were to use nothing but Apple's glue and THINK's inline assembler?
  1171. It just gets muddier from there...
  1172.  
  1173. ---------------------------
  1174.  
  1175. From: pete@othello.dartmouth.edu (Pete Schmitt)
  1176. Subject: code overflow
  1177. Date: 30 Mar 92 15:27:08 GMT
  1178. Organization: Dartmouth College, Hanover, NH
  1179.  
  1180. This bug comes up right after compilation of a 890 line file using %U to
  1181. update the project.  I can't find any reference to this the the Think C 5.0
  1182. docs.  What does it mean?
  1183.  
  1184. - -pete
  1185. - --
  1186. Peter Schmitt, UNIX Systems Specialist, Computing Services, Dartmouth College
  1187. Email: peter.schmitt@dartmouth.edu                        Phone: 603-646-2085
  1188. ******* Let us not give up meeting together, as some are in the habit *******
  1189. ******* of doing, but let us encourage one another.    -Hebrews 10:25 *******
  1190.  
  1191. +++++++++++++++++++++++++++
  1192.  
  1193. From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
  1194. Organization: Kalamazoo College
  1195. Date: Mon, 30 Mar 1992 18:40:16 GMT
  1196.  
  1197. pete@othello.dartmouth.edu (Pete Schmitt) writes:
  1198. >This bug comes up right after compilation of a 890 line file using %U to
  1199. >update the project.  I can't find any reference to this the Think C 5.0
  1200. >docs.
  1201.  
  1202. Did you look on page 488?  "Code Overflow:  You have more than 32K of
  1203. code or data in one file.  Break your file up into smaller files."
  1204. Since there's only 890 lines, you're probably declaring a huge array.
  1205.  
  1206. This FAQ has come up several times before--are there a lot of misprinted
  1207. manuals out there?  Or do people just not think to look in the "Error
  1208. Messages" appendix to figure out an error message?
  1209. - -- 
  1210.  Jamie McCarthy     Internet: k044477@kzoo.edu     AppleLink: j.mccarthy
  1211.  
  1212. +++++++++++++++++++++++++++
  1213.  
  1214. From: overdriv@tsoft.sf-bay.org (Paul A. Pelton)
  1215. Organization: The TeleSoft BBS and Public Access Unix, +1 415 969 7958
  1216. Date: Sat, 4 Apr 1992 02:14:45 GMT
  1217.  
  1218. In article <1992Mar30.152708.17482@dartvax.dartmouth.edu> pete@othello.dartmouth.edu (Pete Schmitt) writes:
  1219. >This bug comes up right after compilation of a 890 line file using %U to
  1220. >update the project.  I can't find any reference to this the the Think C 5.0
  1221. >docs.  What does it mean?
  1222.  
  1223. This is a long-shot. Are you using THINK C's object extensions?
  1224.  
  1225. I got this error when I compiled a bunch of .c files which contained no 
  1226. function definitions but simply included a .h file. Basically, all I was 
  1227. compiling was a bunch of class declarations and method prototypes but no 
  1228. actual code.
  1229.  
  1230. You might look for something like that. If you find out exactly what "code
  1231. overflow" means, I'd like to know too.
  1232.  
  1233. Good luck,
  1234. Paul
  1235.  
  1236. ---------------------------
  1237.  
  1238. From: ozma@kuhub.cc.ukans.edu
  1239. Subject: Beginner C question (char or Boolean)
  1240. Date: 1 Apr 92 23:29:07 CST
  1241. Organization: University of Kansas Academic Computing Services
  1242.  
  1243. Being new to C, I have a rather anally-retentive question.
  1244.  
  1245. What's with the char/Boolean/short variables?  If I want to represent a
  1246. quantity that is either TRUE or FALSE, which of the above is best to use?  I
  1247. have seen code that uses one of any of the three variable types.
  1248.  
  1249. Further, I have had some minor problems when trying to return chars from a
  1250. function.  As in:
  1251.   char HasColor (void);
  1252. It seems some things like: if (HasColor()) fall on their face.  It may be that
  1253. I'm doing other things wrong from within my functions.  Sometimes code like:
  1254. if (HasColor() == TRUE) will seem to work.  Other times it seems like I have to
  1255. do the ol' casting with (char) or (short) or somesuch.  Seems rather grundgy.
  1256.  
  1257. Inspecting THINK C's header files revealed the constants TRUE & FALSE declared
  1258. as (for all I know) shorts or ints.  It occurs to me that comparing chars and
  1259. shorts could be unpredictable.
  1260.  
  1261. So is there a "rule" that those-in-the-know tend to follow?
  1262. Thank you for the rather academic help.  I have perhaps 6 or more books with C
  1263. code in them (tutorials and the like) and I just can't find a consensus on
  1264. this.  I have a problem (while learning) with seeing many approaches to
  1265. something.  I'm always led to the question, "But what's the best way?"
  1266.  
  1267. john calhoun-
  1268.  
  1269.  
  1270. +++++++++++++++++++++++++++
  1271.  
  1272. From: rfischer@Xenon.Stanford.EDU (Ray Fischer)
  1273. Organization: Computer Science Department, Stanford University.
  1274. Date: Thu, 2 Apr 1992 22:23:18 GMT
  1275.  
  1276. ozma@kuhub.cc.ukans.edu writes ...
  1277. >What's with the char/Boolean/short variables?  If I want to represent a
  1278. >quantity that is either TRUE or FALSE, which of the above is best to use?  I
  1279. >have seen code that uses one of any of the three variable types.
  1280.  
  1281. Welcome to C.  You've discovered one of the fuzzier aspects to C, namely
  1282. what's the difference between char, boolean, and integer types.
  1283.  
  1284. Answer: none, really.  They're all numeric integers at heart.  The only
  1285. difference is in the size.  A long is a 32-bit int.  An int is (on the
  1286. Mac usually) 16 bits, and a char is (generally) 8 bits.
  1287.  
  1288. So why the problems?  Size.  Note (this is important!) that if you use
  1289. a function without explicitly declaring it, you will NOT get a syntax error!
  1290. The C compiler will give the function an implicit type of 'function
  1291. returning an int'.  In the case of a function returning booleans or chars,
  1292. the function may return 8-bits of result and the caller will be expecting
  1293. a 16 (or 32) bit result.  The extra bits may well be garbage, and your
  1294. boolean test won't work.
  1295.  
  1296. Rather than have functions that return chars, you might notice that
  1297. in stdio.h, most of the I/O functions that one would expect to return
  1298. characters actually are defined to return ints.  Two reasons.
  1299. 1) since the result is usually returned in a register, it doesn't
  1300.    affect the amount of storage used.
  1301. 2) It allows non-char results such as EOF to be returned.
  1302. 3) (ok, three reasons), chars are just small ints anyway.
  1303.  
  1304. There is no boolean type in C.  A boolean test is true if it is non-zero.
  1305. TRUE and FALSE are usually defined to be 1 and 0 just for clarity.
  1306. 'a' is true (but not == TRUE) and '\0' is false (and == FALSE).
  1307.  
  1308. >Inspecting THINK C's header files revealed the constants TRUE & FALSE declared
  1309. >as (for all I know) shorts or ints.  It occurs to me that comparing chars and
  1310. >shorts could be unpredictable.
  1311.  
  1312. The compiler (if it is correct in its assumption about the types of values)
  1313. is smart enough to convert dissimilar numeric types to a common type for
  1314. assignment and/or comparison.
  1315.  
  1316. >So is there a "rule" that those-in-the-know tend to follow?
  1317.  
  1318. Yes.  Define all of your functions before you use them.
  1319.  
  1320. Ray
  1321. rfischer@cs.stanford.edu
  1322.  
  1323. ---------------------------
  1324.  
  1325. From: don@ohm.york.ac.uk (Don Goodeve)
  1326. Subject: Application icons (attatching to existing apps)
  1327. Date: 3 Apr 92 13:32:02 GMT
  1328. Organization: Electronics Department, University of York, UK
  1329.  
  1330. I have an application on the Mac to which I want to attatch
  1331. an Icon. Using Icon editor and resedit I have generated and
  1332. icon list (ID 128). This is referenced by an FREF entry
  1333. (local ID 0 type APPN). Additionally the BNDL has an
  1334. entry for the icon (ICN#) mapping local ID 0 to 
  1335. ID 128. This all seems together and OK..
  1336.  
  1337. It doesnt appear to work. The file still has its default icon...
  1338.  
  1339. Pursuing this further I understand in the directory
  1340. entry for the file there is a flag bit to indicate if the
  1341. the files icon can be seen. Another bit indicates whether the
  1342. file has a bundle. Try as I may I can see no easy high-level
  1343. way of modifying these (with resedit or any other util I 
  1344. have). Advice please?
  1345.  
  1346. Cheers
  1347.     Don
  1348.  
  1349. don@ohm.york.ac.uk
  1350. - -- 
  1351.  ---------------------------------------------
  1352. | Don --- Well why not? Someone has got to be!|
  1353.  ---------------------------------------------
  1354.  
  1355. +++++++++++++++++++++++++++
  1356.  
  1357. From: jh4o+@andrew.cmu.edu (Jeffrey T. Hutzelman)
  1358. Date: 4 Apr 92 07:58:41 GMT
  1359. Organization: Sophomore, Electrical and Computer Engineering, Carnegie Mellon, Pittsburgh, PA
  1360.  
  1361. Within ResEdit (2.0 or later, I believe), select "Get File/Folder Info" from
  1362. the File menu, and pick the file in question.  This will bring up a dialog
  1363. with the file's type and creator, and lots of checkboxes.  Make sure the
  1364. box labelled "Bundle" is checked, and the box labeled "Initted" is not
  1365. checked. Then CLOSE the info box (answer yes to the save question), and
  1366. open the folder containing the file in Finder.  You should see a change.
  1367. Rebuilding the desktop also helps here, but is a little extreme.
  1368.  
  1369. - -- Jeffrey Hutzelman
  1370.  
  1371. jh4o+@andrew.cmu.edu, jhutz@drycas.BITNET, or JeffreyH11 on America Online
  1372.  
  1373. ---------------------------
  1374.  
  1375. End of C.S.M.P. Digest
  1376. **********************
  1377.