<> <> <> <> <<>> DIRECTORY Commander USING [CommandProc, Register], Express USING [ClientProcList, Fcn, FreeFcn, ParseError, RopeToFcn], IO USING [Put, real, rope], Real USING [Fix], Rope USING [Length, ROPE, Substr]; ExpressExampleClient: CEDAR MONITOR IMPORTS C: Commander, EX: Express, IO, Real, Rope ~ { <> DoStuff: C.CommandProc ~ { fcn: EX.Fcn _ EX.RopeToFcn[expression: cmd.commandLine, symbols: LIST["i", "j"], cProcs: clientProcList ! --NOTE: We don't use oldFcn here, 'cause we'd have to make fcn global EX.ParseError => { IO.Put [cmd.out, IO.rope[error.reason], IO.rope[": "]]; IO.Put [cmd.out, IO.rope[Rope.Substr[base: cmd.commandLine, len: error.position]], IO.rope["\000"], IO.rope[IF Rope.Length[cmd.commandLine]<=error.position THEN NIL ELSE Rope.Substr[base: cmd.commandLine, start: error.position] ] ]; GOTO DidntParse; }; ]; FOR i: REAL _ 1, i+1.0 WHILE i<=5.0 DO IO.Put[cmd.out, IO.rope["\t"]]; FOR j: REAL _ 1, j+1.0 WHILE j<=5.0 DO value: REAL _ lastValue _ fcn[i, j]; IO.Put[cmd.out, IO.real[value], IO.rope["\t"]]; ENDLOOP; IO.Put[cmd.out, IO.rope["\n"]]; ENDLOOP; TRUSTED {EX.FreeFcn[fcn]}; EXITS DidntParse => RETURN }; <> lastValue: REAL _ 0; Last: PROC RETURNS [REAL] ~ {RETURN[lastValue]}; At: PROC [addr: REAL] RETURNS [REAL] ~ TRUSTED { address: LONG POINTER TO LONG CARDINAL _ LOOPHOLE[Real.Fix[addr]]; RETURN[address^]; }; clientProcList: Express.ClientProcList ~ LIST [ [Last, "last"], [At, "at"], [At, "@"] ]; <> C.Register[key: "Evaluate", doc: "Evaluate f[i,j] for 5 x 5", proc: DoStuff]; }.