home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-06-04 | 41.9 KB | 1,380 lines |
- C.S.M.P. Digest Wed, 06 May 92 Volume 1 : Issue 73
-
- Today's Topics:
-
- How to program algebraic expression interpretation
- Copyright and Freeware
- code overflow
- Beginner C question (char or Boolean)
- Application icons (attatching to existing apps)
-
-
- The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
-
- These digests are available (by using FTP, account anonymous, your email
- address as password) in the pub/mac/csmp-digest directory on ftp.cs.uoregon.
- edu. This is also the home of the comp.sys.mac.programmer Frequently Asked
- Questions list. The last several issues of the digest are available from
- sumex-aim.stanford.edu as well.
-
- These digests are also available via email. Just send a note saying that you
- want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
- automatically receive each new digest as it is created.
-
- The digest is a collection of articles from the internet newsgroup comp.sys.
- mac.programmer. It is designed for people who read c.s.m.p. semi-regularly
- and want an archive of the discussions. If you don't know what a newsgroup
- is, you probably don't have access to it. Ask your systems administrator(s)
- for details. (This means you can't post questions to the digest.)
-
- The articles in these digests are taken directly from comp.sys.mac.programmer.
- They are not edited; all articles included in this digest are in their original
- posted form. The only articles that are -not- included in these digests are
- those which didn't receive any replies (except those that give information
- rather than ask a question). All replies to each article are concatenated
- onto the original article in the order in which they were received. Article
- threads are not added to the digests until the last article added to the
- thread is at least one month old (this is to ensure that the thread is dead
- before adding it to the digests).
-
- Send administrative mail to mkelly@cs.uoregon.edu.
-
- -------------------------------------------------------
-
- From: jess@gn.ecn.purdue.edu (Jess M Holle)
- Subject: How to program algebraic expression interpretation
- Date: 25 Mar 92 18:39:19 GMT
- Organization: Purdue University Engineering Computer Network
-
- I was giving some thought to summer programming projects and found that
- many would need to take a user entered algebraic expression, parse it,
- store it, and then QUICKLY calculate the result of the expression.
-
- Basically, I guess I would like a little clue as to how spreadsheets work
- their magic. How do you take this user entry and run calculations with it
- quickly?
-
- Thanks to all who reply,
-
- Jess Holle
-
- +++++++++++++++++++++++++++
-
- From: orpheus@reed.edu (P. Hawthorne)
- Date: 25 Mar 92 22:56:18 GMT
- Organization: Reed College, Portland OR
-
-
- jess@gn.ecn.purdue.edu (Jess M Holle) writes:
- . I was giving some thought to summer programming projects and found that
- . many would need to take a user entered algebraic expression, parse it,
- . store it, and then QUICKLY calculate the result of the expression.
-
- Well, I needed to write the same thing a couple of months ago. For the
- first implementation, I was mostly concerned with getting it done than with
- making it fast. So the object is not a fast one, but it is correct.
- Since this particular object is not a crucial as some of the others in
- the class library I have written, perhaps it could benefit from being exposed
- to the world at large. Maybe you have some time...
-
-
- unit Evaluator;
-
- interface
-
- uses
- Script, SANE, Picker, Types, Routines;
-
- const
- maxOperands = 12;
- maxFunctions = 12;
-
- lesserPrecedence = -1;
- equivalentPrecedence = 0;
- higherPrecedence = 1;
-
- dynamicParameters = -1;
-
- type
- Evaluator = object(Abstract)
- numOperands: Integer;
- operandList: array[1..maxOperands] of record
- Name: Text;
- Relative: Boolean;
- end;
- operandTable: array[0..maxOperands, 0..maxOperands] of Integer;
-
- numFunctions: Integer;
- functionList: array[1..maxOperands] of record
- Name: Text;
- Params: Integer;
- end;
-
- TermStack: array[0..255] of Number;
- StackIndex: Integer;
-
- infix, postfix, solution: Str255;
-
- function Evaluator.Construct: Boolean;
- procedure Evaluator.Destruct;
-
- procedure Evaluator.OperandInit;
- function Evaluator.GetOperandIndex (anOperand: Text): Integer;
- procedure Evaluator.MarkPrecedence (a: Text; prec: Integer; b: Text);
- procedure Evaluator.UniversalPrecedence (a: Text; prec, start, finish:
- Integer);
- procedure Evaluator.IncludeOperand (anOperand: Text);
- procedure Evaluator.RelativeOperand (anOperand: Text);
- function Evaluator.RelativeOperator (anOperand: Text): Boolean;
- function Evaluator.PrecedenceHigher (a, b: Integer): Boolean;
-
- procedure Evaluator.FunctionInit;
- function Evaluator.GetFunctionIndex (aFunction: Text): Integer;
- procedure Evaluator.IncludeFunction (aFunction: Text; aParameterCount:
- Integer);
-
- function Evaluator.LetterOrDigit (aTestCase: Str255): Boolean;
- function Evaluator.JoinParts (partOne, partTwo: Str255): Str255;
- function Evaluator.LexicalCheck (var aStr: Str255): Boolean;
- function Evaluator.InfixToPostfix (aStr: Str255): Str255;
- function Evaluator.Evaluate (aStr: Str255): Number;
- end;
-
- var
- theEvaluator: Evaluator;
-
- procedure InitEvaluator;
- procedure ExitEvaluator;
-
- implementation
-
- procedure InitEvaluator;
- begin
- New(theEvaluator);
- if theEvaluator = nil then
- Danger('Not enough memory to create an evaluator.');
- if not theEvaluator.Construct then
- Danger('Not enough memory to construct an evaluator.');
- end;
-
- procedure ExitEvaluator;
- begin
- theEvaluator.Destruct;
- end;
-
- function Evaluator.Construct: Boolean;
- begin
- Construct := false;
-
- Lock;
-
- OperandInit;
- FunctionInit;
-
- Construct := true;
- end;
-
- procedure Evaluator.Destruct;
- begin
- Dispose;
- end;
-
- function Evaluator.GetOperandIndex (anOperand: Text): Integer;
- var
- a: Integer;
- begin
- GetOperandIndex := 0;
- for a := 1 to numOperands do
- if operandList[a].Name = anOperand then
- begin
- GetOperandIndex := a;
- Leave;
- end;
- end;
-
- procedure Evaluator.MarkPrecedence (a: Text; prec: Integer; b: Text);
- var
- aPos, bPos: Integer;
- begin
- aPos := GetOperandIndex(a);
- bPos := GetOperandIndex(b);
- if ((aPos > 0) and (bPos > 0)) then
- begin
- operandTable[aPos, bPos] := prec;
- operandTable[bPos, aPos] := -prec;
- end
- else
- Danger('Invalid operator for precedence declaration.');
- end;
-
- procedure Evaluator.UniversalPrecedence (a: Text; prec, start, finish:
- Integer);
- var
- aPos, bPos, e: Integer;
- begin
- aPos := GetOperandIndex(a);
- if finish > numOperands then
- finish := numOperands;
- if (aPos > 0) then
- begin
- for e := start to finish do
- begin
- operandTable[aPos, e] := prec;
- operandTable[e, aPos] := -prec;
- end;
- end
- else
- Danger('Invalid operator for precedence declaration.');
- end;
-
- procedure Evaluator.IncludeOperand (anOperand: Text);
- begin
- numOperands := numOperands + 1;
- operandList[numOperands].Name := anOperand;
- operandList[numOperands].Relative := false;
- end;
-
- procedure Evaluator.RelativeOperand (anOperand: Text);
- var
- anIndex: Integer;
- begin
- anIndex := GetOperandIndex(anOperand);
- if anIndex > 0 then
- operandList[numOperands].Relative := true;
- end;
-
- function Evaluator.RelativeOperator (anOperand: Text): Boolean;
- var
- anIndex: Integer;
- begin
- anIndex := GetOperandIndex(anOperand);
- if anIndex > 0 then
- RelativeOperator := operandList[numOperands].Relative
- else
- RelativeOperator := false;
- end;
-
- function Evaluator.PrecedenceHigher (a, b: Integer): Boolean;
- begin
- PrecedenceHigher := false;
- if a > 0 then
- PrecedenceHigher := (operandTable[a, b] = higherPrecedence)
- end;
-
- procedure Evaluator.OperandInit;
- var
- a, e: Integer;
- begin
- for a := 0 to maxOperands do
- for e := 0 to maxOperands do
- operandTable[a, e] := equivalentPrecedence;
-
- numOperands := 0;
- IncludeOperand('^');
- IncludeOperand('/');
- IncludeOperand('*');
- IncludeOperand('+');
- IncludeOperand('-');
- IncludeOperand('=');
- IncludeOperand('<>');
- IncludeOperand('<');
- IncludeOperand('>');
- IncludeOperand('<=');
- IncludeOperand('>=');
-
- RelativeOperand('=');
- RelativeOperand('<>');
- RelativeOperand('<');
- RelativeOperand('>');
- RelativeOperand('<=');
- RelativeOperand('>=');
-
- MarkPrecedence('^', higherPrecedence, '/');
- MarkPrecedence('^', higherPrecedence, '*');
- MarkPrecedence('^', higherPrecedence, '+');
- MarkPrecedence('^', higherPrecedence, '-');
-
- MarkPrecedence('/', higherPrecedence, '*');
- MarkPrecedence('/', higherPrecedence, '+');
- MarkPrecedence('/', higherPrecedence, '-');
-
- MarkPrecedence('*', higherPrecedence, '+');
- MarkPrecedence('*', higherPrecedence, '-');
-
- UniversalPrecedence('=', lesserPrecedence, 1, 5);
- UniversalPrecedence('<>', lesserPrecedence, 1, 5);
- UniversalPrecedence('<', lesserPrecedence, 1, 5);
- UniversalPrecedence('>', lesserPrecedence, 1, 5);
- UniversalPrecedence('<=', lesserPrecedence, 1, 5);
- UniversalPrecedence('>=', lesserPrecedence, 1, 5);
- end;
-
- function Evaluator.GetFunctionIndex (aFunction: Text): Integer;
- var
- a: Integer;
- begin
- GetFunctionIndex := 0;
- aFunction := Caseless(aFunction);
- for a := 1 to numFunctions do
- if functionList[a].Name = aFunction then
- begin
- GetFunctionIndex := a;
- Leave;
- end;
- end;
-
- procedure Evaluator.IncludeFunction (aFunction: Text; aParameterCount:
- Integer);
- begin
- numFunctions := numFunctions + 1;
- aFunction := Caseless(aFunction);
- with functionList[numFunctions] do
- begin
- Name := aFunction;
- LwrText(@Name[1], Length(Name));
- Params := aParameterCount;
- end;
- end;
-
- procedure Evaluator.FunctionInit;
- begin
- numFunctions := 0;
- IncludeFunction('sum', dynamicParameters);
- IncludeFunction('average', dynamicParameters);
- IncludeFunction('max', dynamicParameters);
- IncludeFunction('min', dynamicParameters);
- IncludeFunction('if', 3);
- IncludeFunction('percentage', 2);
- end;
-
- function Evaluator.LetterOrDigit (aTestCase: Str255): Boolean;
- var
- c: Char;
- begin
- c := aTestCase[1];
- LetterOrDigit := ((c >= 'a') and (c <= 'z')) or ((c >= 'A') and (c <= 'Z'))
- or ((c >=
- '0') and (c <= '9')) or (c = '.');
- end;
-
- function Evaluator.JoinParts (partOne, partTwo: Str255): Str255;
- begin
- if partOne <> '' then
- if partOne[Length(partOne)] <> ' ' then
- partOne := Concat(partOne, ' ');
- if partOne = ' ' then
- partOne := '';
- if partTwo = ' ' then
- partTwo := '';
- JoinParts := Concat(partOne, partTwo);
- end;
-
- function Evaluator.LexicalCheck (var aStr: Str255): Boolean;
- var
- a, e, i, parenCount: Integer;
- c: Char;
- outString: Str255;
- tempTerm: Str255;
- errorCondition: Boolean;
- begin
- parenCount := 0;
- outString := '';
- a := 1;
- errorCondition := ((Length(aStr) = 0) or (Length(aStr) > 254));
- if not errorCondition then
- repeat
- c := aStr[a];
- a := a + 1;
- if (c = '(') then
- parenCount := parenCount + 1
- else if (c = ')') then
- parenCount := parenCount - 1;
- if ((c >= '0') and (c <= '9')) or (c = '.') then
- begin
- i := 1;
- for e := a to Length(aStr) do
- if ((aStr[e] >= '0') and (aStr[e] <= '9')) or (aStr[e] = '.') then
- i := i + 1
- else
- e := Length(aStr);
- outString := Concat(outstring, Copy(aStr, a - 1, i));
- a := a + i - 1;
- end
- else if ((c >= 'A') and (c <= 'Z')) or ((c >= 'a') and (c <= 'z')) or (c =
- ':')
- then
- begin
- i := 1;
- for e := a to Length(aStr) do
- if ((aStr[e] >= 'A') and (aStr[e] <= 'Z')) or ((aStr[e] >= 'a') and
- (aStr[e] <=
- 'z')) or (aStr[e] = ':') then
- i := i + 1
- else
- e := Length(aStr);
- tempTerm := Copy(aStr, a - 1, i);
- outString := Concat(outstring, tempTerm);
- a := a + i - 1;
- end
- else if ((c >= '<') and (c <= '>')) then
- begin
- i := 1;
- for e := a to Length(aStr) do
- if ((aStr[e] >= '<') and (aStr[e] <= '>')) then
- i := i + 1
- else
- e := Length(aStr);
- tempTerm := Copy(aStr, a - 1, i);
- LwrText(@tempTerm[1], Length(tempTerm));
- outString := Concat(outstring, tempTerm);
- a := a + i - 1;
- end
- else if c <> ' ' then
- outString := Concat(outString, c);
- if outString[Length(outString)] <> ' ' then
- outString := Concat(outString, ' ');
- until a > Length(aStr);
- aStr := outString;
- if not errorCondition then
- errorCondition := (parenCount <> 0);
- LexicalCheck := (not errorCondition)
- end;
-
- function Evaluator.InfixToPostfix (aStr: Str255): Str255;
- var
- aNumeric: Number;
- aLookahead: Str255;
-
- procedure UnexpectedEnd;
- begin
- Caution('Unexpected end.');
- Exit(InfixToPostfix);
- end;
-
- procedure OutOfRange;
- begin
- Caution('Out of range.');
- Exit(InfixToPostfix);
- end;
-
- procedure ParameterDeficit;
- begin
- Caution('Not enough parameters.');
- Exit(InfixToPostfix);
- end;
-
- procedure ParameterSurplus;
- begin
- Caution('Too many parameters.');
- Exit(InfixToPostfix);
- end;
-
- procedure PopNext;
- begin
- if not BreakTerm(aStr, aLookahead) then
- Nothing;
- end;
-
- function Expression: Str255;
- forward;
-
- function Term: Str255;
- forward;
-
- function Rest: Str255;
- forward;
-
- function Parameters (var aResult: Str255): Integer;
- forward;
-
- function Expression: Str255;
- begin
- Expression := JoinParts(Term, Rest);
- if (aLookahead = ')') then
- PopNext;
- end;
-
- function Parameters (var aResult: Str255): Integer;
- var
- parameterCount: Integer;
- begin
- parameterCount := 1;
- aResult := '';
- if aLookahead = '(' then
- PopNext
- else
- ParameterDeficit;
- while (aLookahead <> ')') and (aLookahead <> '') do
- begin
- aResult := JoinParts(aResult, Rest);
- if aLookahead = ',' then
- begin
- parameterCount := parameterCount + 1;
- PopNext;
- end
- else if (aLookahead <> ')') and (aLookahead <> '') then
- if not RelativeOperator(aLookahead) then
- ParameterSurplus;
- end;
- Parameters := parameterCount;
- end;
-
- function Term: Str255;
- var
- anOperand: Str255;
- aResult, aParameterSet: Str255;
- functionIndex, parameterCount: Integer;
- begin
- if LetterOrDigit(aLookahead) then
- begin
- functionIndex := GetFunctionIndex(aLookahead);
- if functionIndex > 0 then
- begin
- aResult := aLookahead;
- PopNext;
- parameterCount := Parameters(aParameterSet);
- if functionList[functionIndex].Params = dynamicParameters then
- aParameterSet := JoinParts(aParameterSet, IntegerToText(parameterCount))
- else if parameterCount < functionList[functionIndex].Params then
- ParameterDeficit
- else if parameterCount > functionList[functionIndex].Params then
- ParameterSurplus;
- aResult := JoinParts(aParameterSet, aResult);
- if aLookahead = ')' then
- PopNext;
- end
- else
- begin
- aResult := aLookahead;
- PopNext;
- end;
- end
- else if aLookahead = '(' then
- begin
- PopNext;
-
- if aLookahead = '-' then
- begin
- anOperand := aLookahead;
- PopNext;
- end
- else
- anOperand := '';
-
- aResult := Expression;
-
- if anOperand = '-' then
- aResult := JoinParts(aResult, '-1 *');
- if aLookahead = ')' then
- PopNext;
- end
- else
- aResult := '';
- Term := aResult;
- end;
-
- function Rest: Str255;
- var
- cumulative, right, operand, storedOperand: Str255;
- operandIndex: Integer;
-
- begin
- cumulative := '';
- repeat
- operandIndex := GetOperandIndex(aLookahead);
- if operandIndex > 0 then
- begin
- operand := aLookahead;
- PopNext;
- right := Term;
- while PrecedenceHigher(GetOperandIndex(aLookahead), operandIndex) do
- begin
- storedOperand := aLookahead;
- PopNext;
- right := JoinParts(right, JoinParts(Term, storedOperand));
- end;
- cumulative := JoinParts(cumulative, JoinParts(right, operand))
- end
- else if ((aLookahead <> ')') or (aLookahead <> ',')) and (aStr <> '') then
- cumulative := JoinParts(cumulative, Term);
- until (aStr = '') or (aLookahead = ')') or (aLookahead = ',') or (not
- RelativeOperator(aLookahead));
- {IF (aLookahead = ')') THEN}
- {PopNext;}
- Rest := cumulative;
- end;
-
- procedure Main;
- begin
- if not LexicalCheck(aStr) then
- Danger('Unmatched parentheses.')
- else
- begin
- if not BreakTerm(aStr, aLookahead) then
- UnexpectedEnd;
- InfixToPostfix := Expression;
- end;
- end;
-
- begin
- Main;
- end;
-
- function Evaluator.Evaluate (aStr: Str255): Number;
- var
- aNumeric: Number;
- aTerm: Str255;
- aCounter: Integer;
- a: Integer;
-
- procedure Push (var aValue: Number);
- begin
- TermStack[StackIndex] := aValue;
- StackIndex := StackIndex + 1;
- end;
-
- function Pop: Number;
- var
- aValue: Number;
- begin
- StackIndex := StackIndex - 1;
- if StackIndex < 0 then
- begin
- if true then
- Pop := 0;
- end
- else
- begin
- aValue := TermStack[StackIndex];
- TermStack[StackIndex] := 0;
- Pop := aValue;
- end;
- end;
-
- procedure Exch;
- var
- a, e: Number;
- begin
- a := Pop;
- e := Pop;
- Push(e);
- Push(a);
- end;
-
- function StackEmpty: Boolean;
- begin
- StackEmpty := (StackIndex < 0);
- end;
-
- procedure StackInit;
- var
- a: Integer;
- begin
- StackIndex := 0;
- end;
-
- var
- eNumeric: Number;
- neutralCase: Text;
- begin
- StackInit;
- while BreakTerm(aStr, aTerm) do
- begin
- if aTerm = '+' then
- aNumeric := Pop + Pop
- else if aTerm = '-' then
- begin
- aNumeric := Pop;
- aNumeric := Pop - aNumeric;
- end
- else if aTerm = '*' then
- aNumeric := Pop * Pop
- else if aTerm = '/' then
- begin
- aNumeric := Pop;
- aNumeric := Pop / aNumeric;
- end
- else if aTerm = '^' then
- begin
- aNumeric := Pop;
- aNumeric := xPwrY(Pop, aNumeric);
- end
- else if aTerm = '=' then
- begin
- if (Pop = Pop) then
- aNumeric := 1
- else
- aNumeric := 0;
- end
- else if aTerm = '<>' then
- begin
- if (Pop <> Pop) then
- aNumeric := 1
- else
- aNumeric := 0;
- end
- else if aTerm = '<' then
- begin
- aNumeric := Pop;
- eNumeric := Pop;
- if (eNumeric < aNumeric) then
- aNumeric := 1
- else
- aNumeric := 0;
- end
- else if aTerm = '>' then
- begin
- aNumeric := Pop;
- eNumeric := Pop;
- if (eNumeric > aNumeric) then
- aNumeric := 1
- else
- aNumeric := 0;
- end
- else if aTerm = '<=' then
- begin
- aNumeric := Pop;
- eNumeric := Pop;
- if (eNumeric <= aNumeric) then
- aNumeric := 1
- else
- aNumeric := 0;
- end
- else if aTerm = '>=' then
- begin
- aNumeric := Pop;
- eNumeric := Pop;
- if (eNumeric >= aNumeric) then
- aNumeric := 1
- else
- aNumeric := 0;
- end
- else
- begin
- neutralCase := aTerm;
- LwrText(@neutralCase[1], Length(neutralCase));
- if neutralCase = 'percentage' then
- begin
- aNumeric := Pop;
- aNumeric := Percentage(Pop, aNumeric);
- end
- else if neutralCase = 'max' then
- begin
- aCounter := Trunc(Pop);
- if aCounter < 1 then
- Danger('At least one parameter must follow this function.');
- aNumeric := Pop;
- for a := 2 to aCounter do
- aNumeric := MaxTwo(aNumeric, Pop);
- end
- else if neutralCase = 'min' then
- begin
- aCounter := Trunc(Pop);
- if aCounter < 1 then
- Danger('At least one parameter must follow this function.');
- aNumeric := Pop;
- for a := 2 to aCounter do
- aNumeric := MinTwo(aNumeric, Pop);
- end
- else if neutralCase = 'sum' then
- begin
- aCounter := Trunc(Pop);
- if aCounter < 1 then
- Danger('At least one parameter must follow this function.');
- aNumeric := Pop;
- for a := 2 to aCounter do
- aNumeric := aNumeric + Pop;
- end
- else if neutralCase = 'if' then
- begin
- aNumeric := Pop;
- eNumeric := Pop;
- if Pop <> 0 then
- aNumeric := eNumeric;
- end
- else if neutralCase = 'average' then
- begin
- aCounter := Trunc(Pop);
- if aCounter < 1 then
- Danger('At least one parameter must follow this function.');
- aNumeric := Pop;
- for a := 2 to aCounter do
- aNumeric := aNumeric + Pop;
- aNumeric := aNumeric / aCounter;
- end
- else
- aNumeric := TextToNumber(aTerm);
- end;
- Push(aNumeric);
- end;
-
- Evaluate := Pop;
- end;
-
- end.
-
- +++++++++++++++++++++++++++
-
- From: d88-jwa@byse.nada.kth.se (Jon W{tte)
- Date: 25 Mar 92 22:09:08 GMT
- Organization: Royal Institute of Technology, Stockholm, Sweden
-
- > jess@gn.ecn.purdue.edu (Jess M Holle) writes:
-
- I was giving some thought to summer programming projects and found that
- many would need to take a user entered algebraic expression, parse it,
- store it, and then QUICKLY calculate the result of the expression.
-
- Basically, I guess I would like a little clue as to how spreadsheets work
- their magic. How do you take this user entry and run calculations with it
- quickly?
-
- There are several algorithms. Using two stacks, you can run through
- the text as-is and achieve pretty decent performance; I believe the
- algorithm is called the railroad algo.
-
- However, my favourite starts with building a tree of the expression,
- just like you would in a compiler. For instance:
-
- 3 + 5 * 6
-
- Turns into:
-
- +
- 3 *
- 5 6
-
- That requires lots of small blocks of memory (you can of course use
- an array of "node" type and use indexes into the array. Same thing,
- really)
-
- Now, this is nice and fast and easy to print and/or debug. However,
- it requires memory, and is hard to save to disk. The next step is
- flattening the tree into a byte-code stream like thus:
-
- + I3 * I5 I6
-
- where "I3" of course means a special token for integer, and the
- actual literal.
-
- This kind of sxpression is also easily parsed using one stack, and
- a recursive algorithm. However, it's a little inflexible, so you
- might want to emit some byte-code (I did that in a spreadsheet once,
- to get whizzy macro capabilities) like:
-
- R1=5 R2=6 R1*=R2 R2=3 R1+=3
-
- For an interpreted pseudo-register-machine.
-
- The nice thing about that is that you can have bytes for conditionals,
- jumps, loops, User Interface, ... - you can compile a script languaga
- down top this kind of code. Really nifty. Microsoft Word and Excel
- are both partly written in P-Code, and although I don't know the innards
- of that engine, it's clearly a powerful space-saver. If you just remember
- to flush the cache when needed...
-
- HOWEVER: (Neat hack alert) now that you're emitting code for a pseudo-
- machine, why not go all the way and emit "real" machine code. Granted,
- it's a trifle more complex to keep track of MC68881/2 timing and to
- flush the cache after smitting machine code, but once you have, you
- have a really neat cell type:
-
- MOVEQ #5,D0
- MULS #6,D0
- ADDQ #3,D0
- RTS
-
- Evaluating this is as fast as calling a subroutine written explicitly
- to solve this problem... since that's what is is ! Just remember to
- flush the cache after emitting the instructions.
-
- Note that your tree parser OF COURSE would recognize static constructs
- like these and optimize them once and for all, but substitute cell
- references for "3," "5" and "6" and you see what I mean.
-
- You could even have multiple modes; one mode with the tree, and once
- where the cell is compiled into code, for instance. It all depends
- on your application.
-
- Hope this helps,
-
- - --
- h+@nada.kth.se; Jon W{tte, the Diplomat - NOT!
-
- +++++++++++++++++++++++++++
-
- From: scott@mcl.mcl.ucsb.edu (Scott Bronson)
- Date: 6 Apr 92 01:25:35 GMT
-
- I've been toying around with this idea, because I think allowing the
- user to enter functions, then having the machine compile them would
- speed up many of the shareware and vertical-market applications out
- now to solve specific problems. It seems awfully redundant, though,
- and a massive headache to have each separate application link with
- someone else's library, etc. etc.
-
- I have a solution in mind. I've been meaning to write a simple mathematical
- expression parser and compiler without a front end, then having other apps
- send this program AppleEvents with the expression they want evaluated.
- This program will then reply with the machine code to do this. The
- calling app then locks this down and JMPs to the bottom of the block
- returned. Of course, the block returned would be in the form of a Pascal
- function so anyone could use it.
-
- This would also work over networks. Concievably, you could have entire
- tables for variables (pi, e, user-defined), user-defined functions,
- and on and on. That way, if you were to enter a function (acosh()
- or something arcane like that, but built upon other functions), you
- wouldn't have to add it to each separate program that parses these
- strings. Just add it to your parser and every single program that uses
- your parser is able to take full advantage of it.
-
- I've been meaning to get this project started for some time now, but other
- things always seem more important. If anyone else would like to take a
- weekend and write it, contact me first (if you like). I'll probably be
- able to save you a little time.
-
- - Scott
-
- ---------------------------
-
- From: johnsd2@jec323.its.rpi.edu (Daniel Norman Johnson)
- Subject: Copyright and Freeware
- Organization: Information Technology Services, Rennselaer Polytechnic Institute.
- Date: Fri, 27 Mar 1992 23:16:03 GMT
-
- Greetings All. I have a hankering to publish some Freeware, but I do not know
- how to do this. Is this a FAQ? If not could somebody tell me how this is done,
- normally? Or give me a hint? I have asked about this before but I got no
- responces adressing this (or if I did I missed them somehow)
-
- Also, last time I asked about this stuff I asked about copyrights. Symantic
- owns a copyright on the software I used to write my would-be freeware
- (its done in THINK Pascal [not C, as I misspoke previously]); They say that
- all ya hafta do is have a copyright that protects *THEIR* copyright.
-
- The only responce I got adressed this. It [sorry, I do not remember who it
- was!] said that all I had to do was put a copyright notice on my program-
- I didn't have to bother registering if I did not want to! Is this right?
- It sounds a little fishy to me, but then what do I know?
-
- If this is the wrong forum for these questions, could somebody direct me
- to the right one?
-
- Thanks in advance.
- - --
- - Dan Johnson
- And God said "Jeeze, this is dull"... and it *WAS* dull. Genesis 0:0
-
- +++++++++++++++++++++++++++
-
- From: kanderso@mabillon.ICS.UCI.EDU (Kenneth Anderson)
- Date: 27 Mar 92 23:50:51 GMT
-
- In comp.sys.mac.programmer you write:
-
- >Greetings All. I have a hankering to publish some Freeware, but I do not know
- >how to do this. Is this a FAQ? If not could somebody tell me how this is done,
- >normally? Or give me a hint? I have asked about this before but I got no
- >responces adressing this (or if I did I missed them somehow)
-
- >Also, last time I asked about this stuff I asked about copyrights. Symantic
- >owns a copyright on the software I used to write my would-be freeware
- >(its done in THINK Pascal [not C, as I misspoke previously]); They say that
- >all ya hafta do is have a copyright that protects *THEIR* copyright.
-
- You will need to say something like:
-
- This software produced using the Symantic Think Pascal compiler, as such
- portions of this software are Copyright 1992, Symantic.
-
- Because of the adoption by the U.S. of the Berne Convention in 1988, you
- no longer need to place a notice about your copyright, but the one for
- Symantic is required.
-
- >The only responce I got adressed this. It [sorry, I do not remember who it
- >was!] said that all I had to do was put a copyright notice on my program-
- >I didn't have to bother registering if I did not want to! Is this right?
- >It sounds a little fishy to me, but then what do I know?
-
- Registration of your computer software is only helps if you plan on sueing
- someone for copyright infringment. It simply strenthens your case in
- front of the judge. I.E. "How can this guy say he isn't infringing on
- my copyright, when I've got the damn thing registered with the Dept. of
- Copyrights??!!"
-
-
- >If this is the wrong forum for these questions, could somebody direct me
- >to the right one?
-
- You may do better in misc.int-property.
-
- >Thanks in advance.
- >--
- > - Dan Johnson
- >And God said "Jeeze, this is dull"... and it *WAS* dull. Genesis 0:0
- - --
- - --------------------------------------------------------------------------------
- Ken Anderson | "I'd much rather live in perfection,
- U.C. Irvine | than deal with reality." -- Kenbod
- - --------------------------------------------------------------------------------
- Happy! Happy! Happy! Joy! Joy! Joy! | Practice random kindness and
- -- Stimpy | senseless acts of beauty. -- Anonymous
- - --------------------------------------------------------------------------------
-
- +++++++++++++++++++++++++++
-
- From: tinsel@uiuc.edu (Thomas Aaron Insel)
- Date: 27 Mar 92 23:48:13 GMT
- Organization: University of Illinois at Urbana
-
- johnsd2@jec323.its.rpi.edu (Daniel Norman Johnson) writes:
-
- >The only responce I got adressed this. It [sorry, I do not remember who it
- >was!] said that all I had to do was put a copyright notice on my program-
- >I didn't have to bother registering if I did not want to! Is this right?
- >It sounds a little fishy to me, but then what do I know?
-
- I may have been the one who said it, but it's correct. For more information
- on copyright law geared to lay-people, (including the fact that you don't need
- to register a copyright in many cases), and blank forms (if you do want to
- register), write to the Library of Congress in Washington, DC.
- - --
- Thomas Aaron Insel (tinsel@uiuc.edu)
- I speak for myself, and not for the State or University of Illinois.
- "We must not confuse dissent with disloyalty." -- Edward R. Murrow
-
- +++++++++++++++++++++++++++
-
- From: peter@cujo.curtin.edu.au (Peter N Lewis)
- Date: 28 Mar 92 06:18:39 GMT
- Organization: NCRPDA, Curtin University
-
- In article <45ptn8j@rpi.edu>, johnsd2@jec323.its.rpi.edu (Daniel Norman Johnson) writes:
- >From: peter@cujo.curtin.edu.au (Peter N Lewis)
- To: johnsd2@jec323.its.rpi.edu
- Subject: Re: Copyright and Freeware
- References: <45ptn8j@rpi.edu>
- Organization: NCRPDA, Curtin University
-
- In article <45ptn8j@rpi.edu>, johnsd2@jec323.its.rpi.edu (Daniel Norman Johnson) writes:
- >
- > Greetings All. I have a hankering to publish some Freeware, but I do not know
- > how to do this. Is this a FAQ? If not could somebody tell me how this is done,
- > normally? Or give me a hint? I have asked about this before but I got no
- > responces adressing this (or if I did I missed them somehow)
-
- I would certainly have replied if I'd seen it, perhaps your posting
- got eaten by a cruel and nasty net.god?
-
- Anyway, all you do is this: Package all the relevent files, including
- a docs file if at all possible, encode it in an archive (You can use
- StuffIt Classic to make a StuffIt 1.5.1 archive - everyone can decode
- StuffIt 1.5.1 files), BinHex it (StuffIt will do that too), edit the BinHex,
- and right at the start before the (This file...) line, add it a short
- description of your file (here is one I used:
-
- *****
- Finger v1.3.5 & Fingerd v1.3.5 is an implementation of the UNIX Finger
- protocol for Macs with MacTCP. Fingerd is a background only application
- that allows you to be fingered, while Finger is a finger client, allowing
- you to finger other machines, as well as allowing others to finger you.
- Both are System 7 friendly (but hopefully not dependent).
-
- They are Povertyware, which basically means you get to send me five
- dollars if you can. If you use these programs, drop me a note and say hello!
-
- Hope you like them,
- Peter <peter@cujo.curtin.edu.au>.
-
- Finger 1.3.5 & Fingerd 1.3.5 Copyright 1991-1992, Peter N Lewis
- ******
-
- (Note: You must keep your signiture at the bottom to one line according to
- the posting guidelines for sumex-aim)
-
- Then mail that file to macgifts@rascal.ics.utexas.edu and it will be
- resent to all the major archives (umich, sumex, rascal...), as well
- as to comp.binaries.mac.
- >
- > Also, last time I asked about this stuff I asked about copyrights. Symantic
- > owns a copyright on the software I used to write my would-be freeware
- > (its done in THINK Pascal [not C, as I misspoke previously]); They say that
- > all ya hafta do is have a copyright that protects *THEIR* copyright.
-
- Just put:
- Prograname copyright 1992 Your Name
- Portions of this code are copyright by Symantec
-
- Your code is automatically copyrighted to you as soon as you write it, there
- is no need to register it, or even to put the above messages on, but the
- above messages are a GOOD idea, and will give you a much better legal
- standing if it were ever necessary to do anything legal about it.
- (Disclaimer: I am not a laywer!). Also put the fact that the program
- is free in the about box, otherwise people won't know and should assume
- that it is not free...
-
- HTH,
- Peter.
-
- ______________________________________________________________________
- Peter N Lewis, NCRPDA, Curtin University peter@cujo.curtin.edu.au
- GPO Box U1987, Perth WA 6001, AUSTRALIA FAX: +61 9 367 8141
-
- +++++++++++++++++++++++++++
-
- From: jahnke@joplin.biosci.arizona.edu (Jerome Jahnke)
- Date: 29 Mar 92 18:25:01 GMT
- Organization: Biology Learning Center
-
- In article <9203271550.aa20554@Paris.ics.uci.edu>, kanderso@mabillon.ICS.UCI.EDU (Kenneth Anderson) writes:
- > You will need to say something like:
- >
- > This software produced using the Symantic Think Pascal compiler, as such
- > portions of this software are Copyright 1992, Symantic.
- >
- > Because of the adoption by the U.S. of the Berne Convention in 1988, you
- > no longer need to place a notice about your copyright, but the one for
- > Symantic is required.
-
- Nope, the license agreement in the Manual states CLEARLY:
- "you also have the right to use, distribute, and license such programs to
- third parties without payment of any further license fees, so long as a
- copyright notice sufficent to protect YOUR copyright in the software in
- United States or any other coutry is included in the graphic display of
- your software and on the labels affixed to the media on which your software
- is distriuted."
-
- See it does not say a THING about Symantec needing to be referenced in the
- about. They are granting you rights to the software. I assume that if you
- release the software are public domain that you will then have to put a
- copyright to Symantec on it.
-
- When in doubt read the licensing agreement. With MacApp you have to pay
- Apple to distribute a program which uses MacApp. I don't remember if you have
- to include an Apple Copyright. But in Thinks product you only have to include
- your own copyright.
-
- Jer,
- - ----
- Jerome Jahnke
- Biology Learning Center
- University of Arizona
- 'jahnke@biosci.arizona.edu' or +1 (602) 621-3820
-
- +++++++++++++++++++++++++++
-
- From: scott@mcl.mcl.ucsb.edu (Scott Bronson)
- Date: 6 Apr 92 03:18:07 GMT
-
- Now that Symantec is using Apple's libraries as include, header, and glue
- doesn't that mean that portions are copyright (c) Apple Computer?
-
- What if I were to use nothing but Apple's glue and THINK's inline assembler?
- It just gets muddier from there...
-
- ---------------------------
-
- From: pete@othello.dartmouth.edu (Pete Schmitt)
- Subject: code overflow
- Date: 30 Mar 92 15:27:08 GMT
- Organization: Dartmouth College, Hanover, NH
-
- This bug comes up right after compilation of a 890 line file using %U to
- update the project. I can't find any reference to this the the Think C 5.0
- docs. What does it mean?
-
- - -pete
- - --
- Peter Schmitt, UNIX Systems Specialist, Computing Services, Dartmouth College
- Email: peter.schmitt@dartmouth.edu Phone: 603-646-2085
- ******* Let us not give up meeting together, as some are in the habit *******
- ******* of doing, but let us encourage one another. -Hebrews 10:25 *******
-
- +++++++++++++++++++++++++++
-
- From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy)
- Organization: Kalamazoo College
- Date: Mon, 30 Mar 1992 18:40:16 GMT
-
- pete@othello.dartmouth.edu (Pete Schmitt) writes:
- >This bug comes up right after compilation of a 890 line file using %U to
- >update the project. I can't find any reference to this the Think C 5.0
- >docs.
-
- Did you look on page 488? "Code Overflow: You have more than 32K of
- code or data in one file. Break your file up into smaller files."
- Since there's only 890 lines, you're probably declaring a huge array.
-
- This FAQ has come up several times before--are there a lot of misprinted
- manuals out there? Or do people just not think to look in the "Error
- Messages" appendix to figure out an error message?
- - --
- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy
-
- +++++++++++++++++++++++++++
-
- From: overdriv@tsoft.sf-bay.org (Paul A. Pelton)
- Organization: The TeleSoft BBS and Public Access Unix, +1 415 969 7958
- Date: Sat, 4 Apr 1992 02:14:45 GMT
-
- In article <1992Mar30.152708.17482@dartvax.dartmouth.edu> pete@othello.dartmouth.edu (Pete Schmitt) writes:
- >This bug comes up right after compilation of a 890 line file using %U to
- >update the project. I can't find any reference to this the the Think C 5.0
- >docs. What does it mean?
-
- This is a long-shot. Are you using THINK C's object extensions?
-
- I got this error when I compiled a bunch of .c files which contained no
- function definitions but simply included a .h file. Basically, all I was
- compiling was a bunch of class declarations and method prototypes but no
- actual code.
-
- You might look for something like that. If you find out exactly what "code
- overflow" means, I'd like to know too.
-
- Good luck,
- Paul
-
- ---------------------------
-
- From: ozma@kuhub.cc.ukans.edu
- Subject: Beginner C question (char or Boolean)
- Date: 1 Apr 92 23:29:07 CST
- Organization: University of Kansas Academic Computing Services
-
- Being new to C, I have a rather anally-retentive question.
-
- What's with the char/Boolean/short variables? If I want to represent a
- quantity that is either TRUE or FALSE, which of the above is best to use? I
- have seen code that uses one of any of the three variable types.
-
- Further, I have had some minor problems when trying to return chars from a
- function. As in:
- char HasColor (void);
- It seems some things like: if (HasColor()) fall on their face. It may be that
- I'm doing other things wrong from within my functions. Sometimes code like:
- if (HasColor() == TRUE) will seem to work. Other times it seems like I have to
- do the ol' casting with (char) or (short) or somesuch. Seems rather grundgy.
-
- Inspecting THINK C's header files revealed the constants TRUE & FALSE declared
- as (for all I know) shorts or ints. It occurs to me that comparing chars and
- shorts could be unpredictable.
-
- So is there a "rule" that those-in-the-know tend to follow?
- Thank you for the rather academic help. I have perhaps 6 or more books with C
- code in them (tutorials and the like) and I just can't find a consensus on
- this. I have a problem (while learning) with seeing many approaches to
- something. I'm always led to the question, "But what's the best way?"
-
- john calhoun-
-
-
- +++++++++++++++++++++++++++
-
- From: rfischer@Xenon.Stanford.EDU (Ray Fischer)
- Organization: Computer Science Department, Stanford University.
- Date: Thu, 2 Apr 1992 22:23:18 GMT
-
- ozma@kuhub.cc.ukans.edu writes ...
- >What's with the char/Boolean/short variables? If I want to represent a
- >quantity that is either TRUE or FALSE, which of the above is best to use? I
- >have seen code that uses one of any of the three variable types.
-
- Welcome to C. You've discovered one of the fuzzier aspects to C, namely
- what's the difference between char, boolean, and integer types.
-
- Answer: none, really. They're all numeric integers at heart. The only
- difference is in the size. A long is a 32-bit int. An int is (on the
- Mac usually) 16 bits, and a char is (generally) 8 bits.
-
- So why the problems? Size. Note (this is important!) that if you use
- a function without explicitly declaring it, you will NOT get a syntax error!
- The C compiler will give the function an implicit type of 'function
- returning an int'. In the case of a function returning booleans or chars,
- the function may return 8-bits of result and the caller will be expecting
- a 16 (or 32) bit result. The extra bits may well be garbage, and your
- boolean test won't work.
-
- Rather than have functions that return chars, you might notice that
- in stdio.h, most of the I/O functions that one would expect to return
- characters actually are defined to return ints. Two reasons.
- 1) since the result is usually returned in a register, it doesn't
- affect the amount of storage used.
- 2) It allows non-char results such as EOF to be returned.
- 3) (ok, three reasons), chars are just small ints anyway.
-
- There is no boolean type in C. A boolean test is true if it is non-zero.
- TRUE and FALSE are usually defined to be 1 and 0 just for clarity.
- 'a' is true (but not == TRUE) and '\0' is false (and == FALSE).
-
- >Inspecting THINK C's header files revealed the constants TRUE & FALSE declared
- >as (for all I know) shorts or ints. It occurs to me that comparing chars and
- >shorts could be unpredictable.
-
- The compiler (if it is correct in its assumption about the types of values)
- is smart enough to convert dissimilar numeric types to a common type for
- assignment and/or comparison.
-
- >So is there a "rule" that those-in-the-know tend to follow?
-
- Yes. Define all of your functions before you use them.
-
- Ray
- rfischer@cs.stanford.edu
-
- ---------------------------
-
- From: don@ohm.york.ac.uk (Don Goodeve)
- Subject: Application icons (attatching to existing apps)
- Date: 3 Apr 92 13:32:02 GMT
- Organization: Electronics Department, University of York, UK
-
- I have an application on the Mac to which I want to attatch
- an Icon. Using Icon editor and resedit I have generated and
- icon list (ID 128). This is referenced by an FREF entry
- (local ID 0 type APPN). Additionally the BNDL has an
- entry for the icon (ICN#) mapping local ID 0 to
- ID 128. This all seems together and OK..
-
- It doesnt appear to work. The file still has its default icon...
-
- Pursuing this further I understand in the directory
- entry for the file there is a flag bit to indicate if the
- the files icon can be seen. Another bit indicates whether the
- file has a bundle. Try as I may I can see no easy high-level
- way of modifying these (with resedit or any other util I
- have). Advice please?
-
- Cheers
- Don
-
- don@ohm.york.ac.uk
- - --
- ---------------------------------------------
- | Don --- Well why not? Someone has got to be!|
- ---------------------------------------------
-
- +++++++++++++++++++++++++++
-
- From: jh4o+@andrew.cmu.edu (Jeffrey T. Hutzelman)
- Date: 4 Apr 92 07:58:41 GMT
- Organization: Sophomore, Electrical and Computer Engineering, Carnegie Mellon, Pittsburgh, PA
-
- Within ResEdit (2.0 or later, I believe), select "Get File/Folder Info" from
- the File menu, and pick the file in question. This will bring up a dialog
- with the file's type and creator, and lots of checkboxes. Make sure the
- box labelled "Bundle" is checked, and the box labeled "Initted" is not
- checked. Then CLOSE the info box (answer yes to the save question), and
- open the folder containing the file in Finder. You should see a change.
- Rebuilding the desktop also helps here, but is a little extreme.
-
- - -- Jeffrey Hutzelman
-
- jh4o+@andrew.cmu.edu, jhutz@drycas.BITNET, or JeffreyH11 on America Online
-
- ---------------------------
-
- End of C.S.M.P. Digest
- **********************
-