home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / scheme / boxer / boxer.lha / stream.lisp < prev    next >
Encoding:
Text File  |  1993-07-17  |  20.0 KB  |  623 lines

  1. ;;; -*- MODE: LISP; PACKAGE: (BOXER GLOBAL 1000); BASE: 10.; FONTS: CPTFONT, CPTFONTB -*-
  2.  
  3. #||
  4.             1Copyright 1985 Massachusetts Institute of Technology
  5.  
  6.  Permission to use, copy, modify, distribute, and sell this software
  7.  and its documentation for any purpose is hereby granted without fee,
  8.  provided that the above copyright notice appear in all copies and that
  9.  both that copyright notice and this permission notice appear in
  10.  supporting documentation, and that the name of M.I.T. not be used in
  11.  advertising or publicity pertaining to distribution of the software
  12.  without specific, written prior permission.  M.I.T. makes no
  13.  representations about the suitability of this software for any
  14.  purpose.  It is provided "as is" without express or implied warranty.
  15.  
  16.  
  17. 0                    1This file is part of the BOXER system
  18. 0    
  19.  The stream represenations of 1BOXER-STREAMS0 look like:
  20.  
  21.  1BOX-STREAM    0==  [<init-plist> <row-stream-0> <row-stream-1> ... ]
  22.  1ROW-STREAM    0==  {<cha-stream-0> <cha-stream-1> ...}
  23.  1CHA-STREAM    0==  <box-stream> | <lispm-char-code>
  24.  1EDITOR-STREAM0 ==  {<cha-stream-0> <cha-stream-1>...} ROW-STREAM-1 ROW-STREAM-2...
  25.  
  26. ||#
  27.  
  28. (SETQ *PORT-HASH-TABLE* (MAKE-HASH-TABLE))
  29.  
  30. (DEFCONST *STRT-BOX-CODE* #\[)
  31. (DEFCONST *STOP-BOX-CODE* #\])
  32. (DEFCONST *STRT-ROW-CODE* #\{)
  33. (DEFCONST *STOP-ROW-CODE* #\})
  34. (DEFCONST *QUOTE-CODE* #/)
  35. (DEFCONST *BOXER-STREAM-SPECIAL-CHARACTERS*
  36.       (STRING-APPEND *STRT-ROW-CODE* *STRT-BOX-CODE*
  37.              *STOP-ROW-CODE* *STOP-BOX-CODE*
  38.              *QUOTE-CODE*))
  39.  
  40.  
  41. (DEFSUBST STRT-BOX-CODE? (X)
  42.   (EQ X  *STRT-BOX-CODE*))
  43. (DEFSUBST STOP-BOX-CODE? (X)
  44.   (EQ X  *STOP-BOX-CODE*))
  45. (DEFSUBST STRT-ROW-CODE? (X)
  46.   (EQ X  *STRT-ROW-CODE*))
  47. (DEFSUBST STOP-ROW-CODE? (X)
  48.   (EQ X  *STOP-ROW-CODE*))
  49. (DEFSUBST QUOTE-CODE? (X)
  50.   (EQ X *QUOTE-CODE*))
  51.  
  52.  
  53. ;;;flavor and macro Definitions
  54.  
  55. (DEFFLAVOR BOXER-STREAM
  56.     ()
  57.     ()
  58.   :ABSTRACT-FLAVOR
  59.   (:REQUIRED-METHODS :TYI :TYI-OR-STREAM :UNTYI :TYIPEEK)
  60.   (:DEFAULT-HANDLER BOXER-STREAM-DEFAULT-HANDLER)
  61.   (:DOCUMENTATION  :ESSENTIAL-MIXIN
  62.    "This is an abstract flavor, it is not possible to make instances of the
  63.     BOXER-STREAM flavor. This flavor exists only to mixin to other flavors
  64.     of boxer-streams to provide some functionality common to all kinds of
  65.     boxer-streams. Specifically having this flavor mixed in makes the type
  66.     checking predicate BOXER-STREAM? return t, and sets things up so that
  67.     STREAM-DEFAULT-HANDLER will get called whenever a boxer-stream receives
  68.     a message it doesn't handle."))
  69.  
  70. (DEFUN BOXER-STREAM-DEFAULT-HANDLER (SELF IGNORE OP &OPTIONAL ARG1 &REST ARGS)
  71.   (STREAM-DEFAULT-HANDLER SELF OP ARG1 ARGS))
  72.  
  73. (DEFTYPE-CHECKING-MACROS BOXER-STREAM "A Boxer Editor Stream")
  74.  
  75. (DEFFLAVOR STRING-STREAM
  76.     ((STRING NIL)
  77.      (POINTER 0))
  78.     (BOXER-STREAM)
  79.   (:INIT-KEYWORDS :STRING))
  80.  
  81. (DEFFLAVOR PDL-STREAM
  82.     ((PDL NIL))
  83.     (BOXER-STREAM)
  84.   (:INIT-KEYWORDS :PDL))
  85.  
  86. (DEFFLAVOR ROW-STREAM
  87.     ((ROW NIL)
  88.      (CHA-NO 0))
  89.     (PDL-STREAM)
  90.   (:INIT-KEYWORDS :ROW :CHAS))
  91.  
  92. (DEFTYPE-CHECKING-MACROS ROW-STREAM "a Row-Stream")
  93.  
  94. (DEFFLAVOR BOX-STREAM
  95.     ((BOX NIL))
  96.     (PDL-STREAM)
  97.   (:INIT-KEYWORDS :BOX :INIT-PLIST :ROWS))
  98.  
  99. (DEFTYPE-CHECKING-MACROS BOX-STREAM "a Box-Stream")
  100.  
  101. (DEFFLAVOR EDITOR-STREAM
  102.     ()
  103.     (PDL-STREAM)
  104.   (:INIT-KEYWORDS :ROWS :START-CHAS :END-CHAS))
  105.  
  106. (DEFTYPE-CHECKING-MACROS EDITOR-STREAM "An Editor Stream")
  107.  
  108.  
  109.  
  110. ;;; The major function defined by this file for use outside of this file is
  111. ;;; MAKE-BOXER-STREAM. Make-Boxer-Stream takes any Boxer Obj or the lisp
  112. ;;; representation for any Boxer-Stream, and makes a Boxer-Stream object out
  113. ;;; of it. This function is the fundamental type coercer used by the Boxer
  114. ;;; Editor. This function will-
  115. ;;;   Make any of the following into a Box-Stream:
  116. ;;;      <box> | (:BOX <init-plist> <row-stream-0> <row-stream-1> ...)
  117. ;;;   Make any of the following into a Row-Stream:
  118. ;;;      <row> | (:ROW <cha-stream-0> <cha-stream-1> ...)
  119. ;;;   Make any of the following into a Cha-Stream:
  120. ;;;      <cha> | <row-entry> | <string> | <symbol> | <cha-code> | <list of these>
  121. ;;;      Note that a row-entry  is tested with ROW-ENTRY?
  122.  
  123. (DEFUN MAKE-BOXER-STREAM (STUFF &OPTIONAL OTHER-BP)
  124.   (COND ((BOXER-STREAM? STUFF)
  125.      STUFF)
  126.     ((BOX? STUFF)
  127.      (MAKE-BOX-STREAM STUFF))
  128.     ((ROW? STUFF)
  129.      (MAKE-ROW-STREAM STUFF))
  130.     ((CHA? STUFF)
  131.      (MAKE-CHA-STREAM STUFF))
  132.     ((EDITOR-REGION? STUFF)
  133.      (MAKE-STREAM-FROM-BPS (TELL STUFF :START-BP) (TELL STUFF :STOP-BP)))
  134.     ((AND (BP? STUFF) (BP? OTHER-BP))
  135.      (MAKE-STREAM-FROM-BPS STUFF OTHER-BP))
  136.     ((BP? STUFF)
  137.      (FERROR "You have to specify two BP's. ~A was not a BP" OTHER-BP))
  138.     ((LISTP STUFF)
  139.      (FUNCALL (GET (CAR STUFF) ':MAKE-BOXER-STREAM) STUFF))
  140.     (T
  141.      (FUNCALL (GET (TYPEP STUFF) ':MAKE-BOXER-STREAM) STUFF))))
  142.  
  143.  
  144.  
  145. (DEFPROP :BOX MAKE-BOX-STREAM :MAKE-BOXER-STREAM)
  146.  
  147. (DEFUN MAKE-BOX-STREAM (STUFF)
  148.   (COND ((BOXER-STREAM? STUFF) STUFF)
  149.     ((BOX? STUFF)
  150.      (MAKE-INSTANCE 'BOX-STREAM ':BOX STUFF
  151.             ':INIT-PLIST (TELL STUFF :RETURN-INIT-PLIST-FOR-COPY)))
  152.     ((AND (LISTP STUFF) (EQ (CAR STUFF) ':BOX))
  153.      (MAKE-INSTANCE 'BOX-STREAM ':INIT-PLIST (CADR STUFF)
  154.                     ':ROWS (CDDR STUFF)))
  155.     (T
  156.      (FERROR "Can't make a Box-Stream out of ~S." STUFF))))
  157.  
  158.  
  159. ;since this crock machine represents characters as fixnums, we must change all
  160. ;numbers to strings at this level.  there are probably other functions that
  161. ;make streams that need to do this to, but this might the only one.
  162.  
  163. (DEFPROP :ROW MAKE-ROW-STREAM :MAKE-BOXER-STREAM)
  164.  
  165. ;;; This is used by MAKE-ROW-STREAM only....
  166. (DEFMACRO GET-ROW-STREAM-ELEMENT (CHUNK)
  167.   `(COND ((NUMBERP ,CHUNK)
  168.       (SETQ ALREADY-SPACES? NIL)
  169.       (COLLECT (FORMAT NIL "~A",CHUNK)))
  170.      ((SPACES? ,CHUNK)
  171.       (SETQ ALREADY-SPACES? T)
  172.       (DOTIMES
  173.         (I (GET-SPACES ,CHUNK))
  174.         (COLLECT #\SPACE)))
  175.      ((AND (SYMBOLP ,CHUNK) (GET ,CHUNK 'CONVERTED-CHARACTER))
  176.       (SETQ ALREADY-SPACES? T)
  177.       (COLLECT (GET ,CHUNK 'CONVERTED-CHARACTER)))
  178.      ((EVBOX? ,CHUNK)
  179.       (SETQ ALREADY-SPACES? NIL)
  180.       (COLLECT(MAKE-BOXER-STREAM ,CHUNK)))
  181.      (T (SETQ ALREADY-SPACES? NIL)
  182.         (COLLECT ,CHUNK))))
  183.  
  184. (DEFUN MAKE-ROW-STREAM (STUFF)
  185.   (COND ((BOXER-STREAM? STUFF) STUFF)
  186.     ((ROW? STUFF)
  187.      (MAKE-INSTANCE 'ROW-STREAM ':ROW STUFF))
  188.     ((AND (LISTP STUFF) (EQ (CAR STUFF) ':ROW))
  189.      (MAKE-INSTANCE 'ROW-STREAM ':CHAS (WITH-COLLECTION
  190.                          (DO ((CHUNKS (CDR STUFF) (CDR CHUNKS))
  191.                           (ALREADY-SPACES? NIL))
  192.                          ((NULL CHUNKS))
  193.                            (GET-ROW-STREAM-ELEMENT(CAR CHUNKS))
  194.                            ;; make sure spaces get put in between items
  195.                            (UNLESS (OR ALREADY-SPACES? ;spaces just put in
  196.                                (NULL (CDR CHUNKS)) ;last item
  197.                                ;; spaces about to be put in
  198.                                (SPACES? (CADR CHUNKS))) 
  199.                          (COLLECT #\SPACE))))))
  200.     (T
  201.      (FERROR "Can't make a Row-Stream out of ~S." STUFF))))
  202.  
  203. (DEFPROP :CHA MAKE-CHA-STREAM :MAKE-BOXER-STREAM)
  204. (DEFPROP :STRING MAKE-CHA-STREAM :MAKE-BOXER-STREAM)
  205. (DEFPROP :SYMBOL MAKE-CHA-STREAM :MAKE-BOXER-STREAM)
  206. (DEFPROP :FIXNUM MAKE-CHA-STREAM :MAKE-BOXER-STREAM)
  207.  
  208. (DEFUN MAKE-CHA-STREAM (STUFF)
  209.   (COND ((BOXER-STREAM? STUFF) STUFF)
  210.     ((CHA? STUFF)
  211.      (MAKE-PDL-STREAM `(,(CHA-CODE STUFF))))
  212.     ((OR (STRINGP STUFF) (SYMBOLP STUFF) (FIXNUMP STUFF))
  213.      (MAKE-STRING-STREAM (STRING STUFF)))
  214.     (T
  215.      (FERROR "Can't make a Cha-Stream out of ~S" STUFF))))    
  216.  
  217. (DEFUN MAKE-STRING-STREAM (STRING)
  218.   (MAKE-INSTANCE 'STRING-STREAM ':STRING STRING))
  219.  
  220. ;;; Making an arbitrary stream between two BP's
  221. (DEFUN MAKE-STREAM-FROM-BPS (START-BP STOP-BP)
  222.   (LET ((START-ROW (BP-ROW START-BP)) (STOP-ROW (BP-ROW STOP-BP)))
  223.     (COND ((EQ (BP-ROW START-BP) (BP-ROW STOP-BP))
  224.        (MAKE-INSTANCE 'EDITOR-STREAM
  225.               :START-CHAS
  226.               (TELL START-ROW :CHAS-BETWEEN-CHA-NOS
  227.                           (BP-CHA-NO START-BP)
  228.                       (BP-CHA-NO STOP-BP))))
  229.       (T
  230.        (MAKE-INSTANCE 'EDITOR-STREAM
  231.               :START-CHAS
  232.               (TELL START-ROW :CHAS-BETWEEN-CHA-NOS (BP-CHA-NO START-BP))
  233.               :ROWS
  234.               (LOOP FOR ROW = (TELL START-ROW :NEXT-ROW) THEN (TELL ROW :NEXT-ROW)
  235.                 UNTIL (EQ ROW STOP-ROW)
  236.                 COLLECTING ROW)
  237.               :END-CHAS
  238.               (TELL STOP-ROW :CHAS-BETWEEN-CHA-NOS 0 (BP-CHA-NO STOP-BP)))))))
  239.  
  240.  
  241.  
  242. (DEFMETHOD (STRING-STREAM :INIT) (INIT-PLIST)
  243.   (TELL SELF :SET-STRING (GET INIT-PLIST ':STRING)))
  244.  
  245. (DEFMETHOD (STRING-STREAM :SET-STRING) (NEW-VALUE)
  246.   (SETQ STRING (FORMAT NIL "~a" NEW-VALUE)
  247.     POINTER 0))
  248.  
  249. (DEFMETHOD (STRING-STREAM :TYI) (&REST IGNORE)
  250.   (PROG1 (TELL SELF :TYIPEEK)
  251.      (INCF POINTER)))
  252.  
  253. (DEFMETHOD (STRING-STREAM :TYIPEEK) ()
  254.   (COND ((NULL STRING) NIL)
  255.     ((= POINTER (STRING-LENGTH STRING))
  256.      (SETQ STRING NIL))
  257.     (T
  258.      (CHARACTER (SUBSTRING STRING POINTER (+ POINTER 1))))))
  259.  
  260. (DEFMETHOD-ALIAS (STRING-STREAM :TYI-OR-STREAM) :TYI)
  261.  
  262. (DEFMETHOD (STRING-STREAM :UNTYI) (IGNORE)
  263.   (DECF POINTER))
  264.  
  265.  
  266.  
  267.  
  268. (DEFUN MAKE-PDL-STREAM (PDL)
  269.   (MAKE-INSTANCE 'PDL-STREAM ':PDL PDL))
  270.  
  271. (DEFMETHOD (PDL-STREAM :INIT) (INIT-PLIST)
  272.   (TELL SELF :SET-PDL (GET INIT-PLIST ':PDL)))
  273.  
  274. (DEFMETHOD (PDL-STREAM :GET-PDL) ()
  275.   PDL)
  276.  
  277. (DEFMETHOD (PDL-STREAM :SET-PDL) (NEW-VALUE)
  278.   (SETQ PDL NEW-VALUE))
  279.  
  280. (DEFWHOPPER (PDL-STREAM :TYI) (&REST IGNORE)
  281.   (TELL SELF :PDL-STREAM-TYI NIL))
  282.  
  283. (DEFWHOPPER (PDL-STREAM :TYI-OR-STREAM) (&REST IGNORE)
  284.   (TELL SELF :PDL-STREAM-TYI T))
  285.  
  286. ;;; In order to make it easier for flavors which include the pdl-stream flavor
  287. ;;; to define the required :PDL-STREAM-TYI message, the pdl-stream flavor has
  288. ;;; a whopper around the :pdl-stream-tyi message that handles the message in
  289. ;;; all the "easy" cases. Specifically, the main :pdl-stream-tyi method will
  290. ;;; not be called if:
  291. ;;;  The pdl is empty
  292. ;;;       Returns nil.
  293. ;;;  The top of the pdl is a fixnum.
  294. ;;;       Returns and pops the fixnum.
  295. ;;;  The top of the pdl is a boxer-stream.
  296. ;;;      If return-stream? is non-nil returns the stream.
  297. ;;;      If the stream is empty, pops the stream and strts
  298. ;;;      over again. Otherwise returns what ever the stream
  299. ;;;      returns.
  300.  
  301. (DEFWHOPPER (PDL-STREAM :PDL-STREAM-TYI) (RETURN-STREAM?)
  302.   (COND ((NULL PDL) NIL)
  303.     ((NULL (CAR PDL)) 
  304.      (POP PDL)
  305.      (TELL SELF :PDL-STREAM-TYI RETURN-STREAM?))
  306.     ((FIXNUMP (CAR PDL))
  307.      (POP PDL))
  308.     ((AND (BOXER-STREAM? (CAR PDL))
  309.           (NOT-NULL RETURN-STREAM?))
  310.      (POP PDL))
  311.     ((BOXER-STREAM? (CAR PDL))
  312.      (LET ((CHA-OR-STREAM (TELL (CAR PDL) :TYI-OR-STREAM)))
  313.        (COND ((NULL CHA-OR-STREAM)
  314.           (POP PDL)
  315.           (TELL SELF :PDL-STREAM-TYI RETURN-STREAM?))
  316.          (T
  317.           (PUSH CHA-OR-STREAM PDL)
  318.           (TELL SELF :PDL-STREAM-TYI RETURN-STREAM?)))))
  319.     (T
  320.      (CONTINUE-WHOPPER RETURN-STREAM?))))
  321.  
  322. ;;; For those few people who use pdl streams themselves (not as mixins)
  323. ;;; pdl-streams try to win when what is on the pdl isn't a stream by
  324. ;;; calling make-boxer-stream on it.
  325.  
  326. (DEFMETHOD (PDL-STREAM :PDL-STREAM-TYI) (RETURN-STREAM?)
  327.   (PUSH (MAKE-BOXER-STREAM (POP PDL)) PDL)
  328.   (COND ((NULL RETURN-STREAM?)
  329.      (TELL SELF :PDL-STREAM-TYI NIL))
  330.     (T
  331.      (POP PDL))))
  332.  
  333. ;;; The PDL-STREAM flavor also handles the :UNTYI operation. This is done by
  334. ;;; pushing the cha to be untyied onto the pdl. In addition, the fact that
  335. ;;; this untyi is "unlimited" is used to implement the :TYIPEEK operation.
  336.  
  337. (DEFMETHOD (PDL-STREAM :UNTYI) (X)
  338.   (push x pdl))
  339. ;This doesn't work.  Take it out when you know why.  (tries to stuff things
  340. ;into full string-streams.)
  341. ;  (COND ((BOXER-STREAM? (CAR PDL))
  342. ;     (FUNCALL (CAR PDL) ':UNTYI X))
  343. ;    (T
  344. ;     (PUSH X PDL))))
  345.  
  346. (DEFMETHOD (PDL-STREAM :TYIPEEK) ()
  347.   (if (fixnump (car pdl)) (car pdl)
  348.       (LET ((PEEK (TELL SELF :TYI)))
  349.     (FUNCALL SELF ':UNTYI PEEK)
  350.     PEEK)))
  351.  
  352.  
  353.  
  354.  
  355. (DEFMETHOD (ROW-STREAM :INIT) (INIT-PLIST)
  356.   (LET ((NEW-ROW (GET INIT-PLIST ':ROW))
  357.     (NEW-CHAS (GET INIT-PLIST ':CHAS)))
  358.     (COND ((ROW? NEW-ROW)
  359.        (SETQ ROW NEW-ROW
  360.          CHA-NO 0
  361.          PDL `(,*STRT-ROW-CODE* ,NEW-ROW ,*STOP-ROW-CODE*)))
  362.       (T
  363.        (SETQ ROW NIL
  364.          CHA-NO 0
  365.          PDL (CONS *STRT-ROW-CODE* (APPEND NEW-CHAS `(,*STOP-ROW-CODE*))))))))
  366.  
  367. (DEFGET-METHOD (ROW-STREAM :ROW) ROW)
  368.  
  369. (DEFMETHOD (ROW-STREAM :PDL-STREAM-TYI) (RETURN-STREAM?)
  370.   (COND ((ROW? (CAR PDL))
  371.      (LET ((CHA (TELL ROW :CHA-AT-CHA-NO CHA-NO)))
  372.        (COND ((AND (CHA? CHA) (NOT (BOX? CHA)))
  373.           (INCF CHA-NO)
  374.           (CHA-CODE CHA))
  375.          ((BOX? CHA)
  376.           (INCF CHA-NO)
  377.           (PUSH (MAKE-BOXER-STREAM CHA) PDL)
  378.           (TELL SELF :PDL-STREAM-TYI RETURN-STREAM?))
  379.          (T
  380.           (POP PDL)
  381.           (TELL SELF :PDL-STREAM-TYI RETURN-STREAM?)))))
  382.     (T
  383.      (PUSH (MAKE-BOXER-STREAM (POP PDL)) PDL)
  384.      (TELL SELF :PDL-STREAM-TYI RETURN-STREAM?))))
  385.  
  386. (DEFMETHOD (ROW-STREAM :TYI-A-BOX) (&OPTIONAL (COPY? NIL))
  387.   (WHEN (STRT-BOX-CODE? (CAR PDL))
  388.     (POP PDL))
  389.   (IF (BOX-STREAM? (CAR PDL))
  390.       (COND  ((NULL (TELL (CAR PDL) :BOX))
  391.           (LET ((NEW-BOX (MAKE-INITIALIZED-BOX)))
  392.         (TELL SELF :UNTYI *STRT-BOX-CODE*)
  393.         (TELL NEW-BOX :SET-CONTENTS-FROM-STREAM SELF)
  394.         NEW-BOX))
  395.          ((NOT COPY?)
  396.           (TELL (POP PDL) :BOX))
  397.          (T
  398.           (TELL (TELL (POP PDL) :BOX) :COPY)))
  399.       (FERROR NIL "can't tyi-a-box from ~s" SELF)))
  400.                         
  401. ;;; New, for the chunker, get the next object (box or cha).  DOn't mess around
  402. ;;; Doesn't use the general model for streams.  Treats streams as cha-no-pointer and row
  403. ;;; The PDL isn't side-effected like it should be
  404. (DEFMETHOD (ROW-STREAM :TYI-NEXT-THING) (&OPTIONAL (COPY? NIL))
  405.   (COND ((ROW? ROW)
  406.      (LET ((CHA (TELL ROW :CHA-AT-CHA-NO CHA-NO)))
  407.        (INCF CHA-NO)
  408.        (COND ((AND COPY? (BOX? CHA))
  409.           (TELL CHA :COPY))
  410.          (T CHA))))
  411.     (T (FERROR "Don't know how to :TYI-NEXT-THING"))))
  412.  
  413. ;;; Chunker uses this one too
  414. (DEFMETHOD (ROW-STREAM :PEEK-NEXT-THING) (&OPTIONAL (COPY? NIL))
  415.   (COND ((ROW? ROW)
  416.      (LET ((CHA (TELL ROW :CHA-AT-CHA-NO CHA-NO)))
  417.        (COND ((AND COPY? (BOX? CHA))
  418.           (TELL CHA :COPY))
  419.          (T CHA))))
  420.     (T (FERROR "Don't know how to :TYI-NEXT-THING"))))
  421.  
  422.  
  423.  
  424. (DEFMETHOD (BOX-STREAM :INIT) (INIT-PLIST)
  425.   (LET ((NEW-BOX (GET INIT-PLIST ':BOX))
  426.     (NEW-ROWS (GET INIT-PLIST ':ROWS)))
  427.     (COND ((BOX? NEW-BOX)
  428.        (SETQ BOX NEW-BOX
  429.          PDL `(,*STRT-BOX-CODE*
  430.                ,(MAKE-STRING-STREAM (FORMAT NIL "~:S" (GET INIT-PLIST ':INIT-PLIST)))
  431.                ,(TELL NEW-BOX :FIRST-INFERIOR-ROW)
  432.                ,*STOP-BOX-CODE*)))
  433.       (T
  434.        (SETQ BOX NIL
  435.          PDL (CONS *STRT-BOX-CODE*
  436.                (CONS (MAKE-STRING-STREAM
  437.                    (FORMAT NIL "~:S" (GET INIT-PLIST ':INIT-PLIST)))
  438.                  (APPEND NEW-ROWS `(,*STOP-BOX-CODE*)))))))))
  439.  
  440. ;;; the old one version
  441. ;(DEFMETHOD (BOX-STREAM :INIT) (INIT-PLIST)
  442. ;  (LET ((NEW-BOX (GET INIT-PLIST ':BOX))
  443. ;    (NEW-ROWS (GET INIT-PLIST ':ROWS)))
  444. ;    (COND ((PORT-BOX? NEW-BOX)
  445. ;       (SETQ BOX NEW-BOX
  446. ;         PDL `(,*STRT-BOX-CODE*
  447. ;               ,(MAKE-STRING-STREAM (FORMAT NIL "~:S" (GET INIT-PLIST ':INIT-PLIST)))
  448. ;               ,*STOP-BOX-CODE*)))
  449. ;      ((BOX? NEW-BOX)
  450. ;       (SETQ BOX NEW-BOX
  451. ;         PDL `(,*STRT-BOX-CODE*
  452. ;               ,(MAKE-STRING-STREAM (FORMAT NIL "~:S" (GET INIT-PLIST ':INIT-PLIST)))
  453. ;               ,(TELL NEW-BOX :FIRST-INFERIOR-ROW)
  454. ;               ,*STOP-BOX-CODE*)))
  455. ;      (T
  456. ;       (SETQ BOX NIL
  457. ;         PDL (CONS *STRT-BOX-CODE*
  458. ;               (CONS (MAKE-STRING-STREAM
  459. ;                   (FORMAT NIL "~:S" (GET INIT-PLIST ':INIT-PLIST)))
  460. ;                 (APPEND NEW-ROWS `(,*STOP-BOX-CODE*)))))))))
  461.  
  462.  
  463. (DEFMETHOD (BOX-STREAM :BOX) ()
  464.   (OR BOX
  465.       (LET ((NEW-BOX (MAKE-INITIALIZED-BOX)))
  466.     (TELL NEW-BOX :SET-CONTENTS-FROM-STREAM SELF)
  467.     NEW-BOX)))
  468.  
  469.             
  470. (DEFGET-METHOD (BOX-STREAM :BOX) BOX)
  471.  
  472. (DEFMETHOD (BOX-STREAM :PDL-STREAM-TYI) (RETURN-STREAM?)
  473.   (COND ((ROW? (CAR PDL))
  474.      (LET* ((ROW (POP PDL))
  475.         (NEXT-ROW (TELL ROW :NEXT-ROW)))
  476.        (IF NEXT-ROW (PUSH NEXT-ROW PDL))
  477.        (PUSH (MAKE-ROW-STREAM ROW) PDL))
  478.      (TELL SELF :PDL-STREAM-TYI RETURN-STREAM?))
  479.     (T
  480.      (PUSH (MAKE-ROW-STREAM (POP PDL)) PDL)
  481.      (TELL SELF :PDL-STREAM-TYI RETURN-STREAM?))))
  482.  
  483. (DEFMETHOD (BOX-STREAM :TYI-A-ROW) (&OPTIONAL (COPY? NIL))
  484.   (COND ((AND (ROW-STREAM? (CAR PDL)) (NOT COPY?))
  485.      (TELL (POP PDL) :ROW))
  486.     (T
  487.      (LET ((NEW-ROW (MAKE-INITIALIZED-ROW)))
  488.        (TELL NEW-ROW :SET-CONTENTS-FROM-STREAM SELF)
  489.        NEW-ROW))))
  490.  
  491. (DEFMETHOD (EDITOR-STREAM :INIT) (INIT-PLIST)
  492.   (LET ((START-CHAS (GET INIT-PLIST :START-CHAS))
  493.     (END-CHAS   (GET INIT-PLIST :END-CHAS))
  494.     (ROWS       (GET INIT-PLIST :ROWS)))
  495.   (COND-EVERY ((NOT-NULL START-CHAS)
  496.            (SETQ PDL (CONS *STRT-ROW-CODE* (APPEND START-CHAS `(,*STOP-ROW-CODE*)))))
  497.           ((NOT-NULL ROWS)
  498.            (NCONC PDL ROWS))
  499.           ((NOT-NULL END-CHAS)
  500.            (NCONC PDL (CONS *STRT-ROW-CODE* (APPEND END-CHAS `(,*STOP-ROW-CODE*))))))))
  501.  
  502.  
  503.  
  504. (DEFMETHOD (EDITOR-STREAM :TYI-A-ROW) (&OPTIONAL (COPY? NIL))
  505.   (COND ((AND (ROW-STREAM? (CAR PDL)) (NOT COPY?))
  506.      (TELL (POP PDL) :ROW))
  507.     (T
  508.      (LET ((NEW-ROW (MAKE-INITIALIZED-ROW)))
  509.        (TELL NEW-ROW :SET-CONTENTS-FROM-STREAM SELF)
  510.        NEW-ROW))))
  511.  
  512. (DEFMETHOD (EDITOR-STREAM :TYI-A-BOX) (&OPTIONAL (COPY? NIL))
  513.   (WHEN (STRT-BOX-CODE? (CAR PDL))
  514.     (POP PDL))
  515.   (IF (BOX-STREAM? (CAR PDL))
  516.       (COND  ((NULL (TELL (CAR PDL) :BOX))
  517.           (LET ((NEW-BOX (MAKE-INITIALIZED-BOX)))
  518.         (TELL SELF :UNTYI *STRT-BOX-CODE*)
  519.         (TELL NEW-BOX :SET-CONTENTS-FROM-STREAM SELF)
  520.         NEW-BOX))
  521.          ((NOT COPY?)
  522.           (TELL (POP PDL) :BOX))
  523.          (T
  524.           (TELL (TELL (POP PDL) :BOX) :COPY)))
  525.       (FERROR NIL "can't tyi-a-box from ~s" SELF)))
  526.  
  527. (DEFMETHOD (EDITOR-STREAM :INSERT-STREAM-CONTENTS-AT-BP) (BP &OPTIONAL (COPY? T))
  528.   (LOOP FOR PEEK = (TELL SELF :TYIPEEK) THEN (TELL SELF :TYIPEEK)
  529.     INITIALLY
  530.     (COND ((STRT-ROW-CODE? PEEK)
  531.            (INSERT-ROW-CHAS BP (TELL SELF :TYI-A-ROW COPY?)))
  532.           (T (FERROR "Streams out of synch.")))
  533.     UNTIL (NULL PEEK)
  534.     DO
  535.     (COND ((STRT-ROW-CODE? PEEK)
  536.            (INSERT-ROW BP (TELL SELF :TYI-A-ROW COPY?)))
  537.           (T (FERROR "Streams out of synch.")))))
  538.  
  539. (DEFMETHOD (BOX :SET-CONTENTS-FROM-STREAM) (STREAM &OPTIONAL (COPY? T) (IGNORE-PLIST NIL))
  540.   (COND ((STRT-BOX-CODE? (FUNCALL STREAM ':TYI))
  541.      ;; Stream in synch, OK to go ahead.
  542.      (LET ((INIT-PLIST (READ STREAM)))
  543.        (TELL SELF :SEMI-INIT (IF (NOT IGNORE-PLIST)
  544.                      (LOCF INIT-PLIST)
  545.                      (CONS NIL
  546.                        (TELL SELF
  547.                          :RETURN-INIT-PLIST-FOR-COPY))))
  548.           (DO ((PEEK (FUNCALL STREAM ':TYIPEEK)
  549.                  (FUNCALL STREAM ':TYIPEEK)))
  550.               ((STOP-BOX-CODE? PEEK)
  551.                (FUNCALL STREAM ':TYI))
  552.             (COND ((AND (STRT-ROW-CODE? PEEK)
  553.                 (FUNCALL STREAM
  554.                      ':OPERATION-HANDLED-P
  555.                      ':TYI-A-ROW))
  556.                (LET ((NEW-ROW (FUNCALL STREAM ':TYI-A-ROW COPY?)))
  557.                  (TELL SELF :APPEND-ROW NEW-ROW)
  558.                  (DOLIST (BOX (TELL NEW-ROW :BOXES-IN-ROW))
  559.                    (TELL BOX :INSERT-SELF-ACTION))))
  560.               ((STRT-ROW-CODE? PEEK)
  561.                (LET ((NEW-ROW (MAKE-INITIALIZED-ROW)))
  562.                  (TELL NEW-ROW :SET-CONTENTS-FROM-STREAM STREAM)
  563.                  (TELL SELF :APPEND-ROW NEW-ROW)
  564.                  (DOLIST (BOX (TELL NEW-ROW :BOXES-IN-ROW))
  565.                    (TELL BOX :INSERT-SELF-ACTION))))
  566.               (T
  567.                (FERROR "Streams out of synch."))))))
  568.     (T
  569.      (FERROR "Streams out of synch."))))
  570.  
  571. (DEFMETHOD (ROW :SET-CONTENTS-FROM-STREAM) (STREAM &OPTIONAL (COPY? T))
  572.   (COND ((STRT-ROW-CODE? (FUNCALL STREAM ':TYI))
  573.      ;; Streams in synch, OK to go ahead.
  574.      (DO ((PEEK (FUNCALL STREAM ':TYIPEEK) (FUNCALL STREAM ':TYIPEEK)))
  575.          ((STOP-ROW-CODE? PEEK)
  576.           (FUNCALL STREAM ':TYI))
  577.        (COND
  578.              ((AND (STRT-BOX-CODE? PEEK)
  579.                (FUNCALL STREAM ':OPERATION-HANDLED-P ':TYI-A-BOX))
  580.           (TELL SELF :APPEND-CHA (FUNCALL STREAM ':TYI-A-BOX COPY?)))
  581.          ((STRT-BOX-CODE? PEEK)
  582.           (LET ((NEW-BOX (MAKE-INITIALIZED-BOX)))
  583.             (TELL NEW-BOX :SET-CONTENTS-FROM-STREAM STREAM)
  584.             (TELL SELF :APPEND-CHA NEW-BOX)))
  585.          ((QUOTE-CODE? PEEK)
  586.           (TELL SELF :APPEND-CHA (MAKE-CHA (FUNCALL STREAM ':TYI)))
  587.           (TELL SELF :APPEND-CHA (MAKE-CHA (FUNCALL STREAM ':TYI))))
  588.          (T (TELL SELF :APPEND-CHA (MAKE-CHA (FUNCALL STREAM ':TYI)))))))
  589.     (T
  590.      (FERROR "Streams out of synch."))))
  591.  
  592. ;;; presumably, this can **ONLY** be called from within the (ROW :SET-CONTENTS-FROM-STREAM)
  593. ;;; method which has been passed a BOX-STREAM.   The PDL of the stream had better look like:
  594. ;;; (*STRT-BOX-CODE* #<BOX-STREAM  > ....other stuff...)
  595. ;;; This is necessary for the copying of GRAPHICS boxes which are themselves sub boxes of
  596. ;;; some other box which has been streamified
  597.  
  598. ;;; We need this one for ports too
  599.  
  600. (DEFMETHOD (BOX-STREAM :TYI-A-BOX) (COPY?)
  601.   (WHEN (STRT-BOX-CODE? (CAR PDL))
  602.     (POP PDL))
  603.   (IF (BOX-STREAM? (CAR PDL))
  604.       (COND  ((NULL (TELL (CAR PDL) :BOX))
  605.           (LET ((NEW-BOX (MAKE-INITIALIZED-BOX)))
  606.         (TELL SELF :UNTYI *STRT-BOX-CODE*)
  607.         (TELL NEW-BOX :SET-CONTENTS-FROM-STREAM SELF T)
  608.         NEW-BOX))
  609.          ((NOT COPY?)
  610.           (TELL (POP PDL) :BOX))
  611.          (T
  612.           (TELL (TELL (POP PDL) :BOX) :COPY)))
  613.       (FERROR NIL "can't tyi-a-box from ~s" SELF)))
  614.  
  615.  
  616. ;  (LET ((BOX-STREAM (CADR PDL)))
  617. ;    (COND ((AND (STRT-BOX-CODE? (CAR PDL)) (BOX-STREAM? BOX-STREAM))
  618. ;       (SETQ PDL (NTHCDR 2 PDL))
  619. ;       (IF COPY-P
  620. ;           (TELL (TELL BOX-STREAM :BOX) :COPY)
  621. ;           (TELL BOX-STREAM :BOX)))
  622. ;      (T (FERROR "Can't :TYI a box from the PDL, ~S, of the stream, ~S" PDL SELF)))))
  623.