-- File: SimpleExample.mesa    (note 1.1)
-- Last edited by: Mitchell on December 16, 1982 2:32 pm
DIRECTORY
IO USING [char, Close, CreateViewerStreams, Error, GetChar, GetInt, Handle, IDBreak, int, PeekChar, PutF, PutFR, Reset, rope, SkipOver],
Process USING [Detach],
Rope USING [Cat, Equal, Fetch, Find, FromChar, Length, ROPE, Substr, Upper],
UserExec USING [CommandProc, GetNameAndPassword, RegisterCommand];
SimpleExample: CEDAR MONITOR    --(note 1.2)
IMPORTS IO, Process, Rope, UserExec =   --(note 1.3)
BEGIN
ROPE: TYPE = Rope.ROPE;      --(note 1.4)
windowCount: INT ← 0; -- a count of the number of calculators on the screen
ReverseName: UserExec.CommandProc = BEGIN    --(note 1.5)
-- Reverses the user's login name and prints it out in the exec window.
userName: ROPE ← UserExec.GetNameAndPassword[ ].name;  --(note 1.6)
execStream: IO.Handle ← exec.out; -- exec is an arg to ReverseName(note 1.7)
backwordsName: ROPENIL;
-- Remove ".PA" if it is on the end of the user name, and check for user name Taylor.
dotPos: INT = userName.Find["."];    --(note 1.8)
IF dotPos#-1 THEN userName ← userName.Substr[0, dotPos];
IF userName.Equal[s2: "Taylor", case: FALSE] THEN execStream.PutF["Hi, Bob\n"];
-- Now reverse the name: convert chars to upper cases and concatenate them in reverse order
FOR i: INT DECREASING IN [0..userName.Length[ ]) DO
backwordsName ← backwordsName.Cat[
Rope.FromChar[Rope.Upper[userName.Fetch[i]]]]  --[1.1] (note 1.9)
ENDLOOP;
execStream.PutF["Your user name backwards is: %g\n", IO.rope[backwordsName]];
      --(note 1.10)
END;
MakeCalculator: ENTRY UserExec.CommandProc = BEGIN  --(note 1.11)
-- Puts up a calculator window.
title: ROPE;
windowCount ← windowCount+1;
title ← IO.PutFR["Adding machine number %g", IO.int[windowCount]]; --(note 1.12)
TRUSTED {Process.Detach[FORK Calculate[title]];}   --(note 1.13)
END;
Calculate: PROC[title: ROPE] = BEGIN
-- Creates typescript window separate from UserExec with given title.
-- Uses IO procedures to read an integer expression from the typescript and print its value.
opChar: CHAR;
number: INT;
answer: INT;
in, out: IO.Handle;
[in: in, out: out] ← IO.CreateViewerStreams[title];   --(note 1.14)
DO  -- Read an expression, terminated by a CR:
ENABLE IO.Error =>             --(note 1.15)
IF ec=SyntaxError THEN {
in.Reset[ ];
out.PutF["\nIncorrect input. Please retype the expression.\n\n"];
LOOP}
ELSE EXIT;
opChar ← '+;  -- first integer is positive
answer ← 0;  -- initialize sum to zero
out.PutF["Type one or more integers separated by + and - and terminate with CR to compute value:\n"];
DO -- Read an integer and an operator, skipping leading blanks in both cases
number ← in.GetInt[ ];
SELECT opChar FROM
'+ => answer ← answer + number;
'- => answer ← answer - number;
ENDCASE => {
out.PutF["Illegal operator (%g). Please retype the expression.\n\n", IO.char[opChar]];
EXIT};
IF in.PeekChar[ ]='\n THEN GO TO NextLine; -- the normal way out
in.SkipOver[IO.IDBreak];
opChar ← in.GetChar[ ];
REPEAT
NextLine => {
[ ] ← in.GetChar[ ]; -- toss CR      (note 1.16)
out.PutF["\nThe answer is: %g.\n\n", IO.int[answer]] };
ENDLOOP;
ENDLOOP;
END;
-- Start code registers a Calculate and ReverseName command, which must be invoked for this program to do anything:
UserExec.RegisterCommand[            --(note 1.17)
name: "Calculate", proc: MakeCalculator, briefDoc: "A simple adding machine"];
UserExec.RegisterCommand[
name: "ReverseName", proc: ReverseName, briefDoc: "Reverses your user name"];
END.
CHANGE LOG     --(note 1.18)
Created by Cattell on 21-Apr-82 13:55:09
Changed by Cattell on May 25, 1982 10:58 am
-- added use of RegisterCommand to fire up a Calculator viewer instead of creating it when program first run.
Changed by Mitchell on August 11, 1982 5:00 pm
-- changed main loop of Calculate to correctly catch IO.Error when Destroy menu button invoked.
Edited on December 16, 1982 2:22 pm, by Mitchell
changes to: DIRECTORY IO, --CreateTTYStreams --> CreateViewerStreams, --, UserExec.RegisterCommand[moved out.PutF to NextLine exit of inner loop so it doesn't print out an answer when an incorrect operator is typed