/**
* 14.14.2: The enhanced for statement
*
* @author Lennart Kats <lennart add lclnet.nl>
*/
module dryad/type-check/stm/ForStatement
rules
/**
* Define the type of and conversions for a local variable declared in
* an enhanced for loop.
*/
dryad-tc-foreach(rec) =
?ForEach(_, _, _)
; {| TypeOf :
ForEach(id, rec, id)
; ForEach(dryad-tc-declare-param, id, rec)
|}
; try(dryad-tc-foreach-add-conversion(rec))
/**
* The foreach is defined as a desugaring over the regular for;
* do on-the-fly desugaring to determine the required conversion.
*/
dryad-tc-foreach-add-conversion(rec) :
ForEach(Param(mods, type, Id(x)), list, body) ->
ForEach(Param(mods, type, Id(x)) {conversion}, list, body)
where
rhs-type := <get-foreach-rhs-value; rec; type-attr>
; conversion := <assignment-conversion(|type)> rhs-type
/** @internal */
strategies
get-foreach-rhs-value =
?ForEach(_, list, _)
; where(ArrayType(_) := <dryad-type-of> list)
; !ArrayAccess(list, Lit(Deci("0")))
get-foreach-rhs-value =
?ForEach(_, list, _)
; where(
<type-attr> list
; is-subtype(|TypeIterable())
)
; !Invoke(Method(list, None(), Id("iterator")), [])
; !Invoke(Method(<id>, None(), Id("next")), [])