3 ;"NOTE: This pakcage can only be used compiled.
5 Loading BACKQUOTE causes subsequent READs to interpret backquote as a
6 special character. Backquote quotes the following object EXCEPT for objects
7 within it that are preceeded by a tilde. Thus
13 <CHTYPE (+ .A '.INC) FORM>
15 This is most useful in defining MACROs, although it can be used anywhere a
16 program needs to construct a large object, most of which is constant. Note
17 that BACKQUOTE makes no guarantees about ==?-ness of the objects it creates,
18 so no PUTs or PUTRESTs should be done on them.
20 Backquotes can be nested--they can be used to define macros that define
21 macros. Tilde is not treated as a special character unless it is inside a
24 <NEWTYPE TILDE LIST '<<PRIMTYPE LIST> ANY>>
26 <DEFINE TILDE-READ-MACRO (CHAN CHAR)
27 <CHTYPE (<READ .CHAN>) TILDE>>
29 <DEFINE BACKQUOTE-READ-MACRO (CHAN CHAR)
30 <BIND ((ORT:<OR FALSE <PRIMTYPE VECTOR>>
31 <COND (<ASSIGNED? READ-TABLE> .READ-TABLE)
32 (<GASSIGNED? READ-TABLE> ,READ-TABLE)>)
33 (NRT:<PRIMTYPE VECTOR> <STACK <IVECTOR 128 %<>>>))
35 <SUBSTRUC .ORT 0 <LENGTH .ORT> .NRT>)>
36 <PUT .NRT %<+ <ASCII !\~> 1>
37 [!\~ !\A %<> ,TILDE-READ-MACRO %<>]>
38 <PROG ((READ-TABLE:<SPECIAL <PRIMTYPE VECTOR>> .NRT))
39 <BIND ((B <BACKQUOTIFY <READ .CHAN>>))
40 <COND (<TYPE? .B TILDE> <1 .B>) (ELSE <FORM QUOTE .B>)>>>>>
42 ;"Objects wrapped in a tilde should be evaluated. All other objects should be
43 quoted. BACKQUOTIFY's job is to return an object that contains no TILDEs,
44 although it may (and usually will) return an object of type TILDE to
45 indicate that the EVALUATION of the contents is the object desired, not the
48 The convention of marking objects that should be evaluated with TILDE could
49 be changed to marking objects that should not be evaluated with QUOTE, but
50 since we expect most of the item to be quoted, this would be less efficient."
52 <DEFINE BACKQUOTIFY (OBJ)
54 ;"If the object needs to be evaluated, or couldn't contain any TILDEs,
56 (<OR <TYPE? .OBJ TILDE> <MONAD? .OBJ>> .OBJ)
58 <BIND ((PTYP:ATOM <PRIMTYPE .OBJ>))
59 ;"Only lists and vectors can contain interesting objects (like TILDEs),
60 so any other primtype can just be passed on like the monads."
63 <BIND ((FLAG:<OR FALSE TILDE> %<>))
64 ;"BACKQUOTIFY each of the sub-objects, and remember the last one
65 that came back tilded."
67 <FUNCTION (ROBJ "AUX" B)
68 <1 .ROBJ <SET B <BACKQUOTIFY <1 .ROBJ>>>>
69 <COND (<TYPE? .B TILDE> <SET FLAG .B>)>>
72 ;"If there was a tilded one, then remove the tildes on the
73 sub-objects, quote the un-tilded objects that need quotes,
74 and wrap a tlde around the whole thing. In other words,
75 create an object that wll evaluate to the desired object.
77 If enough objects (three or more in the interpreter, one or
78 more in the compiler) at the end of the list are quoted, use
79 the !'(...) trick to avoid copying list structure."
82 <FUNCTION (ROBJ "AUX" (SUBOBJ <1 .ROBJ>))
84 (<TYPE? .SUBOBJ TILDE>
86 <COND (<AND <==? .SUBOBJ .FLAG>
89 <COND (<FEATURE? "COMPILER"> 0)
92 (<CHTYPE (QUOTE <REST .ROBJ>)
96 ATOM FIX FLOAT STRING BYTES UVECTOR>>
97 ;"the list of self-quoting objects that I trust"
98 <1 .ROBJ <FORM QUOTE .SUBOBJ>>)>>
100 ;"Make sure the object evaluates to the right type, shove it in
101 a tilde, and return it."
102 <COND (<NOT <TYPE? .OBJ LIST>>
103 <SET OBJ <FORM CHTYPE <CHTYPE .OBJ LIST> <TYPE .OBJ>>>)>
106 ;"If all of the sub-objects were quoted, just return the
107 (now un-tilded) object."
110 ;"All of the comments for lists apply to vectors, except for the
113 #DECL ((FLAG) <OR FALSE TILDE>)
115 <FUNCTION (ROBJ "AUX" B)
116 <1 .ROBJ <SET B <BACKQUOTIFY <1 .ROBJ>>>>
117 <COND (<TYPE? .B TILDE> <SET FLAG .B>)>>
118 .OBJ:<PRIMTYPE VECTOR>>
121 <FUNCTION (ROBJ "AUX" (SUBOBJ <1 .ROBJ>))
122 <COND (<TYPE? .SUBOBJ TILDE>
123 <1 .ROBJ <1 .SUBOBJ>>)
125 ATOM FIX FLOAT STRING BYTES
127 ;"the list of self-quoting objects that
129 <1 .ROBJ <FORM QUOTE .SUBOBJ>>)>>
130 .OBJ:<PRIMTYPE VECTOR>>
131 <COND (<NOT <TYPE? .OBJ VECTOR>>
141 <DEFINE BACKQUOTE-INIT ("AUX" RT:<PRIMTYPE VECTOR>)
142 <COND (<GASSIGNED? READ-TABLE>
143 <BIND ((GRT:<OR FALSE VECTOR> ,READ-TABLE))
145 <COND (<L? <LENGTH .GRT> 128>
146 <BIND ((NRT <IVECTOR 128 %<>>))
147 <SUBSTRUC .GRT 0 <LENGTH .GRT> .NRT>
149 (ELSE <SET RT .GRT>)>)
150 (ELSE <SET RT <IVECTOR 128 %<>>>)>>)
151 (ELSE <SET RT <IVECTOR 128 %<>>>)>
152 <PUT .RT %<+ <ASCII !\`> 1>
153 [!\` !\A %<> ,BACKQUOTE-READ-MACRO %<>]>
154 <SETG READ-TABLE .RT>
155 <REPEAT ((LBIND:<OR FALSE LBIND> <CALL NTHR READ-TABLE ,M$$LVAL>))
157 <BIND ((LVAL <CALL NTHR .LBIND ,M$$VALU>))
158 <COND (<TYPE? .LVAL UNBOUND FALSE>
159 <CALL PUTR .LBIND ,M$$VALU .RT>)
161 <BIND ((LRT:<PRIMTYPE VECTOR> .LVAL))
162 <COND (<L? <LENGTH .LRT> 128>
163 <BIND ((NRT:VECTOR <IVECTOR 128 %<>>))
164 <SUBSTRUC .LRT 0 <LENGTH .LRT> .NRT>
166 <CALL PUTR .LBIND ,M$$VALU .LRT>
167 <PUT .LRT %<+ <ASCII !\`> 1>
168 [!\` !\A %<> ,BACKQUOTE-READ-MACRO %<>]>>)>>
169 <SET LBIND <CALL NTHR .LBIND ,M$$PATM>>)
173 <COND (<AND <GASSIGNED? BACKQUOTE-INIT>
174 <TYPE? ,BACKQUOTE-INIT MSUBR>>