|
|
1.1 root 1: (* parse.sml *)
2:
3: structure Parse : PARSE =
4: struct
5:
6: structure BareAbsyn = BareAbsyn
7:
8: exception Eof
9:
10: fun interdec (lex as {nextToken, prompt, advance}: Lex.lexer ) =
11: let
12:
13: open ErrorMsg Symbol PrintUtil Lex
14: open Token
15: open Access Basics BasicTypes TypesUtil Absyn
16: open Env
17: open EnvAccess
18: open ModUtil
19: open SigMatch
20: open FirstSets
21: open Misc
22:
23: infix -->
24:
25: (* constants *)
26:
27: val maxTypSpecs = 100 (*maximum number of type specs in a signature *)
28: val maxStrSpecs = 100 (*maximum number of structure specs in a signature *)
29:
30: (* utility functions *)
31:
32: fun at tok = if !nextToken = tok then (advance(); true) else false
33:
34: fun checkToken tok =
35: if at(tok)
36: then ()
37: else complain("expected "^Token.tokenName tok^
38: ", found "^Token.tokenName(!nextToken))
39:
40: fun getSymbol () = case !nextToken of
41: Token.ID s => (advance(); s)
42: | Token.ASTERISK => (advance(); ASTERISKsym)
43: | Token.EQUAL => (advance(); EQUALsym)
44: | Token.TYVAR s => (advance(); s)
45: | Token.IDDOT s => (advance(); s)
46: | tok => ErrorMsg.impossible("getSymbol: " ^
47: Token.tokenName tok)
48: fun expop () =
49: case !nextToken
50: of EQUAL => lookFIX(EQUALsym)
51: | ASTERISK => lookFIX(ASTERISKsym)
52: | ID s => lookFIX(s)
53: | _ => NONfix
54:
55: fun patop () =
56: case !nextToken
57: of ASTERISK => lookFIX (ASTERISKsym)
58: | ID s => lookFIX(s)
59: | _ => NONfix
60:
61: fun ident() =
62: case !nextToken
63: of ID s => (advance();s)
64: | ASTERISK => (advance();ASTERISKsym)
65: | EQUAL => (advance();EQUALsym)
66: | tok => (complain("expected identifier, found " ^ tokenName tok);
67: bogusID)
68:
69: fun nonfix_ident() =
70: if (case !nextToken of
71: ID s => lookFIX(s)=NONfix
72: | ASTERISK => lookFIX(ASTERISKsym)=NONfix
73: | _ => false)
74: then getSymbol()
75: else (complain("expected nonfix-identifier, found "
76: ^ tokenName(!nextToken));
77: bogusID)
78:
79: fun opid() =
80: case !nextToken
81: of ID s => nonfix_ident()
82: | ASTERISK => nonfix_ident()
83: | OP => (advance();
84: case !nextToken
85: of ID s => getSymbol()
86: | ASTERISK => getSymbol()
87: | EQUAL => getSymbol()
88: | tok => (complain ("op not followed by identifier, found "
89: ^ tokenName tok); bogusID))
90: | tok => (complain("expected identifier or OP, found " ^ tokenName tok);
91: bogusID)
92:
93: fun getSTR id = lookSTR id
94: handle Unbound =>
95: (complain("unbound structure name: " ^ name id);
96: bogusSTR)
97:
98: fun getEXN id = lookCON(id) handle Unbound => unboundEXN id
99:
100: fun rightAssoc(elem:(unit->'a), tok:token, cons:('a*'b->'b), single:('a->'b))
101: : 'b =
102: let fun ra() =
103: let val e1 = elem()
104: in if at(tok) then cons(e1,ra()) else single e1
105: end
106: in ra()
107: end;
108:
109: fun leftAssoc(elem, tok, cons, single) =
110: let fun la e = if at tok then la(cons(e,elem())) else single e
111: in la(elem())
112: end
113:
114: fun precedence(elem,g,checkop) =
115: let fun parse(f, bp, e) =
116: case checkop()
117: of INfix(lbp,rbp) =>
118: if lbp > bp
119: then let val id = getSymbol()
120: val rhs = parse ((fn x=>g(id,e,x)),rbp,elem())
121: in parse(f,bp,rhs)
122: end
123: else f e
124: | _ => f e
125: in parse((fn x=>x), ~100, elem())
126: end
127:
128: fun andList(elem) =
129: let val e1 = elem()
130: in (if at(AND) then e1 :: andList(elem) else [e1])
131: end
132:
133: fun andListProtect(elem) = andList (fn () => protect(protectScope,elem))
134:
135: (* parsing functions *)
136:
137: (* qualified id interpretation *)
138:
139: fun symPath() =
140: case !nextToken
141: of IDDOT s => getSymbol() :: symPath()
142: | ID s => [getSymbol()]
143: | ASTERISK => [getSymbol()]
144: | EQUAL => [getSymbol()]
145: | _ => (complain "incomplete qualified identifier"; [bogusID])
146:
147: fun qid(lookLast) = lookPath(symPath(),lookLast)
148:
149: (* record labels *)
150:
151: fun selector() =
152: let fun sel1 id =
153: let val v = namedLvar id
154: val tyref = ref UNDEFty
155: val v1 = VALvar{name=[id],access=LVAR(v),typ=tyref}
156: val v2 = VALvar{name=[id],access=PATH[v],typ=tyref}
157: in FNexp[RULE(RECORDpat{fields=[(id,VARpat v1)],
158: flex=true,
159: typ=ref UNDEFty, pats=ref nil},
160: VARexp(ref v2))]
161: end
162: in case !nextToken
163: of ID _ => sel1(ident())
164: | INT i => let val s = makestring i
165: in if i < 1
166: then complain ("nonpositive integer label in selector,\
167: \ found " ^ s)
168: else ();
169: sel1(Symbol.symbol(s))
170: end
171: before advance()
172: | _ => (complain "illegal selector function"; bogusExp)
173: end
174:
175: fun labels(parseOne, separator, dotsOK, abbrev) =
176: if (case !nextToken
177: of ID _ => true
178: | INT _ => true
179: | DOTDOTDOT => true
180: | _ => false)
181: then let fun lablist () =
182: case !nextToken
183: of ID _ => field(ident(),abbrev)
184: | INT i => let val s = makestring i
185: in advance();
186: if i < 1
187: then complain ("nonpositive integer label, \
188: \found " ^ s)
189: else ();
190: field(Symbol.symbol(s),
191: (fn id =>
192: condemn("numeric label abbreviations allowed only in patterns: " ^
193: Symbol.name id)))
194: end
195: | DOTDOTDOT => nil
196: | tok => (complain("expected label, found " ^
197: tokenName tok); nil)
198: and field(id,abbrev) =
199: (id,
200: if at(separator) then parseOne()
201: else if !nextToken = COMMA orelse
202: !nextToken = COLON orelse
203: !nextToken = AS orelse
204: !nextToken = RBRACE then abbrev(id)
205: else condemn("expected " ^ Token.tokenName separator ^
206: " after label, found " ^
207: tokenName(!nextToken)),
208: ref 0)
209: :: (if at(COMMA) then lablist() else nil)
210: val l = lablist()
211: val dots = at(DOTDOTDOT)
212: val sl = sort3 l
213: in if length l > length sl
214: then complain "duplicate label in record"
215: else ();
216: if dots andalso not dotsOK
217: then complain "use of ... outside pattern" else ();
218: checkToken(RBRACE);
219: (l,sl,dots)
220: end
221: else (checkToken(RBRACE); (nil,nil,false))
222:
223: exception Clausal of symbol * pat (* for returning clausal patterns from pat *)
224:
225:
226: (* types *)
227:
228: fun noAbbrev(_) =
229: (complain "expected colon after label in record type, found comma";
230: UNDEFty)
231: fun ty() =
232: rightAssoc(ty1,ARROW,
233: (fn (t,ts) => CONty(arrowTycon, [t,ts])),
234: (fn t => t))
235: and ty1() =
236: case rightAssoc(ty2,ASTERISK,op::,single)
237: of [t] => t
238: | l => tupleTy l
239: and ty2() =
240: (* incorporates tyapp and aty nonterminals *)
241: let fun qid_s(t) =
242: case !nextToken
243: of ID _ =>
244: qid_s(CONty(!lookArTYC(getSymbol(),1), [t]))
245: | IDDOT _ =>
246: qid_s(CONty(!lookPathArTYC(symPath(),1), [t]))
247: | _ => t
248: in qid_s(case !nextToken
249: of LPAREN =>
250: let val t1 = (advance(); ty())
251: in if at(RPAREN)
252: then t1
253: else if at(COMMA)
254: then let val tys = t1 :: ty_pc()
255: val arity = length tys
256: in checkToken(RPAREN);
257: case !nextToken
258: of ID s =>
259: CONty(!lookArTYC(ident(),arity),
260: tys)
261: | IDDOT s =>
262: CONty(!lookPathArTYC(symPath(),arity),
263: tys)
264: | tok => condemn("expected type \
265: \constructor, found "
266: ^ tokenName tok)
267: end
268: else (complain("expected RPAREN or COMMA in type\
269: \args, found " ^ tokenName(!nextToken));
270: t1)
271: end
272: | ID s => CONty(!lookArTYC(ident(),0),[])
273: | IDDOT s => CONty(!lookPathArTYC(symPath(),0),[])
274: | Token.TYVAR s => VARty(lookTyvar(getSymbol()))
275: | LBRACE =>
276: (advance();
277: let val (l,sl,_) = labels(ty,COLON,false, noAbbrev)
278: in recordTy(map (fn (id,ty,_) => (id, ty)) sl)
279: end)
280: | tok => condemn("expected a type expression, found token "
281: ^ tokenName tok))
282: end
283: and ty_pc() = rightAssoc(ty,COMMA,op::,single)
284:
285:
286: fun markexp f x = if !System.Control.Debug.debugging
287: then let val one = (!ErrorMsg.fileName,!ErrorMsg.lineNum)
288: val e = f x
289: val two = (!ErrorMsg.fileName,!ErrorMsg.lineNum)
290: in case e
291: of MARKexp _ => e
292: | e' => if one=two then MARKexp(e',one,one)
293: else MARKexp(e',one,two)
294: end
295: else f x
296:
297: fun markdec f x = if !System.Control.Debug.debugging
298: then let val one = (!ErrorMsg.fileName,!ErrorMsg.lineNum)
299: val e = f x
300: val two = (!ErrorMsg.fileName,!ErrorMsg.lineNum)
301: in case e
302: of MARKdec _ => e
303: | e' => if one=two then MARKdec(e',one,one)
304: else MARKdec(e',one,two)
305: end
306: else f x
307:
308:
309: (* expressions -- including local declarations *)
310:
311: fun exp (stamps: Stampset.stampsets) =
312: case !nextToken
313: of FN => (advance(); FNexp(match(stamps)))
314: | CASE => CASEexp((advance(); exp(stamps)),
315: (checkToken(OF); match(stamps)))
316: | WHILE => WHILEexp((advance(); exp(stamps)),
317: (checkToken(DO); markexp exp stamps))
318: | IF => IFexp((advance(); exp(stamps)), (checkToken(THEN); markexp exp stamps),
319: (checkToken(ELSE); markexp exp stamps))
320: | RAISE => RAISEexp(advance(); exp(stamps))
321: | _ => let val e = exp1(stamps)
322: in if !nextToken = HANDLE
323: then (advance(); HANDLEexp(e,HANDLER(FNexp(match(stamps)))))
324: else e
325: end
326:
327: and match (stamps) = rightAssoc((fn () => rule stamps),BAR,op::,single)
328:
329: and rule (stamps) =
330: let val bl = ref nil : (symbol * var) list ref
331: in protect(protectScope,
332: (fn () => RULE(pat(bl,true)
333: handle Clausal(id,_) =>
334: condemn("undefined op in pattern: "^name id),
335: (checkToken(DARROW);
336: if !nextToken=EQUAL then advance() else ();
337: (* Capitalization convention
338: app checkBinding (!bl);
339: *)
340: bindVARs(!bl); markexp exp stamps))))
341: end
342:
343: and exp_ps (stamps) = rightAssoc((fn () => exp stamps),SEMICOLON,op::,single)
344:
345: and exp1 (stamps) = leftAssoc((fn () => markexp exp2 stamps),
346: ORELSE,ORELSEexp,(fn x=>x))
347:
348: and exp2 (stamps) = leftAssoc((fn () => markexp exp3 stamps),
349: ANDALSO,ANDALSOexp,(fn x=>x))
350:
351: (* N.B. above markexp's will cause too much marking, but this is harmless*)
352:
353: and exp3(stamps) =
354: let val e = precedence((fn () => markexp exp5 stamps),
355: (fn(id,a,b)=>APPexp(markexp lookID(id),
356: markexp TUPLEexp[a,b])), expop)
357: in if at(COLON) then CONSTRAINTexp(e,ty()) else e
358: end
359:
360: and exp5 (stamps) =
361: let fun loop e =
362: if firstAexp lookFIX (!nextToken)
363: then loop(markexp APPexp(e,markexp aexp stamps))
364: else e
365: in loop(markexp aexp stamps)
366: end
367:
368: (* note that IF WHILE CASE RAISE FN are matched below, but
369: are not in firstAexp. This is intentional *)
370:
371: and aexp (stamps) =
372: case !nextToken
373: of ID _ => lookID(nonfix_ident())
374: | OP => lookID(opid())
375: | IDDOT s => qid(lookIDinStr)
376: | INT i => INTexp(i) before advance()
377: | REAL s => REALexp(s) before advance()
378: | STRING s => STRINGexp(s) before advance()
379: | HASH => (advance(); selector())
380: | LBRACE => (advance(); exp_brace(stamps))
381: | LPAREN => (advance(); exp_paren(stamps))
382: | LBRACKET => (advance(); exp_bracket(stamps))
383: | LET =>
384: protect(protectScope,
385: (fn()=>(advance();
386: (LETexp(ldecs([],stamps),
387: (checkToken(IN); SEQexp(exp_ps(stamps)))))
388: before checkToken(END))))
389: | FN => exp(stamps)
390: | CASE => exp(stamps)
391: | WHILE => exp(stamps)
392: | IF => exp(stamps)
393: | RAISE => exp(stamps)
394: | tok => (complain ("atomic expression expected, found " ^
395: tokenName tok);
396: bogusExp)
397:
398: and exp_brace (stamps) =
399: let val (l,sl,_) =
400: labels((fn () => exp stamps),EQUAL,false,
401: (fn x => (complain "illegal record-name element abbreviation";
402: bogusExp)))
403: fun assign (i,(_,_,r)::tl) = (r:=i; assign(i+1,tl))
404: | assign (n,nil) = ()
405: in assign(0,sl);
406: RECORDexp(map (fn (id,e,ref n) => (LABEL{name=id,number=n},e)) l)
407: end
408:
409: and exp_paren (stamps) =
410: if at(RPAREN)
411: then unitExp (* TUPLEexp(nil) *)
412: else let val e = exp(stamps)
413: in case !nextToken
414: of RPAREN => (advance(); e)
415: | COMMA =>
416: (advance();
417: TUPLEexp(e::exp_pc(stamps)) before checkToken(RPAREN))
418: | SEMICOLON =>
419: (advance();
420: SEQexp(e::exp_ps(stamps)) before checkToken(RPAREN))
421: | tok => (complain ("expected comma, right paren, or\
422: \ semicolon, found " ^ tokenName tok); e)
423: end
424:
425: and exp_bracket (stamps) =
426: if at(RBRACKET)
427: then LISTexp(nil)
428: else LISTexp(exp(stamps) ::
429: if !nextToken = RBRACKET
430: then (advance(); nil)
431: else (checkToken(COMMA);
432: exp_pc(stamps) before checkToken(RBRACKET)))
433:
434: and exp_pc (stamps) = rightAssoc((fn () => exp stamps),COMMA,op::,single)
435:
436: and pat (bl: (symbol * var) list ref, full: bool) =
437: (* full false means parse atomic pattern *)
438: let fun restrictLAYEREDpat(x as (VARpat _, _)) = LAYEREDpat x
439: | restrictLAYEREDpat(y,z) =
440: (complain "pattern to left of AS must be a variable"; z)
441:
442: fun pat0 () = rightAssoc(pat1,AS,restrictLAYEREDpat,(fn x=>x))
443:
444: and pat1 () =
445: let val e = precedence(
446: pat2,
447: (fn(id,a,b)=>
448: APPpat(lookCON id, TUPLEpat[a,b])
449: handle Unbound =>
450: raise Clausal(id, TUPLEpat[a,b])),
451: patop)
452: in if at(COLON) then CONSTRAINTpat(e,ty()) else e
453: end
454:
455: and pat2 () =
456: let fun useCon(dcon as DATACON{const,name,...}) =
457: case (const,firstApat lookFIX (!nextToken))
458: of (true,false) => CONpat(dcon)
459: | (false,true) => APPpat(dcon,apat())
460: | (_,x) => (complain("improper use of constructor "^
461: Symbol.name(name)^" in pattern");
462: (if x then (apat(); ()) else ());
463: WILDpat)
464: fun simpleId(id) =
465: useCon(lookCON id)
466: handle Unbound =>
467: if firstApat lookFIX (!nextToken)
468: then raise Clausal(id, apat())
469: else VARpat(newVAR(bl,id))
470: in case !nextToken
471: of ID s => (if lookFIX(s) = NONfix
472: then ()
473: else complain("pattern starts with infix: "
474: ^ name(s));
475: simpleId(getSymbol()))
476: | OP => simpleId(opid())
477: | IDDOT s => useCon(qid lookCONinStr)
478: | _ => apat()
479: end
480:
481: and pat_id(id) =
482: (case lookCON id
483: of dcon as DATACON{const=true,...} => CONpat(dcon)
484: | _ => (complain("nonconstant data constructor: " ^ name(id));
485: WILDpat))
486: handle Unbound => VARpat(newVAR(bl,id))
487:
488: and apat() =
489: case !nextToken
490: of OP => pat_id(opid())
491: | ID s => pat_id(nonfix_ident())
492: | IDDOT s => CONpat(qid(lookCONinStr))
493: | INT i => INTpat(i) before advance()
494: | REAL s => REALpat(s) before advance()
495: | STRING s => STRINGpat(s) before advance()
496: | WILD => (advance(); WILDpat)
497: | LPAREN => (advance(); pat_paren())
498: | LBRACKET => (advance(); pat_bracket())
499: | LBRACE => (advance(); pat_brace())
500: | tok => (complain("expected an atomic pattern, found "
501: ^ tokenName tok); WILDpat)
502:
503: and pat_paren () =
504: if at(RPAREN)
505: then unitPat
506: else let val p = pat0()
507: in case !nextToken of
508: RPAREN => (advance(); p)
509: | COMMA =>
510: (advance();
511: TUPLEpat(p::pat_pc()) before checkToken(RPAREN))
512: | tok => (complain ("expected right paren or comma\
513: \ (in pattern), found " ^ tokenName tok);
514: p)
515: end
516:
517: and pat_bracket () =
518: LISTpat(if at(RBRACKET)
519: then nil
520: else pat_pc() before checkToken(RBRACKET))
521:
522: (* bug: we allow {a,b,c} to stand for {a=a,b=b,c=c} but we don't
523: allow {a as zzz} to stand for {a=a as zzz}
524: *)
525:
526: and pat_id_as id =
527: let val e = pat_id id
528: val e' = if at(COLON) then CONSTRAINTpat(e,ty()) else e
529: in if at(AS) then LAYEREDpat(e',pat0()) else e'
530: end
531:
532: and pat_brace () =
533: let val (_,sl,dots) = labels(pat0,EQUAL,true,pat_id_as)
534: in RECORDpat{
535: fields = map (fn(id,pat,_) => (id,pat)) sl,
536: flex = dots,
537: typ = ref UNDEFty,
538: pats = ref nil}
539: end
540:
541: and pat_pc() = rightAssoc(pat0,COMMA,op::,single)
542:
543: in if full then pat0() else apat()
544: end
545:
546: (* variable bindings *)
547:
548: and recdec x = VALRECdec(rvb_pa x)
549: and valdec x = VALdec(vb_pa x)
550: and vb x = markdec (if at(REC) then recdec else valdec) x
551:
552: and vb_pa (stamps) =
553: let val bl = ref nil : (symbol * var) list ref
554: fun vb () =
555: protect(protectTyvars(NONE),
556: (fn () =>
557: let val pat = pat(bl,true)
558: handle Clausal(id,_) =>
559: condemn("undefined op in pattern: "^name id)
560: and exp = (checkToken(EQUAL); exp(stamps))
561: and tvs = currentTyvars()
562: in case (pat,exp)
563: of (CONSTRAINTpat(VARpat(VALvar{name as [n],typ,...}), ty),
564: VARexp(ref(VALvar{access as INLINE _,...})))
565: => let val _::rest = !bl
566: val w = VALvar{name=name,typ=typ,access=access}
567: in bl := (n,w) :: rest;
568: VB{pat=CONSTRAINTpat(VARpat w, ty),
569: exp=exp,tyvars=tvs}
570: end
571:
572: | (VARpat(VALvar{name as [n],typ,...}),
573: VARexp(ref(VALvar{access as INLINE _,...})))
574: => let val _::rest = !bl
575: val w = VALvar{name=name,typ=typ,access=access}
576: in bl := (n,w) :: rest;
577: VB{pat=VARpat w, exp=exp, tyvars=tvs}
578: end
579: | _ => VB{pat=pat,exp=exp,tyvars=tvs}
580: end))
581: in andListProtect(vb)
582: before bindVARs(!bl)
583: end
584:
585: and rvb_pa (stamps) =
586: let val bl = ref nil : (symbol * var) list ref
587: fun rvb () = protect(protectTyvars(NONE),
588: (fn () => (* record bug *)
589: let val var=newVAR(bl,opid())
590: and resultty=constraint_op()
591: and e = (checkToken(EQUAL); exp stamps)
592: and tvs=currentTyvars()
593: in case e of FNexp _ => ()
594: | MARKexp(FNexp _,_,_) => ()
595: | _ => complain "fn expression required in val rec declaration";
596: RVB{var = var, resultty = resultty, exp = e, tyvars = tvs}
597: end))
598: in protect(protectPatchList, (fn()=>
599: protect(protectScope, (fn()=>
600: (openRec(); andListProtect(rvb)) ))
601: before bindVARs(!bl) ))
602: end
603:
604: and fb_pa (stamps) =
605: let val bl = ref nil : (symbol * var) list ref
606: fun fb () = protect(protectTyvars(NONE),
607: (fn () =>
608: let val funSymbol: symbol option ref = ref NONE
609: val clauses=rightAssoc((fn () => clause funSymbol stamps),
610: BAR,op::,single)
611: val CLAUSE{pats=p1,...}::_ = clauses
612: val len = length p1
613: in if exists (fn CLAUSE{pats,...} => length pats <> len) clauses
614: then complain "not all clauses have the same number of patterns"
615: else ();
616: FB{var = let val SOME id = !funSymbol in newVAR(bl,id) end,
617: clauses = clauses,
618: tyvars = currentTyvars()}
619: end))
620: in protect(protectPatchList, fn()=>
621: protect(protectScope, fn()=>
622: (openRec(); markdec (FUNdec o andListProtect) fb))
623: before bindVARs(!bl))
624: end
625:
626: and clause funsym stamps =
627: let val bl = ref nil : (symbol * var) list ref
628: fun pat_p () = if firstApat lookFIX (!nextToken)
629: then (pat(bl,false) (* atomic pattern *)
630: handle Clausal(id,_) =>
631: condemn("undefined op in pattern: "^name id))
632: :: pat_p ()
633: else nil
634: in (pat(bl,true); condemn("no defined function in clausal lhs"))
635: handle Clausal(id,pat1) =>
636: (case !funsym
637: of NONE => funsym := SOME id
638: | SOME f => if Symbol.eq(id,f) then ()
639: else complain "identifiers in clauses don't match";
640: let val pats = pat1::pat_p()
641: val resultty = constraint_op()
642: val exp = protect(protectScope,
643: (fn()=>(checkToken(EQUAL);
644: if !nextToken=DARROW then advance() else ();
645: bindVARs(!bl); markexp exp stamps)))
646: in CLAUSE{pats=pats, resultty=resultty, exp=exp}
647: end)
648: end
649:
650: and constraint () = (checkToken(COLON); ty())
651:
652: and constraint_op() =
653: if at(COLON)
654: then SOME(ty())
655: else NONE
656:
657: and tb(notwith,path,stamps: Stampset.stampsets) =
658: let fun tb1() =
659: let fun equalargs([],[]) = true
660: | equalargs(tv::rest,VARty(tv')::rest') =
661: tv = tv' andalso equalargs(rest,rest')
662: | equalargs _ = false
663: val args = tyvars()
664: val name = ident()
665: val _ = checkToken(EQUAL)
666: val typ = protect(protectTyvars(SOME args), ty)
667: val _ = TypesUtil.bindTyvars args;
668: val binding =
669: case typ
670: of CONty(tycref as ref(TYCON{stamp,arity,eq,path=path',kind}),
671: args') =>
672: if Stampset.tycFixed(stamp) andalso equalargs(args,args')
673: then case kind
674: of UNDEFtyc _ =>
675: (tycref :=
676: TYCON{stamp=stamp,arity=arity,eq=eq,
677: path=path',
678: kind=UNDEFtyc(SOME(name::path))};
679: tycref)
680: | _ => ref(TYCON{stamp=stamp,arity=arity,eq=eq,
681: path=name::path,kind=kind})
682: else ref(mkDEFtyc(name::path,
683: TYFUN{arity=length args, body=typ},
684: if notwith
685: then if isEqType typ then YES else NO
686: else MAYBE,
687: stamps))
688: | _ => ref(mkDEFtyc(name::path,
689: TYFUN{arity=length args, body=typ},
690: if notwith
691: then if isEqType typ then YES else NO
692: else MAYBE,
693: stamps))
694: in bindTYC(name,binding);
695: TB{tyc=binding,def=typ}
696: end
697: in TYPEdec(andList(tb1))
698: end
699:
700: and tyvars() =
701: case !nextToken
702: of Token.TYVAR s => [mkTyvar(mkUBOUND(s))] before advance()
703: | LPAREN =>
704: (advance();
705: tyvar_pc() before
706: checkToken(RPAREN))
707: | _ => nil
708:
709: and tyvar_pc() = rightAssoc(tyvar,COMMA,op::,single)
710:
711: and tyvar() = mkTyvar(mkUBOUND(
712: case !nextToken
713: of Token.TYVAR s => (advance(); s)
714: | tok => (complain ("expected type variable, found "
715: ^ tokenName tok); bogusID)))
716:
717: and db(path,stamps) =
718: let val (datatycs,withtycs) =
719: protect(protectDb(), (fn()=>
720: (andList(db1(ty,path,stamps)),
721: if at(WITHTYPE)
722: then let val TYPEdec x = tb(false,path,stamps) in x end
723: else nil)))
724: val checkeq = defineEqTycon (fn x => x)
725: in app (fn (ref tyc) => checkeq tyc) datatycs;
726: app (fn TB{tyc,...} => checkeq(!tyc)) withtycs;
727: DATATYPEdec{datatycs=datatycs,withtycs=withtycs}
728: end
729:
730: and db1(parsety,path,stamps) () =
731: let val args = tyvars()
732: val name = ident()
733: val arity = length args
734: val rangeType = CONty(!lookArTYC(name,arity), map VARty args)
735: fun constr() =
736: let val sym = (if at OP
737: then warn "unnecessary op in datatype declaration"
738: else ();
739: ident())
740: val const = not(at(OF))
741: val typ = if const then rangeType
742: else CONty(arrowTycon, [parsety(), rangeType])
743: in (sym,const,typ)
744: end
745: in protect(protectTyvars(SOME args),
746: (fn()=>
747: let val dcl = (checkToken(EQUAL); rightAssoc(constr,BAR,op::,single))
748: val sdcl = sort3 dcl
749: val sign = ConRep.boxed(sdcl)
750: fun binddcons ((sym,const,typ)::restdcl,rep::restsign) =
751: let val dcon =
752: DATACON{name = sym, const = const, rep = rep, sign = sign,
753: typ = if arity > 0
754: then ref(POLYty
755: {sign=mkPolySign arity,
756: tyfun=TYFUN{arity=arity,body=typ}})
757: else ref typ}
758: in bindCON(sym, dcon);
759: dcon :: binddcons(restdcl,restsign)
760: end
761: | binddcons ([],[]) = []
762: | binddcons _ = impossible "Parse.db1.fn.binddcons"
763: in if length sdcl < length dcl
764: then complain "duplicate constructor name" else ();
765: TypesUtil.bindTyvars args;
766: let val tycref = ref(mkDATAtyc(name::path,arity,
767: binddcons(sdcl,sign),MAYBE,stamps))
768: in bindTYC(name,tycref);
769: tycref
770: end
771: end))
772: end
773:
774: and ab(path,stamps) =
775: let val mAbstype = openScope()
776: val DATATYPEdec{datatycs,withtycs} = db(path,stamps)
777: val withtycons = map (fn TB{tyc,...} => tyc) withtycs
778: val abstycs = makeAbstract(datatycs,withtycons)
779: val mWith = (openScope(); current())
780: val body = (checkToken(WITH); ldecs(path,stamps))
781: fun bind tyc = bindTYC(tycName(!tyc), tyc)
782: in checkToken(END);
783: splice(mAbstype,mWith);
784: app bind datatycs (* abstycs *);
785: app bind withtycons;
786: ABSTYPEdec{abstycs=datatycs,withtycs=withtycs,body=body}
787: end
788:
789: and eb() = EXCEPTIONdec(andList(eb1))
790:
791: and eb1() =
792: let val name = ident()
793: (* Capitalization convention
794: val _ = if looksLikeExn name then ()
795: else warn "Exception name should be capitalized"
796: *)
797: in case !nextToken
798: of OF =>
799: (advance();
800: let val etype = ty()
801: val exn = DATACON{name = name,
802: const = false,
803: typ = ref(etype --> exnTy),
804: rep = VARIABLE(LVAR(namedLvar(name))),
805: sign = []}
806: in bindCON(name,exn);
807: EBgen{exn=exn,etype=SOME etype}
808: end)
809: | EQUAL =>
810: (advance();
811: let val edef as DATACON{const,typ,rep,sign,...} =
812: case !nextToken
813: of IDDOT s => qid lookEXNinStr
814: | ID s => getEXN(getSymbol())
815: | tok =>
816: (complain("expected exception name, found token"
817: ^ tokenName tok);
818: unboundEXN(bogusID))
819: val exn = DATACON{name=name,const=const,typ=ref(!typ),sign=sign,
820: rep=VARIABLE(LVAR(namedLvar(name)))}
821: in bindCON(name,exn);
822: EBdef{exn=exn,edef=edef}
823: end)
824: | _ =>
825: let val exn = DATACON{name = name,
826: const = true,
827: typ = ref exnTy,
828: rep = VARIABLE(LVAR(namedLvar(name))),
829: sign = []}
830: in bindCON(name,exn);
831: EBgen{exn=exn,etype=NONE}
832: end
833: end
834:
835:
836: and ebx() = EXCEPTIONdec(andList(eb1x))
837:
838: and eb1x() =
839: let val name = ident()
840: val etype = constraint_op()
841: val (const,typ) = case etype
842: of NONE => (true,exnTy)
843: | SOME t => if isUnitTy(t)
844: then (true,exnTy)
845: else (false,t-->exnTy)
846: val edef = if at(EQUAL)
847: then SOME(case !nextToken
848: of IDDOT _ => qid lookEXNinStr
849: | ID s => getEXN(getSymbol())
850: | _ => unboundEXN(bogusExnID) )
851: else NONE
852: val exn = case edef
853: of NONE =>
854: DATACON{name=name, const=const, typ=ref typ,
855: rep=VARIABLE(LVAR(namedLvar(name))),
856: sign=[]}
857: | SOME(DATACON{name=n,const,typ,rep,sign}) =>
858: DATACON{name=name,const=const,typ=ref(!typ),rep=rep,
859: sign=sign} (* changes only name *)
860: in bindCON(name, exn);
861: case edef
862: of NONE => EBgen{exn=exn,etype=etype}
863: | SOME exn' => EBdef{exn=exn,edef=exn'}
864: end
865:
866: and ldec(path,stamps) =
867: case !nextToken
868: of VAL =>
869: (advance(); vb(stamps))
870: | FUN =>
871: (advance(); fb_pa(stamps))
872: | TYPE =>
873: (advance(); tb(true,path,stamps))
874: | DATATYPE =>
875: (advance(); db(path,stamps))
876: | ABSTYPE =>
877: (advance(); ab(path,stamps))
878: | EXCEPTION =>
879: (advance(); eb())
880: | Token.LOCAL =>
881: let val envLocal = openScope()
882: val ld1 = (advance(); ldecs([],stamps))
883: val envIn = (checkToken(IN); openScope(); current())
884: val ld2 = ldecs(path,stamps)
885: in checkToken(END);
886: splice(envLocal,envIn);
887: markdec LOCALdec(ld1,ld2)
888: end
889: | Token.OPEN => (* confusion with Env.OPEN when Env not constrained *)
890: let val strs = (advance(); qid_p())
891: in app openStructureVar strs;
892: markdec OPENdec strs
893: end
894: | INFIX =>
895: let val prec = case (advance(); optprec()) of SOME n=>n|NONE=>0
896: in app (fn i => bindFIX(i,FIXvar{name=i,binding=infixleft prec})) (ops());
897: SEQdec(nil)
898: end
899: | INFIXR =>
900: let val prec = case (advance(); optprec()) of SOME n=>n|NONE=>0
901: in app (fn i => bindFIX(i,FIXvar{name=i,binding=infixright prec})) (ops());
902: SEQdec(nil)
903: end
904: | NONFIX =>
905: (advance();
906: app (fn i => bindFIX(i,FIXvar{name=i,binding=NONfix})) (ops()); SEQdec(nil))
907: | OVERLOAD =>
908: let val id = (advance(); ident())
909: val scheme = (checkToken(COLON);
910: protect(protectScope, (fn () => (* localize tyvars *)
911: protect(protectTyvars(NONE), (fn () =>
912: let val body = ty() (* generalize type variables *)
913: val tvs = currentTyvars()
914: in TypesUtil.bindTyvars tvs;
915: TYFUN{arity=length(tvs),body=body}
916: end)))))
917: fun option() =
918: let val VARexp(ref (v as VALvar{typ,...})) = exp(stamps)
919: in {indicator = TypesUtil.matchScheme(scheme,!typ),
920: variant = v}
921: end
922: val l = (checkToken(AS); andList(option))
923: in bindVAR(id,OVLDvar{name=id,options=ref l,scheme=scheme});
924: SEQdec nil
925: end
926: | tok => (complain ("expected a declaration, found " ^
927: tokenName tok); vb(stamps))
928:
929: and ldecs(path_stamps) =
930: let fun ldecs() =
931: if firstLdec(!nextToken)
932: then ldec(path_stamps) :: (at(SEMICOLON); ldecs())
933: else []
934: in case ldecs() of [dec] => dec | seq => SEQdec seq
935: end
936:
937: and optprec() = case !nextToken of INT i => (advance();SOME(i)) | _ => NONE
938:
939: and qid_p(): structureVar list = (* error if no identifier's ? *)
940: case !nextToken
941: of ID s => getSTR(ident()) :: qid_p()
942: | IDDOT _ => qid(lookSTRinStr)::qid_p()
943: | _ => nil
944:
945: and ops() =
946: let fun ops1() =
947: case !nextToken
948: of ID s => (s) :: (advance(); ops1())
949: | EQUAL => (EQUALsym) :: (advance(); ops1())
950: | ASTERISK => (ASTERISKsym) :: (advance(); ops1())
951: | _ => nil
952: in case ops1()
953: of [] => (complain("operator or identifier expected, found "
954: ^ tokenName (!nextToken)); [])
955: | l => l
956: end
957:
958:
959: (* signatures *)
960:
961: fun addzeros(0,l) = l
962: | addzeros(n,l) = addzeros(n-1,0::l)
963:
964: fun sigbody(depth: int, stamps: Stampset.stampsets) : Structure =
965: let val tComps = array(maxTypSpecs,NULLtyc)
966: and tCount = ref 0
967: fun tNext x = (update(tComps,!tCount,x);
968: INDtyc(!tCount before inc tCount))
969: val sComps = array(maxStrSpecs,NULLstr)
970: and sCount = ref 2 (* slots 0,1 reserved for parent, fct param (if any) *)
971: fun sNext x = (update(sComps,!sCount,x);
972: INDstr(!sCount before inc sCount))
973: val tempenv = REL{t=tComps,s=sComps}
974: fun pairs (nil : spath list list) : (spath*spath) list = nil
975: | pairs ((a::b::r) :: s) = (a,b) :: pairs((b::r) :: s)
976: | pairs ( _ :: s ) = pairs s
977: val strSharing : spath list list ref = ref nil
978: val typeSharing : spath list list ref = ref nil
979:
980: val slot = ref 0
981: fun nextSlot() = (!slot before inc slot)
982:
983: val table = newTable()
984: val tables = ref [table]
985:
986: (* includeSig used to implement include specs *)
987:
988: fun includeSig({strStamps=strStamps0, tycStamps=tycStamps0}: Stampset.stampsets,
989: STRstr{kind=SIGkind{bindings,stamps={strStamps,tycStamps},...},
990: env=REL{s=senv,t=tenv},...}) =
991: let val transStrStamp = Stampset.join(strStamps0,strStamps)
992: val transTycStamp = Stampset.join(tycStamps0,tycStamps)
993: val sOffset = !sCount - 2 (* offset for structure indices *)
994: val tOffset = !tCount (* offset for tycon indices *)
995:
996: (* adjustPath(depth: int, path: int list) *)
997: fun adjustPath(0,[i]) = [i+tOffset]
998: | adjustPath(0,i::r) = (i+sOffset) :: r
999: | adjustPath(0,[]) = impossible "sigBody.includeSig.adjustPath"
1000: | adjustPath(d,0::(r as _::_)) = 0 :: adjustPath(d-1,r)
1001: | adjustPath(d,p) = p
1002:
1003: fun adjustType(depth,ty) =
1004: let fun adjust(CONty(ref(RELtyc(p)),args)) =
1005: CONty(ref(RELtyc(adjustPath(depth,p))), map adjust args)
1006: | adjust(CONty(reftyc,args)) =
1007: CONty(reftyc, map adjust args)
1008: | adjust(POLYty{sign,tyfun=TYFUN{arity,body}}) =
1009: POLYty{sign=sign,
1010: tyfun=TYFUN{arity=arity,body=adjust body}}
1011: | adjust ty = ty
1012: in adjust ty
1013: end
1014:
1015: fun transTBinding depth binding =
1016: case binding
1017: of VARbind(VALvar{name,typ,access}) =>
1018: VARbind(VALvar{name=name,access=access,
1019: typ=ref(adjustType(depth,!typ))})
1020: | CONbind(DATACON{name,typ,const,rep,sign}) =>
1021: CONbind(DATACON{name=name, const=const, sign=sign, rep=rep,
1022: typ=ref(adjustType(depth,!typ))})
1023: | _ => binding
1024:
1025: fun transLBinding table binding =
1026: case binding
1027: of VARbind(VALvar{name=[n],typ,access}) =>
1028: IntStrMap.map table (NameSpace.varKey n)
1029: | CONbind(DATACON{name,typ,const,rep,sign}) =>
1030: IntStrMap.map table (NameSpace.conKey name)
1031: | _ => binding
1032:
1033: fun newTyc(tyc as TYCON{stamp,kind,...}) =
1034: if Stampset.tycFixed(stamp)
1035: then tyc
1036: else (case kind
1037: of ABStyc => setTycStamp(transTycStamp(stamp),tyc)
1038: | DATAtyc _ => setTycStamp(transTycStamp(stamp),tyc)
1039: | _ => tyc)
1040: | newTyc _ = impossible "Parse.includeSig.newTyc"
1041:
1042: fun newEnv(depth,REL{s,t}) =
1043: REL{s=mapSubstrs(newStr depth,s), t=ArrayExt.map(newTyc,t,0)}
1044: | newEnv _ = impossible "Parse.includeSig.newEnv"
1045:
1046: and newStr depth (str as STRstr{stamp,sign,table,env,
1047: kind=SIGkind{stamps,share,bindings}}) =
1048: if Stampset.strFixed(stamp)
1049: then str
1050: else let val newenv as REL{s,t} = newEnv(depth+1,env)
1051: val newtable =
1052: IntStrMap.transform (transTBinding depth) table
1053: val new =
1054: STRstr{stamp=transStrStamp(stamp),
1055: table=newtable,
1056: kind=SIGkind{stamps=stamps,share=share,
1057: bindings=map
1058: (transLBinding newtable)
1059: bindings},
1060: env=newenv, sign=sign}
1061: in ArrayExt.app(ModUtil.resetParent new, s, 2);
1062: new
1063: end
1064: | newStr _ (INDstr i) = impossible("sigbody.newStr INDstr "^
1065: makestring i)
1066: | newStr _ (SHRstr _) = impossible "sigbody.newStr SHRstr"
1067: | newStr _ (NULLstr) = impossible "sigbody.newStr NULLstr"
1068: | newStr _ _ = impossible "sigbody.newStr STRkind"
1069:
1070: fun adjustBinding binding =
1071: case binding
1072: of VARbind(VALvar{name=[n],typ,...}) =>
1073: bindVAR(n,VALvar{name=[n],typ=ref(adjustType(0,!typ)),
1074: access=SLOT(nextSlot())})
1075: | CONbind(DATACON{name,typ,const,rep as VARIABLE(SLOT _),sign}) =>
1076: bindCON(name,DATACON{name=name,
1077: const=const,
1078: sign=sign,
1079: typ=ref(adjustType(0,!typ)),
1080: rep=VARIABLE(SLOT(nextSlot()))})
1081: | CONbind(DATACON{name,typ,const,rep,sign}) =>
1082: bindCON(name,DATACON{name=name,
1083: const=const,
1084: sign=sign,
1085: typ=ref(adjustType(0,!typ)),
1086: rep=rep})
1087: | TYCbind(ref(INDtyc i)) =>
1088: let val tyc = tenv sub i
1089: val name = tycName tyc
1090: in bindTYC(name,ref(tNext(newTyc(tyc))))
1091: end
1092: | STRbind(STRvar{name as [n],binding=INDstr i,...}) =>
1093: bindSTR(n,STRvar{name=name,
1094: binding=sNext(newStr 1 (senv sub i)),
1095: access=SLOT(nextSlot())})
1096: | FIXbind(fixvar as FIXvar{name,...}) =>
1097: bindFIX(name,fixvar)
1098: | _ => impossible "sigBody.adjustBinding"
1099:
1100: in map adjustBinding bindings
1101: end (* includeSig *)
1102: | includeSig _ = impossible "Parse.includeSig - bad arg"
1103:
1104: (* the following four functions help implement the open spec.
1105: lookPathSTRinSig looks like it belongs in EnvAccess *)
1106:
1107: fun lookPathSTRinSig (spath as first::rest) : Structure * int list =
1108: let fun complainUnbound() =
1109: (complain "unbound structure in signature";
1110: print " name: "; printSequence "." printSym spath;
1111: newline();
1112: raise Syntax)
1113: (* second arg of get is expected to be a signature *)
1114: fun get([id],STRstr{table,env as REL{s,...},...}) =
1115: (case lookSTRinTable(table,id)
1116: handle UnboundTable => complainUnbound()
1117: of STRvar{binding=INDstr i,...} => (s sub i, [i])
1118: | STRvar{binding=SHRstr(p as i::r),...} =>
1119: (getEpath(r,s sub i), p) (* not possible? *)
1120: | _ => impossible "lookPathSTRinSig.get")
1121: | get(id::rest,STRstr{table,env=REL{s,...},...}) =
1122: let val STRvar{binding=INDstr k,...} =
1123: lookSTRinTable(table,id)
1124: handle UnboundTable => complainUnbound()
1125: val (str,p) = get(rest, s sub k)
1126: in (str, k::p)
1127: end
1128: | get([],str) = (str,[])
1129: | get(p,NULLstr) =
1130: impossible "sigbody.lookPathSTRinSig.get - NULLstr"
1131: | get(p,INDstr _) =
1132: impossible "sigbody.lookPathSTRinSig.get - INDstr"
1133: | get(p,SHRstr _) =
1134: impossible "sigbody.lookPathSTRinSig.get - SHRstr"
1135: | get _ = impossible "sigbody.lookPathSTRinSig.get - bad args"
1136: fun lookInStr(str) =
1137: (case rest
1138: of [] => str
1139: | _ =>
1140: let val STRvar{binding,...} =
1141: lookPathinStr(str, [], spath, lookSTRinStr)
1142: in binding
1143: end,
1144: [1])
1145: val leadStr = lookSTR0 first
1146: handle Unbound => complainUnbound()
1147: in case leadStr
1148: of (STRvar{binding=INDstr i,...},{path as h::r,strenv=REL{s,...}}) =>
1149: if h < 0 (* indicates signature component *)
1150: then let val (str,p) = get(rest, s sub i)
1151: in (str,path@(i::p))
1152: end
1153: else lookInStr(s sub i)
1154: | (STRvar{binding=SHRstr(i::r),...},{strenv=REL{s,...},...}) =>
1155: lookInStr(getEpath(r, s sub i))
1156: | (STRvar{binding as STRstr _,...},_) => lookInStr binding
1157: | _ => impossible "sigbody.lookPathSTRinSig - leadStr"
1158: end
1159: | lookPathSTRinSig _ = impossible "sigbody.lookPathSTRinSig - bad arg"
1160:
1161: fun openStrIds(): spath list =
1162: case !nextToken
1163: of ID _ => [ident()] :: openStrIds()
1164: | IDDOT _ => symPath()::openStrIds()
1165: | _ => nil
1166:
1167: fun openStrInSig(p:spath) =
1168: case lookPathSTRinSig p
1169: of (STRstr{table,env,...},p) => openOld({path=p,strenv=env},table)
1170: | _ => impossible "openStrInSig -- bad arg"
1171:
1172: fun mergeTables tables =
1173: let val bottom::rest = rev tables
1174: in revfold
1175: (fn (table,acc) => (IntStrMap.app (IntStrMap.add acc) table; acc))
1176: rest bottom
1177: end
1178:
1179: fun spec_s() =
1180: if firstSpec(!nextToken)
1181: then (spec() @ (at(SEMICOLON); spec_s()))
1182: else nil
1183:
1184: and spec() =
1185: case !nextToken
1186: of STRUCTURE => (advance(); strspec())
1187: | DATATYPE => (advance(); dtyspec())
1188: | TYPE => (advance(); tyspec NO)
1189: | EQTYPE => (advance(); tyspec YES)
1190: | VAL => (advance(); valspec())
1191: | EXCEPTION => (advance(); exnspec())
1192: | INFIX => (advance(); infixspec(infixleft))
1193: | INFIXR => (advance(); infixspec(infixright))
1194: | NONFIX =>
1195: (advance();
1196: app (fn i => bindFIX(i,FIXvar{name=i,binding=NONfix})) (ops());
1197: nil)
1198: | SHARING => (advance(); sharespec())
1199: | INCLUDE => (advance(); includespec())
1200: | Token.LOCAL => (advance(); localspec())
1201: | Token.OPEN => (advance(); openspec())
1202: | tok => condemn("expected a spec (component of signature)\
1203: \ found " ^ tokenName tok)
1204:
1205:
1206: and localspec() =
1207: (spec_s(); checkToken(IN); spec_s() before checkToken(END))
1208:
1209: and openspec() =
1210: let val strpaths = openStrIds()
1211: val newtable = newTable()
1212: in case strpaths
1213: of [] => complain "no structure ids in open spec"
1214: | _ =>
1215: (app openStrInSig strpaths;
1216: openNew({path=[~depth],strenv=tempenv},newtable);
1217: tables := newtable :: !tables);
1218: [] (* no bindings returned *)
1219: end
1220:
1221: and includespec() =
1222: let val name = ident()
1223: val SIGvar{binding,...} = lookSIG name
1224: in includeSig(stamps,binding)
1225: end
1226:
1227: and strspec() =
1228: rightAssoc(strspec1,AND,op :: , single)
1229:
1230: and strspec1() =
1231: let val name = ident()
1232: val _ = checkToken(COLON)
1233: val sgn =
1234: case !nextToken
1235: of ID s =>
1236: let val name = s before advance()
1237: val SIGvar{binding,...} = lookSIG(name)
1238: in ModUtil.shiftSigStamps(stamps,binding)
1239: end
1240: | Token.SIG =>
1241: (advance();
1242: sigbody(depth+1,stamps)
1243: before checkToken(END))
1244: | tok => condemn("expected a signature or signature-identifier, \
1245: \found: "^tokenName tok)
1246: in bindSTR(name,STRvar{name=[name],access=SLOT(nextSlot()),
1247: binding=sNext(sgn)})
1248: end
1249:
1250: and dtyspec() =
1251: let val dtycs =
1252: (protect(protectDb(), fn() =>
1253: map (fn (r as ref tyc) =>
1254: (r := tNext tyc; (TYCbind r, tyc)))
1255: (rightAssoc(db1(ty,[],stamps),AND,op ::,single))))
1256: val tycbinds = map (fn (x,_) => x) dtycs
1257: val tycons = map (fn (_,y) => y) dtycs
1258: fun collectdcons(tyc::rest,dcbinds) =
1259: let val TYCON{kind=DATAtyc(dcons),...} = tyc
1260: fun binddcons(DATACON{name,...}::rest',dcbs) =
1261: binddcons(rest',
1262: (let val (b,_) = Env.look(NameSpace.conKey(name))
1263: in b::dcbs
1264: end
1265: handle Unbound => dcbs))
1266: | binddcons([],dcbs) = dcbs
1267: in collectdcons(rest,binddcons(dcons,dcbinds))
1268: end
1269: | collectdcons([],dcbinds) = dcbinds
1270: in app (defineEqTycon (tyconInContext tempenv)) tycons;
1271: tycbinds @ collectdcons(tycons,[])
1272: end
1273:
1274: and tyspec eq =
1275: rightAssoc(tyspec1 eq, AND, op ::, single)
1276:
1277: and tyspec1 eq () =
1278: let val arity = length(tyvars())
1279: val name = ident()
1280: val tycref = ref(tNext(mkABStyc([name],arity,eq,stamps)))
1281: in bindTYC(name, tycref)
1282: end
1283:
1284: and valspec() =
1285: rightAssoc(valspec1,AND,op ::,single)
1286:
1287: and valspec1() =
1288: let val name =
1289: (if at OP
1290: then warn "unnecessary op in val specification"
1291: else ();
1292: case !nextToken
1293: of ID s => getSymbol()
1294: | ASTERISK => getSymbol()
1295: | EQUAL => getSymbol()
1296: | tok =>
1297: (complain("val spec: expected identifier, found "
1298: ^ tokenName tok); bogusID))
1299: val _ = checkToken(COLON)
1300: val typ =
1301: protect(protectScope, (fn () =>
1302: (* localize type variables *)
1303: protect(protectTyvars(NONE), (fn () =>
1304: let val body = ty()
1305: val tvs = currentTyvars()
1306: in case tvs
1307: of [] => body
1308: | _ =>
1309: let val sign = TypesUtil.bindTyvars1 tvs
1310: in POLYty
1311: {sign = sign,
1312: tyfun = TYFUN{arity = length tvs,
1313: body = body}}
1314: end
1315: end))))
1316: in bindVAR(name,VALvar{name=[name],typ=ref typ,access=SLOT(nextSlot())})
1317: end
1318:
1319: and exnspec() =
1320: rightAssoc(exnspec1,AND,op ::,single)
1321:
1322: and exnspec1() =
1323: let val name = ident()
1324: val (const,typ) =
1325: if at(OF) then
1326: (false,
1327: protect(protectScope, (fn () =>
1328: (* localize type variables *)
1329: protect(protectTyvars(NONE), (fn () =>
1330: let val body = ty()
1331: val tvs = currentTyvars()
1332: in case length tvs
1333: of 0 => body --> exnTy
1334: | n =>
1335: (TypesUtil.bindTyvars tvs;
1336: POLYty
1337: {sign = mkPolySign n,
1338: tyfun = TYFUN{arity = n,
1339: body = body --> exnTy}})
1340: end)))))
1341: else (true,exnTy)
1342: in bindCON(name, DATACON{name=name, const=const, typ= ref typ,
1343: rep=VARIABLE(SLOT(nextSlot())),
1344: sign=[]})
1345: end
1346:
1347: and infixspec(mkinfix) =
1348: let val prec = case optprec() of SOME n=>n|NONE=>0
1349: in app (fn i => bindFIX(i,FIXvar{name=i,binding=mkinfix prec}))
1350: (ops());
1351: nil
1352: end
1353:
1354: and sharespec() =
1355: (rightAssoc(sharespec1,AND,discard,discard); nil)
1356:
1357: and sharespec1() =
1358: case !nextToken
1359: of TYPE => (advance(); typeSharing := patheqn() :: !typeSharing)
1360: | ID s => strSharing := patheqn() :: !strSharing
1361: | IDDOT _ => strSharing := patheqn() :: !strSharing
1362: | tok => condemn("unexpected token after \"sharing\": "
1363: ^tokenName tok)
1364:
1365: and patheqn() : spath list =
1366: rightAssoc(symPath,EQUAL,op ::,single)
1367:
1368: val stamp = Stampset.newStamp(#strStamps stamps)
1369: val _ = openStr()
1370: val _ = openNew({path=[~depth],strenv=tempenv},table)
1371: val savedlookArTYC = !lookArTYC
1372: val savedlookPathArTYC = !lookPathArTYC
1373: val bindings = protect(
1374: ((fn () => (lookArTYC := lookArTYCinSig depth;
1375: lookPathArTYC :=
1376: lookPathArTYCinSig depth)),
1377: (fn () => (lookArTYC := savedlookArTYC;
1378: lookPathArTYC := savedlookPathArTYC))),
1379: spec_s)
1380: val _ = closeStr()
1381: val table = mergeTables(!tables)
1382: val senv = ArrayExt.copy(sComps,!sCount)
1383: val env = REL{s=senv, t=ArrayExt.copy(tComps,!tCount)}
1384: val sShare = pairs(!strSharing)
1385: val tShare = pairs(!typeSharing)
1386: val shareSpec =
1387: if null sShare andalso null tShare
1388: then {s=[],t=[]}
1389: else Sharing.doSharing(table,env,stamps,{s=sShare,t=tShare})
1390: val result =
1391: STRstr{stamp=stamp,
1392: sign=Stampset.newStamp(Stampset.sigStamps),
1393: table=table,
1394: env=env,
1395: kind=SIGkind{share=shareSpec,
1396: bindings=bindings,
1397: stamps=stamps}}
1398: in ArrayExt.app((ModUtil.setParent result),senv,2);
1399: result
1400: end (* fun sigbody *)
1401:
1402: fun sign () : Structure =
1403: case !nextToken
1404: of ID s =>
1405: let val name = s before advance()
1406: val SIGvar{binding,...} = lookSIG(name)
1407: in binding
1408: end
1409: | Token.SIG =>
1410: (advance();
1411: sigbody(1,Stampset.newStampsets())
1412: before checkToken(END))
1413: | tok => condemn("expected a signature or signature-identifier, \
1414: \found: "^tokenName tok)
1415:
1416: fun sigconstraint () =
1417: (checkToken(COLON);
1418: sign())
1419:
1420: fun sigconstraint_op () =
1421: if !nextToken = COLON
1422: then (advance(); SOME(sign()))
1423: else NONE
1424:
1425: (* signature bindings *)
1426:
1427: fun sigb() =
1428: let fun sigb1() =
1429: let val name = ident()
1430: in checkToken(EQUAL);
1431: let val sigvar = SIGvar{name=name,binding=sign()}
1432: in bindSIG(name, sigvar);
1433: sigvar
1434: end
1435: end
1436: in rightAssoc(sigb1,AND,op ::,single)
1437: end
1438:
1439: (* structure expressions *)
1440:
1441: fun str(abs: bool, constraint: Structure option, path: spath,
1442: stamps: Stampset.stampsets, param: Structure)
1443: : strexp * Structure * thinning =
1444: case !nextToken
1445: of IDDOT _ =>
1446: let val strVar as STRvar{binding,...} = qid(lookSTRinStr)
1447: in case constraint
1448: of NONE => (VARstr strVar, binding, NONE)
1449: | SOME sgn =>
1450: let val (str,thin) =
1451: SigMatch.match(abs,path,stamps,sgn,binding,param)
1452: in (VARstr strVar, str, thin)
1453: end
1454: end
1455: | Token.STRUCT =>
1456: (advance();
1457: let val _ = openStr()
1458: val body = sdecs(path,stamps)
1459: in (case constraint
1460: of NONE =>
1461: let val (thin,table) = BuildMod.buildStrTable ()
1462: in (STRUCTstr{body=body,locations=thin},
1463: mkSTR(path,table,DIR,stamps),
1464: NONE)
1465: end
1466: | SOME sgn =>
1467: let val (str,thin) =
1468: SigMatch.realize(abs,path,stamps,
1469: Stampset.newStamp(#strStamps stamps),
1470: sgn,param)
1471: in closeStr();
1472: (STRUCTstr{body=body,locations=thin}, str, NONE)
1473: end)
1474: before checkToken(END)
1475: end)
1476: | ID s =>
1477: let val id = getSymbol()
1478: in if at(LPAREN) (* functor application *)
1479: then let val fctVar as FCTvar{binding=fct,...} = lookFCT id
1480: val (argexp,argstr) =
1481: (* parse arg without using parameter sig *)
1482: (if !nextToken = RPAREN
1483: then (STRUCTstr{body=[],locations=[]},nullStr)
1484: else if firstSdec(!nextToken)
1485: then let val _ = openStr()
1486: val body = sdecs([anonParamName],stamps)
1487: val (thin,table) = BuildMod.buildStrTable ()
1488: in (STRUCTstr{body=body,locations=thin},
1489: mkSTR([anonParamName],table,
1490: DIR,stamps))
1491: end
1492: else let val FUNCTOR{paramName,...} = fct
1493: val (strexp,str,_) =
1494: str(false,NONE,[paramName],stamps,NULLstr)
1495: in (strexp,str)
1496: end)
1497: before checkToken(RPAREN)
1498: val (result,thin1) =
1499: Functor.applyFunctor(fct,argstr,path,stamps)
1500: val strexp = APPstr{oper=fctVar,
1501: argexp=argexp,
1502: argthin=thin1}
1503: in case constraint
1504: of NONE => (strexp,result,NONE)
1505: | SOME sgn =>
1506: let val (thinned,thin2) =
1507: SigMatch.match(abs,path,stamps,sgn,result,param)
1508: in (strexp,thinned,thin2)
1509: end
1510: end
1511: else let val strVar as STRvar{binding,...} = getSTR id
1512: in case constraint
1513: of NONE => (VARstr strVar, binding, NONE)
1514: | SOME sgn =>
1515: let val (str,thin) =
1516: SigMatch.match(abs,path,stamps,sgn,binding,param)
1517: in (VARstr strVar, str, thin)
1518: end
1519: end
1520: end
1521: | LET => protect(protectScope,
1522: (fn()=>(advance();
1523: let val locals = sdecs(path,stamps)
1524: val _ = checkToken(IN)
1525: val (bodyexp,bodystr,thin) =
1526: str(abs,constraint,path,stamps,param)
1527: val _ = checkToken(END)
1528: in (LETstr(SEQdec(locals),bodyexp),bodystr,thin)
1529: end)))
1530: | tok => condemn("expected a structure-expression, found " ^
1531: tokenName tok)
1532:
1533: and sdecs(args as (path: spath, stamps: Stampset.stampsets))
1534: : dec list =
1535: let fun sdec() : dec =
1536: if at(STRUCTURE)
1537: then markdec STRdec(strb(false,path,stamps))
1538: else if at(ABSTRACTION)
1539: then markdec ABSdec(strb(true,path,stamps))
1540: else if at(SIGNATURE) (* monster structure hack *)
1541: then (warn "signature found inside structure";
1542: SIGdec(sigb()))
1543: else if at(Token.FUNCTOR) (* monster structure hack *)
1544: then (warn "functor found inside structure";
1545: markdec FCTdec(fctb()))
1546: else if at Token.LOCAL
1547: then let val envLocal = openScope()
1548: val ld1 = sdecs args
1549: val envIn = (checkToken(IN); openScope(); current())
1550: val ld2 = sdecs args
1551: in checkToken(END);
1552: splice(envLocal,envIn);
1553: markdec LOCALdec(SEQdec ld1,SEQdec ld2)
1554: end
1555: else let val dec = ldec(path,stamps)
1556: in Typecheck.decType(dec);
1557: dec
1558: end
1559: in if firstSdec(!nextToken)
1560: then sdec() :: (at(SEMICOLON); sdecs(args))
1561: else nil
1562: end
1563:
1564: (* structure bindings *)
1565:
1566: and strb(abstract:bool,path:spath,stamps:Stampset.stampsets) =
1567: let fun strb1() =
1568: let val name = ident()
1569: val constraint =
1570: if abstract
1571: then SOME(sigconstraint())
1572: else sigconstraint_op()
1573: val _ = checkToken(EQUAL)
1574: val (strexp,str,thin) =
1575: str(abstract,constraint,name::path,stamps,NULLstr)
1576: val strVar = STRvar{access=LVAR(namedLvar(name)),
1577: name=[name],
1578: binding=str}
1579: in (name, strVar,
1580: STRB{strvar=strVar, def=strexp, constraint=constraint, thin=thin})
1581: end
1582: in map (fn (name,strVar,strSyn) => (bindSTR(name,strVar); strSyn))
1583: (rightAssoc(strb1, AND, op ::, single))
1584: end
1585:
1586:
1587: (* functor bindings *)
1588:
1589: and fctb() =
1590: map (fn (name,fctVar,fctSyn) => (bindFCT(name,fctVar); fctSyn))
1591: (rightAssoc(fctb1, AND, op ::, single))
1592:
1593: and fctb1() =
1594: let val name = ident()
1595: val mEntry = openScope()
1596: val (pname,paccess,param,spreadParams) =
1597: (checkToken(LPAREN);
1598: (case !nextToken
1599: of RPAREN => (anonParamName,LVAR(namedLvar(anonParamName)),nullSig,
1600: false)
1601: | ID s => let val tenv = array(0, NULLtyc)
1602: val senv = array(2, NULLstr)
1603: val _ = openNew({path=[~1], strenv=REL{t=tenv,s=senv}},
1604: newTable())
1605: val name = ident()
1606: val access = LVAR(namedLvar(name))
1607: val _ = checkToken(COLON)
1608: val param = sign()
1609: in update(senv,1,param);
1610: bindSTR(name,STRvar{name=[name],
1611: access=access,
1612: binding=INDstr(1)});
1613: (name,access,param,false)
1614: end
1615: | tok => if firstSpec(tok)
1616: then let val plvar = namedLvar(anonParamName)
1617: val param as STRstr{env,table,...} =
1618: sigbody(2,Stampset.newStampsets())
1619: in openOld({path=[~1,1],strenv=env},table);
1620: (anonParamName,LVAR(plvar),param,true)
1621: end
1622: else condemn ("expected functor parameter spec, found "
1623: ^tokenName tok))
1624: before checkToken(RPAREN))
1625: val resSign =
1626: if !nextToken = COLON
1627: then (advance(); SOME(sign()))
1628: else NONE
1629: val _ = if spreadParams
1630: then let val STRstr{table,env,...} = param
1631: and LVAR plvar = paccess
1632: in resetEnv(mEntry);
1633: openOld({path=[plvar],strenv=env},table)
1634: end
1635: else ()
1636: val _ = checkToken(EQUAL)
1637: val bodystamps = Stampset.newStampsets()
1638: val (bodyexp,bodystr,thin) = str(false,resSign,[],bodystamps,param)
1639: val openBody =
1640: case bodystr
1641: of STRstr{stamp=bodystamp,env=DIR,...} =>
1642: Stampset.member(bodystamp,(#strStamps bodystamps))
1643: | _ => false
1644: val paramVis =
1645: case resSign
1646: of SOME _ => true
1647: | NONE => openBody
1648: val body =
1649: if openBody
1650: then Functor.abstractBody(bodystr,param,bodystamps,
1651: Stampset.newStamp(Stampset.sigStamps))
1652: else bodystr
1653: val paramvar = STRvar{name = [pname], access = paccess, binding = param}
1654: val fctv = FCTvar{name=name,
1655: access=LVAR(namedLvar(name)),
1656: binding=FUNCTOR{paramName=pname,
1657: param=param,
1658: body=body,
1659: paramVis=paramVis,
1660: stamps=bodystamps}}
1661: val fb = FCTB{fctvar=fctv, param=paramvar, def=bodyexp, thin=thin,
1662: constraint=resSign}
1663: in resetEnv(mEntry);
1664: (name,fctv,fb)
1665: end
1666:
1667:
1668: (* top level declarations *)
1669:
1670: fun importdec()=
1671: let fun loop() =
1672: (case !nextToken of
1673: SEMICOLON => []
1674: | STRING s => (advance(); s :: loop())
1675: | _ => condemn("string constant (file name) expected, found " ^
1676: tokenName (!nextToken))
1677: )
1678: val files = loop()
1679: in case files of
1680: [] => condemn("string constant (file name) expected, found " ^
1681: tokenName (!nextToken))
1682: | _ => files
1683: end
1684:
1685: val globalStamps = Stampset.globalStamps
1686: val itsym = Symbol.symbol "it"
1687:
1688: fun inner_interdec() =
1689: (prompt := !System.Control.secondaryPrompt;
1690: case !nextToken
1691: of SIGNATURE => (advance(); SIGdec(sigb()))
1692: | Token.FUNCTOR => (advance(); markdec FCTdec(fctb()))
1693: | STRUCTURE =>
1694: (advance(); markdec STRdec(strb(false,[],globalStamps)))
1695: | ABSTRACTION =>
1696: (advance(); markdec STRdec(strb(true,[],globalStamps)))
1697: | IMPORT=>(advance(); IMPORTdec(importdec()))
1698: | EOF => raise Eof
1699: | tok => let val dec =
1700: if firstLdec(!nextToken)
1701: then ldec([],Stampset.globalStamps)
1702: else if firstExp lookFIX (!nextToken)
1703: then (markdec (fn() => VALdec[VB
1704: (protect(protectTyvars(NONE),(fn() =>
1705: {exp=exp(Stampset.globalStamps),
1706: pat=let val v = newVAR(ref nil,itsym)
1707: in bindVAR(itsym,v);
1708: VARpat v
1709: end,
1710: tyvars=currentTyvars()})))]) ())
1711: else condemn("declaration or expression expected, found " ^
1712: tokenName tok)
1713: in Typecheck.decType(dec); dec
1714: end)
1715:
1716: in inner_interdec()
1717: end (* fun interdec *)
1718:
1719: end (* structure Parse *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.