/** * Determines the type from the operation (assumes that the type or the value is unknown) * * @param string $op the operator * @param PC_Obj_MultiType $t1 the type of the first operand * @param PC_Obj_MultiType $t2 the type of the second operand (may be null for unary ops) * @return PC_Obj_MultiType the variable */ protected function get_type_from_op($op, $t1, $t2 = null) { switch ($op) { // bitwise operators have always int as result case '|': case '&': case '^': case '>>': case '<<': case '~': case '?:': return PC_Obj_MultiType::create_int(); // concatenation leads always to string // concatenation leads always to string case '.': return PC_Obj_MultiType::create_string(); case '+': case '-': case '*': case '/': case '%': // if one of them is unknown we don't know whether we would get a float or int if ($t1->is_unknown() || $t1->is_multiple() || $t2 !== null && ($t2->is_unknown() || $t2->is_multiple())) { return new PC_Obj_MultiType(); } $ti1 = $t1->get_first()->get_type(); $ti2 = $t2 === null ? -1 : $t2->get_first()->get_type(); // if both are arrays, the result is an array if ($ti1 == PC_Obj_Type::TARRAY && $ti2 == PC_Obj_Type::TARRAY) { return PC_Obj_MultiType::create_array(); } // if one of them is float, the result is float if ($ti1 == PC_Obj_Type::FLOAT || $ti2 == PC_Obj_Type::FLOAT) { return PC_Obj_MultiType::create_float(); } // otherwise its always int return PC_Obj_MultiType::create_int(); case '==': case '!=': case '===': case '!==': case '<': case '>': case '<=': case '>=': case '&&': case '||': case 'xor': case '!': // always bool return PC_Obj_MultiType::create_bool(); default: FWS_Helper::error('Unknown operator "' . $op . '"'); } }
/** * Returns a variable pointing to the array-element with given key. If it does not exist, it * will be created as soon as the type is assigned. * * @param PC_Obj_MultiType $key the key (null = append) * @return PC_Obj_Variable the type of the element */ public function array_offset($key) { assert(!$this->type->is_multiple() && !$this->type->is_unknown()); $first = $this->type->get_first(); assert($first->get_type() == PC_Obj_Type::TARRAY); // fetch element or create it $akey = $key; if ($key === null) { $akey = $key = $first->get_next_array_key(); } else { if (!$key->is_unknown()) { $akey = $key; $key = $first->get_array_type($key->get_first()->get_value()); } } $var = new self($this->get_file(), $this->get_line(), '', $key); // connect the var to us $var->arrayref = $this; $var->arrayoff = $akey; return $var; }