2 /* (c) Copyright 1984 the Regents of the University of California.
4 This work was produced under the sponsorship of the
5 U.S. Department of Energy. The Government retains
6 certain rights therein. */
8 eval_when([translate,batch,demo],
9 load_package(sharem,"autolo"))$
11 herald_package(defstm)$
13 eval_when([batch,demo,loadfile],matchfix("{","}"))$
16 if not(symbolp(x)) then
17 if part(x,0)='mode and length(x)=2 and
18 symbolp(part(x,1)) and symbolp(part(x,2))
20 else error("if slot name identifier is not a symbol, it must be of the following form:
21 mode(type,slot_name)[= default value] , not",x)$
23 name_of_slot_id(x):=if symbolp(x) then x else part(x,1)$
25 mode_declare(function(equal_op),boolean)$
27 equal_op(x):=if not(atom(x)) and part(x,0)="=" then true$
29 slot_type(types,index):=if listp(types) then types[index] else types$
31 obtain_default_value_for_mode(mode):=
37 otherwise,buildq([],'%undefined%))$
39 %aux_alterant%(alt,extend_name,slot_names,quan,mode_type,obj,args):=
40 (mode_declare([slot_names,args],list,quan,fixnum),
42 mode_declare(result,list),
45 cond(not equal_op(ele),
46 error("alterant argument must specify a value:",ele),
48 not(member(nom:lhs(ele),slot_names)),
49 error("incorrect slot specifier to",alt,":",nom),
53 if slot_names[i]=nom then
54 return(result:endcons(buildq([i,val:rhs(ele),
55 type:slot_type(mode_type,i)],
56 extend_set(temp,i,mode_identity(type,val))),
58 if length(result)=0 then false
60 buildq([result,obj,alt,extend_name],
62 alter_extend_check(temp,'alt,'extend_name),
64 mode_identity(extend_name,temp)))))$
66 %aux_constructor%(construct,slot_names,defaults,quan,mode_type,name,args):=
67 (mode_declare([slot_names,defaults,args],list,quan,fixnum),
68 block([inits:?copy\-tree(defaults)],
69 mode_declare(inits,list),
72 cond(not equal_op(ele),
73 error("constructor argument must specify a value:",ele),
75 not(member(nom:lhs(ele),slot_names)),
76 error("incorrect slot specifier to",construct,":",nom),
80 if slot_names[i]=nom then
81 return(inits[i]:buildq([val:rhs(ele),
82 type:slot_type(mode_type,i)],
83 mode_identity(type,val))))),
85 mode_identity(name,make_extend('name,splice(inits))))))$
87 define_variable(%%existing_structures%%,[],list,
88 "hack to allow the properties of only those structures in a file being
89 translated to appear in the runtime portion of the translated output.")$
91 def_structure(name,options,[slots])::=
92 (mode_declare([options,slots],list),
93 block([construct:concat('make_,name),alt:concat('alter_,name),mode_type:'any,
94 conc:false,include:false,included_values:false,first:false,quan,
95 slot_num:1,default_value:buildq([],'%undefined%),inc_modes],
96 mode_declare([quan,slot_num],fixnum),
97 if not(symbolp(name)) then
98 error("first argument to def_structure must be a name",name),
100 for option in options do
101 if not(atom(option)) and lhs(option)='mode then
102 block([value:rhs(option)],
104 default_value:obtain_default_value_for_mode(mode_type)),
105 for option in options do
108 [but_first,include,mode],error("the",option,"option to def_structure must have a value"),
109 [conc_name],conc:concat(name,"_"),
110 [constructor,alterant],'done,
111 otherwise,error("unknown option to def_structure",option))
113 block([value:rhs(option)],
114 block([multiple_valuesp:listp(value),selector:lhs(option)],
115 mode_declare(multiple_valuesp,boolean),
116 if member(selector,'[constructor,alterant,conc_name,but_first,mode]) then
117 if multiple_valuesp then
118 error("only the include option to def_structure can have a list as its rhs:",option)
120 if not(symbolp(value)) then
121 error("rhs of option",selector,"must be a name"),
123 [constructor],construct:value,
124 [alterant],alt:value,
125 [conc_name],conc:value,
126 [but_first],first:value,
129 include:if multiple_valuesp then first(value) else value,
130 if not(symbolp(include)) then
131 error("first element of rhs list for include option to def_structure must be a name",include),
132 inc_modes:get(include,'mode_types),
133 if multiple_valuesp then
134 block([n_slots:length(value)-1],
135 mode_declare(n_slots,fixnum),
136 if get(include,'n_args)#n_slots then
137 error("incorrect number of slot initializations given to include option of def_structure"),
139 block([defaults:makelist(default_value,m,1,n_slots),
140 specs:rest(value),names:get(include,'slot_names)],
141 slot_num:slot_num+n_slots,
142 for i thru n_slots do
143 block([arg:specs[i]],
144 block([eqp:equal_op(arg)],
145 mode_declare(eqp,boolean),
146 block([name_spec:if eqp then lhs(arg) else arg],
147 block([typ:assess_mode(name_spec),
148 t:name_of_slot_id(name_spec)],
149 if not(member(t,names)) then
150 error(arg,"is a bad slot name for",include)
152 catch(for m thru n_slots do
154 block([dm:slot_type(inc_modes,m)],
155 if typ and typ#dm then
156 error("mode spec for included slot disagrees with slot from original structure"),
158 (defaults[m]:buildq([val:rhs(arg)],val),
159 apply('mode_identity,[dm,rhs(arg)]))))))))),
162 otherwise,error("unknown option to def_structure",selector)))),
163 block([defaults:makelist(default_value,m,1,quan),
164 slot_names:[],ret_macros:[],accessors:[]],
166 block([slot:slots[i]],
167 block([eqp:equal_op(slot)],
168 mode_declare(eqp,boolean),
169 block([nom_spec:if eqp then lhs(slot) else slot],
170 block([type:assess_mode(nom_spec),typed],
171 mode_declare(typed,boolean),
172 if typed:is(type#false) then
173 (if atom(mode_type) and type#mode_type then
174 mode_type:makelist(mode_type,m,1,quan),
175 if listp(mode_type) then
177 defaults[i]:obtain_default_value_for_mode(type))),
178 slot_names:endcons(name_of_slot_id(nom_spec),slot_names),
180 (defaults[i]:buildq([val:rhs(slot)],val),
181 apply('mode_identity,
182 [if typed then type else slot_type(mode_type,i),
184 accessors:if conc=false then slot_names
185 else makelist(concat(conc,slot_names[k]),k,1,quan),
186 block([arg:if first=false then '%x_%
187 else buildq([funct:first],funct(%x_%))],
189 (ret_macros:endcons(buildq([slot_num,element:accessors[j],arg,
190 name,lamode:slot_type(mode_type,j)],
193 mode_identity(lamode,reference_an_extend(arg,'element,'name,slot_num)))),
195 slot_num:slot_num+1)),
196 if include#false then
197 (accessors:append(get(include,'accessors),accessors),
198 slot_names:append(get(include,'slot_names),slot_names),
199 mode_type:cond(listp(mode_type),
200 append(if listp(inc_modes) then inc_modes
201 else makelist(inc_modes,m,1,get(include,'n_args)),
205 append(inc_modes,makelist(mode_type,m,1,quan)),
208 append(makelist(inc_modes,m,1,get(include,'n_args)),
209 makelist(mode_type,m,1,quan))),
210 defaults:append(if included_values=false then get(include,'defaults)
211 else included_values,
213 quan:length(defaults)),
214 push(name,%%existing_structures%%),
215 put(name,quan,'n_args),
216 put(name,defaults,'defaults),
217 put(name,accessors,'accessors),
218 put(name,slot_names,'slot_names),
219 put(name,mode_type,'mode_types),
221 ret_macros:cons(buildq([alt,slot_names,quan,mode_type,name],
222 alt(%obj_%,[%args_%])::=
223 %aux_alterant%('alt,'name,'slot_names,quan,
224 'mode_type,%obj_%,%args_%)),
226 if construct#false then
227 ret_macros:cons(buildq([construct,slot_names,defaults,quan,mode_type,name],
228 construct([%args_%])::=
229 %aux_constructor%('construct,'slot_names,'defaults,
230 quan,'mode_type,'name,%args_%)),
232 buildq([name,ret_macros],(splice(ret_macros),'name)))))$
234 initialize_structure_list():=%%existing_structures%%:[]$
236 save_runtime_structure_info(file):=
237 block([path:?merge\-pathname\-defaults('?"=.lsp",?stripdollar(file))],
238 block([nfile:?intern(?namestring(path)),
239 name:concat(?intern(?pathname\-name(path))),
240 version_no:?pathname\-version(path)],
241 put(name,if version_no=false then '%unknown% else version_no,'version),
242 apply('save,append([nfile,name,'"{"],%%existing_structures%%)),
243 %%existing_structures%%:[],
244 compile_lisp_file(nfile)))$