/
env.rml
187 lines (137 loc) · 5.11 KB
/
env.rml
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
(**********************************************************************
*
* Environments
*
* An environment is a stack of frames, where each frame contains a
* number of class and variable bindings.
*
**********************************************************************)
module Env:
with "exp.rml"
with "explode.rml"
with "mod.rml"
with "types.rml"
with "classinf.rml"
datatype FrameVar = FRAMEVAR of Explode.Ident
* Types.VarAttr
* Types.Type
* ClassInf.State
* Exp.Exp option (* equation *)
datatype Frame = FRAME of (Explode.Ident*FrameVar) list
* (Explode.Ident*Explode.Class*Mod.Mod) list
type Env = Frame list
val empty_frame : Frame
val empty_env : Env
relation new_frame : Env => Env
relation extend_frame_c : (Env, Explode.Class, Mod.Mod) => Env
relation extend_frame_v : (Env, FrameVar) => Env
relation lookup_class : (Env, Explode.Path) => (Explode.Class, Mod.Mod)
relation lookup_var : (Env,Explode.ComponentRef)
=> (Types.VarAttr,Types.Type,ClassInf.State)
relation lookup_var_local : (Env, Explode.Ident) => FrameVar
end
val empty_frame = FRAME([],[])
val empty_env = []
relation new_frame: Env => Env =
axiom new_frame(env) => empty_frame::env
end
(**********************************************************************
*
* Lookup functions
*
* These relations look up class and variable names in the environment.
* The names are supplied as a path, and if the path is qualified, a
* variable named as the first part of the path is searched for, and the
* nave is looked for in it.
*
**********************************************************************)
relation lookup_class_f: ((Explode.Ident * Explode.Class * Mod.Mod) list,
Explode.Ident)
=> (Explode.Class,Mod.Mod) =
rule (* print " lookup_class_f(" & print id & print "): " &
print n & print "\n" & *)
id = n
---------------------------------------------------------
lookup_class_f((n,c,m)::_, id) => (c,m)
rule lookup_class_f(fs,id) => (c,m)
------------------------------
lookup_class_f(_::fs,id) => (c,m)
end
relation lookup_class: (Env,Explode.Path) => (Explode.Class,Mod.Mod) =
rule lookup_class_f(cs,id) => (c,m)
---------------------
lookup_class(FRAME(_,cs)::fs,Exp.IDENT(id)) => (c,m)
rule lookup_class(fs,id) => (c,m)
---------------------
lookup_class(f::fs,id) => (c,m)
end
relation lookup_var2: ((Explode.Ident * FrameVar) list,Explode.Ident)
=> FrameVar =
rule id = n
--------------------------------------------
lookup_var2((n,fv)::_,id) => fv
rule lookup_var2(fs,id) => fv
------------------------
lookup_var2(_::fs,id) => fv
end
relation check_subscripts : (Types.ArrayDim, Exp.Subscript list) => () =
(* FIXME: Check range too? *)
axiom check_subscripts(Types.NODIM, [])
axiom check_subscripts(Types.ONEDIM(_), [_])
axiom check_subscripts(Types.TWODIM(_,_), [_,_])
end
relation lookup_in_var: (Types.Type, Explode.ComponentRef)
=> (Types.VarAttr,Types.Type,ClassInf.State) =
(* FIXME: Check protected flag *)
(* FIXME: Should I really strip the ArrayDim? *)
rule Types.lookup_component(ty, id)
=> ((_,Types.ATTR(ad,fl,vt,di),ty',st)) &
check_subscripts(ad, ss)
------------------------
lookup_in_var(ty, [(id,ss)])
=> (Types.ATTR(Types.NODIM,fl,vt,di),ty',st)
rule Types.lookup_component(ty, id)
=> ((_,Types.ATTR(ad,fl,vt,di),ty',_)) &
check_subscripts(ad, ss) &
lookup_in_var(ty', vs) => (attr, ty'',st)
--------------------------------------
lookup_in_var(ty, (id,ss)::vs) => (attr,ty'',st)
end
relation lookup_var_f : ((Explode.Ident * FrameVar) list, Explode.ComponentRef)
=> (Types.VarAttr, Types.Type, ClassInf.State) =
rule (* print " lookup_var_f 1: " & print id & print "\n" & *)
lookup_var2(f, id) => FRAMEVAR(n,Types.ATTR(ad,f,vt,di),ty,st,_) &
check_subscripts(ad,ss)
----------------------------------
lookup_var_f(f,[(id,ss)]) => (Types.ATTR(Types.NODIM,f,vt,di),ty,st)
rule (* print " lookup_var_f 2: " & print id & print "\n" & *)
lookup_var2(f, id) => FRAMEVAR(n,Types.ATTR(ad,_,_,_),ty,_,_) &
check_subscripts(ad,ss) &
lookup_in_var(ty, ids) => (attr,ty,st)
----------------------------------
lookup_var_f(f,(id,ss)::ids) => (attr,ty,st)
end
relation lookup_var: (Env,Explode.ComponentRef)
=> (Types.VarAttr,Types.Type,ClassInf.State) =
rule (* print " lookup_var: looking in frame\n" & *)
lookup_var_f(vs,ref) => (attr,ty,st)
-------------------------
lookup_var(FRAME(vs,_)::fs,ref) => (attr,ty,st)
rule (* print " lookup_var: next frame\n" & *)
lookup_var(fs,ref) => (attr,ty,st)
--------------------
lookup_var(_::fs,ref) => (attr,ty,st)
end
relation lookup_var_local : (Env, Explode.Ident) => FrameVar =
rule lookup_var2(vs, id) => fv
-------------------------
lookup_var_local(FRAME(vs,_)::_, id) => fv
end
relation extend_frame_c : (Env, Explode.Class, Mod.Mod) => Env =
axiom extend_frame_c(FRAME(vs,cs)::fs,c as Explode.CLASS(n,_,_,_),m)
=> ((FRAME(vs,(n,c,m)::cs)::fs))
end
relation extend_frame_v : (Env,FrameVar) => Env =
axiom extend_frame_v(FRAME(vs,cs)::fs,v as FRAMEVAR(n,_,_,_,_))
=> (FRAME((n,v)::vs,cs)::fs)
end