parent = $parent; $this->expressions = $expressions; $this->method = $method; $this->variables = array( array('name' => 'arguments', 'type' => 'arguments') ); $this->positions = array(); if ( ! $this->parent) { self::$root = $this; } } function add($name, $type, $immediate = FALSE) { $name = ''.$name; if ($this->shared && ! $immediate) { return $this->parent->add($name, $type, $immediate); } if (isset($this->positions[$name])) { $this->variables[$this->positions[$name]]['type'] = $type; } else { $this->variables[] = array('name' => $name, 'type' => $type); $this->positions[$name] = count($this->variables) - 1; } } function assign($name, $value) { $this->add($name, array('value' => $value, 'assigned' => TRUE), TRUE); $this->has_assignments = TRUE; } function assigned_variables() { $tmp = array(); foreach ($this->variables as $v) { $type = $v['type']; if (is_array($type) && isset($type['assigned']) && $type['assigned']) { $tmp[] = "{$v['name']} = {$type['value']}"; } } return $tmp; } function check($name, $immediate = FALSE) { $name = ''.$name; $found = !! $this->type($name); if ($found || $immediate) { return $found; } return $this->parent ? $this->parent->check($name) : FALSE; } function declared_variables() { $real_vars = array(); $temp_vars = array(); foreach ($this->variables as $v) { if ($v['type'] === 'var') { if ($v['name']{0} === '_') { $temp_vars[] = $v['name']; } else { $real_vars[] = $v['name']; } } } asort($real_vars); asort($temp_vars); return array_merge($real_vars, $temp_vars); } function find($name, $options = array()) { if ($this->check($name, $options)) { return TRUE; } $this->add($name, 'var'); return FALSE; } function free_variable($name, $reserve = TRUE) { $index = 0; while ($this->check(($temp = $this->temporary($name, $index)))) { $index++; } if ($reserve) { $this->add($temp, 'var', TRUE); } return $temp; } function has_assignments() { return $this->has_assignments; } function has_declarations() { return !! count($this->declared_variables()); } function parameter($name) { if ($this->shared && $this->parent->check($name, TRUE)) { return; } $this->add($name, 'param'); } function temporary($name, $index) { if (strlen($name) > 1) { return '_'.$name.($index > 1 ? $index - 1 : ''); } else { $val = strval(base_convert($index + intval($name, 36), 10, 36)); $val = preg_replace('/\d/', 'a', $val); return '_'.$val; } } function type($name) { foreach ($this->variables as $v) { if ($v['name'] === $name) { return $v['type']; } } return NULL; } } ?>