E-mail aliases
[hcoop/domtool2.git] / src / tycheck.sml
index fa006df..ac69a6d 100644 (file)
@@ -14,7 +14,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-*)
+ *)
 
 (* Domtool configuration language type checking *)
 
@@ -112,9 +112,6 @@ datatype type_error =
        | UnboundVariable of string
        | WrongPred of string * pred * pred
 
-fun preface (s, d) = printd (PD.hovBox (PD.PPS.Rel 0,
-                                       [PD.string s, PD.space 1, d]))
-
 fun describe_unification_error t ue =
     case ue of
        UnifyPred (p1, p2) =>
@@ -281,6 +278,24 @@ fun whnorm (tAll as (t, loc)) =
        TUnif (_, ref (SOME tAll)) => whnorm tAll
       | _ => tAll
 
+fun baseCondition t =
+    case whnorm t of
+       (TBase name, _) => typeRule name
+      | (TList t, _) =>
+       (case baseCondition t of
+            NONE => NONE
+          | SOME f => SOME (fn (EList ls, _) => List.all f ls
+                             | _ => false))
+      | _ => NONE
+
+fun hasTyp (e, t1, t2) =
+    if (case baseCondition t2 of
+           NONE => false
+         | SOME rule => rule e) then
+       ()
+    else
+       subTyp (t1, t2)
+
 fun checkTyp G (tAll as (t, loc)) =
     let
        val err = ErrorMsg.error (SOME loc)
@@ -316,7 +331,7 @@ fun checkExp G (eAll as (e, loc)) =
                          let
                              val t' = checkExp G e'
                          in
-                             (subTyp (t', t);
+                             (hasTyp (eAll, t', t);
                               if isError t' then
                                   (TList (TError, loc), loc)
                               else
@@ -356,8 +371,8 @@ fun checkExp G (eAll as (e, loc)) =
                val tf = checkExp G func
                val ta = checkExp G arg
            in
-               (subTyp (tf, (TArrow (dom, ran), loc));
-                subTyp (ta, dom)
+               (hasTyp (func, tf, (TArrow (dom, ran), loc));
+                hasTyp (arg, ta, dom)
                 handle Unify ue =>
                        dte (WrongType ("Function argument",
                                        arg,
@@ -637,7 +652,7 @@ fun checkDecl G (d, _, loc) =
 
            val t = checkExp G e
        in
-           subTyp (t, to)
+           hasTyp (e, t, to)
            handle Unify ue =>
                   describe_type_error loc
                                       (WrongType ("Bound value",
@@ -658,7 +673,7 @@ fun checkFile G tInit (ds, eo) =
            let
                val t = checkExp G' e
            in
-               subTyp (t, tInit)
+               hasTyp (e, t, tInit)
                handle Unify ue =>
                       (ErrorMsg.error (SOME loc) "Bad type for final expression of source file.";
                        preface ("Actual:", p_typ t);