Annotation of researchv10no/cmd/sml/src/parse/parse.sml, revision 1.1.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.