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

  1. ;-*- mode:lisp; package: Boxer;Base: 10.;  fonts: cptfont, cptfontb -*-
  2.  
  3. #|
  4.             Copyright 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.                                          +-Data--+
  18.                 This file is part of the | BOXER | system
  19.                                          +-------+
  20.  
  21.   This file contains the BOXER Evaluator.
  22.  
  23.  
  24. |#
  25.  
  26. (DEFSUBST NAMED-BOX? (THING)
  27.   (AND (BOX? THING) (NAME-ROW? (TELL THING :NAME-ROW))))
  28.  
  29. (COMPILER:MAKE-OBSOLETE NAMED-BOX-P "Use NAMED-BOX? instead")
  30.  
  31.  
  32. ;;;;;;;;;;;;;;;;;;;;;;;
  33. ;;;; Input Flavors ;;;;
  34. ;;;;;;;;;;;;;;;;;;;;;;;
  35.  
  36. (DEFINE-EVAL-MARKER FORCE-PORT-MARKER  :PORT-TO     :COERCE (PORTIFY BU:PORTIFY
  37.                                      PORT-TO BU:PORT-TO) #\)
  38. (DEFINE-EVAL-MARKER MAKE-NUMBER-MARKER :NUMBERIZE   :COERCE (NUMBERIZE BU:NUMBERIZE))
  39. (DEFINE-EVAL-MARKER FORCE-DATA-MARKER  :DATAFY      :COERCE (DATAFY BU:DATAFY) #\')
  40. (DEFINE-EVAL-MARKER FORCE-DOIT-MARKER  :DOITIFY     :COERCE (DOITIFY BU:DOITIFY))
  41. (DEFINE-EVAL-MARKER DONT-PORT-MARKER   :DONT-PORT   :COERCE (DONT-PORT BU:DONT-PORT))
  42. (DEFINE-EVAL-MARKER DONT-DATAFY-MARKER :DONT-DATAFY :COERCE (DONT-DATAFY BU:DONT-DATAFY))
  43. (DEFINE-EVAL-MARKER BUILD-IT-MARKER    :BUILD       :COERCE (BUILD BU:BUILD))
  44.  
  45. ;;; These are internal to the Evaluator and are used to handle things like named boxes and
  46. ;;; spaces (if they make it past the READER)
  47. (DEFINE-EVAL-MARKER IGNORE-TOKEN-MARKER :IGNORE      :INTERNAL      (IGNORE))
  48. (DEFINE-EVAL-MARKER DONT-IGNORE-MARKER  :DONT-IGNORE :INTERNAL (DONT-IGNORE))
  49.  
  50. ;;; Various flavors of collection
  51. ;;; The vanilla flavored REST markers collect all of the remaining args on the line
  52. ;;; The delimited REST markers collect the args up to the next delimiter stopping at EOL
  53. ;;; the args can be collected into either a LIST (for internal use by the evaluator)
  54. ;;; or a BOX.  BOXER users should only use the Boxifying versions.  The Listifying versions
  55. ;;; exist only as an efficiency hack for Boxer primitives.
  56.  
  57. (DEFINE-EVAL-MARKER LIST-REST-MARKER :LIST-REST :COLLECT (LIST-REST BU:LIST-REST))
  58. (DEFINE-EVAL-MARKER BOX-REST-MARKER  :BOX-REST  :COLLECT (BOX-REST BU:BOX-REST BU:REST) #\)
  59. (DEFINE-EVAL-MARKER DELIM-LIST-REST-MARKER
  60.             :DELIMITED-LIST-REST :COLLECT (DELIM-BOX-REST BU:DELIM-BOX-REST))
  61. (DEFINE-EVAL-MARKER DELIM-BOX-REST-MARKER
  62.             :DELIMITED-BOX-REST :COLLECT (DELIM-LIST-REST BU:DELIM-LIST-REST) #\
  63. )
  64.  
  65. (DEFUN SAME-PNAME? (S1 S2)
  66.   (STRING-EQUAL (GET-PNAME S1) (GET-PNAME S2)))
  67.  
  68. (DEFUN EVAL-SPECIAL-MARKER? (THING)
  69.   (AND (SYMBOLP THING) (CONVERT-MARKER THING NIL)))
  70.  
  71.  
  72.  
  73. ;;; Rules for Merging Markers
  74. ;;; When two markers refer to the same type of action (e.g. :DATAFY vs :DONT-DATAFY), the
  75. ;;; EXISTING-ACTION (which correspond to something which was typed by the User on the screen)
  76. ;;; always takes precedence over the NEW-ACTION (corresponding to the desired coercion in the 
  77. ;;; arglist of the caller).
  78. ;;; When two markers are orthogonal, then they are grouped together in a list
  79. ;;; When merging list(s) each element must be checked for orthogonality
  80.  
  81. (DEFUN SAME-ACTION? (ACT1 ACT2)
  82.   "Do the two special evaluator markers refer to the same type of action i.e. porting. "
  83.   (EQ (GET ACT1 :ACTION-TYPE) (GET ACT2 :ACTION-TYPE)))
  84.  
  85. (DEFUN COMPONENT-ACTION? (ACT ACTS)
  86.   (MEM #'SAME-ACTION? ACT ACTS))
  87.  
  88. (DEFUN DEL-ACTION (ACT ACTIONS)
  89.   (DEL #'SAME-ACTION? ACT ACTIONS))
  90.  
  91. (DEFUN TRIM-ACTION-FROM-ACTIONS (ACTION ACTIONS)
  92.   (COND ((AND (SYMBOLP ACTIONS) (SAME-ACTION? ACTION ACTIONS)) NIL)
  93.     ((SYMBOLP ACTIONS) ACTIONS)
  94.     (T (DEL-ACTION ACTION ACTIONS))))
  95.  
  96. (DEFUN CONVERT-MARKER (MARKER &OPTIONAL (SIGNAL-ERROR? T))
  97.   "Converts an alias for a marker to the defined keyword symbol for that marker.
  98. If the first arg is not a valid flavored input, then either an error is signalled
  99. or NIL is returned depending upon the value of the second arg. "
  100.   (OR (GET MARKER :BOXER-INPUT-FLAVOR)
  101.       (AND SIGNAL-ERROR? (FERROR "~A is not a valid flavored input marker. " MARKER))))
  102.  
  103. (DEFUN CONVERT-ACTIONS (ACTIONS)
  104.   (COND ((NULL ACTIONS) NIL)
  105.     ((LISTP ACTIONS) (MAPCAR #'CONVERT-MARKER ACTIONS))
  106.     (T (CONVERT-MARKER ACTIONS))))
  107.  
  108. (DEFUN MERGE-ACTION-MARKERS (EXISTING-ACTION NEW-ACTION)
  109.   (COND ((NULL EXISTING-ACTION) NEW-ACTION)
  110.     ((NULL NEW-ACTION) EXISTING-ACTION)
  111.     ((OR (AND (SYMBOLP EXISTING-ACTION) (SYMBOLP NEW-ACTION)
  112.           (SAME-ACTION? EXISTING-ACTION NEW-ACTION))
  113.          (AND (LISTP EXISTING-ACTION) (SYMBOLP NEW-ACTION)
  114.           (COMPONENT-ACTION? NEW-ACTION EXISTING-ACTION))
  115.          (NULL NEW-ACTION))
  116.      ;; if the NEW-ACTION refers to an already existing one, it does nothing
  117.      EXISTING-ACTION)
  118.     ((AND (SYMBOLP EXISTING-ACTION) (SYMBOLP NEW-ACTION))
  119.      (LIST EXISTING-ACTION NEW-ACTION))
  120.     ((AND (LISTP EXISTING-ACTION) (SYMBOLP NEW-ACTION))
  121.      (NCONC EXISTING-ACTION (NCONS NEW-ACTION)))
  122.     ((AND (SYMBOLP EXISTING-ACTION) (LISTP NEW-ACTION)
  123.           (COMPONENT-ACTION? EXISTING-ACTION NEW-ACTION))
  124.      (NCONC (NCONS EXISTING-ACTION) (DEL-ACTION EXISTING-ACTION NEW-ACTION)))
  125.     ((AND (SYMBOLP EXISTING-ACTION) (LISTP NEW-ACTION))
  126.      (NCONC (NCONS EXISTING-ACTION) NEW-ACTION))
  127.     ((AND (LISTP EXISTING-ACTION) (LISTP NEW-ACTION))
  128.      (DOLIST (EXIST EXISTING-ACTION)
  129.        (SETQ NEW-ACTION (DEL-ACTION EXIST NEW-ACTION)))
  130.      (NCONC EXISTING-ACTION NEW-ACTION))
  131.     (T (FERROR "Bad format for existing action, ~A, or new action ~A"))))
  132.  
  133. (DEFUN COLLECT-AND-MERGE-ACTION-MARKERS (CURRENT-ACTION DESIRED-ACTIONS REST)
  134.   (LOOP WITH FINAL-ACTIONS = (MERGE-ACTION-MARKERS (CONVERT-ACTIONS CURRENT-ACTION)
  135.                            (CONVERT-ACTIONS DESIRED-ACTIONS))
  136.     FOR EXP = REST THEN (CDR EXP)
  137.     FOR TOKEN = (CAR EXP)
  138.     UNTIL (NOT (EVAL-SPECIAL-MARKER? TOKEN))
  139.     DO (SETQ FINAL-ACTIONS (MERGE-ACTION-MARKERS (CONVERT-ACTIONS TOKEN) FINAL-ACTIONS))
  140.     WHEN (NULL EXP)
  141.     DO (FERROR "The expression, ~A, seems to be only evaluator markers" REST)
  142.     FINALLY
  143.     (RETURN (VALUES EXP FINAL-ACTIONS))))
  144.  
  145.  
  146.  
  147. ;;; SOme interface
  148.  
  149. ;;; Lets get everything into the BOXER package for convenience
  150. ;;; Returns a symbol for the evaluator to dispatch on.
  151. ;;; EvBoxes are made transparent to the evaluator here by returning the correct token type
  152. ;;; For each type, there should be a (:PROPERTY <type> EVAL-HANDLER) defined which specifies
  153. ;;; what the evaluator is supposed to do when it encounters an object of type <type>
  154.  
  155. (DEFUN TOKEN-TYPE (TOKEN)
  156.   (COND ((LABEL-PAIR? TOKEN) 'LABEL-PAIR)
  157.     ((UNBOX-TOKEN? TOKEN) 'UNBOX-TOKEN)
  158.     ((EVAL-IT-TOKEN? TOKEN) 'EVAL-TOKEN)
  159.     ((NUMBERP TOKEN) 'NUMBER)
  160.     ((ACCESS-PAIR? TOKEN) 'ACCESS-PAIR)    ;??????
  161.     ((TURTLE? TOKEN) 'TURTLE)
  162.     ((SPRITE-BOX? TOKEN) 'SPRITE-BOX)
  163.     ((GRAPHICS-DATA-BOX? TOKEN) 'GRAPHICS-DATA-BOX)
  164.     ((EVAL-SPECIAL-MARKER? TOKEN) 'SPECIAL-MARKER)
  165.     ((FUNCTIONP TOKEN) 'PRIMITIVE)
  166.     ((EVAL-DOIT? TOKEN) 'DOIT-BOX)
  167.     ((EVAL-DATA? TOKEN) 'DATA-BOX)
  168.     ((EVAL-PORT? TOKEN) 'PORT-BOX)
  169.     ((SPACES?    TOKEN) 'SPACES)        ;just in case they happen to creep in
  170.     (T (OR (CDR (ASSQ (TYPEP TOKEN)
  171.               '((:SYMBOL . SYMBOL)
  172.                 (:LIST . LIST)
  173.                 (:CONS . LIST)
  174.                 (:STRING . STRING)
  175.                 (GRAPHICS-BOX . GRAPHICS-BOX))))
  176.            (FERROR NIL "~S -- Unknown type in Evaluator." TOKEN)))))
  177.  
  178. (DEFUN BOX-HAS-INPUTS? (BOX)
  179.   (MEMQ (GET-FIRST-ELEMENT BOX) *SYMBOLS-FOR-INPUT-LINE*))
  180.  
  181. (DEFUN GET-INPUT-ROW (BOX)
  182.   (LET ((ROW (GET-FIRST-ROW BOX)))
  183.     (WHEN (MEMQ (CAR ROW) *SYMBOLS-FOR-INPUT-LINE*)
  184.       (CDR ROW))))
  185.  
  186. ;;; to get an idea of what is being copied....
  187. (DEFVAR *BOX-COPY-LIST* NIL)
  188. (DEFVAR *BOX-COPY-COUNTER* 0)
  189. (DEFMACRO WITH-COPYING-STATISTICS (&BODY BODY)
  190.   `(PROGN (SETQ *BOX-COPY-LIST*    NIL
  191.         *BOX-COPY-COUNTER* 0)
  192.       . ,BODY))
  193.  
  194. (DEFUN SHOW-COPIES ()
  195.   (FORMAT T "~%Number of Boxes copied: ~D~%Boxes copied: ~%~A"
  196.       *BOX-COPY-COUNTER* *BOX-COPY-LIST*))
  197.  
  198. (DEFUN COPY-FOR-EVAL (THING)
  199.   "The Evaluator copying function.  Copying is disabled/enabled by the variable
  200. *EVALUATOR-COPYING-FUNCTION*.  Different copying strategies can be tested by setqing
  201. the variable *EVALUATOR-COPYING-FUNCTION*. "
  202.   (IF *EVALUATOR-COPYING-ON?*
  203.       (FUNCALL *EVALUATOR-COPYING-FUNCTION* THING)
  204.       THING))
  205.  
  206. (DEFUN MAKE-EVAL-BOX (STUFF)
  207.   (MAKE-BOX STUFF))
  208.  
  209. (DEFSUBST BOXIFY (THING)
  210.   (MAKE-EVDATA ROWS (IF (EVROW? THING) (NCONS THING) (NCONS (MAKE-EVROW-FROM-ENTRY THING)))))
  211.  
  212. ;This subst takes a list of items and makes single-row evbox out of them.
  213. (defsubst boxify-list (things)
  214.   (make-evdata rows (ncons (make-evrow-from-entries things))))
  215.  
  216. (DEFSUBST MAKE-PORT-TO (BOX)
  217. ;(PORT-TO-FOR-EVAL BOX)                ;this makes a REAL Port instead
  218.   (MAKE-EVPORT TARGET BOX))
  219.  
  220. (DEFUN DOITIFY (THING)
  221.   (MAKE-EVDOIT ROWS (IF (OR (EVAL-BOX? THING)(EVAL-PORT? THING))(GET-BOX-ROWS THING)
  222.             (NCONS (NCONS THING)))))
  223.  
  224.  
  225.  
  226. ;; Each type of thing that the evaluator can see should have an EVAL-HANDLER property
  227. ;; which specifies the default behavior for that type of object.  This behavior can be 
  228. ;; described by the evaluator's special markers and can be altered by passing a different
  229. ;; set of special markers to the EVAL-HANDLER procedure.
  230. ;; The EVAL-HANDLER should handle as many of the special evaluator marker as it wants to
  231. ;; and then it can pass the rest explicitly in another call to EV-THING or just ignore them
  232.  
  233. ;; :RUN-THIS markers have to handled at the next higher level (RETURN-VALUE  ) because boxes
  234. ;; may have arguments that need to be bound
  235.  
  236. ;; special markers return themselves
  237. (DEFUN (:PROPERTY SPECIAL-MARKER EVAL-HANDLER) (MARKER &REST IGNORE)
  238.   MARKER)
  239.  
  240. (DEFUN (:PROPERTY SPACES EVAL-HANDLER) (SPACES &REST IGNORE)
  241.   SPACES)
  242.  
  243. (DEFUN (:PROPERTY LABEL-PAIR EVAL-HANDLER) (PAIR &OPTIONAL SPECIAL-ACTION)
  244.   (EV-THING (LABEL-PAIR-ELEMENT PAIR) SPECIAL-ACTION))
  245.  
  246. (DEFUN (:PROPERTY SYMBOL EVAL-HANDLER) (SYMBOL SPECIAL-ACTION)
  247.   (COND ((POINTS-TO-SELF SYMBOL) SYMBOL)
  248.     ((FORCE-DATA-MARKER? SPECIAL-ACTION) (BOXIFY SYMBOL))
  249.     (T (EV-THING (BOXER-SYMEVAL SYMBOL)
  250.              (MERGE-ACTION-MARKERS SPECIAL-ACTION
  251.                ;; will symeval to a named box !!
  252.                DONT-IGNORE-MARKER)))))
  253.  
  254. (DEFUN (:PROPERTY PRIMITIVE EVAL-HANDLER) (PRIM &OPTIONAL SPECIAL-ACTION)
  255.   ;; mostly error checking
  256.   (COND ((FORCE-PORT-MARKER? SPECIAL-ACTION) (FERROR "Trying to port to a primitive"))
  257.     ((FORCE-DATA-MARKER? SPECIAL-ACTION)
  258.      (FERROR "Can't copy a primitive."))
  259.     ((ZEROP (FUNCTION-NUMBER-OF-ARGS PRIM))
  260.      (FUNCALL PRIM))
  261.     (T PRIM)))
  262.  
  263. (DEFUN (:PROPERTY LIST EVAL-HANDLER) (LIST &OPTIONAL IGNORE)
  264.   (EV-EXPRESSION LIST))
  265.  
  266. (DEFUN (:PROPERTY NUMBER EVAL-HANDLER) (NUMBER &REST IGNORE)
  267.   NUMBER)
  268.  
  269. (DEFUN (:PROPERTY DOIT-BOX EVAL-HANDLER) (BOX &OPTIONAL SPECIAL-ACTION)
  270.   (COND
  271.     ;; first, we check for coerce actions
  272.     ((FORCE-PORT-MARKER?  SPECIAL-ACTION)
  273.      ;; let the box do it's stuff BEFORE porting
  274.      (let ((result (run-it box)))
  275.        (cond ((eval-box? result) (make-port-to result))
  276.          ((eval-port? result) result)
  277.          ((numberp result) (make-port-to (boxify result)))
  278.          (t (ferror "Don't know how to port-to ~S" result)))))
  279.     ((MAKE-NUMBER-MARKER? SPECIAL-ACTION) (NUMBERIZE (EV-THING BOX)))
  280.     ((FORCE-DATA-MARKER?  SPECIAL-ACTION) (BOXIFY BOX))
  281.     ((BUILD-IT-MARKER?    SPECIAL-ACTION) (BUILD-INTERNAL BOX))
  282.     ((= 0 (FUNCTION-NUMBER-OF-ARGS BOX))
  283.      ;; No arg doit boxes get executed right away
  284.      (RUN-IT BOX))
  285.     ;; finally, let the box do what it wants
  286.     (T BOX)))
  287.  
  288. (DEFUN (:PROPERTY PORT-BOX EVAL-HANDLER) (PORT &OPTIONAL SPECIAL-ACTION)
  289.   (COND
  290.     ((MAKE-NUMBER-MARKER? SPECIAL-ACTION) (NUMBERIZE PORT))
  291.     ((FORCE-DATA-MARKER?  SPECIAL-ACTION) (BOXIFY PORT))
  292.     ((BUILD-IT-MARKER?    SPECIAL-ACTION)
  293.      ;; perhaps this should be an error instead
  294.      (BUILD-INTERNAL (GET-PORT-TARGET PORT)))
  295.     (T PORT)))
  296.     
  297. (DEFUN (:PROPERTY DATA-BOX EVAL-HANDLER) (BOX SPECIAL-ACTION)
  298.   (COND
  299.     ;; first, we check for coerce actions
  300.     ((FORCE-PORT-MARKER?  SPECIAL-ACTION) (MAKE-PORT-TO BOX))
  301.     ((FORCE-DATA-MARKER?  SPECIAL-ACTION) (BOXIFY BOX))
  302.     ((MAKE-NUMBER-MARKER? SPECIAL-ACTION) (NUMBERIZE BOX))
  303.     ((FORCE-DOIT-MARKER?  SPECIAL-ACTION) (DOITIFY BOX))
  304.     ((BUILD-IT-MARKER?    SPECIAL-ACTION) (BUILD-INTERNAL BOX))
  305.     ;; finally, let the box do what it wants
  306.     (T BOX)))
  307.  
  308. (DEFUN (:PROPERTY GRAPHICS-BOX EVAL-HANDLER) (BOX &OPTIONAL SPECIAL-ACTION)
  309.   (COND
  310.     ((FORCE-PORT-MARKER?  SPECIAL-ACTION) (MAKE-PORT-TO BOX))
  311.     ((FORCE-DATA-MARKER?  SPECIAL-ACTION) (BOXIFY BOX))
  312.     ((BUILD-IT-MARKER?    SPECIAL-ACTION)
  313.      ;; perhaps this should be an error too...
  314.      (BUILD-INTERNAL BOX))
  315.     (T BOX)))
  316.  
  317. (DEFUN (:PROPERTY GRAPHICS-DATA-BOX EVAL-HANDLER) (BOX &OPTIONAL SPECIAL-ACTION)
  318.   (COND
  319.     ((FORCE-PORT-MARKER?  SPECIAL-ACTION) (MAKE-PORT-TO BOX))
  320.     ((FORCE-DATA-MARKER?  SPECIAL-ACTION) (BOXIFY BOX))
  321.     ((BUILD-IT-MARKER?    SPECIAL-ACTION) (BUILD-INTERNAL BOX))
  322.     (T BOX)))
  323.  
  324. (DEFUN (:PROPERTY SPRITE-BOX EVAL-HANDLER) (BOX &OPTIONAL SPECIAL-ACTION)
  325.   (COND
  326.     ((FORCE-PORT-MARKER?  SPECIAL-ACTION) (MAKE-PORT-TO BOX))
  327.     ((FORCE-DATA-MARKER?  SPECIAL-ACTION) (BOXIFY BOX))
  328.     ((BUILD-IT-MARKER?    SPECIAL-ACTION) (BUILD-INTERNAL BOX))
  329.     (T BOX)))
  330.  
  331. (DEFUN (:PROPERTY TURTLE EVAL-HANDLER) (OBJ &OPTIONAL IGNORE)
  332.   OBJ)
  333.   
  334.  
  335.  
  336. ;;; How to handle atsigns and excls at top level
  337.  
  338. ;;;top level !'s are ignored
  339. (DEFUN (:PROPERTY EVAL-TOKEN EVAL-HANDLER) (ET &OPTIONAL SPECIAL-ACTION)
  340.   (EV-THING (EVAL-IT-TOKEN-ELEMENT ET) SPECIAL-ACTION))
  341.  
  342. (DEFUN (:PROPERTY UNBOX-TOKEN EVAL-HANDLER) (UT &OPTIONAL IGNORE)
  343.   (LET ((THING-TO-UNBOX (EV-THING (UNBOX-TOKEN-ELEMENT UT))))
  344.     (COND ((OR (EVAL-BOX? THING-TO-UNBOX) (NUMBERP THING-TO-UNBOX))
  345.        (MAKE-UNBOX-PAIR THING-TO-UNBOX))
  346.       ((eval-port? thing-to-unbox)        ;this is not quite right
  347.        (make-unbox-pair (get-port-target thing-to-unbox)))
  348.       ((UNBOX-PAIR? THING-TO-UNBOX)
  349.        (MAKE-UNBOX-PAIR
  350.          (EV-THING (GET-FIRST-ELEMENT (UNBOX-PAIR-ELEMENT THING-TO-UNBOX)))))
  351.       (T
  352.        (FERROR "~A was not a box.  You can only unbox boxes. " THING-TO-UNBOX)))))
  353.  
  354. ;;; The result of EV-THING on an UNBOX-TOKEN will be an UNBOX-PAIR.  The two ar every similiar
  355. ;;; except that the unbox pair is guaranteed to have a box to unbox (or else an error would 
  356. ;;; have been produced when we tried to make it
  357.  
  358. (DEFUN MAKE-UNBOX-PAIR (BOX)
  359.   (CONS 'UNBOX-PAIR BOX))
  360.  
  361. (DEFSUBST UNBOX-PAIR? (X)
  362.   (AND (LISTP X)
  363.        (EQ (CAR X) 'UNBOX-PAIR)))
  364.  
  365. (DEFSUBST UNBOX-PAIR-ELEMENT (UP)
  366.   (CDR UP))
  367.  
  368. ;;; The Evaluator will call UNBOX-FUNCTION on an UNBOX-PAIR which
  369. ;;; returns a new expression to be passed to RETURN-VALUE which is the result of the unbox
  370. ;;; APPENDED to the rest of the expression AFTER the unbox
  371.  
  372. (DEFUN UNBOX-FUNCTION (TOKEN EXPRESSION)
  373.   (LET ((ROWS (GET-BOX-ROWS (UNBOX-PAIR-ELEMENT TOKEN))))
  374.     (SELECTQ *MULTIPLE-ROW-TOP-LEVEL-UNBOX-ACTION*
  375.       ((:FLATTEN) (APPEND (LEXPR-FUNCALL #'APPEND ROWS) EXPRESSION))
  376.       ((:TRUNCATE) (APPEND (CAR ROWS) EXPRESSION))
  377.       ((:ERROR)
  378.        (IF (= (LENGTH ROWS) 1) (APPEND (CAR ROWS) EXPRESSION)
  379.        (FERROR "The box,~A, has more than one row."
  380.            (UNBOX-PAIR-ELEMENT TOKEN)))))))
  381.  
  382.  
  383.  
  384. ;;; Infix declarations
  385.  
  386. (DEFPROP BU:^ 140 :INFIX-PRECEDENCE)
  387. (DEFPROP BU:* 120 :INFIX-PRECEDENCE)
  388. (DEFPROP BU:// 120 :INFIX-PRECEDENCE)
  389. (DEFPROP BU:+ 100 :INFIX-PRECEDENCE)
  390. (DEFPROP BU:- 100 :INFIX-PRECEDENCE)
  391. (DEFPROP BU:> 80 :INFIX-PRECEDENCE)
  392. (DEFPROP BU:< 80 :INFIX-PRECEDENCE)
  393. (DEFPROP BU: 80 :INFIX-PRECEDENCE)
  394. (DEFPROP BU: 80 :INFIX-PRECEDENCE)
  395. (DEFPROP BU:>= 80 :INFIX-PRECEDENCE)
  396. (DEFPROP BU:<= 80 :INFIX-PRECEDENCE)
  397. (DEFPROP BU:= 80 :INFIX-PRECEDENCE)
  398. (DEFPROP BU: 80 :INFIX-PRECEDENCE)
  399.  
  400.  
  401.  
  402. ;;same as in EVAL
  403. (DEFUN BOXER-FUNCTION? (THING)
  404.   (OR (EVAL-DOIT? THING) (FUNCTIONP THING)
  405.       (AND (EVAL-PORT? THING) (EVAL-DOIT? (GET-PORT-TARGET THING)))))
  406.  
  407. (DEFSUBST APPLY-IT? (CURRENT-TOKEN SPECIAL-ACTION)
  408.   (OR (AND (BOXER-FUNCTION? CURRENT-TOKEN)
  409.        (NOT (OR (FORCE-DATA-MARKER? SPECIAL-ACTION))))
  410.       (FORCE-DOIT-MARKER? SPECIAL-ACTION)))
  411.  
  412. (DEFSUBST RUN-IT? (CURRENT-TOKEN SPECIAL-ACTION)
  413.   (OR (AND (BOXER-FUNCTION? CURRENT-TOKEN)
  414.        (NOT (FORCE-DATA-MARKER? SPECIAL-ACTION))
  415.        (= 0 (FUNCTION-NUMBER-OF-ARGS CURRENT-TOKEN)))
  416.       (AND (FORCE-DOIT-MARKER? SPECIAL-ACTION)
  417.        (= 0 (FUNCTION-NUMBER-OF-ARGS CURRENT-TOKEN)))))
  418.  
  419. (DEFSUBST IGNORE-IT? (CURRENT-TOKEN SPECIAL-ACTION)
  420.   ;; get rid of junk like named boxes here.
  421.   (OR (IGNORE-TOKEN-MARKER? SPECIAL-ACTION)
  422.       (AND (EVAL-NAMED? CURRENT-TOKEN)
  423.        (NOT (DONT-IGNORE-MARKER? SPECIAL-ACTION)))))
  424.  
  425. (DEFSUBST IGNORE-MARKER? (THING)
  426.   (OR (EQ THING :IGNORE-CURRENT-TOKEN) (SPACES? THING)))
  427.  
  428. (DEFSUBST UNBOX-IT? (THING)
  429.   (EQ THING *UNBOX-MARKER*))
  430.  
  431. ;;; Space handling grossness.  This will eventually have to fixed somehwere else BEFORE the
  432. ;;; evaluator gets hold of a form
  433. (DEFSUBST GET-NEXT-MEANINGFUL-THING (EXP)
  434.   (LOOP FOR THING IN EXP
  435.     FOR INDEX = 0 THEN (INCF INDEX)
  436.     UNLESS (IGNORE-MARKER? THING)
  437.       RETURN (VALUES THING (NTHCDR (1+ INDEX) EXP))))
  438.  
  439. ;;; EV-THING has to check for objects to be ignored (like named boxes) since
  440. ;;; unlike, RETURN-VALUE, it looks at the raw uncoerced objects
  441. (DEFUN EV-THING (THING &OPTIONAL SPECIAL-ACTION)
  442.   (LET* ((THING-TYPE (TOKEN-TYPE THING))
  443.      (WHAT-TO-DO (GET THING-TYPE 'EVAL-HANDLER))
  444.      (CANONICAL-ACTION (AND SPECIAL-ACTION (CONVERT-ACTIONS SPECIAL-ACTION))))
  445.     (COND ((NULL WHAT-TO-DO) (FERROR "Don't know how to evaluate ~A" THING))
  446.       ((IGNORE-IT? THING CANONICAL-ACTION) :IGNORE-CURRENT-TOKEN)
  447.       (T (FUNCALL WHAT-TO-DO THING CANONICAL-ACTION)))))
  448.  
  449. (DEFUN RETURN-VALUE (EXPRESSION &OPTIONAL SPECIAL-ACTION OLD-INFIX-LEVEL COPYING-FUNCTION)
  450.   (LET ((F (EV-THING (CAR EXPRESSION) SPECIAL-ACTION))
  451.     ;; we need to process @'s before this !!!
  452.     (NEW-INFIX-LEVEL (WHEN (SYMBOLP (GET-NEXT-MEANINGFUL-THING (CDR EXPRESSION)))
  453.                (GET (GET-NEXT-MEANINGFUL-THING (CDR EXPRESSION))
  454.                 :INFIX-PRECEDENCE)))
  455.     (*EVALUATOR-COPYING-FUNCTION* (OR COPYING-FUNCTION #'SHALLOW-COPY-FOR-EVALUATOR)))
  456.       (COND ((UNBOX-PAIR? F)
  457.          ;; Decide where SPECIAL-ACTION is supposed to be !!!!
  458.          (RETURN-VALUE (UNBOX-FUNCTION F (CDR EXPRESSION)) SPECIAL-ACTION))
  459.         ((EVAL-SPECIAL-MARKER? F)
  460.          (MULTIPLE-VALUE-BIND (EXP NEW-ACTIONS)
  461.          (COLLECT-AND-MERGE-ACTION-MARKERS F SPECIAL-ACTION (CDR EXPRESSION))
  462.            (RETURN-VALUE EXP NEW-ACTIONS)))
  463.         ((IGNORE-MARKER? F)
  464.          (RETURN-VALUE (CDR EXPRESSION) SPECIAL-ACTION OLD-INFIX-LEVEL))        
  465.         ((APPLY-IT? F SPECIAL-ACTION)
  466.          (MULTIPLE-VALUE-BIND (ARGS REST)
  467.          (COLLECT-ARGS F (CDR EXPRESSION))
  468.            (VALUES (BOXER-APPLY F ARGS) REST)))
  469.         ((AND (NOT-NULL NEW-INFIX-LEVEL)
  470.           (OR (NULL OLD-INFIX-LEVEL) (> NEW-INFIX-LEVEL OLD-INFIX-LEVEL)))
  471.          (MULTIPLE-VALUE-BIND (THING AFTER-THING)
  472.          (GET-NEXT-MEANINGFUL-THING (CDR EXPRESSION))
  473.            (RETURN-VALUE (INFIX-EXPRESSION-SMOOSH (EV-THING THING NIL) (COPY-FOR-EVAL F)
  474.                               AFTER-THING NEW-INFIX-LEVEL))))
  475.         (T
  476.          ;;; **** WARNING ****
  477.          ;;; I took out a (COPY-FOR-EVAL F) here
  478.          (VALUES F (CDR EXPRESSION))))))
  479.  
  480. (DEFUN EV-EXPRESSION (EXPRESSION &OPTIONAL ACTIONS)
  481.   (MULTIPLE-VALUE-BIND (RESULT REST)
  482.       (RETURN-VALUE EXPRESSION ACTIONS)
  483.     (IF (NULL REST)
  484.     RESULT
  485.     (EV-EXPRESSION REST))))
  486.  
  487. (DEFUN EVAL-BOX-ROWS (BOX)
  488.   (IF (NUMBERP BOX)
  489.       BOX
  490.       (LOOP WITH RESULT = NIL
  491.         FOR ROW IN (GET-BOX-ROWS-FOR-EVAL BOX)
  492.         UNLESS (NULL ROW)
  493.           DO (SETQ RESULT (EV-EXPRESSION ROW))
  494.         FINALLY
  495.           (RETURN RESULT))))
  496.  
  497. (DEFUN INFIX-EXPRESSION-SMOOSH (FUN ARG1 EXP PRECEDENCE)
  498.   (MULTIPLE-VALUE-BIND (ARG2 REST)
  499.       (RETURN-VALUE EXP NIL PRECEDENCE)
  500.     (APPEND (NCONS (BOXER-APPLY FUN `(,ARG1 ,ARG2))) REST)))
  501.  
  502.  
  503.  
  504. ;;; Stuff used to handle (flavored) arglists
  505.  
  506. (DEFUN BOX-ARGLIST (BOX)            ;returns the raw arglist
  507.   (mapcar #'(LAMBDA (entry)
  508.           (if (label-pair? entry)
  509.           (label-pair-label entry)
  510.           entry))
  511.       (GET-INPUT-ROW box)))
  512.  
  513. (DEFUN GET-ARG-TEMPLATE-FROM-ITEM (ARG-TEMPLATE)
  514.   (COND ((LISTP ARG-TEMPLATE)
  515.      (LET ((ITEM (PARSE-LIST-FOR-EVAL ARG-TEMPLATE)))
  516.        (MAPCAR #'CONVERT-MARKER (FIRSTN (1- (LENGTH ITEM)) ITEM))))
  517.     (T NIL)))
  518.  
  519. (DEFSUBST GET-TEMPLATE-FROM-ARGLIST (ARGLIST)
  520.   (WHEN (FLAVORED-ARGLIST? ARGLIST)        ;otherwise No special handling
  521.     (LOOP FOR ITEM IN ARGLIST
  522.       UNLESS (SPACES? ITEM)
  523.         COLLECTING (GET-ARG-TEMPLATE-FROM-ITEM ITEM))))
  524.  
  525. (DEFSUBST GET-ARG-NAME-FROM-ITEM (ITEM)
  526.   (COND ((LISTP ITEM) (CAR (LAST ITEM)))
  527.     (T ITEM)))
  528.  
  529. (DEFSUBST GET-ARG-NAMES-FROM-ARGLIST (ARGLIST);parses out just the names in a flavored arglist
  530.   (MAPCAR #'GET-ARG-NAME-FROM-ITEM ARGLIST))
  531.  
  532. ;; for lisp functions...
  533.  
  534. (DEFUN GET-ARGS-TEMPLATE (FUN)
  535.   (SEND *FUNNY-FUNCTION-ARGLIST-TABLE* :GET-HASH FUN))
  536.  
  537. (DEFUN REMOVE-ARGS-TEMPLATE (FUN)
  538.   (SEND *FUNNY-FUNCTION-ARGLIST-TABLE* :REM-HASH FUN))
  539.  
  540. (DEFUN SET-ARGS-TEMPLATE (FUN TEMPLATE)
  541.     (SEND *FUNNY-FUNCTION-ARGLIST-TABLE* :PUT-HASH FUN TEMPLATE))
  542.  
  543. ;;; these are the top level functions which should be called to get info about
  544. ;;; a function's arglist
  545.  
  546. (DEFUN GET-TEMPLATE (FUN)
  547.   (IF (FUNCTIONP FUN) (GET-ARGS-TEMPLATE FUN)
  548.       (GET-TEMPLATE-FROM-ARGLIST (BOX-ARGLIST FUN))))
  549.  
  550. (DEFUN GET-ARG-NAMES (FUN)
  551.   (IF (FUNCTIONP FUN) (ARGLIST FUN)
  552.       (GET-ARG-NAMES-FROM-ARGLIST (BOX-ARGLIST FUN))))
  553.  
  554. (DEFUN FUNCTION-NUMBER-OF-ARGS (FUNCTION)
  555.   (COND ((EVAL-BOX? FUNCTION) (LENGTH (BOX-ARGLIST FUNCTION)))
  556.     ((EVAL-PORT? FUNCTION) (LENGTH (BOX-ARGLIST (GET-PORT-TARGET FUNCTION))))
  557.     (T (ldb %%arg-desc-min-args (boxer-args-info FUNCTION)))))
  558.  
  559. (DEFUN COLLECT-ARGS (FUN EXPRESSION)
  560.   (DECLARE (VALUES COLLECTED-ARGS REMAINING-EXPRESSION))
  561.   (LOOP WITH TEMPLATE = (GET-TEMPLATE FUN)
  562.     FOR INDEX FROM 0 TO (1- (FUNCTION-NUMBER-OF-ARGS FUN))
  563.     FOR ARG-TEMP = (NTH INDEX TEMPLATE)
  564.     COLLECT
  565.       (COND ((COLLECT-MARKER? ARG-TEMP)
  566.          (MULTIPLE-VALUE-BIND (RESULT REST)
  567.              (COLLECT-REST-ARGS EXPRESSION ARG-TEMP)
  568.            (SETQ EXPRESSION REST)
  569.            RESULT))
  570.         ;;; ***WARNING ****
  571.         ;;; putting in copying here after removing it from return-value
  572.         ((NOT (NULL EXPRESSION))
  573.          ;; we use this crock to insure that numbers are put into the stack
  574.          ;; frames as BOXes which can be CHANGEd.  Since primitives will
  575.          ;; generally prefer numbers (or ports), this kind of copying only
  576.          ;; applies for DOIT-BOXes
  577. ;         (MULTIPLE-VALUE-BIND (RESULT REST)
  578. ;             (RETURN-VALUE EXPRESSION ARG-TEMP NIL (IF (FUNCTIONP FUN)
  579. ;                                   #'SHALLOW-COPY-FOR-EVALUATOR
  580. ;                                   #'SHALLOW-COPY-FOR-ARGLIST))
  581. ;           (SETQ EXPRESSION REST)
  582. ;           RESULT)
  583.          (MULTIPLE-VALUE-BIND (RESULT REST)
  584.              (RETURN-VALUE EXPRESSION ARG-TEMP NIL)
  585.            (SETQ EXPRESSION REST)
  586.            (let ((*evaluator-copying-function* (IF (FUNCTIONP FUN)
  587.                                    #'SHALLOW-COPY-FOR-EVALUATOR
  588.                                    #'SHALLOW-COPY-FOR-ARGLIST)))
  589.              (copy-for-eval RESULT))))
  590.         (T (FERROR "The function ~A needs more inputs"
  591.                (IF (BOX? FUN) (TELL FUN :NAME) FUN))))
  592.       INTO ARGS
  593.     FINALLY
  594.       (RETURN (VALUES ARGS EXPRESSION))))
  595.  
  596. ;;; Use this for Boxer's version of &REST arguments
  597. (DEFSUBST COLLECT-MARKER? (THING)    ;should probably trim the number of collection styles
  598.   (OR (BOX-REST-MARKER?  THING)
  599.       (LIST-REST-MARKER? THING)
  600.       (DELIM-BOX-REST-MARKER?  THING)
  601.       (DELIM-LIST-REST-MARKER? THING)))
  602.  
  603. (DEFSUBST DELIMITED-COLLECTION? (MARKER)
  604.   (OR (DELIM-BOX-REST-MARKER?  MARKER)
  605.       (DELIM-LIST-REST-MARKER? MARKER)))
  606.  
  607. (DEFSUBST BOXED-COLLECTION? (MARKER)
  608.   (OR (BOX-REST-MARKER? MARKER)
  609.       (DELIM-BOX-REST-MARKER? MARKER)))
  610.  
  611. ;;; this need to hack ports when/if we figure out what port-collect means...
  612. ;;; also, should this be copying the collected args ?
  613. (DEFUN COLLECT-REST-ARGS (EXPRESSION ARG-TEMP)
  614.   (DECLARE (VALUES COLLECTED-ARGS REMAINING-EXPRESSION))
  615.   (MULTIPLE-VALUE-BIND (COLLECTED-ARGS REST)
  616.       (IF (DELIMITED-COLLECTION? ARG-TEMP) (COLLECT-UNTIL-DELIMITER EXPRESSION)
  617.       (VALUES EXPRESSION NIL))
  618.     ;; perhaps do something (copy? port?) to the collected args here...
  619.     (IF (BOXED-COLLECTION? ARG-TEMP)
  620.     (VALUES (MAKE-EVDATA ROWS (NCONS (MAKE-EVROW-FROM-ENTRIES COLLECTED-ARGS))) REST)
  621.     (VALUES COLLECTED-ARGS REST))))
  622.  
  623.  
  624. ;; this doesn't work right.  Needs to be more selective as to what a delimiter is...
  625. ;; also doesn't allow for labels in the collected args....
  626. (DEFUN COLLECT-UNTIL-DELIMITER (EXP)
  627.   (LOOP FOR ITEM IN EXP
  628.     FOR INDEX = 0 THEN (INCF INDEX)
  629.     WHEN (LABEL-PAIR? ITEM)
  630.       RETURN (VALUES (FIRSTN INDEX EXP) (NTHCDR INDEX EXP))
  631.     FINALLY
  632.       (RETURN (VALUES EXP NIL))))
  633.   
  634.  
  635.  
  636. ;;;; APPLY
  637.  
  638. (DEFUN BOXER-APPLY-PRIMITIVE (PRIM ARGS)
  639.   (APPLY PRIM ARGS))
  640.  
  641. ;; calls read on a box if it has to if it is an EVbox just returns the rows
  642. (DEFUN GET-BOX-ROWS-FOR-EVAL (BOX)
  643.   (IF (BOX-HAS-INPUTS? BOX) (CDR (GET-BOX-ROWS BOX))
  644.       (GET-BOX-ROWS BOX)))
  645.  
  646. (DEFSUBST DYNAMIC-CALL? (FUN)
  647.   ;; needs to check for copying (dynamic)  or porting (lexical)
  648.   (NOT (EVAL-PORT? FUN)))
  649.  
  650. (DEFSUBST GET-LEXICAL-ROOT (FUN)
  651.   (COND ((EVAL-PORT? FUN)(GET-PORT-TARGET FUN))
  652.     ((BOX? FUN) FUN)
  653.     ((evbox? fun) fun)
  654.     (T (FERROR "don't know how to get the lexical root of ~A" FUN))))
  655.  
  656. (DEFUN BOXER-APPLY (FUN ARGS)
  657.   (LET ((*CURRENT-FUNCTION-BEING-FUNCALLED* FUN))
  658.     (COND ((FUNCTIONP FUN) (BOXER-APPLY-PRIMITIVE FUN ARGS))
  659.       ((DYNAMIC-CALL? FUN)
  660.        ;; must be a box that has been copied so we build up the stack
  661.        (WITH-DYNAMIC-VALUES-BOUND (MAKE-FRAME FUN ARGS)
  662.          (EVAL-BOX-ROWS FUN)))
  663.       (T
  664.        ;; must be a port i.e. lexical scoping
  665.        ;; don't pass the stack and change the static root
  666.        (WITH-STATIC-ROOT-BOUND (GET-LEXICAL-ROOT FUN)
  667.          (WITH-NEW-DYNAMIC-VALUES (MAKE-FRAME FUN ARGS)
  668.            (EVAL-BOX-ROWS FUN)))))))
  669.  
  670. ;; if there are no args, avoid all contact
  671. (DEFUN RUN-IT (THING)            ;for 0 args objects to be run
  672.   (COND ((FUNCTIONP THING) (FUNCALL THING))
  673.     ((DYNAMIC-CALL? THING)
  674.      (WITH-DYNAMIC-VALUES-BOUND (MAKE-FRAME THING)
  675.        (EVAL-BOX-ROWS THING)))
  676.     (T                    ;must be a lexicall call (running a port)
  677.      (WITH-STATIC-ROOT-BOUND (GET-LEXICAL-ROOT THING)
  678.        (WITH-NEW-DYNAMIC-VALUES (MAKE-FRAME THING)
  679.          (EVAL-BOX-ROWS THING))))))
  680.  
  681.  
  682. ;;;; Printing things
  683.  
  684. (DEFUN CONVERT-EVALUATOR-RETURNED-VALUE (THING)
  685.   "Coerces any evaluator-only object into an object suitable for the editor. "
  686.   (COND ((EVBOX? THING) (MAKE-BOX-FROM-EVBOX THING))
  687.     ((EVPORT? THING) (MAKE-BOX-FROM-EVBOX THING))
  688.     ((BOX? THING) (COPY-TOP-LEVEL-BOX THING))
  689.     (T THING)))
  690.  
  691. (DEFUN PRINT-EVALUATOR-RETURNED-VALUE (E-THING)
  692.   (LET ((THING (CONVERT-EVALUATOR-RETURNED-VALUE E-THING)))
  693.     (COND ((NUMBERP THING) (MAKE-BOX `((,THING))))
  694.       ((MEMQ THING *RETURNED-VALUES-NOT-TO-PRINT*) THING)
  695.       ((SYMBOLP THING) (MAKE-BOX `((,(STRING THING)))))
  696.       ((BOX? THING) THING)
  697.       (T (FORMAT NIL "~A" THING)))))
  698.  
  699.  
  700. (DEFUN EVAL-REGION (REGION)
  701.   (WITH-COPYING-STATISTICS
  702.     (LET ((RS (MAKE-BOXER-STREAM REGION)))
  703.       (LOOP WITH RESULT = :NOPRINT
  704.         FOR EXP = (PARSE-LIST-FOR-EVAL (BOXER-READ RS NIL))
  705.         UNTIL (NULL EXP)
  706.         DO (SETQ RESULT (EV-THING EXP NIL))
  707.         FINALLY
  708.           (RETURN (PRINT-EVALUATOR-RETURNED-VALUE RESULT))))))
  709.  
  710. (DEFUN EVAL-REGION-CATCHING-ERRORS (REGION)
  711.   (IF *BOXER-ERROR-HANDLER-P*
  712.       (CONDITION-CASE (ERROR)
  713.       (EVAL-REGION REGION)
  714.     (ERROR
  715.      (tell error :report-string)))
  716.       (EVAL-REGION REGION)))
  717.