123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- %
- % Format.RED - Formatted print routine
- %
- % Author: Eric Benson
- % Symbolic Computation Group
- % Computer Science Dept.
- % University of Utah
- % Date: 27 August 1981
- % Copyright (c) 1981 University of Utah
- %
- CompileTime <<
- load(Syslisp, Fast!-Vector);
- flag('(format!-freshline format1 format2 clear!-string!-write
- return!-string!-write), 'internalfunction);
- fluid '(FormatForFormat!* string!-write!-channel next!-string!-write!-char
- string!-write!-buffer);
- >>;
- % First, lambda-bind FormatForFormat!*
- lisp procedure Format(Stream, FormatForFormat!*, A1, A2, A3, A4, A5,
- A6, A7, A8, A9, A10,
- A11, A12, A13);
- Format1(Stream, FormatForFormat!*, A1, A2, A3, A4, A5,
- A6, A7, A8, A9, A10,
- A11, A12, A13);
- % Then, push all the registers on the stack and set up a pointer to them
- lap '((!*entry Format1 expr 15)
- (!*PUSH (reg 3))
- (!*LOC (reg 2) (frame 1))
- (!*PUSH (reg 4))
- (!*PUSH (reg 5))
- (!*PUSH (reg 6))
- (!*PUSH (reg 7))
- (!*PUSH (reg 8))
- (!*PUSH (reg 9))
- (!*PUSH (reg 10))
- (!*PUSH (reg 11))
- (!*PUSH (reg 12))
- (!*PUSH (reg 13))
- (!*PUSH (reg 14))
- (!*PUSH (reg 15))
- (!*CALL Format2)
- (!*EXIT 14)
- );
- on SysLisp;
- % Finally, actual Format, with 2 arguments, stream and
- % pointer to array of parameters
- syslsp procedure Format2(Stream, FormatArgs); %. Formatted print
- %
- % If the character is not one of these (either upper or lower case), then an
- % error occurs.
- %
- begin scalar UpLim, I, Ch, UpCh;
- if Stream eq NIL then
- << Stream := lispvar string!-write!-channel;
- clear!-string!-write() >>
- else if Stream eq T then
- Stream := LispVar OUT!*;
- UpLim := StrLen StrInf LispVar FormatForFormat!*;
- I := 0;
- while I <= UpLim do
- << Ch := StrByt(StrInf LispVar FormatForFormat!*, I);
- if Ch neq char !~ then
- ChannelWriteChar(Stream, Ch)
- else
- begin
- I := I + 1;
- Ch := StrByt(StrInf LispVar FormatForFormat!*, I);
- UpCh := if Ch >= char lower A and Ch <= char lower Z
- then IPlus2(IDifference(Ch, char lower A), char A)
- else Ch;
- case UpCh of
- char A:
- << ChannelPrin2(Stream, FormatArgs[0]);
- FormatArgs := &FormatArgs[StackDirection] >>;
- char S:
- << ChannelPrin1(Stream, FormatArgs[0]);
- FormatArgs := &FormatArgs[StackDirection] >>;
- char D:
- << ChannelWriteSysInteger(Stream,
- Int2Sys FormatArgs[0],
- 10);
- FormatArgs := &FormatArgs[StackDirection] >>;
- char B:
- << ChannelWriteSysInteger(Stream,
- Int2Sys FormatArgs[0],
- 2);
- FormatArgs := &FormatArgs[StackDirection] >>;
- char O:
- << ChannelWriteSysInteger(Stream,
- Int2Sys FormatArgs[0],
- 8);
- FormatArgs := &FormatArgs[StackDirection] >>;
- char X:
- << ChannelWriteSysInteger(Stream,
- Int2Sys FormatArgs[0],
- 16);
- FormatArgs := &FormatArgs[StackDirection] >>;
- char !~:
- ChannelWriteChar(Stream, char !~);
- char !%:
- ChannelWriteChar(Stream, char EOL);
- char '!&:
- format!-freshline Stream;
- default:
- StdError BldMsg('"Unknown character code for Format: %r",
- MkID Ch);
- end;
- end;
- I := I + 1 >>;
- if Stream eq LispVar string!-write!-channel then return
- return!-string!-write();
- end;
- off SysLisp;
- lisp procedure format!-freshline Stream;
- (lambda out!*;
- if IGreaterP(Posn(), 0) then
- ChannelWriteChar(Stream, char EOL))(Stream);
- lisp procedure Ferror(Condition, FMT, A1, A2, A3, A4, A5, A6,
- A7, A8, A9, A10, A11, A12, A13);
- Error(Condition, Format(NIL, FMT, A1, A2, A3, A4, A5, A6,
- A7, A8, A9, A10, A11, A12, A13));
- lisp procedure string!-write!-char(stream, ch);
- if IGEQ(next!-string!-write!-char, 5000) then
- StdError "String overflow in FORMAT"
- else
- << next!-string!-write!-char := iadd1 next!-string!-write!-char;
- iputs(string!-write!-buffer, next!-string!-write!-char, ch) >>;
- lisp procedure clear!-string!-write();
- << channelwritechar(string!-write!-channel, char EOL);
- next!-string!-write!-char := -1 >>;
- lisp procedure return!-string!-write();
- begin scalar x, y;
- y := 0;
- next!-string!-write!-char := iadd1 next!-string!-write!-char;
- x := make!-string(next!-string!-write!-char, char NULL);
- while ILEQ(y, next!-string!-write!-char) do
- << iputs(x, y, igets(string!-write!-buffer, y));
- y := iadd1 y >>;
- return x;
- end;
- string!-write!-buffer := make!-string(5000, char NULL);
- specialreadfunction!* := 'WriteOnlyChannel;
- specialwritefunction!* := 'string!-write!-char;
- specialclosefunction!* := 'IllegalStandardChannelClose;
- string!-write!-channel := open("", 'special);
- (lambda (x);
- << LineLength 10000;
- WRS x >> )(WRS string!-write!-channel);
- END;
|