Annotation of researchv10no/cmd/sml/src/parse/parse.sml, revision 1.1

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 *)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.