SCM Repository
Annotation of /sml/branches/SMLNJ/src/compiler/Semant/modules/sigmatch.sml
Parent Directory
|
Revision Log
Revision 125 - (view) (download)
1 : | monnier | 16 | (* Copyright 1996 by AT&T Bell Laboratories *) |
2 : | (* sigmatch.sml *) | ||
3 : | |||
4 : | signature SIGMATCH = | ||
5 : | sig | ||
6 : | |||
7 : | (*** these four functions are only called inside elabmod.sml ***) | ||
8 : | val matchStr : | ||
9 : | {sign : Modules.Signature, | ||
10 : | str : Modules.Structure, | ||
11 : | strExp : Modules.strExp, | ||
12 : | evOp : EntPath.entVar option, | ||
13 : | depth : DebIndex.depth, | ||
14 : | entEnv : Modules.entityEnv, | ||
15 : | rpath : InvPath.path, | ||
16 : | statenv : StaticEnv.staticEnv, | ||
17 : | region : SourceMap.region, | ||
18 : | compInfo : ElabUtil.compInfo} -> {resDec : Absyn.dec, | ||
19 : | resStr : Modules.Structure, | ||
20 : | resExp : Modules.strExp} | ||
21 : | |||
22 : | val matchFct : | ||
23 : | {sign : Modules.fctSig, | ||
24 : | fct : Modules.Functor, | ||
25 : | fctExp : Modules.fctExp, | ||
26 : | depth : DebIndex.depth, | ||
27 : | entEnv : Modules.entityEnv, | ||
28 : | rpath : InvPath.path, | ||
29 : | statenv : StaticEnv.staticEnv, | ||
30 : | region : SourceMap.region, | ||
31 : | compInfo : ElabUtil.compInfo} -> {resDec : Absyn.dec, | ||
32 : | resFct : Modules.Functor, | ||
33 : | resExp : Modules.fctExp} | ||
34 : | |||
35 : | val packStr : | ||
36 : | {sign : Modules.Signature, | ||
37 : | str : Modules.Structure, | ||
38 : | strExp : Modules.strExp, | ||
39 : | depth : DebIndex.depth, | ||
40 : | entEnv : Modules.entityEnv, | ||
41 : | rpath : InvPath.path, | ||
42 : | statenv : StaticEnv.staticEnv, | ||
43 : | region : SourceMap.region, | ||
44 : | compInfo : ElabUtil.compInfo} -> {resDec : Absyn.dec, | ||
45 : | resStr : Modules.Structure, | ||
46 : | resExp : Modules.strExp} | ||
47 : | |||
48 : | val applyFct : | ||
49 : | {fct : Modules.Functor, | ||
50 : | fctExp : Modules.fctExp, | ||
51 : | argStr : Modules.Structure, | ||
52 : | argExp : Modules.strExp, | ||
53 : | evOp : EntPath.entVar option, | ||
54 : | depth : DebIndex.depth, | ||
55 : | epc : EntPathContext.context, | ||
56 : | statenv : StaticEnv.staticEnv, | ||
57 : | rpath : InvPath.path, | ||
58 : | region : SourceMap.region, | ||
59 : | compInfo : ElabUtil.compInfo} -> {resDec : Absyn.dec, | ||
60 : | resStr : Modules.Structure, | ||
61 : | resExp : Modules.strExp} | ||
62 : | |||
63 : | |||
64 : | val debugging : bool ref | ||
65 : | val showsigs : bool ref | ||
66 : | |||
67 : | end (* signature SIGMATCH *) | ||
68 : | |||
69 : | |||
70 : | structure SigMatch: SIGMATCH = | ||
71 : | struct | ||
72 : | |||
73 : | local structure A = Absyn | ||
74 : | structure B = Bindings | ||
75 : | structure DA = Access | ||
76 : | structure DI = DebIndex | ||
77 : | structure EE = EntityEnv | ||
78 : | structure EM = ErrorMsg | ||
79 : | structure EP = EntPath | ||
80 : | structure EPC = EntPathContext | ||
81 : | structure EU = ElabUtil | ||
82 : | structure EV = EvalEntity | ||
83 : | structure INS = Instantiate | ||
84 : | structure II = InlInfo | ||
85 : | structure IP = InvPath | ||
86 : | structure M = Modules | ||
87 : | structure MU = ModuleUtil | ||
88 : | structure PP = PrettyPrint | ||
89 : | structure S = Symbol | ||
90 : | structure SE = StaticEnv | ||
91 : | structure SP = SymPath | ||
92 : | structure ST = Stamps | ||
93 : | structure T = Types | ||
94 : | structure TU = TypesUtil | ||
95 : | structure V = VarCon | ||
96 : | |||
97 : | open Types Modules VarCon ElabDebug | ||
98 : | |||
99 : | in | ||
100 : | exception BadBinding | ||
101 : | |||
102 : | val debugging = Control.CG.smdebugging (* ref false *) | ||
103 : | val showsigs = ref false | ||
104 : | |||
105 : | val say = Control.Print.say | ||
106 : | fun debugmsg (msg: string) = | ||
107 : | if !debugging then (say msg; say "\n") else () | ||
108 : | |||
109 : | fun bug msg = EM.impossible ("SigMatch:" ^ msg) | ||
110 : | val nth = List.nth | ||
111 : | fun for l f = app f l | ||
112 : | |||
113 : | fun symbolsToString [] = "" | ||
114 : | | symbolsToString [n] = S.name n | ||
115 : | | symbolsToString (n::r) = | ||
116 : | concat(S.name n :: foldr (fn(n,b) => (","::S.name n::b)) [] r) | ||
117 : | |||
118 : | val BogusTy = UNDEFty | ||
119 : | |||
120 : | (* | ||
121 : | * Bogus coercion expressions returned by the matching functions. These | ||
122 : | * should never be evaluated. | ||
123 : | *) | ||
124 : | |||
125 : | val bogusStrExp = M.VARstr [] | ||
126 : | val bogusFctExp = M.VARfct [] | ||
127 : | |||
128 : | fun showStr (msg,str) = | ||
129 : | withInternals(fn () => | ||
130 : | debugPrint debugging | ||
131 : | (msg, | ||
132 : | (fn pps => fn str => | ||
133 : | PPModules.ppStructure pps (str, SE.empty, 100)), | ||
134 : | str)) | ||
135 : | |||
136 : | fun exnRep (DA.EXN _, dacc) = DA.EXN dacc | ||
137 : | | exnRep _ = bug "unexpected conrep in exnRep" | ||
138 : | |||
139 : | fun isNamed(SOME _) = true | ||
140 : | | isNamed _ = false | ||
141 : | |||
142 : | val anonSym = S.strSymbol "<anonymousStr>" | ||
143 : | val anonFsym = S.fctSymbol "<anonymousFct>" | ||
144 : | val paramSym = S.strSymbol "<FsigParamInst>" | ||
145 : | |||
146 : | fun ident _ = () | ||
147 : | |||
148 : | (* returns true and the new instantiations if actual type > spec type *) | ||
149 : | (* matches an abstract version of a type with its actual version *) | ||
150 : | fun absEqvTy (spec, actual, dinfo) : (ty list * tyvar list * ty * bool) = | ||
151 : | let val actual = TU.prune actual | ||
152 : | val spec = TU.prune spec | ||
153 : | val (actinst, insttys0) = TU.instantiatePoly actual | ||
154 : | val (specinst, stys) = TU.instantiatePoly spec | ||
155 : | val _ = ListPair.app Unify.unifyTy (insttys0, stys) | ||
156 : | |||
157 : | (* | ||
158 : | * This is a gross hack. Inlining-information such as primops | ||
159 : | * (or inline-able expressions) are propagated through signature | ||
160 : | * matching. However, their types may change. The following code | ||
161 : | * is to figure out the proper type application arguments, insttys. | ||
162 : | * The typechecker does similar hack. We will clean this up in the | ||
163 : | * future (ZHONG). | ||
164 : | *) | ||
165 : | val insttys = | ||
166 : | (case dinfo | ||
167 : | of II.INL_PRIM(_, SOME st) => | ||
168 : | (let val (actinst', insttys') = TU.instantiatePoly st | ||
169 : | in Unify.unifyTy(actinst', actinst) handle _ => (); | ||
170 : | insttys' | ||
171 : | end) | ||
172 : | | _ =>insttys0) | ||
173 : | |||
174 : | val res = (Unify.unifyTy(actinst, specinst); true) handle _ => false | ||
175 : | |||
176 : | val instbtvs = map TU.tyvarType insttys0 | ||
177 : | (* should I use stys here instead, why insttys0 ? *) | ||
178 : | |||
179 : | in (insttys, instbtvs, specinst, res) | ||
180 : | end | ||
181 : | |||
182 : | fun eqvTnspTy (spec, actual, dinfo) : (ty list * tyvar list) = | ||
183 : | let val actual = TU.prune actual | ||
184 : | val (actinst, insttys) = TU.instantiatePoly actual | ||
185 : | |||
186 : | (* | ||
187 : | * This is a gross hack. Inlining-information such as primops | ||
188 : | * (or inline-able expressions) are propagated through signature | ||
189 : | * matching. However, their types may change. The following code | ||
190 : | * is to figure out the proper type application arguments, insttys. | ||
191 : | * The typechecker does similar hack. We will clean this up in the | ||
192 : | * future (ZHONG). | ||
193 : | *) | ||
194 : | val insttys = | ||
195 : | (case dinfo | ||
196 : | of II.INL_PRIM(_, SOME st) => | ||
197 : | (let val (actinst', insttys') = TU.instantiatePoly st | ||
198 : | in Unify.unifyTy(actinst', actinst) handle _ => (); | ||
199 : | insttys' | ||
200 : | end) | ||
201 : | | _ =>insttys) | ||
202 : | |||
203 : | val (specinst, stys) = TU.instantiatePoly spec | ||
204 : | val _ = ((Unify.unifyTy(actinst, specinst)) | ||
205 : | handle _ => bug "unexpected types in eqvTnspTy") | ||
206 : | val btvs = map TU.tyvarType stys | ||
207 : | |||
208 : | in (insttys, btvs) | ||
209 : | end | ||
210 : | |||
211 : | |||
212 : | (************************************************************************** | ||
213 : | * * | ||
214 : | * Matching a structure against a signature: * | ||
215 : | * * | ||
216 : | * val matchStr1 : Signature * Structure * S.symbol * DI.depth * * | ||
217 : | * entityEnv * EP.entPath * IP.path * staticEnv * * | ||
218 : | * region * EU.compInfo * | ||
219 : | * -> A.dec * M.Structure * M.strExp * | ||
220 : | * * | ||
221 : | * WARNING: epath is an inverse entPath, so it has to be reversed to * | ||
222 : | * produce an entPath. * | ||
223 : | * * | ||
224 : | **************************************************************************) | ||
225 : | fun matchStr1(specSig as SIG{closed, fctflag, stamp=sigStamp, elements=sigElements, ...}, | ||
226 : | str as STR{sign = SIG{elements=strElements, | ||
227 : | stamp=strSigStamp, ...}, | ||
228 : | rlzn = {stamp=strStamp, entities=strEntEnv, ...}, | ||
229 : | access = rootAcc, info=rootInfo}, | ||
230 : | strName : S.symbol, depth, matchEntEnv, | ||
231 : | epath: EP.entVar list, rpath: IP.path, statenv, region, | ||
232 : | compInfo as {mkStamp, mkLvar=mkv, error, ...}: EU.compInfo) = | ||
233 : | |||
234 : | let | ||
235 : | |||
236 : | val err = error region | ||
237 : | val _ = let fun h pps sign =PPModules.ppSignature pps (sign,statenv,6) | ||
238 : | val s = ">>matchStr1 - specSig :" | ||
239 : | in debugPrint (showsigs) (s, h, specSig) | ||
240 : | end | ||
241 : | |||
242 : | fun matchTypes (spec, actual, dinfo, name) : (T.ty list * T.tyvar list) = | ||
243 : | if TU.compareTypes(spec, actual) then | ||
244 : | let val (insttys, btvs) = eqvTnspTy(spec, actual, dinfo) | ||
245 : | in (insttys, btvs) | ||
246 : | end | ||
247 : | else (err EM.COMPLAIN | ||
248 : | "value type in structure doesn't match signature spec" | ||
249 : | (fn ppstrm => | ||
250 : | (PPType.resetPPType(); | ||
251 : | PP.add_newline ppstrm; | ||
252 : | app (PP.add_string ppstrm) [" name: ", S.name name]; | ||
253 : | PP.add_newline ppstrm; | ||
254 : | PP.add_string ppstrm "spec: "; | ||
255 : | PPType.ppType statenv ppstrm spec; | ||
256 : | PP.add_newline ppstrm; | ||
257 : | PP.add_string ppstrm "actual: "; | ||
258 : | PPType.ppType statenv ppstrm actual)); | ||
259 : | ([],[])) | ||
260 : | |||
261 : | fun complain s = err EM.COMPLAIN s EM.nullErrorBody | ||
262 : | fun complain' x = (complain x; raise BadBinding) | ||
263 : | |||
264 : | (* | ||
265 : | * Compare datacon names of spec and actual datatype; this uses | ||
266 : | * the fact that datacons have been sorted by name. | ||
267 : | *) | ||
268 : | fun compareDcons(spec,actual) = | ||
269 : | let fun comp(l1 as dc1::r1, l2 as dc2::r2, s_only, a_only) = | ||
270 : | if S.eq(dc1,dc2) then comp(r1,r2,s_only,a_only) | ||
271 : | else if S.symbolGt(dc1,dc2) | ||
272 : | then comp(l1,r2,s_only,dc2::a_only) | ||
273 : | else comp(r1,l2,dc1::s_only,a_only) | ||
274 : | |||
275 : | | comp([], [], s_only, a_only) = (rev s_only, rev a_only) | ||
276 : | | comp([], r, s_only, a_only) = (rev s_only, rev a_only @ r) | ||
277 : | | comp(r, [], s_only, a_only) = (rev s_only @ r, rev a_only) | ||
278 : | in comp(spec,actual,[],[]) | ||
279 : | end | ||
280 : | |||
281 : | fun checkTycBinding(_,T.ERRORtyc,_) = () | ||
282 : | | checkTycBinding(specTycon,strTycon,entEnv) = | ||
283 : | let val specName = S.name(TU.tycName specTycon) | ||
284 : | in case specTycon | ||
285 : | of GENtyc{stamp=s,arity,kind=specKind,eq=ref eqprop,...} => | ||
286 : | if arity <> TU.tyconArity strTycon | ||
287 : | then complain' ("tycon arity for " ^ specName | ||
288 : | ^ " does not match specified arity") | ||
289 : | else (case (specKind, TU.unWrapDefStar strTycon) | ||
290 : | of (DATATYPE{index,family={members,...} ,...}, | ||
291 : | GENtyc{arity=a',kind=DATATYPE{index=index', | ||
292 : | family={members=members',...}, ...}, | ||
293 : | ...}) => | ||
294 : | let val specDconSig = #dcons(Vector.sub(members,index)) | ||
295 : | val strDconSig = #dcons(Vector.sub(members',index')) | ||
296 : | val specnames = map #name specDconSig | ||
297 : | val strnames = map #name strDconSig | ||
298 : | |||
299 : | val _ = app (fn s => | ||
300 : | (debugmsg (S.name s))) specnames | ||
301 : | val _ = debugmsg "******" | ||
302 : | val _ = app (fn s => | ||
303 : | (debugmsg (S.name s))) strnames | ||
304 : | |||
305 : | in case compareDcons (specnames, strnames) | ||
306 : | of ([],[]) => () | ||
307 : | | (s_only, a_only) => | ||
308 : | complain'(concat(List.concat | ||
309 : | [["datatype ",specName, | ||
310 : | " does not match specification"], | ||
311 : | case s_only | ||
312 : | of [] => [] | ||
313 : | | _ => | ||
314 : | ["\n constructors in spec only: ", | ||
315 : | symbolsToString s_only], | ||
316 : | case a_only | ||
317 : | of [] => [] | ||
318 : | | _ => | ||
319 : | ["\n constructors in actual only: ", | ||
320 : | symbolsToString a_only]])) | ||
321 : | end | ||
322 : | | (DATATYPE _, _) => | ||
323 : | complain'("type "^specName^" must be a datatype") | ||
324 : | | (FORMAL, _) => | ||
325 : | if eqprop=YES andalso not(EqTypes.isEqTycon strTycon) | ||
326 : | then complain'("type " ^ specName ^ | ||
327 : | " must be an equality type") | ||
328 : | else () | ||
329 : | | _ => | ||
330 : | (debugPrint(debugging)("specTycon: ", | ||
331 : | PPType.ppTycon statenv, specTycon); | ||
332 : | debugPrint(debugging)("strTycon: ", | ||
333 : | PPType.ppTycon statenv, strTycon); | ||
334 : | bug "checkTycBinding 1" )) | ||
335 : | |||
336 : | | DEFtyc{tyfun=TYFUN{arity,body},strict,stamp,path} => | ||
337 : | let val ntyfun = TYFUN{arity=arity,body=MU.transType entEnv body} | ||
338 : | val specTycon' = DEFtyc{tyfun=ntyfun,strict=strict, | ||
339 : | stamp=stamp,path=path} | ||
340 : | in if TU.equalTycon(specTycon',strTycon) | ||
341 : | then () | ||
342 : | else (debugPrint(debugging)("specTycon': ", | ||
343 : | PPType.ppTycon statenv, specTycon); | ||
344 : | debugPrint(debugging)("strTycon: ", | ||
345 : | PPType.ppTycon statenv, strTycon); | ||
346 : | complain'("type " ^ specName ^ | ||
347 : | " does not match definitional specification")) | ||
348 : | end | ||
349 : | | ERRORtyc => raise BadBinding | ||
350 : | | _ => bug "checkTycBinding 2" | ||
351 : | end | ||
352 : | |||
353 : | (*** lookStr is only used inside the checkSharing function ***) | ||
354 : | fun lookStr (elements,entEnv) (SP.SPATH spath) : (M.Signature * M.entity) = | ||
355 : | let fun loop ([sym],elements,entEnv) = | ||
356 : | ((case MU.getSpec(elements,sym) | ||
357 : | monnier | 106 | of STRspec{entVar,sign,...} => |
358 : | (debugmsg ("$lookStr.1: "^S.name sym^", "^EP.entVarToString entVar); | ||
359 : | (sign,EE.look(entEnv,entVar))) | ||
360 : | monnier | 16 | | _ => bug "looStr 1b") |
361 : | handle MU.Unbound _ => bug "lookStr 1c") | ||
362 : | |||
363 : | | loop (sym::rest,elements,entEnv) = | ||
364 : | ((case MU.getSpec(elements,sym) | ||
365 : | of STRspec{sign=SIG{elements,...},entVar,...} => | ||
366 : | (case EE.look(entEnv,entVar) | ||
367 : | monnier | 106 | of STRent{entities,...} => |
368 : | (debugmsg ("$lookStr.2: "^S.name sym^", "^EP.entVarToString entVar); loop(rest,elements,entities)) | ||
369 : | monnier | 16 | | ERRORent => (ERRORsig,ERRORent) |
370 : | | _ => bug "lookStr 2a") | ||
371 : | | _ => bug "lookStr 2b") | ||
372 : | handle MU.Unbound _ => bug "lookStr 2c") | ||
373 : | |||
374 : | | loop _ = bug "lookStr 3" | ||
375 : | in loop(spath,elements,entEnv) | ||
376 : | end | ||
377 : | |||
378 : | (*** lookTyc is only used inside the checkSharing function ***) | ||
379 : | fun lookTyc (elements,entEnv) (SP.SPATH spath) : T.tycon = | ||
380 : | let fun loop ([sym],elements,entEnv) = | ||
381 : | ((case MU.getSpec(elements,sym) | ||
382 : | of TYCspec{entVar,...} => | ||
383 : | (case EE.look(entEnv,entVar) | ||
384 : | of TYCent tycon => tycon | ||
385 : | | ERRORent => ERRORtyc | ||
386 : | | _ => bug "lookTyc 1a") | ||
387 : | | _ => bug "looTyc 1b") | ||
388 : | handle MU.Unbound _ => bug "lookTyc 1c") | ||
389 : | |||
390 : | | loop (sym::rest,elements,entEnv) = | ||
391 : | ((case MU.getSpec(elements,sym) | ||
392 : | of STRspec{sign=SIG{elements,...},entVar,...} => | ||
393 : | (case EE.look(entEnv,entVar) | ||
394 : | of STRent{entities,...} => loop(rest,elements,entities) | ||
395 : | | ERRORent => ERRORtyc | ||
396 : | | _ => bug "lookTyc 2a") | ||
397 : | | _ => bug "lookTyc 2b") | ||
398 : | handle MU.Unbound _ => bug ("lookTyc 2c:"^Symbol.name sym^ | ||
399 : | SP.toString(SP.SPATH spath))) | ||
400 : | |||
401 : | | loop _ = bug "lookTyc 3" | ||
402 : | in loop(spath,elements,entEnv) | ||
403 : | end | ||
404 : | |||
405 : | (*** verify whether all the sharing constraints are satisfied ***) | ||
406 : | fun checkSharing(sign as ERRORsig, entEnv) = () | ||
407 : | (* don't do anything if an error has occured, resulting in an ERRORsig *) | ||
408 : | | checkSharing(sign as SIG{elements, typsharing, strsharing,...}, | ||
409 : | entEnv) = | ||
410 : | let fun errmsg sp x = SP.toString x ^ " # " ^ SP.toString sp | ||
411 : | |||
412 : | fun eqTyc(_,ERRORtyc) = true | ||
413 : | | eqTyc(ERRORtyc,_) = true | ||
414 : | | eqTyc(tyc1,tyc2) = TU.equalTycon(tyc1,tyc2) | ||
415 : | |||
416 : | val lookStr = lookStr (elements,entEnv) | ||
417 : | |||
418 : | |||
419 : | fun commonElements(SIG{elements=elems1,...},SIG{elements=elems2,...}) = | ||
420 : | let fun elemGt ((s1,_),(s2,_)) = S.symbolGt(s1,s2) | ||
421 : | val elems1 = Sort.sort elemGt elems1 | ||
422 : | val elems2 = Sort.sort elemGt elems2 | ||
423 : | fun intersect(e1 as ((s1,spec1)::rest1), | ||
424 : | e2 as ((s2,spec2)::rest2)) = | ||
425 : | if S.eq(s1,s2) then (s1,spec1,spec2)::intersect(rest1,rest2) | ||
426 : | else if S.symbolGt(s1,s2) then intersect(e1,rest2) | ||
427 : | else intersect(rest1,e2) | ||
428 : | | intersect(_,_) = nil | ||
429 : | in intersect(elems1,elems2) | ||
430 : | end | ||
431 : | | commonElements _ = bug "commonElements" | ||
432 : | |||
433 : | |||
434 : | fun appPairs test nil = () | ||
435 : | | appPairs test (a::r) = | ||
436 : | (app (fn x => test(a,x)) r; appPairs test r) | ||
437 : | |||
438 : | fun compStr((p1,(sign1,ent1)), | ||
439 : | (p2,(sign2,ent2))) = | ||
440 : | (case (ent1,ent2) | ||
441 : | of (STRent{stamp=s1,entities=ee1,...}, | ||
442 : | STRent{stamp=s2,entities=ee2,...}) => | ||
443 : | if ST.eq(s1,s2) then () (* shortcut! *) | ||
444 : | else if MU.eqSign(sign1,sign2) then | ||
445 : | monnier | 106 | let val _ = debugmsg "$compStr: equal signs" |
446 : | val SIG{elements,...} = sign1 | ||
447 : | monnier | 16 | in for elements (fn |
448 : | (sym,TYCspec{entVar,...}) => | ||
449 : | let val TYCent tyc1 = EE.look(ee1,entVar) | ||
450 : | val TYCent tyc2 = EE.look(ee2,entVar) | ||
451 : | in if eqTyc(tyc1,tyc2) then () | ||
452 : | else complain( | ||
453 : | concat["implied type sharing violation: ", | ||
454 : | errmsg (SP.extend(p1,sym)) | ||
455 : | (SP.extend(p2,sym))]) | ||
456 : | end | ||
457 : | | (sym,STRspec{entVar,sign,...}) => | ||
458 : | let val ent1' = EE.look(ee1,entVar) | ||
459 : | val ent2' = EE.look(ee2,entVar) | ||
460 : | in compStr((SP.extend(p1,sym),(sign,ent1')), | ||
461 : | (SP.extend(p2,sym),(sign,ent2'))) | ||
462 : | end | ||
463 : | | _ => ()) | ||
464 : | end | ||
465 : | else | ||
466 : | monnier | 106 | let val _ = debugmsg "$compStr: unequal signs" |
467 : | val common = commonElements(sign1,sign2) | ||
468 : | monnier | 16 | in for common (fn |
469 : | (sym,TYCspec{entVar=v1,...}, | ||
470 : | TYCspec{entVar=v2,...}) => | ||
471 : | let val TYCent tyc1 = EE.look(ee1,v1) | ||
472 : | val TYCent tyc2 = EE.look(ee2,v2) | ||
473 : | in if eqTyc(tyc1,tyc2) then () | ||
474 : | else complain( | ||
475 : | concat["type sharing violation: ", | ||
476 : | errmsg (SP.extend(p1,sym)) | ||
477 : | (SP.extend(p2,sym))]) | ||
478 : | end | ||
479 : | | (sym,STRspec{entVar=v1,sign=sign1',...}, | ||
480 : | STRspec{entVar=v2,sign=sign2',...}) => | ||
481 : | let val str1 = EE.look(ee1,v1) | ||
482 : | val str2 = EE.look(ee2,v2) | ||
483 : | monnier | 106 | in compStr((SP.extend(p1,sym),(sign1',str1)), |
484 : | monnier | 125 | (SP.extend(p2,sym),(sign2',str2))) |
485 : | monnier | 16 | end |
486 : | | _ => ()) (* values, constructors, functors *) | ||
487 : | end | ||
488 : | | (ERRORent,_) => () (* error upstream *) | ||
489 : | | (_,ERRORent) => ()) (* error upstream *) | ||
490 : | |||
491 : | fun checkStr (paths) = | ||
492 : | let val pathstrs = map (fn p => (p,lookStr p)) paths | ||
493 : | in appPairs compStr pathstrs | ||
494 : | end | ||
495 : | |||
496 : | fun checkTyc0 (firstPath, rest) = | ||
497 : | let val lookTyc = lookTyc (elements,entEnv) | ||
498 : | val errMsg = errmsg firstPath | ||
499 : | val first = lookTyc firstPath | ||
500 : | fun checkPath p = | ||
501 : | if eqTyc(first, lookTyc p) then () | ||
502 : | else complain(concat["type sharing violation: ",errMsg p]) | ||
503 : | in app checkPath rest | ||
504 : | end | ||
505 : | |||
506 : | fun checkTyc (sp::rest) = checkTyc0(sp,rest) | ||
507 : | |||
508 : | in app checkStr strsharing; | ||
509 : | app checkTyc typsharing | ||
510 : | end | ||
511 : | |||
512 : | (* | ||
513 : | * Matching: Go through the `elements' of the specified signature, and | ||
514 : | * construct a corresponding realization from entities found in the given | ||
515 : | * structure. The structure's entities are found by using the entPath in | ||
516 : | * each of the given structure signature's elements to access the given | ||
517 : | * structure's realization = stored entEnv. Recurse into substructures. | ||
518 : | * Build the formal realization in parallel. Finally check sharing | ||
519 : | * constraints. | ||
520 : | *) | ||
521 : | |||
522 : | (* | ||
523 : | * val matchElems : | ||
524 : | * (S.symbol * spec) list * entEnv * entityDec list * A.dec list | ||
525 : | * * B.binding list | ||
526 : | * -> (entEnv * entityDec list * A.dec list * B.binding list) | ||
527 : | * | ||
528 : | * Given the elements and the entities of a structure S, and a spec | ||
529 : | * from a signature, extend the realization (entityEnv) with the | ||
530 : | * entity specified by the spec, extend the list of | ||
531 : | * coercions (entity declarations) with a declaration which | ||
532 : | * will evaluate to the newly created entity, and extend the thinning. | ||
533 : | * | ||
534 : | * Assumption: if a match error occurs, then the resulting thinning | ||
535 : | * and the list of entityDecs will never be used -- they will not be | ||
536 : | * well-formed in case of errors. | ||
537 : | *) | ||
538 : | |||
539 : | fun matchDefStr0(sigElements,signD,rlznD,signM,rlznM) = | ||
540 : | let val dropVals = List.filter | ||
541 : | (fn (s,(TYCspec _ | STRspec _ )) => true | _ => false) | ||
542 : | fun elemGt ((s1,_),(s2,_)) = S.symbolGt(s1,s2) | ||
543 : | val commonDM = | ||
544 : | if MU.eqSign(signD,signM) then | ||
545 : | let val SIG{elements=elems,...} = signD | ||
546 : | val elems = Sort.sort elemGt (dropVals elems) | ||
547 : | in map (fn (s,spec) => (s,spec,spec)) elems | ||
548 : | end | ||
549 : | else | ||
550 : | let val SIG{elements=elemsD,...} = signD | ||
551 : | val SIG{elements=elemsM,...} = signM | ||
552 : | val elemsD = Sort.sort elemGt (dropVals elemsD) | ||
553 : | val elemsM = Sort.sort elemGt (dropVals elemsM) | ||
554 : | fun intersect(e1 as ((s1,spec1)::rest1), | ||
555 : | e2 as ((s2,spec2)::rest2)) = | ||
556 : | if S.eq(s1,s2) then (s1,spec1,spec2)::intersect(rest1,rest2) | ||
557 : | else if S.symbolGt(s1,s2) then intersect(e1,rest2) | ||
558 : | else intersect(rest1,e2) | ||
559 : | | intersect(_,_) = nil | ||
560 : | in intersect(elemsD,elemsM) | ||
561 : | end | ||
562 : | val sigElements' = dropVals sigElements | ||
563 : | fun intersect'(elems1 as ((sym1,x)::rest1), | ||
564 : | elems2 as ((sym2,y,z)::rest2)) = | ||
565 : | if S.eq(sym1,sym2) then | ||
566 : | (sym1,x,y,z)::intersect'(rest1,rest2) | ||
567 : | else if S.symbolGt(sym1,sym2) then | ||
568 : | intersect'(elems1,rest2) (* discard sym2 *) | ||
569 : | else intersect'(rest1,elems2) (* discard sym1 *) | ||
570 : | | intersect'(_,_) = nil | ||
571 : | val common = intersect'(sigElements',commonDM) | ||
572 : | fun loop nil = true | ||
573 : | | loop ((sym,spec,specD,specM)::rest) = | ||
574 : | (case spec | ||
575 : | of TYCspec _ => | ||
576 : | let val TYCspec{entVar=evD,...} = specD | ||
577 : | val TYCspec{entVar=evM,...} = specM | ||
578 : | val {entities=eeD,...} = rlznD | ||
579 : | val {entities=eeM,...} = rlznM | ||
580 : | val TYCent tycD = EE.look(eeD,evD) | ||
581 : | val TYCent tycM = EE.look(eeM,evM) | ||
582 : | in TU.equalTycon(tycD,tycM) | ||
583 : | end | ||
584 : | | STRspec{sign=SIG{elements,...},...} => | ||
585 : | let val STRspec{entVar=evD,sign=signD',...} = specD | ||
586 : | val STRspec{entVar=evM,sign=signM',...} = specM | ||
587 : | val {entities=eeD,...} = rlznD | ||
588 : | val {entities=eeM,...} = rlznM | ||
589 : | val STRent rlznD' = EE.look(eeD,evD) | ||
590 : | val STRent rlznM' = EE.look(eeM,evM) | ||
591 : | in matchDefStr0(elements,signD',rlznD',signM',rlznM') | ||
592 : | end | ||
593 : | | _ => bug "matchStr") | ||
594 : | in loop common | ||
595 : | end | ||
596 : | |||
597 : | fun matchDefStr(sigElements,specStr,matchStr) = | ||
598 : | case (specStr,matchStr) | ||
599 : | of (STR{sign=signD,rlzn=rlznD,...},STR{sign=signM,rlzn=rlznM,...}) => | ||
600 : | let val {stamp=sD,...} = rlznD | ||
601 : | val {stamp=sM,...} = rlznM | ||
602 : | in if ST.eq(sD,sM) (* eqOrigin *) | ||
603 : | then true | ||
604 : | else matchDefStr0(sigElements,signD,rlznD,signM,rlznM) | ||
605 : | end | ||
606 : | | _ => bug "matchDefStr" | ||
607 : | |||
608 : | fun matchElems ([], entEnv, entDecs, decs, bindings, succeed) = | ||
609 : | (entEnv, rev entDecs, rev decs, rev bindings, succeed) | ||
610 : | |||
611 : | | matchElems ((sym, spec) :: elems, entEnv, entDecs, decs, bindings, succeed) = | ||
612 : | |||
613 : | let val _ = debugmsg ">>matchElems" | ||
614 : | fun matchErr (kindOp: string option) = | ||
615 : | let val entEnv' = | ||
616 : | case MU.getSpecVar spec | ||
617 : | of SOME v => EE.bind(v, ERRORent, entEnv) | ||
618 : | | NONE => entEnv | ||
619 : | |||
620 : | (* synthesize a new error binding to remove improper error | ||
621 : | messages on inlInfo (ZHONG) *) | ||
622 : | val bindings' = | ||
623 : | case spec | ||
624 : | of TYCspec _ => bindings | ||
625 : | | CONspec {slot=NONE, ...} => bindings | ||
626 : | | _ => (B.CONbind bogusEXN)::bindings | ||
627 : | |||
628 : | in case kindOp | ||
629 : | of SOME kind => | ||
630 : | complain("unmatched " ^ kind ^ " specification: " ^ S.name sym) | ||
631 : | | NONE => (); | ||
632 : | matchElems(elems, entEnv', entDecs, decs, bindings', false) | ||
633 : | end | ||
634 : | |||
635 : | fun typeInMatched (kind,typ) = | ||
636 : | (MU.transType entEnv typ) | ||
637 : | handle EE.Unbound => | ||
638 : | (debugPrint (debugging) (kind, PPType.ppType statenv,typ); | ||
639 : | raise EE.Unbound) | ||
640 : | |||
641 : | fun typeInOriginal (kind,typ) = | ||
642 : | (MU.transType strEntEnv typ) | ||
643 : | handle EE.Unbound => | ||
644 : | (debugPrint (debugging) (kind, PPType.ppType statenv,typ); | ||
645 : | raise EE.Unbound) | ||
646 : | |||
647 : | in case spec | ||
648 : | of TYCspec{spec=specTycon,entVar,scope} => | ||
649 : | (let val _ = debugmsg(String.concat[">>matchElems TYCspec: ", | ||
650 : | S.name sym, ", ", | ||
651 : | ST.stampToString entVar]) | ||
652 : | val (strTycon, strEntVar) = | ||
653 : | MU.getTyc(strElements, strEntEnv, sym) | ||
654 : | handle EE.Unbound => | ||
655 : | (debugPrint(debugging) ("strEntEnv: ", | ||
656 : | (fn pps => fn ee => | ||
657 : | PPModules.ppEntityEnv pps (ee,statenv,6)), | ||
658 : | strEntEnv); raise EE.Unbound) | ||
659 : | |||
660 : | val _ = debugmsg ("--matchElems TYCspec - strEntVar: "^ | ||
661 : | ST.stampToString strEntVar) | ||
662 : | |||
663 : | (*** DAVE: please check the following ! ***) | ||
664 : | val tycEntExp = | ||
665 : | case epath of [] => CONSTtyc strTycon | ||
666 : | | _ => VARtyc(rev(strEntVar::epath)) | ||
667 : | |||
668 : | val _ = debugmsg "--matchElems TYCspec >> checkTycBinding" | ||
669 : | val _ = checkTycBinding(specTycon, strTycon, entEnv) | ||
670 : | val entEnv' = EE.bind(entVar, TYCent strTycon, entEnv) | ||
671 : | val entDecs' = TYCdec(entVar, tycEntExp) :: entDecs | ||
672 : | val _ = debugmsg "<<matchElems TYCspec << checkTycBinding" | ||
673 : | |||
674 : | in matchElems(elems, entEnv', entDecs', decs, bindings, succeed) | ||
675 : | end handle MU.Unbound sym => matchErr (SOME "type") | ||
676 : | | BadBinding => matchErr NONE | ||
677 : | | EE.Unbound => | ||
678 : | (debugmsg ("$matchElems(TYCspec): "^S.name sym); | ||
679 : | raise EE.Unbound)) | ||
680 : | |||
681 : | | STRspec{sign=thisSpecSig, entVar, def, ...} => | ||
682 : | (let val _ = debugmsg(String.concat["--matchElems STRspec: ", | ||
683 : | S.name sym,", ", | ||
684 : | ST.stampToString entVar]) | ||
685 : | val (strStr, strEntVar) = | ||
686 : | MU.getStr(strElements, strEntEnv, sym, rootAcc, rootInfo) | ||
687 : | |||
688 : | (* verify spec definition, if any *) | ||
689 : | (* BUG: shallow test, comparing stamps -- | ||
690 : | * needs to be augmented with component-wise test when | ||
691 : | * stamps disagree [dbm] *) | ||
692 : | (* how should this verification interact with signatures? *) | ||
693 : | val _ = | ||
694 : | case def | ||
695 : | of NONE => () | ||
696 : | | SOME(sd,_) => | ||
697 : | let val specStr = MU.strDefToStr(sd,entEnv) | ||
698 : | in if matchDefStr(sigElements,specStr,strStr) then () | ||
699 : | else | ||
700 : | (case sd | ||
701 : | of M.VARstrDef(sign,ep) => | ||
702 : | debugmsg("spec def VAR: "^ | ||
703 : | EP.entPathToString ep ^ "\n") | ||
704 : | | M.CONSTstrDef _ => | ||
705 : | debugmsg("spec def CONST\n"); | ||
706 : | showStr("specStr: ", specStr); | ||
707 : | showStr("strStr: ", strStr); | ||
708 : | complain("structure def spec for "^ | ||
709 : | S.name sym ^ " not matched")) | ||
710 : | end | ||
711 : | |||
712 : | val epath' = strEntVar::epath | ||
713 : | val rpath' = IP.extend(rpath, sym) | ||
714 : | val (thinDec, thinStr, strExp) = | ||
715 : | matchStr1(thisSpecSig, strStr, sym, depth, entEnv, epath', | ||
716 : | rpath', statenv, region, compInfo) | ||
717 : | |||
718 : | val entEnv' = | ||
719 : | let val strEnt = | ||
720 : | case thinStr of M.STR{rlzn, ...} => rlzn | ||
721 : | | _ => M.bogusStrEntity | ||
722 : | in EE.bind(entVar, M.STRent strEnt, entEnv) | ||
723 : | end | ||
724 : | |||
725 : | val entDecs' = M.STRdec(entVar, strExp, sym) :: entDecs | ||
726 : | val decs' = thinDec :: decs | ||
727 : | val bindings' = (B.STRbind thinStr)::bindings | ||
728 : | |||
729 : | in matchElems(elems, entEnv', entDecs', decs', bindings', succeed) | ||
730 : | end handle MU.Unbound sym => matchErr (SOME "structure")) | ||
731 : | |||
732 : | | FCTspec{sign=specSig, entVar, ...} => | ||
733 : | (let val _ = debugmsg(String.concat["--matchElems FCTspec: ", | ||
734 : | S.name sym,", ", | ||
735 : | ST.stampToString entVar]) | ||
736 : | |||
737 : | val (strFct, fctEntVar) = | ||
738 : | MU.getFct(strElements, strEntEnv, sym, rootAcc, rootInfo) | ||
739 : | val exp' = M.VARfct(rev(fctEntVar::epath)) | ||
740 : | val rpath' = IP.extend(rpath,sym) | ||
741 : | val (thinDec, thinFct, fctExp) = | ||
742 : | matchFct1(specSig, strFct, sym, depth, entEnv, exp', | ||
743 : | rpath', statenv, region, compInfo) | ||
744 : | |||
745 : | val entEnv' = | ||
746 : | let val fctEnt = | ||
747 : | case thinFct of M.FCT{rlzn, ...} => rlzn | ||
748 : | | _ => M.bogusFctEntity | ||
749 : | in EE.bind(entVar, M.FCTent fctEnt, entEnv) | ||
750 : | end | ||
751 : | |||
752 : | val entDecs' = M.FCTdec(entVar, fctExp) :: entDecs | ||
753 : | val decs' = thinDec :: decs | ||
754 : | val bindings' = (B.FCTbind thinFct)::bindings | ||
755 : | |||
756 : | in matchElems(elems, entEnv', entDecs', decs', bindings', succeed) | ||
757 : | end handle MU.Unbound sym => matchErr(SOME "functor")) | ||
758 : | |||
759 : | | VALspec{spec=spectyp, ...} => | ||
760 : | ((case (MU.getSpec(strElements, sym)) | ||
761 : | of VALspec{spec=acttyp, slot=actslot} => | ||
762 : | let val spectyp = typeInMatched("$specty(val/val)", spectyp) | ||
763 : | val acttyp = typeInOriginal("$actty(val/val)", acttyp) | ||
764 : | val dacc = DA.selAcc(rootAcc, actslot) | ||
765 : | val dinfo = II.selInfo(rootInfo, actslot) | ||
766 : | val (instys,btvs) = | ||
767 : | matchTypes(spectyp, acttyp, dinfo, sym) | ||
768 : | |||
769 : | val spath = SP.SPATH[sym] | ||
770 : | val actvar = VALvar{path=spath, typ=ref acttyp, | ||
771 : | access=dacc, info=dinfo} | ||
772 : | |||
773 : | val (decs', nv) = | ||
774 : | case (TU.headReduceType acttyp, | ||
775 : | TU.headReduceType spectyp) | ||
776 : | of ((POLYty _, _) | (_, POLYty _))=> | ||
777 : | let val acc = DA.namedAcc(sym, mkv) | ||
778 : | val specvar = | ||
779 : | VALvar{path=spath, typ=ref spectyp, | ||
780 : | access=acc, info=dinfo} | ||
781 : | val vb = | ||
782 : | A.VB {pat=A.VARpat specvar, | ||
783 : | exp=A.VARexp(ref actvar, instys), | ||
784 : | boundtvs=btvs, tyvars=ref []} | ||
785 : | |||
786 : | in ((A.VALdec [vb])::decs, specvar) | ||
787 : | end | ||
788 : | | _ => (decs, actvar) | ||
789 : | |||
790 : | val bindings' = (B.VALbind nv)::bindings | ||
791 : | |||
792 : | in matchElems(elems, entEnv, entDecs, decs', bindings', succeed) | ||
793 : | end | ||
794 : | |||
795 : | | CONspec{spec=DATACON{typ=acttyp, name, const, | ||
796 : | monnier | 106 | rep, sign, lazyp}, slot} => |
797 : | monnier | 16 | let val spectyp = typeInMatched("$specty(val/con)", spectyp) |
798 : | val acttyp = typeInOriginal("$actty(val/con)", acttyp) | ||
799 : | val (instys, btvs) = | ||
800 : | matchTypes(spectyp, acttyp, II.nullInfo, name) | ||
801 : | |||
802 : | val nrep = | ||
803 : | case slot | ||
804 : | of SOME s => exnRep(rep, DA.selAcc(rootAcc, s)) | ||
805 : | | NONE => rep | ||
806 : | |||
807 : | val (decs', bindings') = | ||
808 : | let val con = | ||
809 : | DATACON{typ=acttyp, name=name, const=const, | ||
810 : | monnier | 106 | rep=nrep, sign=sign, lazyp=lazyp} |
811 : | monnier | 16 | val acc = DA.namedAcc(name, mkv) |
812 : | val specvar = | ||
813 : | VALvar{path=SP.SPATH[name], access=acc, | ||
814 : | info=II.nullInfo, typ=ref spectyp} | ||
815 : | val vb = | ||
816 : | A.VB {pat=A.VARpat specvar, | ||
817 : | exp=A.CONexp(con, instys), | ||
818 : | boundtvs=btvs, tyvars=ref []} | ||
819 : | in ((A.VALdec [vb])::decs, | ||
820 : | (B.VALbind specvar)::bindings) | ||
821 : | end | ||
822 : | in matchElems(elems, entEnv, entDecs, decs', | ||
823 : | bindings', succeed) | ||
824 : | end | ||
825 : | |||
826 : | | _ => bug "matchVElem.1") | ||
827 : | handle MU.Unbound sym => matchErr(SOME "value")) | ||
828 : | |||
829 : | monnier | 106 | | CONspec{spec=DATACON{name, typ=spectyp, lazyp, |
830 : | monnier | 16 | rep=specrep, ...},...} => |
831 : | ((case MU.getSpec(strElements, sym) | ||
832 : | of CONspec{spec=DATACON{typ=acttyp, rep=actrep, const, | ||
833 : | sign, ...}, slot} => | ||
834 : | if (DA.isExn specrep) = (DA.isExn actrep) then | ||
835 : | let val spectyp = typeInMatched("$specty(con/con)", spectyp) | ||
836 : | val acttyp = typeInOriginal("$actty(con/con)", acttyp) | ||
837 : | val _ = matchTypes(spectyp, acttyp, II.nullInfo, name) | ||
838 : | |||
839 : | val bindings' = | ||
840 : | case slot | ||
841 : | of NONE => bindings | ||
842 : | | SOME s => | ||
843 : | let val dacc = DA.selAcc(rootAcc, s) | ||
844 : | val nrep = exnRep(actrep, dacc) | ||
845 : | val con = DATACON{typ=acttyp, name=name, | ||
846 : | const=const, rep=nrep, | ||
847 : | monnier | 106 | sign=sign, lazyp=lazyp} |
848 : | monnier | 16 | in (B.CONbind(con)) :: bindings |
849 : | end | ||
850 : | |||
851 : | in matchElems(elems, entEnv, entDecs, decs, bindings', succeed) | ||
852 : | end | ||
853 : | else raise MU.Unbound sym | ||
854 : | |||
855 : | | VALspec _ => | ||
856 : | if DA.isExn specrep then matchErr(SOME "exception") | ||
857 : | else matchErr(SOME "constructor") | ||
858 : | | _ => bug "matchVElem.2") | ||
859 : | handle MU.Unbound sym => | ||
860 : | if DA.isExn specrep then matchErr(SOME "exception") | ||
861 : | else matchErr(SOME "constructor")) | ||
862 : | |||
863 : | end (* function matchElems *) | ||
864 : | |||
865 : | fun matchIt entEnv = | ||
866 : | let val _ = debugmsg ">>matchIt" | ||
867 : | |||
868 : | val (resultEntEnv, entDecs, absDecs, bindings, succeed) = | ||
869 : | matchElems(sigElements, entEnv, [], [], [], true) | ||
870 : | handle EE.Unbound => (debugmsg "$matchIt 1"; raise EE.Unbound) | ||
871 : | in if succeed then | ||
872 : | let val resultEntEnv = EE.mark(mkStamp, resultEntEnv) | ||
873 : | val _ = debugmsg "--matchIt: elements matched successfully" | ||
874 : | |||
875 : | val _ = checkSharing(specSig, resultEntEnv) | ||
876 : | handle EE.Unbound => (debugmsg "$matchIt 3"; raise EE.Unbound) | ||
877 : | val _ = debugmsg "--matchIt: sharing checked" | ||
878 : | |||
879 : | val resStr = | ||
880 : | let val strEnt = {stamp = strStamp, entities = resultEntEnv, | ||
881 : | lambdaty = ref NONE, rpath=rpath} | ||
882 : | val dacc = DA.newAcc(mkv) | ||
883 : | val dinfo = II.mkStrInfo (map MU.extractInfo bindings) | ||
884 : | in M.STR{sign=specSig, rlzn=strEnt, access=dacc, info=dinfo} | ||
885 : | end | ||
886 : | |||
887 : | val resDec = | ||
888 : | let val body = A.LETstr(A.SEQdec absDecs, A.STRstr bindings) | ||
889 : | in A.STRdec [A.STRB{name=strName, str=resStr, def=body}] | ||
890 : | end | ||
891 : | |||
892 : | val resExp = M.STRUCTURE{stamp = GETSTAMP(M.VARstr(rev epath)), | ||
893 : | entDec = SEQdec(entDecs)} | ||
894 : | |||
895 : | val _ = debugmsg "<<matchIt" | ||
896 : | in (resDec, resStr, resExp) | ||
897 : | end | ||
898 : | else (A.SEQdec[],ERRORstr,M.CONSTstr(M.bogusStrEntity)) | ||
899 : | end | ||
900 : | |||
901 : | in | ||
902 : | |||
903 : | (* we should not do such short-cut matching because we need to | ||
904 : | recalculuate the tycpath information for functor components. | ||
905 : | But completely turning this off is a bit too expensive, so | ||
906 : | we add a fctflag in the signature to indicate whether it | ||
907 : | contains functor components. | ||
908 : | *) | ||
909 : | if (ST.eq(sigStamp, strSigStamp)) andalso closed andalso (not fctflag) | ||
910 : | then (A.SEQdec [], str, M.VARstr (rev epath)) (* short-cut matching *) | ||
911 : | else matchIt (if closed then EE.empty else matchEntEnv) | ||
912 : | end | ||
913 : | |||
914 : | | matchStr1 _ = (A.SEQdec [], ERRORstr, bogusStrExp) | ||
915 : | (* end of matchStr1 *) | ||
916 : | |||
917 : | |||
918 : | (*************************************************************************** | ||
919 : | * val matchStr : * | ||
920 : | * * | ||
921 : | * {sign : Modules.Signature, * | ||
922 : | * str : Modules.Structure, * | ||
923 : | * strExp : Modules.strExp, * | ||
924 : | * evOp : EntPath.entVar, * | ||
925 : | * depth : DebIndex.depth, * | ||
926 : | * entEnv : Modules.entityEnv, * | ||
927 : | * rpath : InvPath.path, * | ||
928 : | * statenv : StaticEnv.staticEnv, * | ||
929 : | * region : SourceMap.region, * | ||
930 : | * compInfo : ElabUtil.compInfo} -> {resDec : Absyn.dec, * | ||
931 : | * resStr : Modules.Structure, * | ||
932 : | * resExp : Modules.strExp} * | ||
933 : | * * | ||
934 : | ***************************************************************************) | ||
935 : | and matchStr {sign, str, strExp, evOp, depth, entEnv, rpath, statenv, region, | ||
936 : | compInfo=compInfo as {mkStamp,...}: EU.compInfo} = | ||
937 : | |||
938 : | let val _ = debugmsg ">>matchStr" | ||
939 : | |||
940 : | val uncoerced = case evOp of SOME x => x | NONE => mkStamp() | ||
941 : | val (resDec, resStr, exp) = | ||
942 : | matchStr1 (sign, str, anonSym, depth, entEnv, [uncoerced], rpath, | ||
943 : | statenv, region, compInfo) | ||
944 : | |||
945 : | val resExp = M.CONSTRAINstr{boundvar=uncoerced, raw=strExp, coercion=exp} | ||
946 : | (* val resExp = M.LETstr(M.STRdec(uncoerced, strExp), exp) *) | ||
947 : | (* val resExp = M.APPLY(M.LAMBDA{param=uncoerced, body=exp}, strExp) *) | ||
948 : | val _ = debugmsg "<<matchStr" | ||
949 : | |||
950 : | in {resDec=resDec, resStr=resStr, resExp=resExp} | ||
951 : | end | ||
952 : | handle EE.Unbound => (debugmsg "$matchStr"; raise EE.Unbound) | ||
953 : | |||
954 : | |||
955 : | (*************************************************************************** | ||
956 : | * * | ||
957 : | * Matching a functor against a functor signature: * | ||
958 : | * * | ||
959 : | * val matchFct1 : fctSig * Functor * S.symbol * DI.depth * * | ||
960 : | * entityEnv * M.fctExp * IP.path * staticEnv * * | ||
961 : | * region * EU.compInfo * | ||
962 : | * -> A.dec * M.Functor * M.fctExp * | ||
963 : | * * | ||
964 : | * Arguments: funsig F(fsigParVar : fsigParSig) = fsigBodySig * | ||
965 : | * functor F(fctParVar : fctParSig) : fctBodySig = bodyExp * | ||
966 : | * * | ||
967 : | * Result: functor F(fctParVar : fctParSig) : fctBodySig = resBodyExp * | ||
968 : | * * | ||
969 : | ***************************************************************************) | ||
970 : | and matchFct1(specSig as FSIG{paramsig=fsigParamSig,paramvar=fsigParamVar, | ||
971 : | paramsym,bodysig=fsigBodySig,...}, | ||
972 : | fct as FCT{rlzn=fctRlzn, ...}, fctName : S.symbol, | ||
973 : | depth, entEnv, uncoercedFct, rpath, statenv, region, | ||
974 : | compInfo as {mkStamp, mkLvar=mkv,...}: EU.compInfo) | ||
975 : | : A.dec * M.Functor * M.fctExp = | ||
976 : | (let | ||
977 : | |||
978 : | (*** the entity var for the source functor "uncoercedFct" *) | ||
979 : | val uncoerced = mkStamp() | ||
980 : | val srcFctExp = M.VARfct [uncoerced] | ||
981 : | val paramSym = case paramsym of SOME x => x | ||
982 : | | NONE => paramSym | ||
983 : | |||
984 : | (*** parameter signature instantiation ***) | ||
985 : | val {rlzn=fsigParEnt, tycpaths=paramTps} = | ||
986 : | INS.instParam{sign=fsigParamSig, entEnv=entEnv, depth=depth, | ||
987 : | rpath=IP.IPATH[paramSym], region=region, compInfo=compInfo} | ||
988 : | |||
989 : | val depth'= DI.next depth | ||
990 : | val fsigParInst = | ||
991 : | let val fsigParDacc = DA.newAcc(mkv) | ||
992 : | in M.STR{sign=fsigParamSig, rlzn=fsigParEnt, | ||
993 : | access=fsigParDacc, info=II.nullInfo} | ||
994 : | end | ||
995 : | |||
996 : | (*** applying fct to the fsigParInst structure ***) | ||
997 : | val paramId = fsigParamVar (* mkStamp() *) | ||
998 : | val {resDec=resDec1, resStr=resStr1, resExp=resExp1} = | ||
999 : | let val paramExp = M.VARstr [paramId] | ||
1000 : | in applyFct{fct=fct, fctExp=srcFctExp, argStr=fsigParInst, | ||
1001 : | argExp=paramExp, evOp=NONE, depth=depth', | ||
1002 : | epc=EPC.initContext (* ? ZHONG *), statenv=statenv, | ||
1003 : | rpath = IP.empty, region=region, compInfo=compInfo} | ||
1004 : | end | ||
1005 : | |||
1006 : | (*** matching the result structure against the body sig ***) | ||
1007 : | val fsigBodySigEnv = EE.bind(fsigParamVar, STRent fsigParEnt, entEnv) | ||
1008 : | val {resDec=resDec2, resStr=resStr2, resExp=resExp2} = | ||
1009 : | let val rp = IP.IPATH[S.strSymbol "<FctResult>"] | ||
1010 : | in matchStr{sign=fsigBodySig, str=resStr1, strExp=resExp1, evOp=NONE, | ||
1011 : | depth=depth', entEnv=fsigBodySigEnv, rpath=rp, | ||
1012 : | statenv=statenv, region=region, compInfo=compInfo} | ||
1013 : | end | ||
1014 : | |||
1015 : | (*** constructing the tycpath for the resulting functor ***) | ||
1016 : | val resTps = | ||
1017 : | case resStr2 | ||
1018 : | of M.STR{rlzn, sign, ...} => | ||
1019 : | INS.getTycPaths{sign=sign, rlzn=rlzn, entEnv=fsigBodySigEnv, | ||
1020 : | compInfo=compInfo} | ||
1021 : | | _ => [] | ||
1022 : | |||
1023 : | (*** the resulting coerced functor ***) | ||
1024 : | val resFct = | ||
1025 : | let val resExp3 = M.LETstr(M.FCTdec(uncoerced, M.CONSTfct fctRlzn), | ||
1026 : | resExp2) | ||
1027 : | val resClosure = CLOSURE{param=paramId, body=resExp3, env=entEnv} | ||
1028 : | val tps = T.TP_FCT(paramTps, resTps) | ||
1029 : | |||
1030 : | val resRlzn = {stamp = (#stamp fctRlzn), (*** DAVE ? ***) | ||
1031 : | closure = resClosure, rpath=rpath, | ||
1032 : | tycpath=SOME tps, lambdaty=ref NONE} | ||
1033 : | |||
1034 : | in FCT{sign = specSig, rlzn = resRlzn, | ||
1035 : | access = DA.newAcc(mkv), info = II.nullInfo} | ||
1036 : | end | ||
1037 : | |||
1038 : | (*** the resulting functor absyn ***) | ||
1039 : | val fdec = | ||
1040 : | let val bodyAbs = A.LETstr(A.SEQdec [resDec1, resDec2], A.VARstr resStr2) | ||
1041 : | val fctexp = A.FCTfct {param=fsigParInst, argtycs=paramTps, def=bodyAbs} | ||
1042 : | in A.FCTdec [A.FCTB {name=anonFsym, fct=resFct, def=fctexp}] | ||
1043 : | end | ||
1044 : | |||
1045 : | (*** the functor entity expression ***) | ||
1046 : | val fctExp = | ||
1047 : | M.LETfct(M.FCTdec(uncoerced, uncoercedFct), | ||
1048 : | M.LAMBDA_TP{param = paramId, body = resExp2, sign=specSig}) | ||
1049 : | |||
1050 : | in | ||
1051 : | (fdec, resFct, fctExp) | ||
1052 : | |||
1053 : | end handle Match => (A.SEQdec [], ERRORfct, bogusFctExp)) | ||
1054 : | (* | ||
1055 : | * This is intended to handle only the two left-hand side | ||
1056 : | * occurrences of STR{ ... } above, and is very crude. | ||
1057 : | * It should be replaced by case-expressions on the results of | ||
1058 : | * match etc. | ||
1059 : | *) | ||
1060 : | |||
1061 : | | matchFct1 _ = (A.SEQdec [], ERRORfct, bogusFctExp) | ||
1062 : | |||
1063 : | |||
1064 : | (*************************************************************************** | ||
1065 : | * * | ||
1066 : | * val matchFct : * | ||
1067 : | * * | ||
1068 : | * {sign : Modules.fctSig, * | ||
1069 : | * fct : Modules.Functor, * | ||
1070 : | * fctExp : Modules.fctExp, * | ||
1071 : | * depth : DebIndex.depth, * | ||
1072 : | * entEnv : Modules.entityEnv, * | ||
1073 : | * rpath : InvPath.path, * | ||
1074 : | * statenv : StaticEnv.staticEnv, * | ||
1075 : | * region : SourceMap.region, * | ||
1076 : | * compInfo : ElabUtil.compInfo} -> {resDec : Absyn.dec, * | ||
1077 : | * resFct : Modules.Functor, * | ||
1078 : | * resExp : Modules.fctExp} * | ||
1079 : | * * | ||
1080 : | ***************************************************************************) | ||
1081 : | and matchFct{sign, fct, fctExp, depth, entEnv, rpath, | ||
1082 : | statenv, region, compInfo} = | ||
1083 : | let val _ = debugmsg ">>matchFct" | ||
1084 : | |||
1085 : | val (resDec, resFct, resExp) = | ||
1086 : | matchFct1 (sign, fct, anonFsym, depth, entEnv, fctExp, rpath, | ||
1087 : | statenv, region, compInfo) | ||
1088 : | |||
1089 : | val _ = debugmsg "<<matchFct" | ||
1090 : | |||
1091 : | in {resDec=resDec, resFct=resFct, resExp=resExp} | ||
1092 : | end | ||
1093 : | handle EE.Unbound => (debugmsg "$matchFct"; raise EE.Unbound) | ||
1094 : | |||
1095 : | |||
1096 : | (************************************************************************** | ||
1097 : | * * | ||
1098 : | * Packing a structure against a signature: * | ||
1099 : | * * | ||
1100 : | * val packStr1 : Signature * strEntity * Structure * TU.tycset * * | ||
1101 : | * S.symbol * int * entityEnv * IP.path * staticEnv * * | ||
1102 : | * region * EU.compInfo -> A.dec * M.Structure * | ||
1103 : | * * | ||
1104 : | **************************************************************************) | ||
1105 : | and packStr1(specSig as M.SIG {elements=sigElements, ...}, | ||
1106 : | resRlzn as {entities=resEntEnv, ...}, | ||
1107 : | str as M.STR {rlzn=srcRlzn as {entities=srcEntEnv, ...}, | ||
1108 : | access=rootAcc, info=rootInfo, ...}, | ||
1109 : | abstycs, strName, depth, entEnv, rpath, statenv, region, | ||
1110 : | compInfo as {mkLvar=mkv, error, ...}: EU.compInfo) | ||
1111 : | : Absyn.dec * M.Structure = | ||
1112 : | |||
1113 : | let | ||
1114 : | |||
1115 : | fun typeInRes (kind,typ) = | ||
1116 : | (MU.transType resEntEnv typ) | ||
1117 : | handle EE.Unbound => | ||
1118 : | (debugPrint (debugging) (kind, PPType.ppType statenv, typ); | ||
1119 : | raise EE.Unbound) | ||
1120 : | |||
1121 : | fun typeInSrc (kind,typ) = | ||
1122 : | (MU.transType srcEntEnv typ) | ||
1123 : | handle EE.Unbound => | ||
1124 : | (debugPrint (debugging) (kind, PPType.ppType statenv, typ); | ||
1125 : | raise EE.Unbound) | ||
1126 : | |||
1127 : | fun packElems ([], entEnv, decs, bindings) = (rev decs, rev bindings) | ||
1128 : | | packElems ((sym, spec) :: elems, entEnv, decs, bindings) = | ||
1129 : | let val _ = debugmsg ">>packElems" | ||
1130 : | in case spec | ||
1131 : | of STRspec{sign=thisSpecsig, entVar=ev, slot=s,...} => | ||
1132 : | (case (EE.look(resEntEnv, ev), EE.look(srcEntEnv, ev)) | ||
1133 : | of (M.STRent resStrRlzn, M.STRent srcStrRlzn) => | ||
1134 : | let val srcStr = M.STR{sign=thisSpecsig, rlzn=srcStrRlzn, | ||
1135 : | access=DA.selAcc(rootAcc,s), | ||
1136 : | info=II.selInfo(rootInfo,s)} | ||
1137 : | |||
1138 : | val rpath' = IP.extend(rpath, sym) | ||
1139 : | val (thinDec, thinStr) = | ||
1140 : | packStr1(thisSpecsig, resStrRlzn, srcStr, abstycs, | ||
1141 : | sym, depth, entEnv, rpath', statenv, | ||
1142 : | region, compInfo) | ||
1143 : | |||
1144 : | val entEnv' = | ||
1145 : | let val strEnt = | ||
1146 : | case thinStr of M.STR{rlzn, ...} => rlzn | ||
1147 : | | _ => M.bogusStrEntity | ||
1148 : | in EE.bind(ev, M.STRent strEnt, entEnv) | ||
1149 : | end | ||
1150 : | |||
1151 : | val decs' = thinDec :: decs | ||
1152 : | val bindings' = (B.STRbind thinStr) :: bindings | ||
1153 : | |||
1154 : | in packElems(elems, entEnv', decs', bindings') | ||
1155 : | end | ||
1156 : | | _ => (* missing element, error has occurred - do nothing *) | ||
1157 : | packElems(elems, entEnv, decs, bindings)) | ||
1158 : | |||
1159 : | | FCTspec{sign=thisSpecsig, entVar=ev, slot=s} => | ||
1160 : | (case (EE.look(resEntEnv, ev), EE.look(srcEntEnv, ev)) | ||
1161 : | of (M.FCTent resFctRlzn, M.FCTent srcFctRlzn) => | ||
1162 : | let val srcFct = M.FCT{sign=thisSpecsig, rlzn=srcFctRlzn, | ||
1163 : | access=DA.selAcc(rootAcc,s), | ||
1164 : | info=II.selInfo(rootInfo,s)} | ||
1165 : | |||
1166 : | val rpath' = IP.extend(rpath, sym) | ||
1167 : | |||
1168 : | val (thinDec, thinFct) = | ||
1169 : | packFct1(thisSpecsig, resFctRlzn, srcFct, abstycs, | ||
1170 : | sym, depth, entEnv, rpath', statenv, | ||
1171 : | region, compInfo) | ||
1172 : | |||
1173 : | val entEnv' = | ||
1174 : | let val fctEnt = | ||
1175 : | case thinFct of M.FCT{rlzn, ...} => rlzn | ||
1176 : | | _ => M.bogusFctEntity | ||
1177 : | in EE.bind(ev, M.FCTent fctEnt, entEnv) | ||
1178 : | end | ||
1179 : | |||
1180 : | val decs' = thinDec :: decs | ||
1181 : | val bindings' = (B.FCTbind thinFct) :: bindings | ||
1182 : | |||
1183 : | in packElems(elems, entEnv', decs', bindings') | ||
1184 : | end | ||
1185 : | | _ => packElems(elems, entEnv, decs, bindings)) | ||
1186 : | |||
1187 : | | VALspec{spec=spectyp, slot=s} => | ||
1188 : | (let val restyp = typeInRes("$spec-resty(packStr-val)", spectyp) | ||
1189 : | val srctyp = typeInSrc("$spec-srcty(packStr-val)", spectyp) | ||
1190 : | val dacc = DA.selAcc(rootAcc, s) | ||
1191 : | val dinfo = II.selInfo(rootInfo, s) | ||
1192 : | val (instys, btvs, resinst, eqflag) = | ||
1193 : | absEqvTy(restyp, srctyp, dinfo) | ||
1194 : | |||
1195 : | val spath = SP.SPATH[sym] | ||
1196 : | val srcvar = VALvar{path=spath, typ=ref srctyp, | ||
1197 : | access=dacc, info=dinfo} | ||
1198 : | |||
1199 : | val (decs', nv) = | ||
1200 : | if eqflag then (decs, srcvar) | ||
1201 : | else (let val acc = DA.namedAcc(sym, mkv) | ||
1202 : | val resvar = | ||
1203 : | VALvar{path=spath, typ=ref restyp, | ||
1204 : | access=acc, info=II.nullInfo} | ||
1205 : | |||
1206 : | val ntycs = TU.filterSet(resinst, abstycs) | ||
1207 : | val exp = | ||
1208 : | A.PACKexp(A.VARexp(ref srcvar, instys), | ||
1209 : | resinst, ntycs) | ||
1210 : | |||
1211 : | val vb = A.VB {pat=(A.VARpat resvar), exp=exp, | ||
1212 : | boundtvs=btvs, tyvars=ref []} | ||
1213 : | |||
1214 : | in ((A.VALdec [vb])::decs, resvar) | ||
1215 : | end) | ||
1216 : | |||
1217 : | |||
1218 : | val bindings' = (B.VALbind nv)::bindings | ||
1219 : | in packElems(elems, entEnv, decs', bindings') | ||
1220 : | end) | ||
1221 : | |||
1222 : | monnier | 106 | | CONspec{spec=DATACON{name, typ, rep, const, sign, lazyp}, slot} => |
1223 : | monnier | 16 | (let val bindings' = |
1224 : | case slot | ||
1225 : | of NONE => bindings | ||
1226 : | | SOME s => | ||
1227 : | let val restyp = | ||
1228 : | typeInRes("$spec-resty(packStr-con)", typ) | ||
1229 : | val dacc = DA.selAcc(rootAcc, s) | ||
1230 : | val nrep = exnRep(rep, dacc) | ||
1231 : | monnier | 106 | val con = DATACON{typ=restyp, name=name, lazyp=lazyp, |
1232 : | monnier | 16 | const=const, rep=nrep, sign=sign} |
1233 : | in (B.CONbind(con)) :: bindings | ||
1234 : | end | ||
1235 : | |||
1236 : | in packElems(elems, entEnv, decs, bindings') | ||
1237 : | end) | ||
1238 : | |||
1239 : | | TYCspec{spec=specTycon,entVar=ev,scope} => | ||
1240 : | (let val entEnv' = EE.bind(ev, EE.look(resEntEnv, ev), entEnv) | ||
1241 : | in packElems(elems, entEnv', decs, bindings) | ||
1242 : | end) | ||
1243 : | |||
1244 : | end (* function packElems *) | ||
1245 : | |||
1246 : | |||
1247 : | val (absDecs, bindings) = packElems(sigElements, entEnv, [], []) | ||
1248 : | |||
1249 : | val resStr = | ||
1250 : | let val dacc = DA.newAcc(mkv) | ||
1251 : | val dinfo = II.mkStrInfo (map MU.extractInfo bindings) | ||
1252 : | in M.STR{sign=specSig, rlzn=resRlzn, access=dacc, info=dinfo} | ||
1253 : | end | ||
1254 : | |||
1255 : | val resDec = | ||
1256 : | let val body = A.LETstr(A.SEQdec absDecs, A.STRstr bindings) | ||
1257 : | in A.STRdec [A.STRB{name=strName, str=resStr, def=body}] | ||
1258 : | end | ||
1259 : | |||
1260 : | in (resDec, resStr) | ||
1261 : | end | ||
1262 : | |||
1263 : | | packStr1 _ = (A.SEQdec [], ERRORstr) | ||
1264 : | |||
1265 : | |||
1266 : | (*************************************************************************** | ||
1267 : | * Abstraction matching of a structure against a signature: * | ||
1268 : | * * | ||
1269 : | * val packStr : * | ||
1270 : | * {sign : Modules.Signature, * | ||
1271 : | * str : Modules.Structure, * | ||
1272 : | * strExp : Modules.strExp, * | ||
1273 : | * depth : DebIndex.depth, * | ||
1274 : | * entEnv : Modules.entityEnv, * | ||
1275 : | * rpath : InvPath.path, * | ||
1276 : | * statenv : StaticEnv.staticEnv, * | ||
1277 : | * region : SourceMap.region, * | ||
1278 : | * compInfo : ElabUtil.compInfo} -> {resDec : Absyn.dec, * | ||
1279 : | * resStr : Modules.Structure, * | ||
1280 : | * resExp : Modules.strExp} * | ||
1281 : | * * | ||
1282 : | * INVARIANT: the base signature for str should be exactly sign; in other * | ||
1283 : | * words, str should have been matched against sign before it * | ||
1284 : | * being packed against sign. * | ||
1285 : | ***************************************************************************) | ||
1286 : | and packStr {sign, str, strExp, depth, entEnv, rpath, | ||
1287 : | statenv, region, compInfo} = | ||
1288 : | let val _ = debugmsg ">>>packStr" | ||
1289 : | |||
1290 : | val {rlzn=resRlzn, abstycs=abstycs, tyceps=_} = | ||
1291 : | let val srcRlzn = case str of M.STR{rlzn, ...} => rlzn | ||
1292 : | | _ => M.bogusStrEntity | ||
1293 : | in INS.instAbstr {sign=sign, entEnv=entEnv, srcRlzn=srcRlzn, | ||
1294 : | rpath=rpath, region=region, compInfo=compInfo} | ||
1295 : | end | ||
1296 : | val _ = debugmsg "packStr - instantiate done" | ||
1297 : | |||
1298 : | val abstycs' = foldr TU.addTycSet (TU.mkTycSet()) abstycs | ||
1299 : | |||
1300 : | val (resDec, resStr) = | ||
1301 : | packStr1 (sign, resRlzn, str, abstycs', anonSym, depth, | ||
1302 : | entEnv, rpath, statenv, region, compInfo) | ||
1303 : | val _ = debugmsg "packStr - packStr1 done" | ||
1304 : | |||
1305 : | val resExp = M.ABSstr(sign, strExp) | ||
1306 : | val _ = debugmsg "<<<packStr" | ||
1307 : | |||
1308 : | in {resDec=resDec, resStr=resStr, resExp=resExp} | ||
1309 : | end | ||
1310 : | |||
1311 : | |||
1312 : | (*************************************************************************** | ||
1313 : | * * | ||
1314 : | * Packing a functor against a functor signature: * | ||
1315 : | * * | ||
1316 : | * val packFct1 : fctSig * fctEntity * Functor * tycon list * * | ||
1317 : | * S.symbol * DI.depth * entityEnv * IP.path * staticEnv * * | ||
1318 : | * region * EU.compInfo -> A.dec * M.Functor * | ||
1319 : | * * | ||
1320 : | ***************************************************************************) | ||
1321 : | and packFct1(specSig as FSIG{paramsig, paramvar, bodysig, ...}, resFctRlzn, | ||
1322 : | srcFct as FCT {rlzn=srcFctRlzn, ...}, | ||
1323 : | abstycs1, fctName, depth, entEnv, rpath, statenv, region, | ||
1324 : | compInfo as {mkStamp, mkLvar=mkv, error, ...}: EU.compInfo) | ||
1325 : | : Absyn.dec * M.Functor = | ||
1326 : | |||
1327 : | let | ||
1328 : | |||
1329 : | val {rlzn=paramEnt, tycpaths=paramTps} = | ||
1330 : | INS.instParam{sign=paramsig, entEnv=entEnv, depth=depth, | ||
1331 : | rpath=IP.IPATH[paramSym], region=region, compInfo=compInfo} | ||
1332 : | |||
1333 : | val depth'= DI.next depth | ||
1334 : | val paramStr = | ||
1335 : | let val paramDacc = DA.newAcc(mkv) | ||
1336 : | in M.STR{sign=paramsig, rlzn=paramEnt, access=paramDacc, info=II.nullInfo} | ||
1337 : | end | ||
1338 : | |||
1339 : | val {resDec=rdec1, resStr=bodyStr, resExp=_} = | ||
1340 : | applyFct{fct=srcFct, fctExp=CONSTfct srcFctRlzn, argStr=paramStr, | ||
1341 : | argExp=CONSTstr paramEnt, evOp=NONE, depth=depth', | ||
1342 : | epc=EPC.initContext (* ? ZHONG *), statenv=statenv, | ||
1343 : | rpath=IP.empty, region=region, compInfo=compInfo} | ||
1344 : | |||
1345 : | (* val bodyRlzn = EV.evalApp(srcFctRlzn, paramEnt, depth', epc, compInfo) *) | ||
1346 : | val bodyRlzn = | ||
1347 : | case bodyStr of M.STR {rlzn, ...} => rlzn | ||
1348 : | | _ => M.bogusStrEntity | ||
1349 : | |||
1350 : | val {rlzn=resRlzn, abstycs=abstycs2, tyceps=_} = | ||
1351 : | let val entEnv' = | ||
1352 : | EE.mark(mkStamp, EE.bind(paramvar, STRent paramEnt, entEnv)) | ||
1353 : | in INS.instAbstr {sign=bodysig, entEnv=entEnv', srcRlzn=bodyRlzn, | ||
1354 : | rpath=rpath, region=region, compInfo=compInfo} | ||
1355 : | end | ||
1356 : | |||
1357 : | val abstycs = foldr TU.addTycSet abstycs1 abstycs2 | ||
1358 : | |||
1359 : | val (rdec2, resStr) = | ||
1360 : | let val rpath' = IP.IPATH[S.strSymbol "<FctResult>"] | ||
1361 : | in packStr1(bodysig, resRlzn, bodyStr, abstycs, anonSym, | ||
1362 : | depth', entEnv, rpath', statenv, region, compInfo) | ||
1363 : | end | ||
1364 : | |||
1365 : | val resFct = | ||
1366 : | let val resDacc = DA.newAcc(mkv) | ||
1367 : | in M.FCT{sign=specSig, rlzn=resFctRlzn, access=resDacc, info=II.nullInfo} | ||
1368 : | end | ||
1369 : | |||
1370 : | val resDec = | ||
1371 : | let val body = A.LETstr(rdec1, A.LETstr(rdec2, A.VARstr resStr)) | ||
1372 : | val fctexp = A.FCTfct{param=paramStr, argtycs=paramTps, def=body} | ||
1373 : | in A.FCTdec [A.FCTB {name=fctName, fct=resFct, def=fctexp}] | ||
1374 : | end | ||
1375 : | |||
1376 : | in (resDec, resFct) | ||
1377 : | |||
1378 : | end (* function packFct1 *) | ||
1379 : | |||
1380 : | | packFct1 _ = (A.SEQdec [], ERRORfct) | ||
1381 : | |||
1382 : | |||
1383 : | (*************************************************************************** | ||
1384 : | * val applyFct : * | ||
1385 : | * * | ||
1386 : | * {fct : Modules.Functor, * | ||
1387 : | * fctExp : Modules.fctExp, * | ||
1388 : | * argStr : Modules.Structure, * | ||
1389 : | * argExp : Modules.strExp, * | ||
1390 : | * evOp : EntPath.entVar option, * | ||
1391 : | * depth : DebIndex.depth, * | ||
1392 : | * epc : EntPathContext.context, * | ||
1393 : | * statenv : StaticEnv.staticEnv, * | ||
1394 : | * rpath : InvPath.path, * | ||
1395 : | * region : SourceMap.region, * | ||
1396 : | * compInfo : ElabUtil.compInfo} -> {resDec : Absyn.dec, * | ||
1397 : | * resStr : Modules.Structure, * | ||
1398 : | * resExp : Modules.strExp} * | ||
1399 : | * * | ||
1400 : | * Matches and coerces the argument and then do the functor application. * | ||
1401 : | * Returns the result structure, the result entity expression, and the * | ||
1402 : | * result abstract syntax declaration of resStr. * | ||
1403 : | * * | ||
1404 : | * The argument matching takes place in the entityEnv stored in the * | ||
1405 : | * functor closure; this is where the paramsig must be interpreted. * | ||
1406 : | * * | ||
1407 : | ***************************************************************************) | ||
1408 : | and applyFct{fct as FCT{sign=FSIG{paramsig, bodysig, ...}, | ||
1409 : | rlzn = fctRlzn as {closure=CLOSURE{env=fctEntEnv, | ||
1410 : | ...}, ...}, | ||
1411 : | ...}, | ||
1412 : | fctExp, argStr, argExp, evOp, epc, depth, statenv, rpath, region, | ||
1413 : | compInfo as {mkStamp, mkLvar=mkv, ...}} = | ||
1414 : | |||
1415 : | let val _ = debugmsg ">>applyFct" | ||
1416 : | |||
1417 : | (*** step #1: match the argument structure against paramSig ***) | ||
1418 : | val {resDec=argDec1, resStr=argStr1, resExp=argExp1} = | ||
1419 : | matchStr {sign=paramsig, str=argStr, strExp=argExp, evOp=evOp, | ||
1420 : | depth=depth, entEnv=fctEntEnv, rpath=IP.IPATH[] (* ?DAVE *), | ||
1421 : | statenv=statenv, region=region, compInfo=compInfo} | ||
1422 : | |||
1423 : | (*** step #2: do the functor application ***) | ||
1424 : | val argRlzn = case argStr1 of M.STR{rlzn, ...} => rlzn | ||
1425 : | | _ => M.bogusStrEntity | ||
1426 : | val bodyRlzn = EV.evalApp(fctRlzn, argRlzn, depth, epc, rpath, compInfo) | ||
1427 : | val resStr = | ||
1428 : | let val bodyDacc = DA.namedAcc(anonSym,mkv) | ||
1429 : | in M.STR {sign=bodysig, rlzn=bodyRlzn, | ||
1430 : | access=bodyDacc, info=II.nullInfo} | ||
1431 : | end | ||
1432 : | |||
1433 : | val resDec = | ||
1434 : | let val argtycs = INS.getTycPaths{sign=paramsig, rlzn=argRlzn, | ||
1435 : | entEnv=fctEntEnv, compInfo=compInfo} | ||
1436 : | val body = A.APPstr{oper=fct, arg=argStr1, argtycs=argtycs} | ||
1437 : | val resAbs = A.LETstr(argDec1, body) | ||
1438 : | |||
1439 : | in A.STRdec [A.STRB{name=anonSym, str=resStr, def=resAbs}] | ||
1440 : | end | ||
1441 : | |||
1442 : | val resExp = M.APPLY(fctExp, argExp1) | ||
1443 : | val _ = debugmsg "<<applyFct" | ||
1444 : | |||
1445 : | in {resDec=resDec, resStr=resStr, resExp=resExp} | ||
1446 : | end | ||
1447 : | |||
1448 : | | applyFct {fct=ERRORfct, ...} = | ||
1449 : | {resDec=A.STRdec [], resStr=M.ERRORstr, | ||
1450 : | resExp=M.CONSTstr M.bogusStrEntity} | ||
1451 : | | applyFct _ = bug "unexpected case in applyFct" | ||
1452 : | |||
1453 : | |||
1454 : | (*** top leve wrappers: used for profiling the compilation time *) | ||
1455 : | (* | ||
1456 : | val matchStr = | ||
1457 : | Stats.doPhase (Stats.makePhase "Compiler 034 1-matchStr") matchStr | ||
1458 : | |||
1459 : | val matchFct = | ||
1460 : | Stats.doPhase (Stats.makePhase "Compiler 034 2-matchFct") matchFct | ||
1461 : | |||
1462 : | val packStr = | ||
1463 : | Stats.doPhase (Stats.makePhase "Compiler 034 3-packStr") packStr | ||
1464 : | |||
1465 : | val applyFct = | ||
1466 : | Stats.doPhase (Stats.makePhase "Compiler 034 4-applyFct") applyFct | ||
1467 : | *) | ||
1468 : | |||
1469 : | end (* local *) | ||
1470 : | end (* structure SigMatch *) | ||
1471 : | |||
1472 : | |||
1473 : | (* | ||
1474 : | monnier | 113 | * $Log$ |
1475 : | monnier | 16 | *) |
1476 : |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |