OLD | NEW |
| 1 \subsection*{Field lookup} |
| 2 |
| 3 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u
psilon_k}}{\many{\mathit{ce}}}) \in \Phi \\ |
| 4 \fieldDecl{x}{\tau} \in \many{\mathit{ce}} |
| 5 } |
| 6 {\fieldLookup{\Phi}{\TApp{C}{\tau_0, \ldots, \tau_n}}{x}{\subst{\tau_0,
\ldots, \tau_n}{T_0, \ldots, T_n}{\tau}} |
| 7 } |
| 8 |
| 9 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u
psilon_k}}{\many{\mathit{ce}}}) \in \Phi \quad x \notin \many{\mathit{ce}} \\ |
| 10 \fieldLookup{\Phi}{\TApp{C'}{\upsilon_0, \ldots, \upsilon_k}}{x}{\tau} |
| 11 } |
| 12 {\fieldLookup{\Phi}{\TApp{C}{\tau_0, \ldots, \tau_n}}{x}{\subst{\tau_0,
\ldots, \tau_n}{T_0, \ldots, T_n}{\tau}} |
| 13 } |
| 14 |
| 15 |
| 16 \subsection*{Method lookup} |
| 17 |
| 18 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u
psilon_k}}{\many{\mathit{ce}}}) \in \Phi \\ |
| 19 \methodDecl{m}{\tau}{\sigma} \in \many{\mathit{ce}} |
| 20 } |
| 21 {\methodLookup{\Phi} |
| 22 {\TApp{C}{\tau_0, \ldots, \tau_n}}{m} |
| 23 {\subst{\tau_0, \ldots, \tau_n}{T_0, \ldots, T_n}{\tau}} |
| 24 {\subst{\tau_0, \ldots, \tau_n}{T_0, \ldots, T_n}{\sigma}} |
| 25 } |
| 26 |
| 27 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u
psilon_k}}{\many{\mathit{ce}}}) \in \Phi \quad m \notin \many{\mathit{ce}} \\ |
| 28 \methodLookup{\Phi}{\TApp{C'}{\upsilon_0, \ldots, \upsilon_k}}{m}{\tau}
{\sigma} |
| 29 } |
| 30 {\methodLookup{\Phi}{\TApp{C}{\tau_0, \ldots, \tau_n}}{m} |
| 31 {\subst{\tau_0, \ldots, \tau_n}{T_0, \ldots, T_n}{\tau}} |
| 32 {\subst{\tau_0, \ldots, \tau_n}{T_0, \ldots, T_n}{\sigma}} |
| 33 } |
| 34 |
| 35 \subsection*{Method and field absence} |
| 36 |
| 37 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u
psilon_k}}{\many{\mathit{ce}}}) \in \Phi \quad x \notin \many{\mathit{ce}} \\ |
| 38 \fieldAbsent{\Phi}{\TApp{C'}{\upsilon_0, \ldots, \upsilon_k}}{x} |
| 39 } |
| 40 {\fieldAbsent{\Phi}{\TApp{C}{\tau_0, \ldots, \tau_n}}{x} |
| 41 } |
| 42 |
| 43 \infrule{(C : \dclass{\TApp{C}{T_0,\ldots,T_n}}{\TApp{C'}{\upsilon_0, \ldots, \u
psilon_k}}{\many{\mathit{ce}}}) \in \Phi \quad m \notin \many{\mathit{ce}} \\ |
| 44 \methodAbsent{\Phi}{\TApp{C'}{\upsilon_0, \ldots, \upsilon_k}}{m}{\tau}
{\sigma} |
| 45 } |
| 46 {\methodAbsent{\Phi}{\TApp{C}{\tau_0, \ldots, \tau_n}}{m} |
| 47 } |
| 48 |
| 49 \iftrans{ |
| 50 |
| 51 \subsection*{Type translation} |
| 52 |
| 53 To translate covariant generics, we essentially want to treat all contravariant |
| 54 occurrences of type variables as $\Dynamic$. The type translation |
| 55 $\down{\tau}$ implements this. It is defined in terms of the dual operator |
| 56 $\up{\tau}$ which translates positive occurences of type variables as $\Dynamic$
. |
| 57 |
| 58 \begin{eqnarray*} |
| 59 \down{T} & = & T \\ |
| 60 \down{\Arrow[k]{\tau_0, \ldots, \tau_n}{\tau_r}} & = & |
| 61 \Arrow[k]{\up{\tau_0}, \ldots, \up{\tau_n}}{\down{\tau_r}} \\ |
| 62 \down{\TApp{C}{\tau_0, \ldots, \tau_n}} & = & \TApp{C}{\down{\tau_0}, \ldots,
\down{\tau_n}} \\ |
| 63 \down{\tau} & = & \tau\ \mbox{otherwise} |
| 64 \end{eqnarray*} |
| 65 |
| 66 \begin{eqnarray*} |
| 67 \up{T} & = & \Dynamic \\ |
| 68 \up{\Arrow[k]{\tau_0, \ldots, \tau_n}{\tau_r}} & = & |
| 69 \Arrow[k]{\down{\tau_0}, \ldots, \down{\tau_n}}{\up{\tau_r}} \\ |
| 70 \up{\TApp{C}{\tau_0, \ldots, \tau_n}} & = & \TApp{C}{\up{\tau_0}, \ldots, \up{
\tau_n}} \\ |
| 71 \up{\tau} & = & \tau\ \mbox{if $\tau$ is base type.} |
| 72 \end{eqnarray*} |
| 73 |
| 74 |
| 75 } |
1 \subsection*{Expression typing: $\yieldsOk{\Phi, \Delta, \Gamma}{e}{\opt{\tau}}{
e'}{\tau'}$} | 76 \subsection*{Expression typing: $\yieldsOk{\Phi, \Delta, \Gamma}{e}{\opt{\tau}}{
e'}{\tau'}$} |
2 \hrulefill\\ | 77 \hrulefill\\ |
3 | 78 |
4 | 79 |
5 \sstext{ Expression typing is a relation between typing contexts, a term ($e$), | 80 \sstext{ Expression typing is a relation between typing contexts, a term ($e$), |
6 an optional type ($\opt{\tau}$), and a type ($\tau'$). The general idea is | 81 an optional type ($\opt{\tau}$), and a type ($\tau'$). The general idea is |
7 that we are typechecking a term ($e$) and want to know if it is well-typed. | 82 that we are typechecking a term ($e$) and want to know if it is well-typed. |
8 The term appears in a context, which may (or may not) impose a type constraint | 83 The term appears in a context, which may (or may not) impose a type constraint |
9 on the term. For example, in $\dvar{x:\tau}{e}$, $e$ appears in a context | 84 on the term. For example, in $\dvar{x:\tau}{e}$, $e$ appears in a context |
10 which requires it to be a subtype of $\tau$, or to be coercable to $\tau$. | 85 which requires it to be a subtype of $\tau$, or to be coercable to $\tau$. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 declared types. | 156 declared types. |
82 }{ | 157 }{ |
83 | 158 |
84 A fully annotated function elaborates to a function with an elaborated body. | 159 A fully annotated function elaborates to a function with an elaborated body. |
85 The rest of the function elaboration rules fill in the reified type using | 160 The rest of the function elaboration rules fill in the reified type using |
86 contextual information if present and applicable, or $\Dynamic$ otherwise. | 161 contextual information if present and applicable, or $\Dynamic$ otherwise. |
87 | 162 |
88 } | 163 } |
89 | 164 |
90 \infrule{\Gamma' = \extends{\Gamma}{\many{x}}{\many{\tau}} \quad\quad | 165 \infrule{\Gamma' = \extends{\Gamma}{\many{x}}{\many{\tau}} \quad\quad |
91 \yieldsOk{\Phi, \Delta, \Gamma'}{e}{\sigma}{e'}{\sigma'} | 166 \stmtOk{\Phi, \Delta, \Gamma'}{s}{\sigma}{s'}{\Gamma'} |
92 } | 167 } |
93 {\yieldsOk{\Phi, \Delta, \Gamma} | 168 {\yieldsOk{\Phi, \Delta, \Gamma} |
94 {\elambda{\many{x:\tau}}{\sigma}{e}} | 169 {\elambda{\many{x:\tau}}{\sigma}{s}} |
95 {\_} | 170 {\_} |
96 {\elambda{\many{x:\tau}}{\sigma}{e'}} | 171 {\elambda{\many{x:\tau}}{\sigma}{s'}} |
97 {\Arrow[-]{\many{\tau}}{\sigma}} | 172 {\Arrow[-]{\many{\tau}}{\sigma}} |
98 } | 173 } |
99 | 174 |
100 \sstext{A function with a missing argument type is well-typed if it is well-type
d with | 175 \sstext{A function with a missing argument type is well-typed if it is well-type
d with |
101 the argument type replaced with $\Dynamic$.} | 176 the argument type replaced with $\Dynamic$.} |
102 {} | 177 {} |
103 | 178 |
104 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} | 179 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} |
105 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\Dynamic, \ldots, x_n:
\opt{\tau_n}}{\opt{\sigma}}{e}} | 180 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\Dynamic, \ldots, x_n:
\opt{\tau_n}}{\opt{\sigma}}{s}} |
106 {\opt{\tau}} | 181 {\opt{\tau}} |
107 {e_f} | 182 {e_f} |
108 {\tau_f} | 183 {\tau_f} |
109 } | 184 } |
110 {\yieldsOk{\Phi, \Delta, \Gamma} | 185 {\yieldsOk{\Phi, \Delta, \Gamma} |
111 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\_, \ldots, x_n:\opt{\
tau_n}}{\opt{\sigma}}{e}} | 186 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\_, \ldots, x_n:\opt{\
tau_n}}{\opt{\sigma}}{s}} |
112 {\opt{\tau}} | 187 {\opt{\tau}} |
113 {e_f} | 188 {e_f} |
114 {\tau_f} | 189 {\tau_f} |
115 } | 190 } |
116 | 191 |
117 \sstext{A function with a missing argument type is well-typed if it is well-type
d with | 192 \sstext{A function with a missing argument type is well-typed if it is well-type
d with |
118 the argument type replaced with the corresponding argument type from the context | 193 the argument type replaced with the corresponding argument type from the context |
119 type. Note that this rule overlaps with the previous: the formal presentation | 194 type. Note that this rule overlaps with the previous: the formal presentation |
120 leaves this as a non-deterministic choice.}{} | 195 leaves this as a non-deterministic choice.}{} |
121 | 196 |
122 \infrule{\tau_c = \Arrow[k]{\upsilon_0, \ldots, \upsilon_n}{\upsilon_r} \\ | 197 \infrule{\tau_c = \Arrow[k]{\upsilon_0, \ldots, \upsilon_n}{\upsilon_r} \\ |
123 \yieldsOk{\Phi, \Delta, \Gamma} | 198 \yieldsOk{\Phi, \Delta, \Gamma} |
124 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\upsilon_i, \ldots, x_
n:\opt{\tau_n}}{\opt{\sigma}}{e}} | 199 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\upsilon_i, \ldots, x_
n:\opt{\tau_n}}{\opt{\sigma}}{s}} |
125 {\tau_c} | 200 {\tau_c} |
126 {e_f} | 201 {e_f} |
127 {\tau_f} | 202 {\tau_f} |
128 } | 203 } |
129 {\yieldsOk{\Phi, \Delta, \Gamma} | 204 {\yieldsOk{\Phi, \Delta, \Gamma} |
130 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\_, \ldots, x_n:\opt{\
tau_n}}{\opt{\sigma}}{e}} | 205 {\elambda{x_0:\opt{\tau_0}, \ldots, x_i:\_, \ldots, x_n:\opt{\
tau_n}}{\opt{\sigma}}{s}} |
131 {\tau_c} | 206 {\tau_c} |
132 {e_f} | 207 {e_f} |
133 {\tau_f} | 208 {\tau_f} |
134 } | 209 } |
135 | 210 |
136 \sstext{A function with a missing return type is well-typed if it is well-typed
with | 211 \sstext{A function with a missing return type is well-typed if it is well-typed
with |
137 the return type replaced with $\Dynamic$.}{} | 212 the return type replaced with $\Dynamic$.}{} |
138 | 213 |
139 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} | 214 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} |
140 {\elambda{\many{x:\opt{\tau}}}{\Dynamic}{e}} | 215 {\elambda{\many{x:\opt{\tau}}}{\Dynamic}{s}} |
141 {\opt{\tau_c}} | 216 {\opt{\tau_c}} |
142 {e_f} | 217 {e_f} |
143 {\tau_f} | 218 {\tau_f} |
144 } | 219 } |
145 {\yieldsOk{\Phi, \Delta, \Gamma} | 220 {\yieldsOk{\Phi, \Delta, \Gamma} |
146 {\elambda{\many{x:\opt{\tau}}}{\_}{e}} | 221 {\elambda{\many{x:\opt{\tau}}}{\_}{s}} |
147 {\opt{\tau_c}} | 222 {\opt{\tau_c}} |
148 {e_f} | 223 {e_f} |
149 {\tau_f} | 224 {\tau_f} |
150 } | 225 } |
151 | 226 |
152 \sstext{A function with a missing return type is well-typed if it is well-typed
with | 227 \sstext{A function with a missing return type is well-typed if it is well-typed
with |
153 the return type replaced with the corresponding return type from the context | 228 the return type replaced with the corresponding return type from the context |
154 type. Note that this rule overlaps with the previous: the formal presentation | 229 type. Note that this rule overlaps with the previous: the formal presentation |
155 leaves this as a non-deterministic choice. }{} | 230 leaves this as a non-deterministic choice. }{} |
156 | 231 |
157 \infrule{\tau_c = \Arrow[k]{\upsilon_0, \ldots, \upsilon_n}{\upsilon_r} \\ | 232 \infrule{\tau_c = \Arrow[k]{\upsilon_0, \ldots, \upsilon_n}{\upsilon_r} \\ |
158 \yieldsOk{\Phi, \Delta, \Gamma} | 233 \yieldsOk{\Phi, \Delta, \Gamma} |
159 {\elambda{\many{x:\opt{\tau}}}{\upsilon_r}{e}} | 234 {\elambda{\many{x:\opt{\tau}}}{\upsilon_r}{s}} |
160 {\tau_c} | 235 {\tau_c} |
161 {e_f} | 236 {e_f} |
162 {\tau_f} | 237 {\tau_f} |
163 } | 238 } |
164 {\yieldsOk{\Phi, \Delta, \Gamma} | 239 {\yieldsOk{\Phi, \Delta, \Gamma} |
165 {\elambda{\many{x:\opt{\tau}}}{\_}{e}} | 240 {\elambda{\many{x:\opt{\tau}}}{\_}{s}} |
166 {\tau_c} | 241 {\tau_c} |
167 {e_f} | 242 {e_f} |
168 {\tau_f} | 243 {\tau_f} |
169 } | 244 } |
170 | 245 |
171 | 246 |
172 \sstext{Instance creation creates an instance of the appropriate type.}{} | 247 \sstext{Instance creation creates an instance of the appropriate type.}{} |
173 | 248 |
174 % FIXME(leafp): inference | 249 % FIXME(leafp): inference |
175 % FIXME(leafp): deal with bounds | 250 % FIXME(leafp): deal with bounds |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 {e_a'} | 323 {e_a'} |
249 {\tau_a'} \quad \mbox{for}\ e_a \in \many{e_a} | 324 {\tau_a'} \quad \mbox{for}\ e_a \in \many{e_a} |
250 } | 325 } |
251 {\yieldsOk{\Phi, \Delta, \Gamma} | 326 {\yieldsOk{\Phi, \Delta, \Gamma} |
252 {\ecall{e}{\many{e_a}}} | 327 {\ecall{e}{\many{e_a}}} |
253 {\_} | 328 {\_} |
254 {\edcall{e'}{\many{e_a'}}} | 329 {\edcall{e'}{\many{e_a'}}} |
255 {\Dynamic} | 330 {\Dynamic} |
256 } | 331 } |
257 | 332 |
| 333 \iftrans{ |
258 \sstext{A dynamic call expression is well-typed so long as the applicand and the | 334 \sstext{A dynamic call expression is well-typed so long as the applicand and the |
259 arguments are well-typed at any type.}{} | 335 arguments are well-typed at any type.}{} |
260 | 336 |
261 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} | 337 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} |
262 {e} | 338 {e} |
263 {\Dynamic} | 339 {\Dynamic} |
264 {e'} | 340 {e'} |
265 {\tau} \\ | 341 {\tau} \\ |
266 \yieldsOk{\Phi, \Delta, \Gamma} | 342 \yieldsOk{\Phi, \Delta, \Gamma} |
267 {e_a} | 343 {e_a} |
268 {\_} | 344 {\_} |
269 {e_a'} | 345 {e_a'} |
270 {\tau_a} \quad \mbox{for}\ e_a \in \many{e_a} | 346 {\tau_a} \quad \mbox{for}\ e_a \in \many{e_a} |
271 } | 347 } |
272 {\yieldsOk{\Phi, \Delta, \Gamma} | 348 {\yieldsOk{\Phi, \Delta, \Gamma} |
273 {\edcall{e}{\many{e_a}}} | 349 {\edcall{e}{\many{e_a}}} |
274 {\_} | 350 {\_} |
275 {\edcall{e'}{\many{e_a'}}} | 351 {\edcall{e'}{\many{e_a'}}} |
276 {\Dynamic} | 352 {\Dynamic} |
277 } | 353 } |
278 | 354 |
| 355 } |
| 356 |
279 \sstext{A method load is well-typed if the term is well-typed, and the method na
me is | 357 \sstext{A method load is well-typed if the term is well-typed, and the method na
me is |
280 present in the type of the term.}{} | 358 present in the type of the term.}{} |
281 | 359 |
282 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} | 360 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} |
283 {e} | 361 {e} |
284 {\_} | 362 {\_} |
285 {e'} | 363 {e'} |
286 {\sigma} \quad\quad | 364 {\sigma} \quad\quad |
287 \methodLookup{\Phi}{\sigma}{m}{\tau} | 365 \methodLookup{\Phi}{\sigma}{m}{\sigma}{\tau} |
288 } | 366 } |
289 {\yieldsOk{\Phi, \Delta, \Gamma} | 367 {\yieldsOk{\Phi, \Delta, \Gamma} |
290 {\eload{e}{m}} | 368 {\eload{e}{m}} |
291 {\_} | 369 {\_} |
292 {\eload{e'}{m}} | 370 {\eload{e'}{m}} |
293 {\tau} | 371 {\tau} |
294 } | 372 } |
295 | 373 |
296 \sstext{A method load from a term of type $\Dynamic$ is well-typed if the term i
s | 374 \sstext{A method load from a term of type $\Dynamic$ is well-typed if the term i
s |
297 well-typed.} | 375 well-typed.} |
(...skipping 10 matching lines...) Expand all Loading... |
308 {e'} | 386 {e'} |
309 {\tau} | 387 {\tau} |
310 } | 388 } |
311 {\yieldsOk{\Phi, \Delta, \Gamma} | 389 {\yieldsOk{\Phi, \Delta, \Gamma} |
312 {\eload{e}{m}} | 390 {\eload{e}{m}} |
313 {\_} | 391 {\_} |
314 {\edload{e'}{m}} | 392 {\edload{e'}{m}} |
315 {\Dynamic} | 393 {\Dynamic} |
316 } | 394 } |
317 | 395 |
| 396 \iftrans{ |
318 \sstext{A dynamic method load is well typed so long as the term is well-typed.}{
} | 397 \sstext{A dynamic method load is well typed so long as the term is well-typed.}{
} |
319 | 398 |
320 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} | 399 \infrule{\yieldsOk{\Phi, \Delta, \Gamma} |
321 {e} | 400 {e} |
322 {\Dynamic} | 401 {\Dynamic} |
323 {e'} | 402 {e'} |
324 {\tau} | 403 {\tau} |
325 } | 404 } |
326 {\yieldsOk{\Phi, \Delta, \Gamma} | 405 {\yieldsOk{\Phi, \Delta, \Gamma} |
327 {\edload{e}{m}} | 406 {\edload{e}{m}} |
328 {\_} | 407 {\_} |
329 {\edload{e'}{m}} | 408 {\edload{e'}{m}} |
330 {\Dynamic} | 409 {\Dynamic} |
331 } | 410 } |
332 | 411 |
| 412 } |
| 413 |
333 \sstext{A field load from $\ethis$ is well-typed if the field name is present in
the | 414 \sstext{A field load from $\ethis$ is well-typed if the field name is present in
the |
334 type of $\ethis$.}{} | 415 type of $\ethis$.}{} |
335 | 416 |
336 \infrule{\Gamma = \Gamma_\tau & \fieldLookup{\Phi}{\tau}{x}{\sigma} | 417 \infrule{\Gamma = \Gamma_\tau & \fieldLookup{\Phi}{\tau}{x}{\sigma} |
337 } | 418 } |
338 {\yieldsOk{\Phi, \Delta, \Gamma} | 419 {\yieldsOk{\Phi, \Delta, \Gamma} |
339 {\eload{\ethis}{x}} | 420 {\eload{\ethis}{x}} |
340 {\_} | 421 {\_} |
341 {\eload{\ethis}{x}} | 422 {\eload{\ethis}{x}} |
342 {\sigma} | 423 {\sigma} |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 {\ethrow} | 470 {\ethrow} |
390 {\_} | 471 {\_} |
391 {\ethrow} | 472 {\ethrow} |
392 {\sigma} | 473 {\sigma} |
393 } | 474 } |
394 | 475 |
395 \sstext{A cast expression is well-typed so long as the term being cast is well-t
yped. | 476 \sstext{A cast expression is well-typed so long as the term being cast is well-t
yped. |
396 The synthesized type is the cast-to type. We require that the cast-to type be a | 477 The synthesized type is the cast-to type. We require that the cast-to type be a |
397 ground type.}{} | 478 ground type.}{} |
398 | 479 |
399 \comment{TODO(leafp): specify ground types} | |
400 | |
401 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} \quad\quad \mbox{$\t
au$ is ground} | 480 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} \quad\quad \mbox{$\t
au$ is ground} |
402 } | 481 } |
403 {\yieldsOk{\Phi, \Delta, \Gamma} | 482 {\yieldsOk{\Phi, \Delta, \Gamma} |
404 {\eas{e}{\tau}} | 483 {\eas{e}{\tau}} |
405 {\_} | 484 {\_} |
406 {\eas{e'}{\tau}} | 485 {\eas{e'}{\tau}} |
407 {\tau} | 486 {\tau} |
408 } | 487 } |
409 | 488 |
410 \sstext{An instance check expression is well-typed if the term being checked is | 489 \sstext{An instance check expression is well-typed if the term being checked is |
411 well-typed. We require that the cast to-type be a ground type.}{} | 490 well-typed. We require that the cast to-type be a ground type.}{} |
412 | 491 |
413 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} \quad\quad \mbox{$\t
au$ is ground} | 492 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} \quad\quad \mbox{$\t
au$ is ground} |
414 } | 493 } |
415 {\yieldsOk{\Phi, \Delta, \Gamma} | 494 {\yieldsOk{\Phi, \Delta, \Gamma} |
416 {\eis{e}{\tau}} | 495 {\eis{e}{\tau}} |
417 {\_} | 496 {\_} |
418 {\eis{e'}{\tau}} | 497 {\eis{e'}{\tau}} |
419 {\Bool} | 498 {\Bool} |
420 } | 499 } |
421 | 500 |
| 501 \iftrans{ |
| 502 |
422 \sstext{A check expression is well-typed so long as the term being checked is | 503 \sstext{A check expression is well-typed so long as the term being checked is |
423 well-typed. The synthesized type is the target type of the check.}{} | 504 well-typed. The synthesized type is the target type of the check.}{} |
424 | 505 |
425 | 506 |
426 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} | 507 \infrule{\yieldsOk{\Phi, \Delta, \Gamma}{e}{\_}{e'}{\sigma} |
427 } | 508 } |
428 {\yieldsOk{\Phi, \Delta, \Gamma} | 509 {\yieldsOk{\Phi, \Delta, \Gamma} |
429 {\echeck{e}{\tau}} | 510 {\echeck{e}{\tau}} |
430 {\_} | 511 {\_} |
431 {\echeck{e'}{\tau}} | 512 {\echeck{e'}{\tau}} |
432 {\tau} | 513 {\tau} |
433 } | 514 } |
434 | 515 |
| 516 } |
| 517 |
435 \subsection*{Declaration typing: $\declOk[d]{\Phi, \Delta, \Gamma}{\mathit{vd}}{
\mathit{vd'}}{\Gamma'}$} | 518 \subsection*{Declaration typing: $\declOk[d]{\Phi, \Delta, \Gamma}{\mathit{vd}}{
\mathit{vd'}}{\Gamma'}$} |
436 \hrulefill\\ | 519 \hrulefill\\ |
437 | 520 |
438 \sstext{ | 521 \sstext{ |
439 Variable declaration typing checks the well-formedness of the components, and | 522 Variable declaration typing checks the well-formedness of the components, and |
440 produces an output context $\Gamma'$ which contains the binding introduced by | 523 produces an output context $\Gamma'$ which contains the binding introduced by |
441 the declaration. | 524 the declaration. |
442 | 525 |
443 A simple variable declaration with a declared type is well-typed if the | 526 A simple variable declaration with a declared type is well-typed if the |
444 initializer for the declaration is well-typed at the declared type. The output | 527 initializer for the declaration is well-typed at the declared type. The output |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 \sstext{A sequence statement is well-typed if the first component is well-typed,
and the | 630 \sstext{A sequence statement is well-typed if the first component is well-typed,
and the |
548 second component is well-typed with the output context of the first component as | 631 second component is well-typed with the output context of the first component as |
549 its input context. The final output context is the output context of the second | 632 its input context. The final output context is the output context of the second |
550 component.}{} | 633 component.}{} |
551 | 634 |
552 \infrule{\stmtOk{\Phi, \Delta, \Gamma}{s_1}{\tau_r}{s_1'}{\Gamma'} \quad\quad | 635 \infrule{\stmtOk{\Phi, \Delta, \Gamma}{s_1}{\tau_r}{s_1'}{\Gamma'} \quad\quad |
553 \stmtOk{\Phi, \Delta, \Gamma'}{s_2}{\tau_r}{s_2'}{\Gamma''} | 636 \stmtOk{\Phi, \Delta, \Gamma'}{s_2}{\tau_r}{s_2'}{\Gamma''} |
554 } | 637 } |
555 {\stmtOk{\Phi, \Delta, \Gamma}{s_1;s_2}{\tau_r}{s_1';s_2'}{\Gamma''} | 638 {\stmtOk{\Phi, \Delta, \Gamma}{s_1;s_2}{\tau_r}{s_1';s_2'}{\Gamma''} |
556 } | 639 } |
| 640 |
| 641 \subsection*{Class member typing: $\declOk[ce]{\Phi, \Delta, \Gamma}{\mathit{vd
} : \mathit{ce}}{\mathit{vd}'}{\Gamma'}$} |
| 642 \hrulefill\\ |
| 643 |
| 644 \sstext{ |
| 645 |
| 646 A class member is well-typed with a given signature ($\mathit{ce}$) taken from |
| 647 the class hierarchy if the signature type matches the type on the definition, |
| 648 and if the definition is well-typed. |
| 649 |
| 650 } |
| 651 { |
| 652 |
| 653 Elaborating class members is done with respect to a signature. The field |
| 654 translation simply translates the field as a variable declaration. |
| 655 |
| 656 } |
| 657 |
| 658 |
| 659 \infrule{ |
| 660 \declOk[d]{\Phi, \Delta, \Gamma} |
| 661 {\dvar{x:\opt{\tau}}{e}} |
| 662 {\mathit{vd'}} |
| 663 {\Gamma'} |
| 664 } |
| 665 { |
| 666 \declOk[ce]{\Phi, \Delta, \Gamma} |
| 667 {\dvar{x:\opt{\tau}}{e} : \fieldDecl{x}{\opt{\tau}}} |
| 668 {\mathit{vd'}} |
| 669 {\Gamma'} |
| 670 } |
| 671 |
| 672 |
| 673 \iftrans{ |
| 674 |
| 675 Translating methods requires introducing guard expressions. The signature |
| 676 provides an internal and an external type for the method. The external type is |
| 677 the original declared type of the method, and is the signature which the method |
| 678 presents to external clients. Because we implement covariant generics, clients |
| 679 may see an instantiation of this signature which will allow them to violate the |
| 680 contract expected by the implementation. To handle this, we rewrite the method |
| 681 to match an internal signature which is in fact soundly covariant in the type |
| 682 parameters (that is, all contravariant type parameters are replaced with |
| 683 $\Dynamic$, and hence all remaining type parameters occur in properly covariant |
| 684 positions). This property is enforced in the override checking relation: from |
| 685 the perspective of this relation, there is simply another internal type which |
| 686 defines how to wrap the method with guards. |
| 687 |
| 688 The translation insists that the internal and external types be function types |
| 689 of the appropriate arity, and that the external type is equal to the type of the |
| 690 declaration. The declaration is translated using the underlying function |
| 691 definition translation, but is then wrapped with guards to enforce the type |
| 692 contract, producing a valid function of the internal (covariant) type. The |
| 693 original body of the function is wrapped in a lambda function, which is applied |
| 694 using a dynamic call which checks that the arguments (which may have negative |
| 695 occurrences of type variables which are treated as $\Dynamic$ in the internal |
| 696 type) are appropriate for the actual body. The original function returns a type |
| 697 $\tau_r$ which may be a super-type of the internal type (since negative |
| 698 occurrences of type variables must be treated as dynamic), and so we insert a |
| 699 check expression to guard against runtime type mismatches here. |
| 700 |
| 701 This is a very simplistic translation for now. We could choose, in the case |
| 702 that the body returns a lambda, to push the checking down into the lambda |
| 703 (essentially wrapping it in place). |
| 704 |
| 705 } |
| 706 |
| 707 \infrule{ \mathit{vd} = \dfun{\tau_r}{f}{x_0:\tau_0, \ldots, x_n:\tau_n}{s} \\ |
| 708 \sigma_e = \Arrow[+]{\tau_0, \ldots, \tau_n}{\tau_r} |
| 709 \iftrans{\quad\quad |
| 710 \sigma_i = \Arrow{\upsilon_0, \ldots, \upsilon_n}{\upsilon_r} |
| 711 } \\ |
| 712 \declOk[d]{\Phi, \Delta, \Gamma} |
| 713 {\mathit{vd}} |
| 714 {\dfun{\tau_r}{f}{x_0:\tau_0, \ldots, x_n:\tau_n}{s'}} |
| 715 {\Gamma'} |
| 716 \iftrans{\\ |
| 717 e_g = \elambda{x_0:\tau_0, \ldots, x_n:\tau_n}{\tau_r}{s'}\\ |
| 718 s_g = \sreturn{(\echeck{\edcall{e_g}{x_0 , \ldots, x_n}}{\upsil
on_r})} \\ |
| 719 \mathit{vd}_g = \dfun{\upsilon_r}{f}{x_0:\upsilon_0, \ldots, x_
n:\upsilon_n}{s_g} |
| 720 } |
| 721 } |
| 722 { |
| 723 \declOk[ce]{\Phi, \Delta, \Gamma} |
| 724 {\mathit{vd} : \methodDecl{f}{\sigma_i}{\sigma_e}} |
| 725 {\mathit{vd}_g} |
| 726 {\Gamma'} |
| 727 } |
| 728 |
| 729 \subsection*{Class declaration typing: $\declOk[c]{\Phi, \Gamma}{\mathit{cd}}{\
mathit{cd'}}{\Gamma'}$} |
| 730 \hrulefill\\ |
| 731 |
| 732 \sstext{ |
| 733 |
| 734 A class declaration is well-typed with a given signature ($\Sig$) taken from the |
| 735 class hierarchy if the signature matches the definition, and if each member of |
| 736 the class is well-typed with the corresponding signature from the class |
| 737 signature. The members are checked with the generic type parameters bound in |
| 738 the type context, and with the type of the current class set as the type of |
| 739 $\ethis$ on the term context $\Gamma$. |
| 740 |
| 741 } |
| 742 { |
| 743 |
| 744 Elaboration of a class requires that the class hierarchy $\Phi$ have a matching |
| 745 signature for the class declaration. Each class member in the class is |
| 746 elaborated using the corresponding class element from the signature. |
| 747 |
| 748 } |
| 749 |
| 750 |
| 751 \infrule{\mathit{cd} = \dclass{\TApp{C}{\many{T}}}{\TApp{G}{\many{\tau}}}{\mathi
t{vd}_0, \ldots, \mathit{vd}_n} \\ |
| 752 (C : \dclass{\TApp{C}{\many{T}}}{\TApp{G}{\many{\tau}}}{\mathit{ce}_0,
\ldots, \many{ce}_n}) \in \Phi \\ |
| 753 \Delta = \many{T} \quad |
| 754 \Gamma_i = |
| 755 \begin{cases} |
| 756 \Gamma_{\TApp{C}{\many{T}}} & \mbox{if $\mathit{vd}_i$ is a method} \
\ |
| 757 \Gamma & \mbox{if $\mathit{vd}_i$ is a field} \\ |
| 758 \end{cases}\\ |
| 759 |
| 760 \declOk[ce]{\Phi, \Delta, \Gamma_i}{\mathit{vd}_i : \mathit{ce}_i}{\mat
hit{vd}'_i}{\Gamma'_i} \quad\quad |
| 761 \mbox{for}\ i \in 0, \ldots, n |
| 762 \iftrans{\\ |
| 763 \mathit{cd'} = \dclass{\TApp{C}{\many{T}}}{\TApp{G}{\many{\tau}}}{\many
{\mathit{vd'}}} |
| 764 } |
| 765 } |
| 766 {\declOk[c]{\Phi, \Gamma} |
| 767 {\mathit{cd}} |
| 768 {\mathit{cd'}}{\Gamma'} |
| 769 } |
| 770 |
| 771 \subsection*{Override checking:\\ \quad\quad$\overrideOk{\Phi} |
| 772 {\TApp{C}{T_0, \ldots, T_n}} |
| 773 {\TApp{G}{\tau_0, \ldots, \tau_k}} |
| 774 {\mathit{ce}}$} |
| 775 \hrulefill\\ |
| 776 |
| 777 \sstext{ |
| 778 |
| 779 The override checking relation is the primary relation that checks the |
| 780 consistency of the class hierarchy. We assume a non-cyclic class hierarchy as a |
| 781 syntactic pre-condition. The override check relation checks that in a class |
| 782 declaration $\TApp{C}{T_0, \ldots, T_n}$ which extends $\TApp{G}{\tau_0, \ldots, |
| 783 \tau_k}$, the definition of an element with signature $\mathit{ce}$ is valid.
|
| 784 |
| 785 }{ |
| 786 |
| 787 Override checking remains largely the same, with the exception of additional |
| 788 consistency constraints on the internal signatures for methods. |
| 789 |
| 790 } |
| 791 |
| 792 \sstext{ |
| 793 |
| 794 A field with the type elided is a valid override if the same field with type |
| 795 $\Dynamic$ is valid. |
| 796 |
| 797 }{ |
| 798 |
| 799 } |
| 800 |
| 801 \infrule{ |
| 802 \overrideOk{\Phi} |
| 803 {\TApp{C}{T_0, \ldots, T_n}} |
| 804 {\TApp{G}{\tau_0, \ldots, \tau_k}} |
| 805 {\fieldDecl{x}{\Dynamic}} |
| 806 |
| 807 } |
| 808 { |
| 809 \overrideOk{\Phi} |
| 810 {\TApp{C}{T_0, \ldots, T_n}} |
| 811 {\TApp{G}{\tau_0, \ldots, \tau_k}} |
| 812 {\fieldDecl{x}{\_}} |
| 813 } |
| 814 |
| 815 \sstext{ |
| 816 |
| 817 A field with a type $\tau$ is a valid override if it appears in the super type |
| 818 with the same type. |
| 819 |
| 820 }{ |
| 821 |
| 822 } |
| 823 |
| 824 \infrule{\fieldLookup{\Phi}{\TApp{G}{\tau_0, \ldots, \tau_k}}{x}{\tau} |
| 825 } |
| 826 { |
| 827 \overrideOk{\Phi} |
| 828 {\TApp{C}{T_0, \ldots, T_n}} |
| 829 {\TApp{G}{\tau_0, \ldots, \tau_k}} |
| 830 {\fieldDecl{x}{\tau}} |
| 831 } |
| 832 |
| 833 \sstext{ |
| 834 |
| 835 A field with a type $\tau$ is a valid override if it does not appear in the supe
r type. |
| 836 |
| 837 }{ |
| 838 |
| 839 } |
| 840 |
| 841 \infrule{\fieldAbsent{\Phi}{\TApp{G}{\tau_0, \ldots, \tau_k}}{x} |
| 842 } |
| 843 { |
| 844 \overrideOk{\Phi} |
| 845 {\TApp{C}{T_0, \ldots, T_n}} |
| 846 {\TApp{G}{\tau_0, \ldots, \tau_k}} |
| 847 {\fieldDecl{x}{\tau}} |
| 848 } |
| 849 |
| 850 \sstext{ |
| 851 |
| 852 A method with a type $\sigma$ is a valid override if it does not appear in the s
uper type. |
| 853 |
| 854 }{ |
| 855 |
| 856 For a non-override method, we require that the internal type $\tau$ be a subtype |
| 857 of $\down{\sigma}$ where $\sigma$ is the declared type. Essentially, this |
| 858 enforces the property that the initial declaration of a method in the hierarchy |
| 859 has a covariant internal type. |
| 860 |
| 861 } |
| 862 |
| 863 \infrule{ |
| 864 \iftrans{ |
| 865 \Delta = T_0, \ldots, T_n \quad\quad |
| 866 \subtypeOf{\Phi, \Delta}{\tau}{\down{\sigma}}\ \\ |
| 867 } |
| 868 \methodAbsent{\Phi}{\TApp{G}{\tau_0, \ldots, \tau_k}}{f} |
| 869 } |
| 870 { |
| 871 \overrideOk{\Phi} |
| 872 {\TApp{C}{T_0, \ldots, T_n}} |
| 873 {\TApp{G}{\tau_0, \ldots, \tau_k}} |
| 874 {\methodDecl{f}{\tau}{\sigma}} |
| 875 } |
| 876 |
| 877 \sstext{ |
| 878 |
| 879 A method with a type $\sigma$ is a valid override if it appears in the super |
| 880 type, and $\sigma$ is a subtype of the type of the method in the super class. |
| 881 |
| 882 }{ |
| 883 |
| 884 For a method override, we require two coherence conditions. As before, we |
| 885 require that the internal type $\tau$ be a subtype of the $\down{\sigma}$ where |
| 886 $\sigma$ is the external type. Moreover, we also insist that the external type |
| 887 $\sigma$ be a subtype of the external type of the method in the superclass, and |
| 888 that the internal type $\tau$ be a subtype of the internal type in the |
| 889 superclass. Note that it this last consistency property that ensures that |
| 890 covariant generics are ``poisonous'' in the sense that non-generic subclasses of |
| 891 generic classes must still have additional checks. For example, a superclass |
| 892 with a method of external type $\sigma_s = \Arrow{T}{T}$ will have internal type |
| 893 $\tau_s = \Arrow{\Dynamic}{T}$. A subclass of an instantiation of this class |
| 894 with $\Num$ can validly override this method with one of external type $\sigma = |
| 895 \Arrow{\Num}{\Num}$. This is unsound in general since the argument occurrence |
| 896 of $T$ in $\sigma_s$ is contra-variant. However, the additional consistency |
| 897 requirement is that the internal type of the subclass method must be a subtype |
| 898 of $\subst{\Num}{T}{\tau_s} = \Arrow{\Dynamic}{\Num}$. This enforces the |
| 899 property that the overridden method must expect to be used at type |
| 900 $\Arrow{\Dynamic}{\Num}$, and hence must check its arguments (and potentially |
| 901 its return value as well in the higher-order case). This checking code is |
| 902 inserted during the elaboration of class members above. |
| 903 |
| 904 } |
| 905 |
| 906 \infrule{ |
| 907 \iftrans{ |
| 908 \Delta = T_0, \ldots, T_n \quad\quad |
| 909 \subtypeOf{\Phi, \Delta}{\tau}{\down{\sigma}}\ \\ |
| 910 } |
| 911 \methodLookup{\Phi}{\TApp{G}{\tau_0, \ldots, \tau_k}}{f}{\tau_s}{\sigma_s}
\\ |
| 912 \iftrans{ |
| 913 \subtypeOf{\Phi, \Delta}{\tau}{\tau_s}\quad\quad |
| 914 } |
| 915 \subtypeOf{\Phi, \Delta}{\sigma}{\sigma_s} |
| 916 } |
| 917 { |
| 918 \overrideOk{\Phi} |
| 919 {\TApp{C}{T_0, \ldots, T_n}} |
| 920 {\TApp{G}{\tau_0, \ldots, \tau_k}} |
| 921 {\methodDecl{f}{\tau}{\sigma}} |
| 922 } |
| 923 |
| 924 \subsection*{Toplevel declaration typing: $\declOk[t]{\Phi, \Gamma}{\mathit{td}
}{\mathit{td'}}{\Gamma'}$} |
| 925 \hrulefill\\ |
| 926 |
| 927 \sstext{ |
| 928 |
| 929 Top level variable declarations are well-typed if they are well-typed according |
| 930 to their respective specific typing relations. |
| 931 |
| 932 }{ |
| 933 |
| 934 Top level declaration elaboration falls through to the underlying variable and |
| 935 class declaration code. |
| 936 |
| 937 } |
| 938 |
| 939 \infrule |
| 940 {\declOk[d]{\Phi, \epsilon, \Gamma}{\mathit{vd}}{\mathit{vd'}}{\Gamma'} |
| 941 |
| 942 } |
| 943 {\declOk[t]{\Phi, \Gamma}{\mathit{vd}}{\mathit{vd'}}{\Gamma'} |
| 944 } |
| 945 |
| 946 \infrule |
| 947 {\declOk[c]{\Phi, \Gamma}{\mathit{cd}}{\mathit{cd'}}{\Gamma'} |
| 948 |
| 949 } |
| 950 {\declOk[t]{\Phi, \Gamma}{\mathit{cd}}{\mathit{cd'}}{\Gamma'} |
| 951 } |
| 952 |
| 953 |
| 954 \subsection*{Well-formed class signature: $\ok{\Phi}{\Sig}$} |
| 955 \hrulefill\\ |
| 956 |
| 957 \sstext{ |
| 958 |
| 959 The well-formed class signature relation checks whether a class signature is |
| 960 well-formed with respect to a given class hierarchy $\Phi$. |
| 961 |
| 962 }{ |
| 963 |
| 964 } |
| 965 |
| 966 \sstext{ |
| 967 |
| 968 The $\Object$ signature is always well-formed. |
| 969 |
| 970 }{ |
| 971 |
| 972 } |
| 973 |
| 974 \axiom{\ok{\Phi}{\Object} |
| 975 } |
| 976 |
| 977 \sstext{ |
| 978 |
| 979 A signature for a class $C$ is well-formed if its super-class signature is |
| 980 well-formed, and if every element in its signature is a valid override of the |
| 981 super-class. |
| 982 |
| 983 }{ |
| 984 |
| 985 } |
| 986 |
| 987 \infrule{\Sig = \dclass{\TApp{C}{\many{T}}} |
| 988 {\TApp{G}{\tau_0, \ldots, \tau_k}} |
| 989 {\mathit{ce}_0, \ldots, \mathit{ce}_n} \\ |
| 990 (G : \Sig') \in \Phi \quad\quad \ok{\Phi}{\Sig'} \\ |
| 991 \overrideOk{\Phi}{\TApp{C}{\many{T}}}{\TApp{G}{\tau_0, \ldots, \tau_k}}{
\mathit{ce}_i} |
| 992 \quad\quad |
| 993 \mbox{for}\ \mathit{ce}_i \in \mathit{ce}_0, \ldots, \mathit{ce}_n |
| 994 } |
| 995 {\ok{\Phi}{\Sig} |
| 996 } |
| 997 |
| 998 \subsection*{Well-formed class hierarchy: $\ok{}{\Phi}$} |
| 999 \hrulefill\\ |
| 1000 |
| 1001 \sstext{ |
| 1002 |
| 1003 A class hierarchy is well-formed if all of the signatures in it are well-formed |
| 1004 with respect to it. |
| 1005 |
| 1006 }{ |
| 1007 |
| 1008 } |
| 1009 |
| 1010 \infrule{\ok{\Phi}{\Sig}\ \mbox{for}\, \Sig\, \in \Phi |
| 1011 } |
| 1012 {\ok{}{\Phi} |
| 1013 } |
| 1014 |
| 1015 \subsection*{Program typing: $\programOk{\Phi}{P}{P'}$} |
| 1016 \hrulefill\\ |
| 1017 |
| 1018 %%Definitions: |
| 1019 %% |
| 1020 %% \begin{eqnarray*} |
| 1021 %% \sigof{\mathit{vd}} & = & |
| 1022 %% \begin{cases} |
| 1023 %% \fieldDecl{x}{\tau} & \mbox{if}\ \mathit{vd} = \dvar{x:\tau}{e}\\ |
| 1024 %% \fieldDecl{x}{\Dynamic} & \mbox{if}\ \mathit{vd} = \dvar{x:\_}{e}\\ |
| 1025 %% \methodDecl{f}{\tau_f}{\Arrow[+]{\many{\tau}}{\sigma}} & \mbox{if}\ \math
it{vd} = \dfun{\sigma}{f}{\many{x:\tau}}{s} |
| 1026 %% \end{cases}\\ |
| 1027 %% \sigof{\mathit{cd}} & = & C\, : \, \dclass{\TApp{C}{\many{T}}} |
| 1028 %% {\TApp{G}{\tau_0, \ldots, \tau_k}} |
| 1029 %% {\mathit{ce}_0, \ldots, \mathit{ce}_
n} \\ |
| 1030 %% \mbox{where} && |
| 1031 %% \mathit{cd} = \dclass{\TApp{C}{\many{T}}} |
| 1032 %% {\TApp{G}{\tau_0, \ldots, \tau_k}} |
| 1033 %% {\mathit{vd}_0, \ldots, \mathit{vd}_n} \\ |
| 1034 %% \mbox{and} && |
| 1035 %% \mathit{ce}_i = \sigof{vd_i} \quad \mbox{for}\ i \in 0, \ldots, n |
| 1036 %%\end{eqnarray*} |
| 1037 |
| 1038 \sstext{ |
| 1039 |
| 1040 Program well-formedness is defined with respect to a class hierarchy $\Phi$. It |
| 1041 is not specified how $\Phi$ is produced, but the well-formedness constraints in |
| 1042 the various judgments should constrain it appropriately. A program is |
| 1043 well-formed if each of the top level declarations in the program is well-formed |
| 1044 in a context in which all of the previous variable declarations have been |
| 1045 checked and inserted in the context, and if the body of the program is |
| 1046 well-formed in the final context. We allow classes to refer to each other in |
| 1047 any order, since $\Phi$ is pre-specified, but do not model out of order |
| 1048 definitions of top level variables and functions. We assume as a syntactic |
| 1049 property that the class hierarchy $\Phi$ is acyclic. |
| 1050 |
| 1051 }{ |
| 1052 |
| 1053 } |
| 1054 |
| 1055 \infrule{ \Gamma_0 = \epsilon \quad\quad |
| 1056 \declOk[t]{\Phi, \Gamma_i}{\mathit{td}_i}{\mathit{td}'_i}{\Gamma_{i+1
}} \quad |
| 1057 \mbox{for}\ i \in 0,\ldots,n\\ |
| 1058 \stmtOk{\Phi, \epsilon, \Gamma_{n+1}}{s}{\tau}{s'}{\Gamma_{n+1}'} |
| 1059 } |
| 1060 { \programOk{\Phi}{\program{\mathit{td}_0, \ldots, \mathit{td}_n}{s}} |
| 1061 {\program{\mathit{td}'_0, \ldots, \mathit{td}'_n}{s'}} |
| 1062 } |
OLD | NEW |