1(*
2    Copyright (c) 2013-2015 David C.J. Matthews
3
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License version 2.1 as published by the Free Software Foundation.
7    
8    This library is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11    Lesser General Public License for more details.
12    
13    You should have received a copy of the GNU Lesser General Public
14    License along with this library; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16*)
17
18(*
19    Derived from the original parse-tree
20
21    Copyright (c) 2000
22        Cambridge University Technical Services Limited
23
24    Further development:
25    Copyright (c) 2000-13 David C.J. Matthews
26
27    Title:      Parse Tree Structure and Operations.
28    Author:     Dave Matthews, Cambridge University Computer Laboratory
29    Copyright   Cambridge University 1985
30
31*)
32
33
34functor TYPECHECK_PARSETREE (
35
36structure BASEPARSETREE : BaseParseTreeSig
37structure PRINTTREE: PrintParsetreeSig
38structure EXPORTTREE: ExportParsetreeSig
39structure LEX : LEXSIG
40structure CODETREE : CODETREESIG
41structure STRUCTVALS : STRUCTVALSIG;
42structure TYPETREE : TYPETREESIG
43structure VALUEOPS : VALUEOPSSIG;
44structure PRETTY : PRETTYSIG
45structure COPIER: COPIERSIG
46structure DATATYPEREP: DATATYPEREPSIG
47
48structure UTILITIES :
49sig
50    type lexan;
51    type location =
52        { file: string, startLine: FixedInt.int, startPosition: FixedInt.int,
53          endLine: FixedInt.int, endPosition: FixedInt.int }
54
55    val noDuplicates: (string * 'a * 'a -> unit) -> 
56                       { apply: (string * 'a -> unit) -> unit,
57                         enter:  string * 'a -> unit,
58                         lookup: string -> 'a option};
59
60    val searchList: unit -> { apply: (string * 'a -> unit) -> unit,
61                            enter:  string * 'a -> unit,
62                            lookup: string -> 'a option };
63
64    val checkForDots:  string * lexan * location -> unit;
65
66    val splitString: string -> { first:string,second:string }
67
68    structure Sharing:
69    sig
70        type lexan = lexan
71    end
72end
73
74structure PRINTTABLE :
75sig
76    type typeConstrs
77    type codetree
78
79    val getOverloads: string -> (typeConstrs * codetree) list
80
81    structure Sharing:
82    sig
83        type codetree = codetree
84        and  typeConstrs = typeConstrs
85    end
86end;
87
88structure MISC :
89sig  
90    exception InternalError of string; (* compiler error *)
91
92    val quickSort : ('a -> 'a -> bool) -> 'a list -> 'a list;
93
94    val lookupDefault :  ('a -> 'b option) -> ('a -> 'b option) -> 'a -> 'b option
95end
96
97sharing LEX.Sharing = TYPETREE.Sharing = STRUCTVALS.Sharing = COPIER.Sharing
98       = VALUEOPS.Sharing = UTILITIES.Sharing = PRETTY.Sharing
99       = CODETREE.Sharing = PRINTTABLE.Sharing = DATATYPEREP.Sharing
100       = BASEPARSETREE.Sharing = PRINTTREE.Sharing = EXPORTTREE.Sharing
101
102): TypeCheckParsetreeSig =
103   
104struct
105    open MISC
106    open LEX
107    open CODETREE
108    open STRUCTVALS
109    open TYPETREE
110    open VALUEOPS
111    open UTILITIES
112    open PRETTY
113    open PRINTTABLE
114    open DATATYPEREP
115  
116    open BASEPARSETREE
117    open PRINTTREE
118    open EXPORTTREE
119  
120    val emptyType            = EmptyType
121    val badType              = BadType
122  
123   (* Second pass of ML parse tree. *)
124   
125    (* This is pass 2 of the compiler. It walks over the parse tree
126       generated by pass 1 and looks up identifiers to match them to
127       declarations. It performs the type checking. "makeTypeId" is used
128       to construct unique identifiers for types depending on the context
129       (i.e. in a signature, structure or functor). *)
130    fun pass2 (v, makeTypeId, env, lex, sigTypeIdMap) =
131    let
132        (* Returns a function which can be passed to unify or apply to
133           print a bit of context info. *)
134        fun foundNear v () =
135        let
136            val errorDepth = errorDepth lex
137        in
138            displayParsetree (v, errorDepth)
139        end
140
141      (* A simpler error message routine for lookup_... where the message
142         does not involve pretty-printing anything. *)
143      fun giveError (v, lex, line)  =
144        fn message => errorNear (lex, true, v, line, message);
145
146      fun checkForBuiltIn (name, v, lex, lineno, isConstr) =
147      (* ML97 does not allow the standard constructors to be rebound and does
148         not allow "it" to become a constructor. *)
149         if name = "true" orelse name = "false" orelse name = "nil"
150         orelse name = "::" orelse name = "ref" orelse (isConstr andalso name = "it")
151         then errorNear(lex, true, v, lineno,
152                     "Rebinding or specifying \"" ^ name ^ "\" is illegal")
153         else ()
154
155        (* Turn a result from unifyTypes into a pretty structure so that it
156           can be included in a message. *)
157        fun unifyErrorReport(lex, typeEnv) = unifyTypesErrorReport(lex, typeEnv, typeEnv, "unify")
158
159        (* Error message for incompatible types.  Displays both expressions and their types. *)
160        fun typeMismatch (title, left, right, detail, lex : lexan, location, moreInfo) =
161        let
162            val message =
163                PrettyBlock(3, true, [],
164                    [
165                        PrettyString title,
166                        PrettyBreak(1, 0), left,
167                        PrettyBreak(1, 0), right,
168                        PrettyBreak(1, 0),
169                        PrettyBlock(0, false, [],
170                            [PrettyString "Reason:", PrettyBreak(1, 3), detail])
171                    ])
172        in
173            reportError lex
174            {
175                location = location,
176                hard = true,
177                message = message,
178                context = SOME (moreInfo ())
179            }
180        end;
181
182        (* Error message for single expressions with the wrong type. e.g. "if" not followed
183           by a "bool". *)
184        fun typeWrong (title, value, detail, lex : lexan, location, moreInfo) =
185        let
186            val message =
187                PrettyBlock(3, true, [],
188                    [
189                        PrettyString title,
190                        PrettyBreak(1, 0), value,
191                        PrettyBreak(1, 0),
192                        PrettyBlock(0, false, [],
193                            [ PrettyString "Reason:", PrettyBreak(1, 3), detail])
194                    ])
195        in
196            reportError lex
197            {
198                location = location,
199                hard = true,
200                message = message,
201                context = SOME (moreInfo ())
202            }
203        end;
204
205        (* Display a value and its type as part of an error message. *)
206        fun valTypeMessage (lex, typeEnv) (title, value, valType) =
207        let
208            val errorDepth = errorDepth lex
209        in
210            PrettyBlock(3, false, [],
211                [
212                    PrettyString title,
213                    PrettyBreak(1, 0),
214                    displayParsetree (value, errorDepth),
215                    PrettyBreak(1, 0),
216                    PrettyString ":",
217                    PrettyBreak(1, 0),
218                    display(valType, 10000 (* All of it *), typeEnv)
219                ])
220        end
221
222        fun matchTypeMessage (lex, typeEnv) (title, match, valType) =
223        let
224            val errorDepth = errorDepth lex
225        in
226            PrettyBlock(3, false, [],
227                [
228                    PrettyString title,
229                    PrettyBreak(1, 0),
230                    displayMatch (match, errorDepth),
231                    PrettyBreak(1, 0),
232                    PrettyString ":",
233                    PrettyBreak(1, 0),
234                    display(valType, 10000 (* All of it *), typeEnv)
235                ])
236        end
237
238        (* Old error message and unification functions.  These will eventually be
239           removed.  *)
240        fun matchError 
241            (error: matchResult, lex : lexan, location : LEX.location, moreInfo : unit -> pretty, typeEnv) : unit =
242            reportError lex
243            {
244                location = location,
245                hard = true,
246                message = unifyErrorReport(lex, typeEnv) error,
247                context = SOME (moreInfo ())
248           }
249
250        fun unify (alpha, beta, lex, location, moreInfo, typeEnv) =
251            case unifyTypes (alpha, beta) of
252                NONE => ()
253            |   SOME error =>
254                    matchError (error, lex, location, moreInfo, typeEnv)
255
256        fun apply (f, arg, lex, location, moreInfo, typeEnv) =
257            case eventual f of
258                FunctionType {arg=farg, result} =>
259                (
260                    unify (farg, arg, lex, location, moreInfo, typeEnv);
261                    result
262                )
263            |   ef => (* Type variables etc. - Use general case. *)
264                let  (* Make arg->'a, and unify with the function. *)
265                    val resType  = mkTypeVar (generalisable, false, false, false)
266                    val fType    = mkFunctionType (arg, resType)
267      
268                    (* This may involve more than just assigning the type to "ef". *)
269                    val () = unify (ef, fType, lex, location, moreInfo, typeEnv);
270                in
271                    resType (* The result is the type variable unified to the result. *)
272                end
273
274        (* These cases currently use the "apply" or "unify" and may need to be improved in
275           order to produce better messages.
276           apply:
277              Literals.  The conversion functions are applied to the string literal.  In effect this produces the set
278              of overloadings of the literal.  This should never produce an error message.
279              Constructors in patterns to their args.
280              "case": the patterns are "applied" to the value to be tested.
281
282           unify:
283              Layered patterns, to set the variable. Also checks the pattern against any explicit type.
284              Handlers: the handling patterns are unified against a function from exn -> the result type of the
285              expression being handled.
286         *)
287
288    fun stringsOfSearchList { apply: (string * 'a -> unit) -> unit, ...} () =
289    let
290        val v = ref []
291        val () = apply (fn (s, _) => v := s :: !v)
292    in
293        !v
294    end
295
296    fun assignValues (level, letDepth, env, near, v)  =
297    let
298        val typeEnv =
299        {
300            lookupType = fn s => case #lookupType env s of NONE => NONE | SOME t => SOME(t, NONE),
301            lookupStruct = fn s => case #lookupStruct env s of NONE => NONE | SOME t => SOME(t, NONE)
302        }
303         (* Process each item of the sequence and return the type of the
304            last item. A default item is returned if the list is empty. *)
305        fun assignSeq(env, depth, l, isExp) =
306        let
307            fun applyList last []       = last
308            |   applyList _ ((h, _) :: t) =
309                let
310                    val expT = assignValues(level, depth, env, v, h)
311                    val _ =
312                        if isExp andalso not (null t)
313                        then (* It's not the last value and we're going to discard it *)
314                        case checkDiscard(expT, lex) of
315                            NONE => ()
316                        |   SOME s => errorNear (lex, false, h, getLocation h, s)
317                        else ()
318                in
319                    applyList expT t
320                end
321        in
322            applyList badType l
323        end
324
325        (* Variables, constructors and fn are non-expansive.
326           [] is a derived form of "nil" so must be included.
327           Integer and string constants are also constructors but
328           cannot involve imperative type variables. Constrained
329           versions are also non-expansive.
330           This has been extended and made more explicit in ML 97. *)
331        fun nonExpansive (Fn _)   = true
332        |   nonExpansive (Ident _) = true
333        |   nonExpansive (List{elements = [], ...}) = true
334        |   nonExpansive (List{elements, ...}) =
335                List.foldl (fn (v, a) => a andalso nonExpansive v) true elements
336        |   nonExpansive (Constraint {value, ...}) = nonExpansive value
337        |   nonExpansive (Literal _) = true
338        |   nonExpansive (Unit _) = true
339        |   nonExpansive (TupleTree{fields, ...}) = 
340                List.foldl (fn (v, a) => a andalso nonExpansive v) true fields
341        |   nonExpansive (Labelled{recList, ...}) =
342                List.foldl (fn ({valOrPat, ...}, a) => a andalso nonExpansive valOrPat)
343                        true recList (* Every element must be non-expansive *)
344        |   nonExpansive (Applic{f, arg, ...}) =
345                isNonRefConstructor f andalso nonExpansive arg
346        |   nonExpansive (Selector _) = true (* derived from fn {..} => ...*)
347        |   nonExpansive (Parenthesised(p, _)) = nonExpansive p
348        |   nonExpansive _       = false
349
350        (* An application is non-expansive only if it is a, possibly
351           constrained, constructor which is not ref. *)
352        and isNonRefConstructor (Ident {value=ref v, ...}) =
353            (* It is possible to rebind ref by way of datatype replication so we have
354               to check the type here. *)
355            let
356                fun isRefConstructor t =
357                    case eventual t of
358                        FunctionType{result, ...} =>
359                            (case eventual result of
360                                TypeConstruction{constr, ...} =>
361                                    sameTypeId (tcIdentifier constr, tcIdentifier refConstr)
362                            |   _ => false)
363                    |   _ => false
364            in
365                isConstructor v andalso not (isRefConstructor(valTypeOf v))
366            end
367        | isNonRefConstructor (Constraint {value, ...}) =
368                isNonRefConstructor value
369        | isNonRefConstructor (Parenthesised(p, _)) =
370                isNonRefConstructor p
371        | isNonRefConstructor _ = false
372
373        (* Applies "assignValues" or "processPattern" to every element of a list and unifies the
374           types. Returns a type variable if the list is empty.
375           This is used for lists, function values (fn .. => ...),
376           handlers and case expressions. *)
377        fun assignList _ _ [] = mkTypeVar (generalisable, false, false, false)
378        |   assignList (processValue: 'a->types, _, _) _ [single] = processValue single
379
380        |   assignList (processValue: 'a->types, displayValue, typeMsg)
381                            (errorMsg, itemName, separator, location, near) (tlist as hd :: tl) =
382            let
383                val firstType = processValue hd
384
385                fun printList (doPrint: 'a*FixedInt.int->pretty) (c: 'a list, separator, depth): pretty list =
386                    if depth <= 0 then [PrettyString "..."]
387                    else
388                    case c of
389                        []      => []
390                    |   [v]     => [doPrint (v, depth)]
391                    |   (v::vs) =>
392                            PrettyBlock (0, false, [],
393                                [
394                                    doPrint (v, depth),
395                                    PrettyBreak
396                                       (if separator = "," orelse separator = ";" orelse separator = "" then 0 else 1, 0),
397                                    PrettyString separator
398                                ]
399                                ) ::
400                            PrettyBreak (1, 0) ::
401                            printList doPrint (vs, separator, depth - 1)
402
403                fun applyList(ty, _, []) = ty
404                |   applyList(ty, n, h::t) =
405                    let
406                        val typ = processValue h
407                    in
408                        case unifyTypes (ty, typ) of
409                            NONE => applyList(ty, n+1, t)
410                        |   SOME report =>
411                            let
412                                (* We have a type error but we don't know which is correct.
413                                   The previous items must have produced a consistent type
414                                   otherwise we'd already have reported an error but we
415                                   can't identify exactly where the error occurred. *)
416                                val errorDepth = errorDepth lex
417                                val previousValsAndType =
418                                    PrettyBlock(3, false, [],
419                                        [
420                                            PrettyString (
421                                                if n = 1 then itemName ^ " 1:"
422                                                else itemName ^ "s 1-" ^ Int.toString n ^ ":"),
423                                            PrettyBreak(1, 0),
424                                            PrettyBlock(0, false, [],
425                                                printList (*displayParsetree*)displayValue (List.take(tlist, n),
426                                                separator, errorDepth)),
427                                            PrettyBreak(1, 0),
428                                            PrettyString ":",
429                                            PrettyBreak(1, 0),
430                                            display(ty, 10000 (* All of it *), typeEnv)
431                                        ])
432                            in
433                                typeMismatch(errorMsg,
434                                    previousValsAndType,
435                                    (*valTypeMessage*)typeMsg(lex, typeEnv) (concat[itemName, " ", Int.toString(n+1), ":"], h, typ),
436                                    unifyErrorReport(lex, typeEnv) report, lex, location, foundNear near);
437                                (* Continue with "bad" which suppresses further error messages
438                                   and return "bad" as the result. *)
439                                applyList(badType, n+1, t)
440                            end
441                    end
442            in
443                applyList(firstType, 1, tl)
444            end
445
446        fun ptAssignTypes (t, near) =
447            assignTypes
448                (t,
449                fn (s, line) => 
450                    lookupTyp 
451                        ({lookupType = #lookupType env, lookupStruct = #lookupStruct env},
452                        s, giveError (near, lex, line)),
453                lex);
454
455        (* Makes a type for an instance of an identifier. *)
456
457        (* Get the current overload set for the function and return a new
458           instance of the type containing the overload set. *)
459        fun overloadType(Value{typeOf, access = Overloaded TypeDep, name, ...}, isConv) =
460                #1 (generaliseOverload(typeOf, List.map #1 (getOverloads name), isConv))
461        |   overloadType(Value{typeOf, ...}, _) =  #1 (generalise typeOf)
462
463        fun instanceType (v as Value{access=Overloaded TypeDep, ...}) =
464          (* Look up the current overloading for this function. *)
465                overloadType(v, false)
466
467        |   instanceType(Value{typeOf, ...}) = #1 (generalise typeOf)
468            (* The types of constructors and variables are copied 
469               to create new instances of type variables. *)
470
471        fun processPattern(pat, enterResult, level, notConst, mkVar, isRec) =
472        let
473            val mapProcessPattern =
474                map (fn x => processPattern(x, enterResult, level, notConst, mkVar, isRec));
475        in
476            case pat of
477                Ident {name, value, expType, location, possible, ...} => (* Variable or nullary constructor. *)
478                let
479                    (* Look up the name. If it is a constructor then use it,
480                        otherwise return `undefined'. If it is a qualified name,
481                        i.e. it contains a full-stop, we assume it is a constructor
482                        and give an error message if it does not exist. *)
483                    (* In ML 97 recursive declarations such as val rec f = ...
484                         override constructor status.  If this is a recursive declaration
485                         we don't check for constructor status. *)
486                    val names   = splitString name;
487                    val nameVal =
488                        if isRec
489                        then undefinedValue
490                        else if #first names = ""
491                        then (* Not qualified - may be a variable. *)
492                            getOpt (#lookupVal env name, undefinedValue) 
493              
494                        else (* Qualified - cannot be a variable. *)
495                            lookupValue
496                                ("Constructor",
497                                {lookupVal= #lookupVal env, lookupStruct= #lookupStruct env},
498                                name,
499                                giveError (pat, lex, location))
500
501                    (* Remember the possible names here. *)
502                    val () = possible := #allValNames env
503
504                    val instanceType = 
505                        (* If the result is a constructor use it. *)
506                        if isConstructor nameVal (* exceptions. *)
507                        then if notConst
508                        then
509                        (
510                            errorNear (lex, true, pat, location,
511                                    "Identifier before `as' must not be a constructor.");
512                            badType
513                        )
514                        else
515                        (* Must be a nullary constructor otherwise it should
516                           have been applied to something. *)
517                        let
518                            (* set this value in the record *)
519                            val () = value := nameVal;
520                            val isNullary =
521                                case nameVal of
522                                    Value{class=Constructor{nullary, ...}, ...} => nullary
523                                |   Value{typeOf, ...} => (* exception *) not (isSome(getFnArgType typeOf))
524                        in
525                            if isNullary then instanceType nameVal
526                            else
527                            (
528                                errorNear (lex, true, pat, location,
529                                            "Constructor must be applied to an argument pattern.");
530                                badType
531                            )
532                        end
533      
534                        (* If undefined or another variable, construct a new variable. *)
535                        else
536                        let
537                            val props = [DeclaredAt location, SequenceNo (newBindingId lex)]
538                            val var =  mkVar(name, mkTypeVar (level, false, false, false), props)
539                        in
540                            checkForDots (name, lex, location); (* Must not be qualified *)
541                            (* Must not be "true", "false" etc. *)
542                            checkForBuiltIn (name, v, lex, location, false);
543                            enterResult (name, var);
544                            value := var;
545                            valTypeOf var (* and return its type *)
546                        end;
547                in
548                    expType := instanceType; (* Record the instance type.*)
549                    instanceType
550                end
551    
552            |   Literal{converter, expType, location, ...} =>
553                let
554                    (* Find out the overloadings on this converter and
555                       construct an instance of it.  The converters are
556                       all functions from string to the result type. *)
557                    val instanceType = overloadType(converter, true)
558                    (* Apply the converter to string to get the type of the
559                       literal. *)
560                    val instance =
561                        apply(instanceType, stringType, lex, location, foundNear pat, typeEnv)
562                in
563                    expType := instance; (* Record the instance type.*)
564                    instance
565                end
566
567            |   Applic {f = con, arg, location, expType, ...} =>
568                let
569                    (* Apply the function to the argument and return the result. *)
570                    (* Function must be a constructor. *)
571                    val conType = 
572                        case con of
573                            Ident {name, value, location, expType, possible, ...} =>
574                            let (* Look up the value and return the type. *)
575                            
576                                (* Remember the possible names here. *)
577                                val () = possible := #allValNames env
578
579                                val constrVal =
580                                    lookupValue 
581                                        ("Constructor",
582                                        {lookupVal   = #lookupVal env, lookupStruct = #lookupStruct env},
583                                        name, giveError (pat, lex, location));
584                            in
585                                if isConstructor constrVal
586                                then
587                                let
588                                    val cType = instanceType constrVal
589                                in
590                                    value := constrVal;
591                                    expType := cType; (* Record the instance type.*)
592                                    cType
593                                end
594                                else (* Undeclared or a variable. *)
595                                (
596                                    if isUndefinedValue constrVal then ()
597                                    else errorNear (lex, true, pat, location, name ^ " is not a constructor");
598                                    badType
599                                )
600                            end
601        
602                        |   _ => (* con is not an Ident *)
603                            (
604                                errorNear (lex, true, pat, location,
605                                    "Constructor in a pattern was not an identifier");
606                                badType
607                            )
608    
609                    val patType = processPattern(arg, enterResult, level, notConst, mkVar, isRec);
610                    (* Apply to the pattern type. *)
611                    val resultType = apply (conType, patType, lex, location, foundNear pat, typeEnv)
612                in
613                    expType := resultType; (* Record the instance type.*)
614                    resultType
615                end (* Applic *)
616
617            |   TupleTree{fields, expType, ...} =>
618                let
619                    (* Construct the type obtained by mapping "processPattern"
620                       onto each element of the tuple. *)
621                    val tupleType = mkProductType (mapProcessPattern fields)
622                in
623                    expType := tupleType;
624                    tupleType
625                end
626
627            |   Labelled {recList, frozen, expType, ...} =>
628                let (* Process each item in the list. *)
629
630                    fun mapLabels [] = []
631                    |   mapLabels ({name, valOrPat, expType, ...}::T) =
632                        (* Type is a label entry with the label name
633                           and the type of the pattern. *)
634                        let
635                            val ty = processPattern(valOrPat, enterResult, level, notConst, mkVar, isRec)
636                        in
637                            expType := ty;
638                            mkLabelEntry(name, ty) :: mapLabels T
639                        end;
640                    val patType = mkLabelled (sortLabels(mapLabels recList), frozen);
641                in
642                    expType := patType;
643                    patType
644                end
645
646            |   (aList as List{elements, location, expType}) =>
647                let
648                    (* Applies "processPattern" to every element of a list and
649                       unifies the types. Returns a type variable if the list
650                       is empty *)
651                    fun processElement elem =
652                        processPattern(elem, enterResult, level, notConst, mkVar, isRec)
653                    val elementType =
654                        assignList (processElement, displayParsetree, valTypeMessage)
655                            ("Elements in a list have different types.", "Item", ",", location, aList) elements
656                    val resType =
657                        if isBadType elementType
658                        then badType
659                        else mkTypeConstruction ("list", tsConstr listConstr, [elementType], [DeclaredAt inBasis])
660                in
661                    expType := resType;
662                    resType
663                end
664
665            |   aConstraint as Constraint {value, given, location} =>
666                let
667                    val valType  = processPattern(value, enterResult, level, notConst, mkVar, isRec);
668                    val theType = ptAssignTypes(given, pat);
669                in
670                    (* These must be unifiable. *)
671                    case unifyTypes(valType, theType) of
672                        NONE => () (* OK. *)
673                    |   SOME report =>
674                            typeMismatch("Type mismatch in type constraint.",
675                                valTypeMessage (lex, typeEnv) ("Value:", value, valType),
676                                PrettyBlock(0, false, [],
677                                    [
678                                        PrettyString "Constraint:",
679                                        PrettyBreak(1, 0),
680                                        display(theType, 10000 (* All of it *), typeEnv)
681                                    ]),
682                                unifyErrorReport (lex, typeEnv) report,
683                                lex, location, foundNear aConstraint);
684                    theType
685                end
686
687            |   Layered {var, pattern, location} =>
688                let
689                    (* Unify the variable and the pattern - At this stage that simply
690                     involves assigning the type of the pattern to the variable,
691                     but it may result in more unification when the variable is
692                     used *)
693              
694                    (* The "variable" must be either id or id: ty but we have to
695                     check that the id is not a constructor. *)
696                    val varType = processPattern(var,     enterResult, level, true, mkVar, isRec);
697                    val patType = processPattern(pattern, enterResult, level, notConst, mkVar, isRec)
698                    val () = unify (varType, patType, lex, location, foundNear pat, typeEnv);
699                in
700                    varType
701                end
702
703            |   Unit _ => unitType
704
705            |   WildCard _ => mkTypeVar (generalisable, false, false, false)
706
707            |   Parenthesised(p, _) =>
708                    processPattern(p, enterResult, level, notConst, mkVar, isRec)
709
710            |   _ => (* not a legal pattern *)
711                    badType
712
713        end (* processPattern *)
714
715        (* val assValues = assignValues level line env; *)
716        and assValues near v =
717          case v of
718            Ident {name, value, expType, location, possible, ...} =>
719            let
720                val expValue =
721                    lookupValue 
722                        ("Value or constructor",
723                            {lookupVal = #lookupVal env, lookupStruct = #lookupStruct env},
724                            name, giveError (near, lex, location));
725                (* Set the value and type found. *)
726                val instanceType = instanceType expValue;
727            in
728                (* Include this reference in the list of local references. *)
729                case expValue of
730                    Value { references=SOME{localRef, ...}, ...} =>
731                        localRef := location :: ! localRef
732                |   _ => ();
733                (* Include this type in the list of instance types. *)
734                case expValue of
735                    Value { instanceTypes=SOME instanceRef, ...} =>
736                        instanceRef := instanceType :: ! instanceRef
737                |   _ => ();
738                expType := instanceType;
739                value  := expValue;
740                possible := #allValNames env;
741                instanceType (* Result is the instance type. *)
742            end
743
744          | Literal{converter, expType, location, ...} =>
745            let
746                (* Find out the overloadings on this converter and
747                   construct an instance of it.  The converters are
748                   all functions from string to the result type. *)
749                val instanceType = overloadType(converter, true)
750                val instance =
751                    apply(instanceType, stringType, lex, location, foundNear near, typeEnv)
752            in
753                expType := instance;
754                instance
755            end
756
757          | Applic {f, arg, location, expType, ...} => 
758            let
759                (* Apply the function to the argument and return the result. *)
760                val funType = assValues near f;
761                val argType = assValues near arg;
762                (* If this is not a constructor the expression is expansive.  We need to unify this
763                   with a type-variable with local (non-generalisable) scope to force any type
764                   variables to be monomorphic.  The reason for this is that if there are polymorphic
765                   type variables remaining in identifiers in the next pass we treat the identifier as
766                   polymorphic and wrap a function round it. *)
767                val () =
768                    if nonExpansive v
769                    then ()
770                    else (unifyTypes (funType, mkTypeVar(level, false, false, false)); ())
771                (* Test to see if we have a function. *)
772                val fType =
773                    case eventual funType of
774                        FunctionType {arg, result} => SOME(arg, result)
775                    |   _ => (* May be a simple type variable. *)
776                        let
777                            val funResType = mkTypeVar (generalisable, false, false, false)
778                            val funArgType = mkTypeVar (generalisable, false, false, false)
779                            val fType    = mkFunctionType (funArgType, funResType)
780                        in
781                            case unifyTypes (fType, funType) of
782                                NONE => SOME(funArgType, funResType)
783                            |   SOME _ =>
784                                (
785                                    (* It's not a function. *)
786                                    typeMismatch("Type error in function application.",
787                                        valTypeMessage (lex, typeEnv) ("Function:", f, funType),
788                                        valTypeMessage (lex, typeEnv) ("Argument:", arg, argType),
789                                        PrettyString "Value being applied does not have a function type",
790                                        lex, location, foundNear near);
791                                    NONE
792                                )
793                        end
794
795            in
796                case fType of
797                    NONE => badType (* Not a function *)
798                |   SOME (fArg, fResult) =>
799                    (
800                        case unifyTypes (fArg, argType) of
801                            NONE => ()
802                        |   SOME report =>
803                                typeMismatch("Type error in function application.",
804                                    valTypeMessage (lex, typeEnv) ("Function:", f, funType),
805                                    valTypeMessage (lex, typeEnv) ("Argument:", arg, argType),
806                                    unifyErrorReport (lex, typeEnv) report, lex, location, foundNear near);
807                        expType := fResult; (* Preserve for browsing. *)
808                        fResult
809                    )
810            end
811
812          | Cond {test, thenpt, elsept, location, ...} =>
813            let
814                (* The test must be bool, and the then and else parts must be the
815                   same. The result is either of these two once they have been
816                   unified. *)
817                val testType = assValues v test;
818                val thenType = assValues v thenpt;
819                val elseType = assValues v elsept;
820            in
821                case unifyTypes(testType, boolType) of
822                    NONE => ()
823                |   SOME report =>
824                        typeWrong("Condition in if-statement must have type bool.",
825                            valTypeMessage (lex, typeEnv) ("If:", test, testType),
826                            unifyErrorReport (lex, typeEnv) report, lex, location, foundNear v);
827
828                case unifyTypes(thenType, elseType) of
829                    NONE => thenType (* or equally elseType *)
830                |   SOME report =>
831                    (
832                        typeMismatch("Type mismatch between then-part and else-part.",
833                            valTypeMessage (lex, typeEnv) ("Then:", thenpt, thenType),
834                            valTypeMessage (lex, typeEnv) ("Else:", elsept, elseType),
835                            unifyErrorReport (lex, typeEnv) report, lex, location, foundNear v);
836                        badType
837                    )
838            end
839
840            |   TupleTree{fields, expType, ...} =>
841                let
842                    (* Construct the type obtained by mapping "assignValue" onto
843                       each element of the tuple. *)
844                    val tupleType = mkProductType (map (assValues near) fields)
845                in
846                    expType := tupleType;
847                    tupleType
848                end
849          
850          | Labelled {recList, frozen, expType, ...} =>
851            let
852                (* Process each item in the list. *)              
853                fun labEntryToLabType {name, valOrPat, expType, ...} =
854                let
855                    val ty = assValues v valOrPat
856                in
857                    expType := ty;
858                    {name = name, typeof = ty }
859                end
860            
861              val expressionType =
862                mkLabelled 
863                  (sortLabels (map labEntryToLabType recList), frozen) (* should always be true *);
864            in
865                expType := expressionType;
866                expressionType
867            end
868
869          | Selector {typeof, ...} =>
870              typeof (* Already made. *)
871
872          | ValDeclaration {dec, explicit, implicit, ...} =>
873                (assValDeclaration (dec, explicit, implicit); badType (* Should never be used. *))
874
875          | FunDeclaration fund =>
876                (assFunDeclaration fund; badType (* Should never be used. *))
877
878          | OpenDec{decs=ptl, variables, structures, typeconstrs, ...} =>
879                let
880                    (* Go down the list of names opening the structures. *)
881                    (* We have to be careful because open A B is not the same as
882                       open A; open B if A contains a structure called B. *)
883                    (* We accumulate the values so that we can produce debugging
884                       information if we need to.  Note: we have to be careful if
885                       we have the same name in multiple structures. *)
886                    val valTable = HashTable.hashMake 10
887                    and typeTable = HashTable.hashMake 10
888                    and structTable = HashTable.hashMake 10
889    
890                    (* First get the structures... *)
891                    fun findStructure ({name, location, value, ...}: structureIdentForm) =
892                    let
893                        val foundStruct =
894                            lookupStructure
895                                ("Structure", {lookupStruct = #lookupStruct env}, name,
896                                    giveError (v, lex, location))
897                        val () = value := foundStruct (* Remember in case we export. *)
898                    in
899                        case foundStruct of
900                            SOME str => SOME(str, location)
901                        |   NONE => NONE
902                    end
903        
904                    val strs = List.mapPartial findStructure ptl
905                        
906                    (* Value and substructure entries in a structure will generally have
907                       "Formal" access which simply gives the offset of the entry within
908                       the parent structure.  We need to convert these into "Select"
909                       entries to capture the address of the base structure. *)
910                    fun copyEntries (str as Struct{locations, signat = sigTbl, name=strName, ...}, varLoc) =
911                    let
912                        val openLocs =
913                        (* If we have a declaration location for the structure set this as the structure
914                           location.  Add in here as the "open location". *)
915                            case List.find (fn DeclaredAt _ => true | _ => false) locations of
916                                SOME (DeclaredAt loc) => [StructureAt loc, OpenedAt varLoc]
917                            |   _ => [OpenedAt varLoc]
918
919                        (* Open the structure.  Formal entries are turned into Selected entries. *)
920                        val _ =
921                            COPIER.openSignature 
922                            (sigTbl,
923                            {
924                                enterType   =
925                                fn (name, TypeConstrSet(ty, valConstrs)) =>
926                                    let
927                                        (* We also have to turn the value constructors into
928                                           "selected" entries in case we use datatype
929                                           replication. Unlike with "include" in signatures,
930                                           there's no guarantee that the constructors will also
931                                           be part of the value environment. They could have
932                                           been redefined. *)
933                                        val newTypeSet =
934                                            TypeConstrSet(ty,
935                                                List.map (fn c => mkSelectedVar (c, str, openLocs)) valConstrs)
936                                    in
937                                        HashTable.hashSet(typeTable, name, newTypeSet);
938                                        #enterType env (name, newTypeSet)
939                                    end,
940                                enterStruct =
941                                fn (name, strVal) =>
942                                    let
943                                        val selectedStruct = 
944                                            makeSelectedStruct (strVal, str, openLocs);
945                                    in
946                                        HashTable.hashSet(structTable, name, selectedStruct);
947                                        #enterStruct env (name, selectedStruct)
948                                    end,
949                                enterVal    =
950                                fn (name, value) =>
951                                    let
952                                        val selectedVar = 
953                                            mkSelectedVar (value, str, openLocs);
954                                    in
955                                        HashTable.hashSet(valTable, name, selectedVar);
956                                        #enterVal env (name, selectedVar)
957                                    end
958                            },
959                            (* Add the structure we're opening here to the types of
960                               the values.  The name will be removed in messages if the type
961                               constructor is in scope but if it has been redefined we can
962                               get an identifiable name. *)
963                            strName ^ ".");
964                    in
965                        ()
966                    end
967    
968                    (* ...then put them into the name space. *)
969                    val () = List.app copyEntries strs;
970                in
971                    variables := HashTable.fold (fn (_, v, t) => v :: t) [] valTable;
972                    structures := HashTable.fold (fn (_, v, t) => v :: t) [] structTable;
973                    typeconstrs := HashTable.fold (fn (_, v, t) => v :: t) [] typeTable;
974                    badType (* Does not return a type *)
975                end
976    
977          | TypeDeclaration(tlist, _) =>
978            let (* This is either a type abbreviation in the core language, in a structure
979                   or in a signature or it is a type specification in a signaure. *)
980                fun messFn(name, _, new) = 
981                    errorNear (lex, true, v, declaredAt(tcLocations new),
982                        name ^ " has already been bound in this declaration");
983               
984                val newEnv = noDuplicates messFn;
985              
986                (* First match all the types on the right-hand sides. *)
987                fun processTypeBody (TypeBind {decType = SOME decType, ...}) = ptAssignTypes(decType, v)
988                |   processTypeBody _ = emptyType (* Specification. *)
989                
990                val resTypes = List.map processTypeBody tlist;
991              
992                (* Can now declare the new types. *)
993                fun processType (TypeBind {name, typeVars, isEqtype, nameLoc, tcon=tcRef, ...}, decType) =
994                let
995                    (* Construct a type constructor which is an alias of the
996                       right-hand side of the declaration.  If we are effectively
997                       giving a new name to a type constructor we use the same type
998                       identifier.  This is needed to check "well-formedness" in signatures. *)
999                    val props = [DeclaredAt nameLoc, SequenceNo (newBindingId lex)]
1000
1001                    val tcon =
1002                        if isEmpty decType
1003                        then (* Type specification *)
1004                        let
1005                            val description = { location = nameLoc, name = name, description = "" }
1006                        in
1007                            makeTypeConstructor (name, typeVars,
1008                                makeTypeId(isEqtype, false, (typeVars, EmptyType), description), props)
1009                        end
1010                        else case typeNameRebinding(typeVars, decType) of
1011                            SOME typeId =>
1012                                makeTypeConstructor (name,  typeVars,typeId, props)
1013                        |   NONE =>
1014                            let
1015                                val description = { location = nameLoc, name = name, description = "" }
1016                            in
1017                                makeTypeConstructor (name, typeVars,
1018                                    makeTypeId(isEqtype, false, (typeVars, decType), description), props)
1019                            end
1020                in
1021                    checkForDots  (name, lex, nameLoc); (* Must not be qualified *)
1022                    #enter newEnv (name, tcon); (* Check for duplicates. *)
1023                    tcRef := TypeConstrSet(tcon, []);
1024                    #enterType env  (name, TypeConstrSet(tcon, []))  (* Put in the surrounding scope. *)
1025                end
1026                   
1027                val () = ListPair.app processType (tlist, resTypes);
1028            in
1029                badType (* Does not return a type *)
1030            end
1031        
1032          | AbsDatatypeDeclaration absData => assAbsData absData
1033
1034          | DatatypeReplication{oldType, newType, oldLoc, newLoc, ...} =>
1035                  (* Adds both the type and the constructors to the
1036                   current environment. *)
1037              let
1038                (* Look up the type constructor in the environment. *)
1039                val oldTypeCons: typeConstrSet =
1040                    lookupTyp 
1041                         ({lookupType = #lookupType env, lookupStruct = #lookupStruct env},
1042                          oldType,
1043                          giveError (near, lex, oldLoc))
1044
1045                (* Copy the datatype, converting any Formal constructors to Selected. *)
1046                local
1047                    (* If the type name was qualified (e.g. S.t) we need to find the
1048                       value constructors from the same structure. *)
1049                    val {first = namePrefix, ...} = splitString oldType;
1050                    val baseStruct =
1051                        if namePrefix = ""
1052                        then NONE
1053                        else lookupStructure("Structure", {lookupStruct = #lookupStruct env},
1054                                    namePrefix, giveError (v, lex, oldLoc))
1055                    val TypeConstrSet(tcons, tcConstructors) = oldTypeCons
1056                    val newName = newType
1057                    val locations = [DeclaredAt newLoc, SequenceNo (newBindingId lex)]
1058                    (* Create a new constructor with the same unique ID. *)
1059                    val typeID = tcIdentifier tcons
1060                    val newTypeCons = makeTypeConstructor(newName, tcTypeVars tcons, typeID, locations)
1061    
1062                    (* Copy the value constructors. *)
1063                    fun copyAConstructor(Value{name=cName, typeOf, class, access, ...}) =
1064                        let
1065                            (* Copy the types of value constructors replacing
1066                               occurrences of the old type with the new one.
1067                               This is not strictly necessary but improves printing.
1068                               e.g. local datatype X = A | B in datatype Y = datatype X end;
1069                               A; prints  A: Y rather than A: X *)
1070                            fun copyTypeCons (tcon : typeConstrs) : typeConstrs =
1071                                if sameTypeId(tcIdentifier tcon, typeID)
1072                                then newTypeCons
1073                                else tcon;
1074                            fun copyTyp (t : types) : types =
1075                               copyType (t, fn x => x, (* Don't bother with type variables. *)
1076                                   copyTypeCons);
1077                            val newType = copyTyp typeOf;
1078                            val newAccess =
1079                                case (access, baseStruct) of
1080                                    (* If we are opening a structure we must have a base structure
1081                                       and we turn Formal entries into Selected.  If we are replicating
1082                                       a datatype within a signature the original constructors will
1083                                       be Formal. *)
1084                                    (Formal addr, SOME(Struct{access, ...})) => Selected{base=access, addr=addr}
1085                                |    (Formal _, NONE) => access
1086                                |    _ => access; (* Probably already a global. *)
1087                        in
1088                            Value{name=cName, typeOf=newType, class=class, access=newAccess, locations=locations,
1089                                  references = NONE, instanceTypes=NONE}
1090                        end
1091
1092                in
1093                    val newValConstrs = map copyAConstructor tcConstructors
1094                    val newTypeCons = TypeConstrSet(newTypeCons, newValConstrs)
1095                end
1096            in
1097                (* This previously checked that it was a datatype but that's
1098                   not actually correct. *)
1099                (* Enter the value constrs in the environment. *)
1100                List.app (fn c => (#enterVal env) (valName c, c)) newValConstrs;
1101                (* Add this type constructor to the environment. *)
1102                (#enterType env) (newType, newTypeCons);
1103                badType (* Does not return a type *)
1104            end
1105
1106          | (aList as List{elements, location, expType, ...}) =>
1107            let
1108                val elementType =
1109                    assignList(assValues v, displayParsetree, valTypeMessage)
1110                        ("Elements in a list have different types.", "Item", ",", location, aList) elements
1111                val resType =
1112                    if isBadType elementType
1113                    then badType
1114                    else mkTypeConstruction ("list", tsConstr listConstr, [elementType], [DeclaredAt inBasis])
1115            in
1116                expType := resType;
1117                resType
1118            end
1119
1120          | Constraint {value, given, location} =>
1121            let
1122                val valType = assValues near value;
1123                val theType = ptAssignTypes(given, v)
1124            in
1125                (* These must be unifiable. *)
1126                case unifyTypes(valType, theType) of
1127                    NONE => () (* OK. *)
1128                |   SOME report =>
1129                        typeMismatch("Type mismatch in type constraint.",
1130                            valTypeMessage (lex, typeEnv) ("Value:", value, valType),
1131                            PrettyBlock(0, false, [],
1132                                [
1133                                    PrettyString "Constraint:",
1134                                    PrettyBreak(1, 0),
1135                                    display(theType, 10000 (* All of it *), typeEnv)
1136                                ]),
1137                            unifyErrorReport (lex, typeEnv) report,
1138                            lex, location, foundNear v);
1139                theType
1140            end
1141
1142          | (aFun as Fn {matches, location, expType, ...}) =>  (* Must unify the types of each of the alternatives.*)
1143            let
1144                val resType =
1145                    assignList(assMatchTree aFun, displayMatch, matchTypeMessage)
1146                        ("Clauses in fn expression have different types.", "Clause", "|", location, aFun) matches
1147            in
1148                expType := resType;
1149                resType
1150            end
1151
1152          | Unit _ =>
1153              unitType
1154
1155          | Localdec {decs, body, isLocal, varsInBody, ...} =>
1156            let (* Local declarations or expressions. *)
1157              val newValEnv  = searchList();
1158              val newTypeEnv = searchList();
1159              val newStrEnv  = searchList();
1160              val newLetDepth = if isLocal then letDepth else letDepth+1;
1161              (* The environment for the local declarations. *)
1162              val localEnv =
1163                {
1164                   lookupVal     = lookupDefault (#lookup newValEnv)  (#lookupVal env),
1165                   lookupType    = lookupDefault (#lookup newTypeEnv) (#lookupType env),
1166                   lookupFix     = #lookupFix env,
1167                   (* This environment is needed if we open a 
1168                      structure which has sub-structures. *)
1169                   lookupStruct  = lookupDefault (#lookup newStrEnv) (#lookupStruct env),
1170                   lookupSig     = #lookupSig env,
1171                   lookupFunct   = #lookupFunct env,
1172                   lookupTvars   = #lookupTvars env,
1173                   enterVal      = #enter newValEnv,
1174                   enterType     = #enter newTypeEnv,
1175                  (* Fixity has already been dealt with in the parsing process.  The only reason
1176                     we deal with it here is to ensure that declarations are printed in the
1177                     correct order.  We simply need to make sure that local fixity declarations
1178                     are ignored. *)
1179                   enterFix      = fn _ => (),
1180                   enterStruct   = #enter newStrEnv,
1181                   enterSig      = #enterSig env,
1182                   enterFunct    = #enterFunct env,
1183                   allValNames   = fn () => (stringsOfSearchList newValEnv () @ #allValNames env ())
1184                };
1185        
1186              (* Process the local declarations and discard the result. *)
1187              val _ : types = assignSeq(localEnv, newLetDepth, decs, false)
1188        
1189              (* This is the environment used for the body of the declaration.
1190                 Declarations are added both to the local environment and to
1191                 the surrounding scope. *)
1192              val bodyEnv =
1193                { 
1194                  (* Look-ups come from the local environment *)
1195                  lookupVal     = #lookupVal localEnv,
1196                  lookupType    = #lookupType localEnv,
1197                  lookupFix     = #lookupFix localEnv,
1198                  lookupStruct  = #lookupStruct localEnv,
1199                  lookupSig     = #lookupSig localEnv,
1200                  lookupFunct   = #lookupFunct localEnv,
1201                  lookupTvars   = #lookupTvars localEnv,
1202                  enterVal      =
1203                    fn (pair as (_, v)) =>
1204                      (varsInBody := v :: ! varsInBody;
1205                       #enter newValEnv pair;
1206                       #enterVal env      pair),
1207                  enterType     =
1208                    fn pair =>
1209                      (#enter newTypeEnv pair;
1210                       #enterType env      pair),
1211                  enterFix      = #enterFix env,
1212                  enterStruct   =
1213                    fn pair =>
1214                      (#enter newStrEnv pair;
1215                       #enterStruct env   pair),
1216                  enterSig      = #enterSig env,
1217                  enterFunct    = #enterFunct env,
1218                  allValNames   = #allValNames localEnv
1219                };
1220              (* Now the body, returning its result if it is an expression. *)
1221                val resType = assignSeq(bodyEnv, newLetDepth, body, not isLocal)
1222            in
1223                resType
1224            end (* LocalDec *)
1225
1226          | ExpSeq (ptl, _) =>
1227             (* A sequence of expressions separated by semicolons.
1228                Result is result of last expression. *)
1229              assignSeq (env, letDepth, ptl, true)
1230
1231          | ExDeclaration(tlist, _) =>
1232            let
1233                fun messFn(name, _, line) =
1234                    errorNear (lex, true, v, line,
1235                        name ^ " has already been bound in this declaration");
1236         
1237                (* Construct an environment to check for duplicate declarations.
1238                   Include the declaration location as the value. *)
1239                val dupEnv = noDuplicates messFn;
1240  
1241                fun processException (ExBind {name, previous, ofType, value, nameLoc, ...}) =
1242                let
1243                    (* Fill in any types.  If there was no type given the exception has type exn
1244                       otherwise it has type ty->exn. *)
1245                    val oldType =
1246                        case ofType of
1247                            NONE => exnType
1248                        |   SOME typeof => mkFunctionType(ptAssignTypes(typeof, v), exnType)
1249                    val locations = [DeclaredAt nameLoc, SequenceNo (newBindingId lex)]
1250    
1251                    val exValue = 
1252                        case previous of 
1253                            EmptyTree => mkEx (name, oldType, locations) (* Generative binding. *)
1254                                
1255                        |   Ident {name = prevName, value = prevValue, location, expType, possible, ...} =>
1256                            let 
1257                                (* ex = ex' i.e. a non-generative binding? *)
1258                                (* Match up the previous exception. *)
1259                                val prev = 
1260                                    lookupValue 
1261                                        ("Exception",
1262                                            {lookupVal= #lookupVal env,
1263                                            lookupStruct= #lookupStruct env},
1264                                            prevName,
1265                                            giveError (v, lex, location))
1266                                val excType = valTypeOf prev
1267                            in
1268                                (* Check that it is an exception *)
1269                                case prev of
1270                                    Value{class=Exception, ...} => ()
1271                                |    _ => errorNear (lex, true, v, location, "(" ^ prevName ^ ") is not an exception.");
1272                                prevValue := prev; (* Set the value of the looked-up identifier. *)
1273                                expType := excType; (* And remember the type. *)
1274                                possible := #allValNames env;
1275                                (* The result is an exception with the same type. *)
1276                                mkEx (name, excType, locations)
1277                            end
1278                        | _ =>
1279                            raise InternalError "processException: badly-formed parse-tree"
1280                in
1281                    (* Save this value. *)
1282                    value := exValue;
1283        
1284                    (* In the check environment *)
1285                    #enter dupEnv (name, nameLoc);
1286        
1287                    (* Must not be qualified *)
1288                    checkForDots (name, lex, nameLoc) : unit;
1289                    (* Must not be "true", "false" etc. *)
1290                    checkForBuiltIn (name, v, lex, nameLoc, true) : unit;
1291        
1292                    (* Put this exception into the env *)
1293                    #enterVal env (name, exValue) 
1294                end
1295  
1296                val () = List.app processException tlist;
1297            in
1298                badType
1299            end (* ExDeclaration *)
1300        
1301          | Raise (pt, line) =>
1302            let
1303                val exType = assValues v pt
1304            in
1305                (* The exception value must have type exn. *)
1306                case unifyTypes(exType, exnType) of
1307                    NONE => ()
1308                |   SOME report =>
1309                        typeWrong("Exception to be raised must have type exn.",
1310                            valTypeMessage (lex, typeEnv) ("Raise:", pt, exType),
1311                            unifyErrorReport (lex, typeEnv) report, lex, line, foundNear v);
1312                (* Matches anything *)
1313                mkTypeVar (generalisable, false, false, false)
1314            end
1315  
1316        | (aHandler as HandleTree {exp, hrules, location, ...}) =>
1317            let
1318                (* If the expression returns type E
1319                 the handler must be exn -> E *)
1320                val expType = assValues aHandler exp;
1321                (* Unify the handler with a function from exn -> expType *)
1322                val clauses =
1323                    assignList(assMatchTree aHandler, displayMatch, matchTypeMessage)
1324                        ("Clauses in handler have different types.", "Clause", "|", location, aHandler) hrules
1325                (* The result type of the handlers must match the result type of the expression being
1326                   handled and the arguments must all have type exn. *)
1327                val () = 
1328                    unify (clauses, mkFunctionType (exnType, expType), lex, location, foundNear v, typeEnv);
1329            in
1330              expType (* Result is expType. *)
1331            end
1332
1333          | While {test, body, location, ...} =>
1334            let
1335                val testType = assValues v test
1336            in
1337                (* Test must be bool. Result is unit *)
1338                case unifyTypes(testType, boolType) of
1339                    NONE => ()
1340                |   SOME report =>
1341                        typeWrong("Loop condition of while-expression must have type bool.",
1342                            valTypeMessage (lex, typeEnv) ("While:", test, testType),
1343                            unifyErrorReport (lex, typeEnv) report, lex, location, foundNear v);
1344                assValues v body; (* Result of body is discarded. *)
1345                unitType
1346            end
1347
1348          | aCase as Case {test, match, location, expType, ...} =>
1349            let
1350                val funType =
1351                    assignList(assMatchTree aCase, displayMatch, matchTypeMessage)
1352                        ("Clauses in case have different types.", "Clause", "|", location, aCase) match;
1353                val argType = assValues aCase test;
1354                (* The matches constitute a function from the test type to
1355                   the result of the case statement, so we apply the match type
1356                   to the test. *)
1357                val resType = apply (funType, argType, lex, location, foundNear aCase, typeEnv)
1358            in
1359                expType := resType;
1360                resType
1361            end
1362
1363          | anAndAlso as Andalso {first, second, location} =>
1364            let
1365                (* Both parts must be bool and the result is bool. *)
1366                fun mkTupleTree(fields, location) = TupleTree { fields=fields, location=location, expType = ref EmptyType }
1367                val pairArgs = mkTupleTree([first, second], location)
1368                val argTypes  = assValues anAndAlso pairArgs;
1369                val boolStarBool = mkProductType[boolType, boolType]
1370                val () =
1371                    case unifyTypes(argTypes, boolStarBool) of
1372                        NONE => ()
1373                    |   SOME report =>
1374                            typeWrong("Arguments of andalso must have type bool*bool.",
1375                                valTypeMessage (lex, typeEnv) ("Arguments:", pairArgs, argTypes),
1376                                unifyErrorReport (lex, typeEnv) report, lex, location, foundNear anAndAlso)
1377            in
1378                boolType
1379            end
1380
1381          | anOrElse as Orelse {first, second, location} =>
1382            let
1383                (* Both parts must be bool and the result is bool. *)
1384                fun mkTupleTree(fields, location) = TupleTree { fields=fields, location=location, expType = ref EmptyType }
1385                val pairArgs = mkTupleTree([first, second], location)
1386                val argTypes  = assValues anOrElse pairArgs;
1387                val boolStarBool = mkProductType[boolType, boolType]
1388                val () =
1389                    case unifyTypes(argTypes, boolStarBool) of
1390                        NONE => ()
1391                    |   SOME report =>
1392                            typeWrong("Arguments of orelse must have type bool*bool.",
1393                                valTypeMessage (lex, typeEnv) ("Arguments:", pairArgs, argTypes),
1394                                unifyErrorReport (lex, typeEnv) report, lex, location, foundNear anOrElse)
1395            in
1396                boolType
1397            end
1398
1399          | Directive { tlist, fix, ... } => 
1400                  (
1401                (* Infix declarations have already been processed by the parser.  We include
1402                   them here merely so that we get all declarations in the correct order. *)
1403                List.app (fn name => #enterFix env (name, FixStatus(name, fix))) tlist;
1404                badType
1405                )
1406
1407          | WildCard _ => (* Should never occur in an expression. *)
1408                  raise InternalError "assignTypes: wildcard found"
1409
1410          | Layered _ => 
1411                  raise InternalError "assignTypes: layered pattern found"
1412
1413          | EmptyTree => 
1414                  raise InternalError "assignTypes: emptytree found"
1415
1416          | Parenthesised(p, _) => assValues near p
1417                
1418            (* end of assValues *)
1419
1420          and assMatchTree _ (MatchTree {vars, exp, resType, argType, ...}) =
1421            let 
1422              (* A match is a function from the pattern to the expression *)
1423              
1424              (* Process the pattern looking for variables. *)
1425        
1426               (* Construct a new environment for the variables. *)
1427              fun messFn(name, _, Value{locations, ...}) =  
1428                    errorNear (lex, true, v, declaredAt locations,
1429                        name ^ " has already been bound in this match");
1430              
1431              val newEnv   = noDuplicates messFn;
1432              val newLevel = level + 1;
1433              val decs     = processPattern(vars, #enter newEnv, newLevel, false, mkPattVar, false)
1434        
1435              (* The identifiers declared in the pattern are available in the
1436                 body of the function. *)
1437              val bodyEnv =
1438                {
1439                  lookupVal     = lookupDefault (#lookup newEnv) (#lookupVal env),
1440                  lookupType    = #lookupType env,
1441                  lookupFix     = #lookupFix env,
1442                  lookupStruct  = #lookupStruct env,
1443                  lookupSig     = #lookupSig env,
1444                  lookupFunct   = #lookupFunct env,
1445                  lookupTvars   = #lookupTvars env,
1446                  enterVal      = #enterVal env,
1447                  enterType     = #enterType env,
1448                  enterFix      = #enterFix env,
1449                  enterStruct   = #enterStruct env,
1450                  enterSig      = #enterSig env,
1451                  enterFunct    = #enterFunct env,
1452                  allValNames   =
1453                    fn () => (stringsOfSearchList newEnv () @ #allValNames env ())
1454                };
1455        
1456              (* Now the body. *)
1457              val expType = assignValues(newLevel, letDepth, bodyEnv, v, exp);
1458            in
1459              resType := expType;
1460              argType := decs;
1461              (* Result is a function from the type of the pattern to the type
1462                 of the body. This previously generalised the resulting type. Why? *)
1463              mkFunctionType (decs, expType)
1464            end (* MatchTree *)
1465
1466        and assValDeclaration (valdecs: valbind list, explicit, implicit) =
1467        (* assignTypes for a val-declaration. *)
1468        let
1469            val newLevel = level + 1;
1470      
1471            (* Set the scope of explicit type variables. *)
1472            val () = #apply explicit(fn (_, tv) => setTvarLevel (tv, newLevel));
1473
1474            (* For each implicit type variable associated with this value declaration,
1475               link it to any type variable with the same name in an outer
1476               scope. *)
1477            val () = 
1478                #apply implicit
1479                    (fn (name, tv) =>
1480                        case #lookupTvars env name of SOME v => linkTypeVars(v, tv) | NONE => setTvarLevel (tv, newLevel));
1481            (* If it isn't there set the level of the type variable. *)
1482
1483            (* Construct a new environment for the variables. *)
1484            val newEnv =
1485                noDuplicates
1486                (fn(name, _, Value{locations, ...}) =>
1487                    errorNear (lex, true, v, declaredAt locations,
1488                        name ^ " has already been bound in this declaration"));
1489
1490            (* This environment is those identifiers declared by recursive bindings *)
1491            val recEnv = searchList ();
1492
1493            (* If this is a recursive declaration we will have to find all
1494               the variables declared by the patterns in each binding before
1495               we can look at the bodies of the bindings. For simplicity we
1496               process the patterns first even if this is not recursive but
1497               arrange for the variables to be added to the environment
1498               after rather than before processing the bodies. The result of
1499               processing the patterns is a list of their types. Each item
1500               in the list must be unified with the type of the
1501               corresponding body. *)
1502
1503            (* Process the patterns. *)
1504            local
1505                fun doVal (ValBind {dec, isRecursive, variables, ...}) =
1506                    let
1507                        fun enterVals(pair as (_, value)) =
1508                        (
1509                            #enter newEnv pair;
1510                            if isRecursive then #enter recEnv pair else ();
1511                            variables := value :: ! variables
1512                        )
1513
1514                        val patType =
1515                            processPattern(dec, enterVals, newLevel, false, mkValVar, isRecursive);
1516                    in
1517                        patType
1518                    end;
1519                
1520            in
1521                val decs = List.map doVal (valdecs)
1522            end
1523
1524            (* Now the bodies. *)
1525            local
1526                (* Check that the types match by going down the list of value
1527                   bindings and the list of types produced from the patterns,
1528                   and matching corresponding types. *)
1529                fun checkTypes (patType, (ValBind {dec, exp, line, isRecursive, ...})) =
1530                    let
1531                        val newEnv =
1532                        { (* If this is recursive we find the recursive names
1533                             and others in the surrounding scope. *)
1534                            lookupVal     = 
1535                                if isRecursive
1536                                then lookupDefault (#lookup recEnv) (#lookupVal env)
1537                                else #lookupVal env,
1538                            lookupType    = #lookupType env,
1539                            lookupFix     = #lookupFix env,
1540                            lookupStruct  = #lookupStruct env,
1541                            lookupSig     = #lookupSig env,
1542                            lookupFunct   = #lookupFunct env,
1543                            (* Extend the environment of type variables. *)
1544                            lookupTvars   =
1545                                lookupDefault (#lookup explicit)
1546                                    (lookupDefault (#lookup implicit) (#lookupTvars env)),
1547                            enterVal      = #enterVal env,
1548                            enterType     = #enterType env,
1549                            enterFix      = #enterFix env,
1550                            enterStruct   = #enterStruct env,
1551                            enterSig      = #enterSig env,
1552                            enterFunct    = #enterFunct env,
1553                            allValNames   =
1554                                if isRecursive
1555                                then fn () => (stringsOfSearchList recEnv () @ #allValNames env ())
1556                                else #allValNames env
1557                        }
1558
1559                        val expType = assignValues(newLevel, letDepth, newEnv, exp, exp);
1560            
1561                        val () =
1562                            case unifyTypes(patType, expType) of
1563                                NONE => () (* OK*)
1564                            |   SOME report =>
1565                                    typeMismatch("Pattern and expression have incompatible types.",
1566                                        valTypeMessage (lex, typeEnv) ("Pattern:", dec, patType),
1567                                        valTypeMessage (lex, typeEnv) ("Expression:", exp, expType),
1568                                        unifyErrorReport (lex, typeEnv) report, lex, line, foundNear v)
1569        
1570                        (* true if the expression is a possibly-constrained fn-expression.
1571                           It isn't clear whether a parenthesised expression is allowed here.
1572                           As often, the definition is informal.  On p8 of the ML97
1573                           definition it says "exp must be of the form fn match".  In ML90
1574                           it added "possibly constrained by one or more type expressions".
1575                           This is such a mess that I'm allowing both contraints and parentheses
1576                           here. *)
1577                        fun isConstrainedFn (Constraint {value, ...}) = isConstrainedFn value
1578                        |   isConstrainedFn (Fn _)  = true
1579                        |   isConstrainedFn (Parenthesised(p, _)) = isConstrainedFn p
1580                        |   isConstrainedFn _       = false;
1581                    in
1582                        (* Must check that the expression is of the form FN match. *)
1583                        (* N.B. the code generator assumes this is true. *)
1584                        if isRecursive andalso not (isConstrainedFn exp)
1585                        then errorNear (lex, true, v, line, 
1586                            "Recursive declaration is not of the form `fn match'")
1587                        else ()
1588                    end
1589            in
1590                val () = ListPair.app checkTypes (decs, valdecs)
1591            end
1592
1593            (* Now allow generalisation on the variables being declared.
1594               For imperative type variables we have to know whether the
1595               expression is expansive. *)
1596            fun allowGen (d, (ValBind {exp, line, ...})) =
1597                (
1598                    allowGeneralisation 
1599                        (d, newLevel, nonExpansive exp, lex, line, foundNear v, typeEnv)
1600                ) (* allowGen *)
1601        in
1602            ListPair.appEq allowGen (decs, valdecs);
1603            (* And declare the new names into the surrounding environment. *)
1604            let
1605                fun enterDec(s, v as Value{instanceTypes, ...}) =
1606                (
1607                    valOf instanceTypes := []; (* Remove any recursive references. *)
1608                    #enterVal env (s, v)
1609                )
1610            in
1611                #apply newEnv enterDec
1612            end
1613        end (* assValDeclaration *)
1614
1615        and assFunDeclaration {dec=tlist: fvalbind list, explicit, implicit, ...} =
1616        (* Assigntypes for a fun-declaration. *)
1617        let
1618            val funLevel = level + 1; (* Level for function names. *)
1619      
1620            (* Set the scope of explicit type variables. *)
1621            val () =
1622                #apply explicit(fn (_, tv) => setTvarLevel (tv, funLevel));
1623
1624            (* For each implicit type variable associated with this value declaration,
1625               link it to any type variable with the same name in an outer
1626               scope. *)
1627            val () = 
1628                #apply implicit
1629                  (fn (name, tv) =>
1630                      case #lookupTvars env name of SOME v => linkTypeVars(v, tv) | NONE => setTvarLevel (tv, funLevel));
1631            (* If it isn't there set the level of the type variable. *)
1632
1633            (* Construct a new environment for the variables. *)
1634            fun msgFn(name, _, Value{locations, ...}) = 
1635                errorNear (lex, true, v, declaredAt locations,
1636                    name ^ " has already been bound in this declaration");
1637           
1638            val newEnv = noDuplicates msgFn;
1639           
1640            (* Since this is a recursive declaration we must get the function
1641               names first. Because of the way they are parsed they are hidden
1642               as applications of the function to one or more patterns. There
1643               may be more than one clause in a function binding but each
1644               should declare the same function and have the same number of
1645               patterns. We need to know the number of patterns and the
1646               function name in the third pass so we save them in the
1647               function binding. *)
1648
1649            local
1650                fun findNameAndPatts (FValBind {clauses = (FValClause {dec, line, ...}::_), numOfPatts, functVar, ...}) =
1651                let
1652                    (* Just look at the first clause for the moment. *)
1653                    val { ident = { name, location, ... }, ... } = dec;
1654                    (* Declare a new identifier with this name. *)
1655                    val locations = [DeclaredAt location, SequenceNo (newBindingId lex)]
1656                    val funVar =
1657                        mkValVar (name, mkTypeVar (funLevel, false, false, false), locations)
1658
1659                    val arity = case dec of { args, ...} => List.length args
1660                    val () = numOfPatts := arity;
1661                    val () =
1662                        (* Put the results onto the function binding. *)
1663                        if arity = 0
1664                        then errorNear (lex, true, v, line,
1665                                "Clausal function does not have any parameters.")
1666                        else ()
1667                in
1668                    (* Must not be qualified *)
1669                    checkForDots (name, lex, line);
1670                    (* Must not be "true", "false" etc. but may be "it" *)
1671                    checkForBuiltIn (name, v, lex, line, false);
1672                    functVar := funVar; (* Save the variable. *)
1673                    (* Enter it in the environment. *)
1674                    #enter newEnv (name, funVar)
1675                end
1676                |   findNameAndPatts _ = raise InternalError "findNameAndPatts: badly-formed parse-tree";
1677
1678            in
1679                val () = List.app findNameAndPatts tlist
1680            end;
1681
1682            local
1683                (* Can now process the clausal functions in the environment 
1684                   of the function names and using the information about
1685                   function name and number of patterns we have saved. *)
1686                fun processBinding
1687                    (fvalBind as FValBind {clauses, functVar=ref functVar, argType, resultType, location, ...}) =
1688                let
1689                    (* Each fun binding in the declaration may consist of several
1690                       clauses. Each must have the same function name, the same
1691                       number of patterns and a unifiable type. *)
1692                    (* The type information is built up from the bottom so that if there are
1693                       errors we can report them in the most appropriate place.
1694                       Build a type to be used for the function.  This will later be unified
1695                       with the type that we've already created for the function variable. *)
1696                    val funType = mkTypeVar(generalisable, false, false, false)
1697
1698                    fun processClause (clause as FValClause {dec, exp, line, ...}) =
1699                    let
1700                        val { ident = ident, args, constraint, ... } = dec
1701
1702                        fun mkClausal(clauses, location) : fvalbind =
1703                           FValBind
1704                             { 
1705                               clauses    = clauses,
1706                               numOfPatts = ref 0,
1707                               functVar   = ref undefinedValue,
1708                               argType    = ref badType,
1709                               resultType = ref badType,
1710                               location   = location
1711                             }
1712    
1713                        fun mkFunDeclaration (dec, explicit, implicit, location) : parsetree =
1714                          FunDeclaration
1715                            {
1716                                dec=dec,
1717                                explicit = explicit,
1718                                implicit = implicit,
1719                                location = location
1720                            }
1721
1722                        val clauseAsTree: parsetree =
1723                            (* This clause as a parsetree object for error messages. *)
1724                            mkFunDeclaration([mkClausal([clause], line)], explicit, implicit, line)
1725                        
1726                        val () = (* Set the type.  Only in case we look at the export tree. *)
1727                            #expType ident := valTypeOf functVar
1728
1729                        fun messFn (name, _, Value{locations, ...}) =
1730                            errorNear (lex, true, clauseAsTree, declaredAt locations,
1731                                name ^ " has already been bound in this clause.");
1732                        (* Construct a new environment for the variables in the patts. *)
1733                        val varEnv = noDuplicates messFn;
1734                        val varLevel = funLevel + 1; (* Level for variables. *)
1735
1736                        (* Process the patterns. *)
1737                        val argTypeList =
1738                            List.map (fn arg =>
1739                                        processPattern(arg, #enter varEnv, varLevel, false, mkPattVar, false))
1740                                args
1741                        (* This list is used for the type of the helper function. *)
1742                        val () = argType :=
1743                            (case argTypeList of
1744                                [] => badType (* error *)
1745                            |   [single] => single
1746                            |   multiple => mkProductType multiple)
1747
1748                        (* The identifiers declared in the pattern are available in the
1749                           body of the function. Since it is recursive the function
1750                           names are also available. *)
1751                        val bodyEnv =
1752                        { 
1753                            lookupVal     = 
1754                                lookupDefault (#lookup varEnv)
1755                                    (lookupDefault (#lookup newEnv) (#lookupVal env)),
1756                            lookupType    = #lookupType env,
1757                            lookupFix     = #lookupFix env,
1758                            lookupStruct  = #lookupStruct env,
1759                            lookupSig     = #lookupSig env,
1760                            lookupFunct   = #lookupFunct env,
1761                            (* Extend the environment of type variables. *)
1762                            lookupTvars   =
1763                                lookupDefault (#lookup explicit)
1764                                    (lookupDefault (#lookup implicit) (#lookupTvars env)),
1765                            enterVal      = #enterVal env,
1766                            enterType     = #enterType env,
1767                            enterFix      = #enterFix env,
1768                            enterStruct   = #enterStruct env,
1769                            enterSig      = #enterSig env,
1770                            enterFunct    = #enterFunct env,
1771                            allValNames   =
1772                                fn () => (stringsOfSearchList varEnv () @
1773                                          stringsOfSearchList newEnv () @ #allValNames env ())
1774                        };
1775           
1776                        (* Now the body. *)
1777                        val expTyp = assignValues(varLevel, letDepth, bodyEnv, exp, exp);
1778                        (* Check the expression type against any explicit type constraint. *)
1779                        (* Return the explicit constraint if possible.  For the purposes of
1780                           type checking this is identical to "expTyp" but if there is a
1781                           type abbreviation this will be used when printing the result.
1782                           .e.g type t = int * int; fun f ((x, y):t): t = (y, x); *)
1783                        val typeOfBody =
1784                            case constraint of
1785                                NONE => expTyp
1786                            |   SOME given =>
1787                                let
1788                                    val theType = ptAssignTypes(given, v)
1789                                in
1790                                    case unifyTypes(expTyp, theType) of
1791                                        NONE => () (* OK. *)
1792                                    |   SOME report =>
1793                                            typeMismatch("Body of fun binding does not match type constraint.",
1794                                                valTypeMessage (lex, typeEnv) ("Expression:", exp, expTyp),
1795                                                PrettyBlock(0, false, [],
1796                                                    [
1797                                                        PrettyString "Constraint:",
1798                                                        PrettyBreak(1, 0),
1799                                                        display(theType, 10000 (* All *), typeEnv)
1800                                                    ]),
1801                                                unifyErrorReport (lex, typeEnv) report,
1802                                                lex, line, foundNear clauseAsTree);
1803                                    theType
1804                                end
1805                        (* Remember the result type for the debugger. Actually this
1806                           assigns the result type for each clause in the fun but
1807                           they'll all be the same. *)
1808                        val () = resultType := typeOfBody
1809                        (* The type of this clause is a function type. *)
1810                        val clauseType = List.foldr mkFunctionType typeOfBody argTypeList
1811                        (* Unify this with the type we're using for the other clauses. *)
1812                        val () =
1813                            case unifyTypes(clauseType, funType) of
1814                                NONE => () (* OK. *)
1815                            |   SOME report =>
1816                                    typeMismatch("Type of clause does not match the type of previous clauses.",
1817                                        valTypeMessage (lex, typeEnv) ("Clause:", clauseAsTree, clauseType),
1818                                        PrettyBlock(0, false, [],
1819                                            [
1820                                                PrettyString "Other clauses:",
1821                                                PrettyBreak(1, 0),
1822                                                display(funType, 10000 (* All *), typeEnv)
1823                                            ]),
1824                                        unifyErrorReport (lex, typeEnv) report,
1825                                        lex, line, foundNear clauseAsTree)
1826                    in (* body of processClause *)
1827                        ()
1828                    end
1829                in (* body of processFun *)
1830                    List.app processClause clauses;
1831                    (* If this function makes any recursive references move those references from the
1832                       local list to the recursive list.  In that way if we're looking for whether a
1833                       function is actually referenced we'll only include it if it's referenced outside
1834                       or from another referenced function. *)
1835                    let
1836                        fun moveRefs(FValBind{functVar=ref(Value{references,...}), ...}) =
1837                        let
1838                            val {localRef as ref locals, recursiveRef, ...} = valOf references
1839                            val callerName = valName functVar (* Name of referring function. *)
1840                        in
1841                            recursiveRef := List.map (fn r => (r, callerName)) locals @ !recursiveRef;
1842                            localRef := []
1843                        end
1844                    in
1845                        List.app moveRefs tlist
1846                    end;
1847                    (* Finally unify the function type with the type of the function variable.  If the
1848                       variable has not yet been used that will simply set its type but if it has been
1849                       used recursively it may have been given an incompatible type. *)
1850                    case unifyTypes(funType, valTypeOf functVar) of
1851                        NONE => () (* OK. *)
1852                    |   SOME report =>
1853                        let
1854                            fun mkFunDeclaration (dec, explicit, implicit, location) : parsetree =
1855                              FunDeclaration
1856                                {
1857                                    dec=dec,
1858                                    explicit = explicit,
1859                                    implicit = implicit,
1860                                    location = location
1861                                }
1862
1863                            fun mkIdent (name, loc) : parsetree = 
1864                              Ident
1865                                {
1866                                  name   = name,
1867                                  expType = ref EmptyType,
1868                                  value  = ref undefinedValue,
1869                                  location = loc,
1870                                  possible = ref(fn () => [])
1871                                }
1872 
1873                            val fvalAsTree = mkFunDeclaration([fvalBind], explicit, implicit, location)
1874                        in
1875                            typeMismatch("Type of function does not match type of recursive application.",
1876                                valTypeMessage (lex, typeEnv) ("Function:", fvalAsTree, funType),
1877                                valTypeMessage (lex, typeEnv)
1878                                    ("Variable:", mkIdent(valName functVar, location), valTypeOf functVar),
1879                                unifyErrorReport (lex, typeEnv) report,
1880                                lex, location, foundNear fvalAsTree)
1881                        end
1882                end
1883            in
1884                val () = List.app processBinding tlist
1885            end;
1886
1887        in
1888            (* Now declare the new names into the surrounding environment,
1889               releasing the copy flags on the type variables. All fun
1890               bindings are non-expansive. *)
1891            List.app
1892                (fn(FValBind{
1893                    functVar as ref(var as Value{typeOf, locations, name, instanceTypes, ...}), ...}) =>
1894                (
1895                    (* Generalise the types.  allowGeneralisation side-effects the type variables,
1896                       replaces any that can be generalised by general variables. *)
1897                    allowGeneralisation(typeOf, funLevel, true, lex, declaredAt locations, foundNear v, typeEnv);
1898                    (* Remove any recursive references.  This really isn't right. *)
1899                    valOf instanceTypes := [];
1900                    #enterVal env (name, var);
1901                    functVar := var
1902                )) tlist
1903        end (* assFunDeclaration *)
1904
1905        and assAbsData({typelist=typeList, withtypes, declist, equalityStatus, isAbsType=isAbs, ...}) =
1906        let
1907            (* A type declaration causes a type to be entered in the type
1908               environment, together with some constructors. *)
1909            fun messFn (name, _, TypeConstrSet(new, _)) = 
1910                errorNear (lex, true, v, declaredAt(tcLocations new),
1911                   name ^ " has already been bound in this declaration");
1912
1913            val localTypeEnv = noDuplicates messFn;
1914      
1915            (* datatype and abstype declarations are both recursive so we can
1916               enter the type names into the environment during a first pass,
1917               and then process the value constructors during a second. *)
1918            fun enterType(typeConstr, typeName) =
1919            (
1920                checkForDots  (typeName, lex, declaredAt(tcLocations(tsConstr typeConstr))); (* Must not be qualified *)
1921                #enter localTypeEnv (typeName, typeConstr) (* Check for duplicates. *)
1922            );
1923       
1924            (* Make the type constructors and put them in a list. *)
1925            fun enterTcon (DatatypeBind {name, tcon, typeVars, nameLoc, ...}) =
1926            let
1927                (* Make a new ID.  If this is within a let declaration we always make
1928                   a free ID because it is purely local and can't be exported. *)
1929                val description = { location = nameLoc, name = name, description = "" }
1930                val arity = length typeVars
1931            
1932                val newId =
1933                    if letDepth = 0
1934                    then makeTypeId(false, true, (typeVars, EmptyType), description)
1935                    else makeFreeIdEqUpdate (arity, Local{addr = ref ~1, level = ref baseLevel}, false, description)
1936                val locations = [DeclaredAt nameLoc, SequenceNo (newBindingId lex)]
1937                val tc = makeTypeConstructor(name, typeVars, newId, locations)
1938            in
1939                tcon := TypeConstrSet(tc, []);
1940                enterType(TypeConstrSet(tc, []), name);
1941                tc
1942            end
1943      
1944            val listOfTypes = map enterTcon typeList;
1945
1946            local
1947                fun lookup(s, line) =
1948                    lookupTyp 
1949                        ({lookupType = lookupDefault(#lookup localTypeEnv) (#lookupType env),
1950                            lookupStruct = #lookupStruct env},
1951                        s, giveError (v, lex, line))
1952            in
1953                fun localAssignTypes decType = assignTypes (decType, lookup, lex)
1954            end
1955
1956            (* First match all the types on the right-hand sides using the
1957               datatypes and the existing bindings. *)
1958            local
1959                fun processType (TypeBind {decType = SOME decType, ...}) = localAssignTypes decType
1960                |   processType _ = emptyType
1961            in
1962                val decTypes = List.map processType withtypes
1963            end;
1964
1965            (* Can now enter the `withtypes'. *)
1966            fun enterWithType (TypeBind {name, typeVars, nameLoc, tcon=tcRef, ...}, decType) =
1967            let
1968                val description = { location = nameLoc, name = name, description = "" }
1969                (* Construct a type constructor which is an alias of the
1970                   right-hand side of the declaration. *)
1971                val locations = [DeclaredAt nameLoc, SequenceNo (newBindingId lex)]
1972                val tcon =
1973                    makeTypeConstructor (name, typeVars,
1974                        makeTypeId(false, false, (typeVars, decType), description), locations)
1975                val tset = TypeConstrSet(tcon, [])
1976            in
1977                tcRef := tset;
1978                enterType(tset, name); (* Checks for duplicates. *)
1979                #enterType env (name, tset) (* Put in the global environment. *)
1980            end
1981
1982            val () = ListPair.app enterWithType (withtypes, decTypes);
1983        
1984            (* For the constructors *)
1985            fun messFn (name, _, Value{locations, ...}) =
1986                errorNear (lex, true, v, declaredAt locations,
1987                    name ^ " has already been used as a constructor in this type");
1988      
1989            val consEnv = noDuplicates messFn;
1990            val abstypeEnv = searchList ();
1991    
1992            (* Now process the types and generate the constructors. *)
1993            fun genValueConstrs (DatatypeBind {name, typeVars, constrs, nameLoc, tcon, ...}, typ) =
1994            let
1995                val numOfConstrs = length constrs;
1996                val typeVarsAsTypes = List.map TypeVar typeVars
1997        
1998                (* The new constructor applied to the type variables (if any) *)
1999                val locations = [DeclaredAt nameLoc, SequenceNo (newBindingId lex)]
2000                val resultType = mkTypeConstruction (name, typ, typeVarsAsTypes, locations)
2001
2002                (* Sort the constructors by name.  This simplifies matching with
2003                   datatypes in signatures. *)
2004                fun leq {constrName=xname: string, ...} {constrName=yname, ...} = xname < yname;
2005                val sortedConstrs = quickSort leq constrs;
2006
2007                fun processConstr ({constrName=name, constrArg, idLocn, constrVal, ...}) =
2008                let
2009                    val (constrType, isNullary) =
2010                        case constrArg of
2011                            NONE => (resultType, true)
2012                        |   SOME argtype =>
2013                                (mkFunctionType (localAssignTypes argtype, resultType), false)
2014                    val locations = [DeclaredAt idLocn, SequenceNo (newBindingId lex)]
2015                    val cons =
2016                        makeValueConstr (name, constrType, isNullary, numOfConstrs, Local{addr = ref ~1, level = ref baseLevel},
2017                                         locations)
2018        
2019                    (* Name must not be qualified *)
2020                    val () = checkForDots (name, lex, idLocn);
2021                    (* Must not be "true", "false" etc. *)
2022                    val () = checkForBuiltIn (name, v, lex, idLocn, true) : unit;
2023          
2024                    (* Put into the environment. *)
2025                    val () = #enter consEnv (name, cons)
2026                    
2027                    (* Link it in case we export the tree. *)
2028                    val () = constrVal := cons
2029                in    
2030                    cons
2031                end (* processConstr *)
2032                val tset = TypeConstrSet (typ, List.map processConstr sortedConstrs)
2033            in
2034                (* If this is an abstype enter the version with the constructors into
2035                   a local environment and a version without the constructors into the
2036                   global environment.  If it is a datatype enter the version with
2037                   constructors in the global environment. *)
2038                if isAbs
2039                then (#enter abstypeEnv (name, tset); #enterType env (name, TypeConstrSet(typ, [])))
2040                else #enterType env (name, tset);
2041                tcon := tset;
2042                tset
2043            end (* genValueConstrs *)
2044      
2045            val listOfTypeSets = ListPair.map genValueConstrs (typeList, listOfTypes);
2046
2047            (* Third pass - Check to see if equality testing is allowed for
2048               these types. *)
2049            val () = computeDatatypeEqualities(listOfTypeSets, sigTypeIdMap);
2050
2051            (* If this is a datatype declaration the value constructors should be
2052               entered in the surrounding scope, otherwise (abstract type
2053               declaration) we evaluate the declarations in an environment
2054               containing the value constructors, but the value constructors
2055               themselves do not appear in the surrounding scope. *)
2056            val () =
2057                if not isAbs
2058                then #apply consEnv (#enterVal env)
2059                else
2060                let   (* Abstract type *)
2061                    (* The declarations have to be evaluated in an environment in
2062                       which the constructors have been declared. When an identifier
2063                       is looked up it may:
2064                       (a) be one of these new declarations, or else
2065                       (b) be a constructor from the type declarations, or else
2066                       (c) be outside the abstract type declaration.
2067                       New declarations are entered in the local environment so that
2068                       they can be found under (a) and in the surrounding environment
2069                       where they will be available after this declaration. *)
2070                    val decEnv =
2071                    let
2072                        val localEnv = searchList ();
2073                        fun enterValFn pair = (#enter localEnv pair; #enterVal env pair);
2074                        val lookupValFn = 
2075                            lookupDefault (#lookup localEnv)
2076                                (lookupDefault (#lookup consEnv) (#lookupVal env))
2077                        fun allValNames () = (stringsOfSearchList localEnv () @ stringsOfSearchList consEnv () @ #allValNames env ())
2078                        (* We also have to do something similar with types.  This is really
2079                           only for perverse cases where there is a datatype replication
2080                           inside the abstype. *)
2081                        fun enterTypeFn pair = (#enter abstypeEnv pair; #enterType env pair);
2082                        val lookupTypeFn = 
2083                            lookupDefault (#lookup abstypeEnv) (#lookupType env)
2084                    in
2085                        { 
2086                            lookupVal     = lookupValFn,
2087                            lookupType    = lookupTypeFn,
2088                            lookupFix     = #lookupFix env,
2089                            lookupStruct  = #lookupStruct env,
2090                            lookupSig     = #lookupSig env,
2091                            lookupFunct   = #lookupFunct env,
2092                            lookupTvars   = #lookupTvars env,
2093                            enterVal      = enterValFn,
2094                            enterType     = enterTypeFn,
2095                            enterFix      = #enterFix env,
2096                            enterStruct   = #enterStruct env,
2097                            enterSig      = #enterSig env,
2098                            enterFunct    = #enterFunct env,
2099                            allValNames   = allValNames
2100                        }
2101                    end;
2102  
2103                in
2104                    (* Process the declarations, discarding the result. *)
2105                    assignSeq (decEnv, letDepth, declist, false);
2106                    (* Turn off equality outside the with..end block.  This is required by the
2107                       "Abs" function defined in section 4.9 of the ML Definition.
2108                       We need to record the equality status, though, because we need
2109                       to reinstate this for code-generation. *)
2110                    equalityStatus := List.map tcEquality listOfTypes;
2111                    List.app(fn tc => tcSetEquality (tc, false)) listOfTypes;
2112                    ()
2113                end;
2114        in
2115            badType (* Does not return a type *)
2116        end (* assAbsData *)
2117    in 
2118        assValues near v
2119    end (* assignValues *);
2120
2121      val Env gEnv = env
2122      
2123      val env = 
2124          {
2125            lookupVal     = #lookupVal gEnv,
2126            lookupType    = #lookupType gEnv,
2127            lookupFix     = #lookupFix gEnv,
2128            lookupStruct  = #lookupStruct gEnv,
2129            lookupSig     = #lookupSig gEnv,
2130            lookupFunct   = #lookupFunct gEnv,
2131            lookupTvars   = fn _ => NONE,
2132            enterVal      = #enterVal gEnv,
2133            enterType     = #enterType gEnv,
2134            enterFix      = #enterFix gEnv,
2135            enterStruct   = #enterStruct gEnv,
2136            enterSig      = #enterSig gEnv,
2137            enterFunct    = #enterFunct gEnv,
2138            allValNames   = #allValNames gEnv
2139          };
2140    in
2141      assignValues(1, 0, env, v, v)
2142    end (* pass2 *);
2143
2144    (* Before code-generation perform an extra pass through the tree to remove
2145       unnecessary polymorphism.  The type-checking computes a most general
2146       type for a value, typically a function, but it is frequently used in
2147       situations where a less general type would suffice. *)
2148    (* Note: if the less general type involves a local datatype this isn't
2149       done to avoid a possible bug with datatypes defined after the
2150       function. *)
2151    fun setLeastGeneralTypes(p: parsetree, _: lexan) =
2152    let
2153        (* Because of mutual recursion we need to process the set of variables
2154           produced by a fun-declaration or a val rec declaration as a group.
2155           We also process no-recursive val bindings here for simplicity.  *)
2156        fun processVariableSet(variables: values list) =
2157        let
2158            (* Two polymorphic values that are involved in mutual recursion will have
2159               the same type variable in both values.  When we produce the least
2160               general type we have to consider all the types that may be used for
2161               those variables. Unfortunately, because of flexible records we need
2162               to repeat the unification we did in the previous pass. *)
2163            local
2164                fun getTypeVarsAndInstance (Value{typeOf, instanceTypes, ...}, vars) =
2165                let
2166                    val instances = ! (valOf instanceTypes)
2167                    fun getPolyVars typ =
2168                    let
2169                        val (copied, tyVars) = generalise typeOf
2170                        (* Unify the types.  If there's an error we return a fresh set of the type
2171                           variables which gives the most general type.
2172                           There shouldn't be an error but there is one
2173                           circumstance at least where we can get an error here.  If we have a functor
2174                           declaration followed by an application of the functor in the same "program"
2175                           we can set an entry in instanceTypes of a Value used in the functor declaration
2176                           to an instance in the functor application because the instanceTypes value is
2177                           inherited into the functor signature if there's no explicit signature.
2178                           We really need to handle this properly and not inherit the instanceTypes
2179                           value in that case.  Test116 shows this. *)
2180                    in
2181                        if isSome(unifyTypes(copied, typ))
2182                        then #2 (generalise typeOf)
2183                        else tyVars (* Return the type vars instantiated to the instance types. *)
2184                    end
2185                    (* This returns a list, one entry for each instance, of a list of the
2186                       type variables for that instance. *)
2187                    val instanceVarLists = List.map getPolyVars instances
2188                    (* Transpose that list so we get a list, one entry for each type variable,
2189                       of all the instance types that are possible. *)
2190                    fun transpose ([]::_) = []
2191                    |   transpose (args as _::_) = (List.map hd args) :: transpose (List.map tl args)
2192                    |   transpose [] = []
2193                    val instanceVars = transpose instanceVarLists
2194                    (* Get the original type variables. *)
2195                    val originalVars = getPolyTypeVars(typeOf, fn _ => NONE)
2196                    (* Look to see if we already have some of the original vars in the list.
2197                       If we have we use the same ref for each var and merge the instance types. *)
2198                    fun mergeVars(ovar, iTypes) =
2199                        case List.find (fn (tv, _) => sameTv(tv, ovar)) vars of
2200                            NONE => (ovar, ref iTypes)
2201                        |   SOME(matched as (_, otherRef)) =>
2202                                ( otherRef := iTypes @ ! otherRef; matched)
2203                    val mergedList = ListPair.map mergeVars (originalVars, instanceVars) @ vars
2204                in
2205                    mergedList
2206                end
2207            in
2208                (* Get a list of the original type variables each with a reference containing
2209                   the shared list of instance types. *)
2210                val typeVarMap = List.foldl getTypeVarsAndInstance [] variables
2211            end
2212            local
2213                fun reduceTypes(tv, ref types) =
2214                    (* Although tv is a type variable it could occur as the least general type.
2215                       Unify takes care of that. *)
2216                    if isSome(unifyTypes(TypeVar tv, leastGeneral(List.map #value types)))
2217                    then raise InternalError "reduceTypes: Unable to set type vars"
2218                    else ()
2219            in
2220                val () = List.app reduceTypes typeVarMap
2221            end
2222        in
2223            ()
2224        end
2225
2226        fun leastGenExp(ValDeclaration{dec, ...}) =
2227            (
2228                (* Val declarations may be recursive or non-recursive.  In the case of
2229                   recursive declarations we need to handle these in the same way as
2230                   fun-declarations. *)
2231                (* Gather all the variables and process them as a group.  There can't be
2232                   any dependencies between them except for mutual recursion. *)
2233                processVariableSet
2234                        (List.foldl (fn (ValBind{variables=ref variables, ...}, vars) => variables @ vars) [] dec);
2235                List.app (fn ValBind{exp, ...} => leastGenExp exp) dec
2236            )
2237
2238        |   leastGenExp(FunDeclaration{dec, ...}) =
2239            (
2240                (* First process the outer declarations. *)
2241                processVariableSet(List.map(fn FValBind{functVar=ref var, ...} => var) dec);
2242                (* Then process the inner declarations.  Setting the outer type may have set the
2243                   instance types within the bodies. *)
2244                let
2245                    fun processClause(FValClause{exp, ...}) = leastGenExp exp
2246                    fun processBind(FValBind{clauses, ...}) = List.app processClause clauses
2247                in
2248                    List.app processBind dec
2249                end
2250            )
2251
2252        |   leastGenExp(Localdec{decs, body, ...}) =
2253            (
2254                (* Process the body expressions in order but the declarations must be done in
2255                   reverse order after the body. *)
2256                List.app (leastGenExp o #1) body;
2257                List.foldr (fn ((p, _), ()) => leastGenExp p) () decs
2258            )
2259
2260        |   leastGenExp(AbsDatatypeDeclaration { declist, ... }) =
2261                (* Declarations in reverse order *)
2262                List.foldr (fn ((p, _), ()) => leastGenExp p) () declist
2263
2264            (* All the rest of these just involve processing sub-expressions. *)
2265        |   leastGenExp(Applic{f, arg, ...}) = (leastGenExp f; leastGenExp arg)
2266
2267        |   leastGenExp(Cond{test, thenpt, elsept, ...}) =
2268                (leastGenExp test; leastGenExp thenpt; leastGenExp elsept)
2269
2270        |   leastGenExp(TupleTree{fields, ...}) = List.app leastGenExp fields
2271
2272        |   leastGenExp(Constraint{value, ...}) = leastGenExp value
2273
2274        |   leastGenExp(Fn {matches, ...}) = List.app (fn MatchTree{exp, ...} => leastGenExp exp) matches
2275
2276        |   leastGenExp(ExpSeq(ptl, _)) = List.app (leastGenExp o #1) ptl
2277
2278        |   leastGenExp(HandleTree{exp, hrules, ...}) =
2279                (leastGenExp exp; List.app (fn MatchTree{exp, ...} => leastGenExp exp) hrules)
2280
2281        |   leastGenExp(While{test, body, ...}) = (leastGenExp test; leastGenExp body)
2282
2283        |   leastGenExp(Case{test, match, ...}) =
2284                (leastGenExp test; List.app (fn MatchTree{exp, ...} => leastGenExp exp) match)
2285
2286        |   leastGenExp(Andalso {first, second, ...}) = (leastGenExp first; leastGenExp second)
2287
2288        |   leastGenExp(Orelse{first, second, ...}) = (leastGenExp first; leastGenExp second)
2289
2290        |   leastGenExp(Labelled{recList, ...}) = List.app (leastGenExp o #valOrPat) recList
2291
2292        |   leastGenExp(List{elements, ...}) = List.app leastGenExp elements
2293
2294        |   leastGenExp(Parenthesised(p, _)) = leastGenExp p
2295
2296        |   leastGenExp _ = ()
2297
2298    in
2299        leastGenExp p
2300    end
2301
2302    (* Types that can be shared. *)
2303    structure Sharing =
2304    struct
2305        type lexan      = lexan
2306        and  pretty     = pretty
2307        and  codetree   = codetree
2308        and  codeBinding = codeBinding
2309        and  types      = types
2310        and  values     = values
2311        and  typeId     = typeId
2312        and  structVals = structVals
2313        and  typeConstrs= typeConstrs
2314        and  typeVarForm=typeVarForm
2315        and  env        = env
2316        and  fixStatus  = fixStatus
2317        and  structureIdentForm = structureIdentForm
2318        and  typeParsetree = typeParsetree
2319        and  parsetree  = parsetree
2320        and  valbind    = valbind
2321        and  fvalbind   = fvalbind
2322        and  fvalclause = fvalclause
2323        and  typebind   = typebind
2324        and  datatypebind=datatypebind
2325        and  exbind     = exbind
2326        and  labelRecEntry=labelRecEntry
2327        and  ptProperties = ptProperties
2328        and  matchtree   = matchtree
2329        and  typeVarMap = typeVarMap
2330        and  level = level
2331    end
2332
2333end (* PARSETREE *);
2334