File: mltree-check-ty.sml

package info (click to toggle)
mlton 20210117%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 58,464 kB
  • sloc: ansic: 27,682; sh: 4,455; asm: 3,569; lisp: 2,879; makefile: 2,347; perl: 1,169; python: 191; pascal: 68; javascript: 7
file content (137 lines) | stat: -rw-r--r-- 5,901 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
(* mltree-check-ty.sml
 * 
 * Check that MLRISC programs have consistent types. 
 *)

functor MLTreeCheckTy
  (structure T : MLTREE
   val intTy : T.ty (* size of integer word *)) : sig
    val check : T.stm -> bool
  end = struct

   exception AmbiguousType

   exception TypeError

   fun chkEq (ty, tys) = List.all (fn SOME ty' => ty' = ty | NONE => true) tys

   fun chkTys (ty, tys) = if chkEq (ty, tys)
           then ty
           else raise TypeError

 (* check well-formedness of a list of expressions *)
   fun checkRexps (ty, es) = let
          val tys = List.map (fn e => SOME (checkRexp e) handle AmbiguousType => NONE) es
          in
             chkTys(ty, tys)
          end

   and checkRexp (T.REG(ty,_)) = ty
     (* the type of a literal expression depends on its surrounding context *)
     | checkRexp (T.LI _) = raise AmbiguousType  
     | checkRexp (T.LABEL _) = intTy
     (* the type of a literal expression depends on its surrounding context *)
     | checkRexp (T.CONST _) = raise AmbiguousType
     | checkRexp (T.LABEXP e) = checkRexp e
     | checkRexp (T.NEG(ty, e)) = checkRexps(ty, [e])
     | checkRexp (T.ADD(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.SUB(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.MULS(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.DIVS(_,ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.REMS(_,ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.MULU(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.DIVU(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.REMU(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.NEGT(ty,e)) = checkRexps(ty, [e])
     | checkRexp (T.ADDT(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.SUBT(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.MULT(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.DIVT(_,ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.ANDB(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.ORB(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.XORB(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.EQVB(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.NOTB(ty,e)) = checkRexps(ty, [e])
     | checkRexp (T.SRA(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.SRL(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.SLL(ty,e1,e2)) = checkRexps(ty, [e1, e2])
     | checkRexp (T.SX(toTy,fromTy,e)) = (checkRexps(fromTy, [e]); toTy)
     | checkRexp (T.ZX(toTy,fromTy,e)) = (checkRexps(fromTy, [e]); toTy)
     | checkRexp (T.CVTF2I(ty,_,_,_)) = ty
     | checkRexp (T.COND(ty,cce,e1,e2)) = (checkCCexp cce; checkRexps(ty, [e1, e2]))
     | checkRexp (T.LOAD(ty,ea,_)) = (checkRexps(intTy, [ea]); ty)
     | checkRexp (T.PRED(e,_)) = checkRexp e
     | checkRexp (T.LET(_,e)) = checkRexp e
     | checkRexp (T.REXT(ty,_)) = ty
     | checkRexp (T.MARK(e,_)) = checkRexp e
     | checkRexp (T.OP(ty,_,_)) = ty
     | checkRexp (T.ARG(ty,_,_)) = ty
     | checkRexp (T.$(ty,_,_)) = ty
     | checkRexp (T.PARAM _) = intTy
     | checkRexp (T.BITSLICE(ty,_,_)) = ty
     | checkRexp (T.???) = intTy

   and checkFexps (ty, es) = let
          val tys = List.map (fn e => SOME (checkFexp e) handle AmbiguousType => NONE) es
          in
             chkTys(ty, tys)
          end

   and checkFexp (T.FREG(ty,_)) = raise AmbiguousType
     | checkFexp (T.FLOAD(ty,ea,_)) = (checkRexps(intTy, [ea]); ty)
     | checkFexp (T.FADD(ty,e1,e2)) = checkFexps(ty, [e1, e2])
     | checkFexp (T.FSUB(ty,e1,e2)) = checkFexps(ty, [e1, e2])
     | checkFexp (T.FMUL(ty,e1,e2)) = checkFexps(ty, [e1, e2])
     | checkFexp (T.FDIV(ty,e1,e2)) = checkFexps(ty, [e1, e2])
     | checkFexp (T.FABS(ty,e)) = checkFexps(ty, [e])
     | checkFexp (T.FNEG(ty,e)) = checkFexps(ty, [e])
     | checkFexp (T.FSQRT(ty,e)) = checkFexps(ty, [e])
     | checkFexp (T.FCOND(ty,ce,e1,e2)) = (checkCCexp ce; checkFexps(ty, [e1, e2]))
     | checkFexp (T.CVTI2F(ty,_,_)) = ty
     | checkFexp (T.CVTF2F(ty,_,_)) = ty
     | checkFexp (T.FCOPYSIGN(ty,e1,e2)) = checkFexps(ty, [e1, e2])
     | checkFexp (T.FPRED(e,_)) = checkFexp e
     | checkFexp (T.FEXT(ty,_)) = ty
     | checkFexp (T.FMARK(e,_)) = checkFexp e

  (* don't care about ambiguous types *)
   and checkRexpB (ty, e) = checkRexp e = ty handle AmbiguousType => true

   and checkCCexp cce = checkCCexpB cce orelse raise TypeError

   and checkCCexpB cce = (case cce
          of T.NOT cce => checkCCexpB cce
	   | ( T.AND (cce1, cce2) | T.OR (cce1, cce2) | T.XOR (cce1, cce2) | T.EQV (cce1, cce2) ) =>
	     checkCCexpB cce1 andalso checkCCexpB cce2
	   | T.CMP (ty, _, e1, e2) => ty = checkRexp e1 andalso ty = checkRexp e2
	   | T.FCMP (fty, _, e1, e2) => fty = checkFexp e1 andalso fty = checkFexp e2
	   | T.CCMARK (cce, _) => checkCCexpB cce
	   | T.CCEXT (ty, ccext) => true
          (* end case *))

    fun check stm = (case stm
	   of T.MV (ty, d, e) => checkRexpB (ty, e)
	    | T.CCMV (dst, cce) => checkCCexpB cce
	    | T.FMV (fty, dst, e) => checkFexp e = fty
	    | T.COPY _ => true
	    | T.FCOPY _ => true
	    | T.JMP (e, _) => checkRexpB (intTy, e)
	    | T.BCC (cce, _) => checkCCexpB cce
	    | T.CALL {funct, ...} => checkRexpB (intTy, funct)
	    | T.FLOW_TO (stm, _) => check stm
	    | T.RET _ => true
	    | T.IF (cce, stm1, stm2) => checkCCexpB cce andalso check stm1 andalso check stm2
	    | T.STORE (ty, e1, e2, _) => checkRexpB (intTy, e1) andalso checkRexpB(intTy, e2)
	    | T.FSTORE (fty, e1, e2, _) => checkRexpB (intTy, e1) andalso fty = checkFexp e2
	    | T.REGION (stm, _) => check stm
	    | T.SEQ stms => List.all check stms
	    | T.DEFINE _ => true
	    | T.ANNOTATION (stm, _) => check stm
	    | T.EXT _ => true
	    | T.LIVE _ => true
	    | T.KILL _ => true
	    | _ => true
           (* end case *))
	handle TypeError => false

  end (* MLTreeCheckTy *)