protected function generate_op_loop($details, &$body)
{
if (isset($details['empty'])) {
$body->do_if(hexpr(hexec('count', hvar($details['array'])), '==', 0));
$this->generate_op_code($details['empty'], $body);
$body->do_else();
}
/* ForID */
$oldid = $this->forid;
$this->forid = $oldid + 1;
$this->forloop[$this->forid] = array();
if (isset($details['range'])) {
$this->set_safe($details['variable']);
} else {
/* check variable context */
/* Check if the array to iterate is an object */
$var =& $details['array'][0];
if (is_string($var) && $this->var_is_object(array($var), FALSE)) {
/* It is an object, call to get_object_vars */
$body->decl($var . '_arr', hexec('get_object_vars', hvar($var)));
$var .= '_arr';
}
unset($var);
/* variables */
$array = $this->get_filtered_var($details['array'], $varname);
/* Loop body */
if ($this->is_safe(hvar($varname))) {
$this->set_safe(hvar($details['variable']));
}
if ($array instanceof Haanga_AST) {
// filtered var
$tmp = hvar('tmp' . ($oldid + 1));
$body->decl($tmp, $array);
$array = $tmp;
}
$details['array'] = $array;
}
/* for_body {{{ */
$for_body = hcode();
$this->generate_op_code($details['body'], $for_body);
$oid = $this->forid;
$size = hvar('psize_' . $oid);
// counter {{{
if (isset($this->forloop[$oid]['counter'])) {
$var = hvar('forcounter1_' . $oid);
$body->decl($var, 1);
$for_body->decl($var, hexpr($var, '+', 1));
}
// }}}
// counter0 {{{
if (isset($this->forloop[$oid]['counter0'])) {
$var = hvar('forcounter0_' . $oid);
$body->decl($var, 0);
$for_body->decl($var, hexpr($var, '+', 1));
}
// }}}
// last {{{
if (isset($this->forloop[$oid]['last'])) {
if (!isset($cnt)) {
$body->decl('psize_' . $oid, hexec('count', hvar_ex($details['array'])));
$cnt = TRUE;
}
$var = 'islast_' . $oid;
$body->decl($var, hexpr(hvar('forcounter1_' . $oid), '==', $size));
$for_body->decl($var, hexpr(hvar('forcounter1_' . $oid), '==', $size));
}
// }}}
// first {{{
if (isset($this->forloop[$oid]['first'])) {
$var = hvar('isfirst_' . $oid);
$body->decl($var, TRUE);
$for_body->decl($var, FALSE);
}
// }}}
// revcounter {{{
if (isset($this->forloop[$oid]['revcounter'])) {
if (!isset($cnt)) {
$body->decl('psize_' . $oid, hexec('count', hvar_ex($details['array'])));
$cnt = TRUE;
}
$var = hvar('revcount_' . $oid);
$body->decl($var, $size);
$for_body->decl($var, hexpr($var, '-', 1));
}
// }}}
// revcounter0 {{{
if (isset($this->forloop[$oid]['revcounter0'])) {
if (!isset($cnt)) {
$body->decl('psize_' . $oid, hexec('count', hvar_ex($details['array'])));
$cnt = TRUE;
}
$var = hvar('revcount0_' . $oid);
$body->decl($var, hexpr($size, "-", 1));
$for_body->decl($var, hexpr($var, '-', 1));
}
// }}}
/* }}} */
/* Restore old ForID */
$this->forid = $oldid;
/* Merge loop body */
if (!isset($details['range'])) {
$body->do_foreach($array, $details['variable'], $details['index'], $for_body);
if ($this->is_safe(hvar($varname))) {
$this->set_unsafe($details['variable']);
}
} else {
for ($i = 0; $i < 2; $i++) {
if (Haanga_AST::is_var($details['range'][$i])) {
$details['range'][$i] = $this->generate_variable_name($details['range'][$i]['var']);
}
}
if (Haanga_AST::is_var($details['step'])) {
$details['step'] = $this->generate_variable_name($details['step']['var']);
}
$body->do_for($details['variable'], $details['range'][0], $details['range'][1], $details['step'], $for_body);
$this->set_unsafe(hvar($details['variable']));
}
if (isset($details['empty'])) {
$body->do_endif();
}
}