format.red 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. %
  2. % Format.RED - Formatted print routine
  3. %
  4. % Author: Eric Benson
  5. % Symbolic Computation Group
  6. % Computer Science Dept.
  7. % University of Utah
  8. % Date: 27 August 1981
  9. % Copyright (c) 1981 University of Utah
  10. %
  11. CompileTime <<
  12. load(Syslisp, Fast!-Vector);
  13. flag('(format!-freshline format1 format2 clear!-string!-write
  14. return!-string!-write), 'internalfunction);
  15. fluid '(FormatForFormat!* string!-write!-channel next!-string!-write!-char
  16. string!-write!-buffer);
  17. >>;
  18. % First, lambda-bind FormatForFormat!*
  19. lisp procedure Format(Stream, FormatForFormat!*, A1, A2, A3, A4, A5,
  20. A6, A7, A8, A9, A10,
  21. A11, A12, A13);
  22. Format1(Stream, FormatForFormat!*, A1, A2, A3, A4, A5,
  23. A6, A7, A8, A9, A10,
  24. A11, A12, A13);
  25. % Then, push all the registers on the stack and set up a pointer to them
  26. lap '((!*entry Format1 expr 15)
  27. (!*PUSH (reg 3))
  28. (!*LOC (reg 2) (frame 1))
  29. (!*PUSH (reg 4))
  30. (!*PUSH (reg 5))
  31. (!*PUSH (reg 6))
  32. (!*PUSH (reg 7))
  33. (!*PUSH (reg 8))
  34. (!*PUSH (reg 9))
  35. (!*PUSH (reg 10))
  36. (!*PUSH (reg 11))
  37. (!*PUSH (reg 12))
  38. (!*PUSH (reg 13))
  39. (!*PUSH (reg 14))
  40. (!*PUSH (reg 15))
  41. (!*CALL Format2)
  42. (!*EXIT 14)
  43. );
  44. on SysLisp;
  45. % Finally, actual Format, with 2 arguments, stream and
  46. % pointer to array of parameters
  47. syslsp procedure Format2(Stream, FormatArgs); %. Formatted print
  48. %
  49. % If the character is not one of these (either upper or lower case), then an
  50. % error occurs.
  51. %
  52. begin scalar UpLim, I, Ch, UpCh;
  53. if Stream eq NIL then
  54. << Stream := lispvar string!-write!-channel;
  55. clear!-string!-write() >>
  56. else if Stream eq T then
  57. Stream := LispVar OUT!*;
  58. UpLim := StrLen StrInf LispVar FormatForFormat!*;
  59. I := 0;
  60. while I <= UpLim do
  61. << Ch := StrByt(StrInf LispVar FormatForFormat!*, I);
  62. if Ch neq char !~ then
  63. ChannelWriteChar(Stream, Ch)
  64. else
  65. begin
  66. I := I + 1;
  67. Ch := StrByt(StrInf LispVar FormatForFormat!*, I);
  68. UpCh := if Ch >= char lower A and Ch <= char lower Z
  69. then IPlus2(IDifference(Ch, char lower A), char A)
  70. else Ch;
  71. case UpCh of
  72. char A:
  73. << ChannelPrin2(Stream, FormatArgs[0]);
  74. FormatArgs := &FormatArgs[StackDirection] >>;
  75. char S:
  76. << ChannelPrin1(Stream, FormatArgs[0]);
  77. FormatArgs := &FormatArgs[StackDirection] >>;
  78. char D:
  79. << ChannelWriteSysInteger(Stream,
  80. Int2Sys FormatArgs[0],
  81. 10);
  82. FormatArgs := &FormatArgs[StackDirection] >>;
  83. char B:
  84. << ChannelWriteSysInteger(Stream,
  85. Int2Sys FormatArgs[0],
  86. 2);
  87. FormatArgs := &FormatArgs[StackDirection] >>;
  88. char O:
  89. << ChannelWriteSysInteger(Stream,
  90. Int2Sys FormatArgs[0],
  91. 8);
  92. FormatArgs := &FormatArgs[StackDirection] >>;
  93. char X:
  94. << ChannelWriteSysInteger(Stream,
  95. Int2Sys FormatArgs[0],
  96. 16);
  97. FormatArgs := &FormatArgs[StackDirection] >>;
  98. char !~:
  99. ChannelWriteChar(Stream, char !~);
  100. char !%:
  101. ChannelWriteChar(Stream, char EOL);
  102. char '!&:
  103. format!-freshline Stream;
  104. default:
  105. StdError BldMsg('"Unknown character code for Format: %r",
  106. MkID Ch);
  107. end;
  108. end;
  109. I := I + 1 >>;
  110. if Stream eq LispVar string!-write!-channel then return
  111. return!-string!-write();
  112. end;
  113. off SysLisp;
  114. lisp procedure format!-freshline Stream;
  115. (lambda out!*;
  116. if IGreaterP(Posn(), 0) then
  117. ChannelWriteChar(Stream, char EOL))(Stream);
  118. lisp procedure Ferror(Condition, FMT, A1, A2, A3, A4, A5, A6,
  119. A7, A8, A9, A10, A11, A12, A13);
  120. Error(Condition, Format(NIL, FMT, A1, A2, A3, A4, A5, A6,
  121. A7, A8, A9, A10, A11, A12, A13));
  122. lisp procedure string!-write!-char(stream, ch);
  123. if IGEQ(next!-string!-write!-char, 5000) then
  124. StdError "String overflow in FORMAT"
  125. else
  126. << next!-string!-write!-char := iadd1 next!-string!-write!-char;
  127. iputs(string!-write!-buffer, next!-string!-write!-char, ch) >>;
  128. lisp procedure clear!-string!-write();
  129. << channelwritechar(string!-write!-channel, char EOL);
  130. next!-string!-write!-char := -1 >>;
  131. lisp procedure return!-string!-write();
  132. begin scalar x, y;
  133. y := 0;
  134. next!-string!-write!-char := iadd1 next!-string!-write!-char;
  135. x := make!-string(next!-string!-write!-char, char NULL);
  136. while ILEQ(y, next!-string!-write!-char) do
  137. << iputs(x, y, igets(string!-write!-buffer, y));
  138. y := iadd1 y >>;
  139. return x;
  140. end;
  141. string!-write!-buffer := make!-string(5000, char NULL);
  142. specialreadfunction!* := 'WriteOnlyChannel;
  143. specialwritefunction!* := 'string!-write!-char;
  144. specialclosefunction!* := 'IllegalStandardChannelClose;
  145. string!-write!-channel := open("", 'special);
  146. (lambda (x);
  147. << LineLength 10000;
  148. WRS x >> )(WRS string!-write!-channel);
  149. END;