Boot.hx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976
  1. /*
  2. * Copyright (C)2005-2015 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. package php;
  23. @:keep
  24. class Boot {
  25. static var qtypes;
  26. static var ttypes;
  27. static var tpaths;
  28. static var skip_constructor = false;
  29. static function __init__() : Void {
  30. var _hx_class_prefix = untyped __prefix__();
  31. untyped __php__("
  32. function _hx_add($a, $b) {
  33. if (!_hx_is_numeric($a) || !_hx_is_numeric($b)) {
  34. return _hx_string_or_null($a) . _hx_string_or_null($b);
  35. } else {
  36. return $a + $b;
  37. }
  38. }
  39. function _hx_anonymous($arr = array()) {
  40. $o = new _hx_anonymous();
  41. foreach($arr as $k => $v)
  42. $o->$k = $v;
  43. return $o;
  44. }
  45. class _hx_array implements ArrayAccess, IteratorAggregate {
  46. var $a;
  47. var $length;
  48. function __construct($a = array()) {
  49. $this->a = $a;
  50. $this->length = count($a);
  51. }
  52. function concat($a) {
  53. return new _hx_array(array_merge($this->a, $a->a));
  54. }
  55. function copy() {
  56. return new _hx_array($this->a);
  57. }
  58. function &get($index) {
  59. if(isset($this->a[$index])) return $this->a[$index];
  60. return null;
  61. }
  62. function insert($pos, $x) {
  63. array_splice($this->a, $pos, 0, array($x));
  64. $this->length++;
  65. }
  66. function iterator() {
  67. return new _hx_array_iterator($this->a);
  68. }
  69. function getIterator() {
  70. return $this->iterator();
  71. }
  72. function join($sep) {
  73. return implode($sep, array_map('_hx_string_rec',$this->a,array()));
  74. }
  75. function pop() {
  76. $r = array_pop($this->a);
  77. $this->length = count($this->a);
  78. return $r;
  79. }
  80. function push($x) {
  81. $this->a[] = $x;
  82. return ++$this->length;
  83. }
  84. function remove($x) {
  85. for($i = 0; $i < count($this->a); $i++)
  86. if($this->a[$i] === $x) {
  87. unset($this->a[$i]);
  88. $this->a = array_values($this->a);
  89. $this->length--;
  90. return true;
  91. }
  92. return false;
  93. }
  94. function indexOf($x, $fromIndex) {
  95. $i = ($fromIndex === null) ? 0 : $fromIndex;
  96. $len = $this->length;
  97. $a = $this->a;
  98. if ($i < 0) {
  99. $i += $len;
  100. if ($i < 0) $i = 0;
  101. }
  102. while ($i < $len) {
  103. if ($a[$i] === $x)
  104. return $i;
  105. $i++;
  106. }
  107. return -1;
  108. }
  109. function lastIndexOf($x, $fromIndex) {
  110. $len = $this->length;
  111. $i = ($fromIndex === null) ? $len - 1 : $fromIndex;
  112. $a = $this->a;
  113. if ($i >= $len)
  114. $i = $len - 1;
  115. else if ($i < 0)
  116. $i += $len;
  117. while ($i >= 0) {
  118. if ($a[$i] === $x)
  119. return $i;
  120. $i--;
  121. }
  122. return -1;
  123. }
  124. function removeAt($pos) {
  125. if(array_key_exists($pos, $this->a)) {
  126. unset($this->a[$pos]);
  127. $this->length--;
  128. return true;
  129. } else
  130. return false;
  131. }
  132. function reverse() {
  133. $this->a = array_reverse($this->a, false);
  134. }
  135. function shift() {
  136. $r = array_shift($this->a);
  137. $this->length = count($this->a);
  138. return $r;
  139. }
  140. function slice($pos, $end) {
  141. if($end === null)
  142. return new _hx_array(array_slice($this->a, $pos));
  143. else
  144. return new _hx_array(array_slice($this->a, $pos, $end-$pos));
  145. }
  146. function sort($f) {
  147. usort($this->a, $f);
  148. }
  149. function splice($pos, $len) {
  150. if($len < 0) $len = 0;
  151. $nh = new _hx_array(array_splice($this->a, $pos, $len));
  152. $this->length = count($this->a);
  153. return $nh;
  154. }
  155. function toString() {
  156. return '['.implode(',', array_map('_hx_string_rec',$this->a,array())).']';
  157. }
  158. function __toString() {
  159. return $this->toString();
  160. }
  161. function unshift($x) {
  162. array_unshift($this->a, $x);
  163. $this->length++;
  164. }
  165. function map($f) {
  166. return new _hx_array(array_map($f, $this->a));
  167. }
  168. function reduce($f, $first) {
  169. return array_reduce($this->a, $f, $first);
  170. }
  171. function filter($f) {
  172. return new _hx_array(array_values(array_filter($this->a,$f)));
  173. }
  174. // ArrayAccess methods:
  175. function offsetExists($offset) {
  176. return isset($this->a[$offset]);
  177. }
  178. function offsetGet($offset) {
  179. if(isset($this->a[$offset])) return $this->a[$offset];
  180. return null;
  181. }
  182. function offsetSet($offset, $value) {
  183. if($this->length <= $offset) {
  184. $this->a = array_merge($this->a, array_fill(0, $offset+1-$this->length, null));
  185. $this->length = $offset+1;
  186. }
  187. return $this->a[$offset] = $value;
  188. }
  189. function offsetUnset($offset) {
  190. return $this->removeAt($offset);
  191. }
  192. }
  193. class _hx_array_iterator implements Iterator {
  194. private $a;
  195. private $i;
  196. public function __construct($a) {
  197. $this->a = $a;
  198. $this->i = 0;
  199. }
  200. public function next() {
  201. if(!$this->hasNext()) return null;
  202. return $this->a[$this->i++];
  203. }
  204. public function hasNext() {
  205. return $this->i < count($this->a);
  206. }
  207. public function current() {
  208. if (!$this->hasNext()) return false;
  209. return $this->a[$this->i];
  210. }
  211. public function key() {
  212. return $this->i;
  213. }
  214. public function valid() {
  215. return $this->current() !== false;
  216. }
  217. public function rewind() {
  218. $this->i = 0;
  219. }
  220. public function size() {
  221. return count($this->a);
  222. }
  223. }
  224. function _hx_array_get($a, $pos) { return $a[$pos]; }
  225. function _hx_array_increment($a, $pos) { return $a[$pos] += 1; }
  226. function _hx_array_decrement($a, $pos) { return $a[$pos] -= 1; }
  227. function _hx_array_assign($a, $i, $v) { return $a[$i] = $v; }
  228. class _hx_break_exception extends Exception {}
  229. function _hx_cast($v, $type) {
  230. if(Std::is($v, $type)) {
  231. return $v;
  232. } else {
  233. throw new HException('Class cast error');
  234. }
  235. }
  236. function _hx_char_at($o, $i) {
  237. if ($i < 0)
  238. return '';
  239. $c = substr($o, $i, 1);
  240. return FALSE === $c ? '' : $c;
  241. }
  242. function _hx_char_code_at($s, $pos) {
  243. if($pos < 0 || $pos >= strlen($s)) return null;
  244. return ord($s{$pos});
  245. }
  246. function _hx_deref($o) { return $o; }
  247. function _hx_equal($x, $y) {
  248. if(is_null($x)) {
  249. return is_null($y);
  250. } else {
  251. if(is_null($y)) {
  252. return false;
  253. } else {
  254. if((is_float($x) || is_int($x)) && (is_float($y) || is_int($y))) {
  255. return $x == $y;
  256. } else {
  257. return $x === $y;
  258. }
  259. }
  260. }
  261. }
  262. function _hx_mod($x, $y) {
  263. if (is_int($x) && is_int($y)) {
  264. if ($y == 0) return 0;
  265. return $x % $y;
  266. }
  267. if (!is_nan($x) && !is_nan($y) && !is_finite($y) && is_finite($x)) {
  268. return $x;
  269. }
  270. return fmod($x, $y);
  271. }
  272. function _hx_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
  273. if (!(error_reporting() & $errno)) {
  274. return false;
  275. }
  276. $msg = $errmsg . ' (errno: ' . $errno . ') in ' . $filename . ' at line #' . $linenum;
  277. $e = new HException($msg, $errmsg, $errno, _hx_anonymous(array('fileName' => 'Boot.hx', 'lineNumber' => __LINE__, 'className' => 'php.Boot', 'methodName' => '_hx_error_handler')));
  278. $e->setFile($filename);
  279. $e->setLine($linenum);
  280. throw $e;
  281. return null;
  282. }
  283. function _hx_exception_handler($e) {
  284. if(0 == strncasecmp(PHP_SAPI, 'cli', 3)) {
  285. $msg = $e-> getMessage();
  286. $nl = \"\\n\";
  287. $pre = '';
  288. $post = '';
  289. } else {
  290. $msg = '<b>' . $e-> getMessage() . '</b>';
  291. $nl = \"<br />\";
  292. $pre = '<pre>';
  293. $post = '</pre>';
  294. }
  295. if(isset($GLOBALS['%s'])) {
  296. $stack = '';
  297. $i = $GLOBALS['%s']->length;
  298. while(--$i >= 0)
  299. $stack .= 'Called from '.$GLOBALS['%s'][$i].$nl;
  300. die($pre.'uncaught exception: '.$msg.$nl.$nl.$stack.$post);
  301. } else
  302. die($pre.'uncaught exception: '.$msg.$nl.$nl.'in file: '.$e->getFile().' line '.$e->getLine().$nl.$e->getTraceAsString().$post);
  303. }
  304. function _hx_explode($delimiter, $s) {
  305. if($delimiter == '')
  306. return new _hx_array(str_split($s, 1));
  307. return new _hx_array(explode($delimiter, $s));
  308. }
  309. function _hx_explode2($s, $delimiter) {
  310. if($delimiter == '')
  311. return new _hx_array(str_split($s, 1));
  312. return new _hx_array(explode($delimiter, $s));
  313. }
  314. function _hx_field($o, $field) {
  315. if(_hx_has_field($o, $field)) {
  316. if($o instanceof _hx_type) {
  317. if(is_callable($c = array($o->__tname__, $field)) && !property_exists($o->__tname__, $field)) {
  318. return $c;
  319. } else {
  320. $name = $o->__tname__;
  321. return eval('return '.$name.'::$'.$field.';');
  322. }
  323. } else {
  324. if(is_string($o)) {
  325. if($field == 'length') {
  326. return strlen($o);
  327. } else {
  328. switch($field) {
  329. case 'charAt' : return array(new _hx_lambda(array(&$o), '_hx_char_at'), 'execute');
  330. case 'charCodeAt' : return array(new _hx_lambda(array(&$o), '_hx_char_code_at'), 'execute');
  331. case 'indexOf' : return array(new _hx_lambda(array(&$o), '_hx_index_of'), 'execute');
  332. case 'lastIndexOf': return array(new _hx_lambda(array(&$o), '_hx_last_index_of'), 'execute');
  333. case 'split' : return array(new _hx_lambda(array(&$o), '_hx_explode2'), 'execute');
  334. case 'substr' : return array(new _hx_lambda(array(&$o), '_hx_substr'), 'execute');
  335. case 'toUpperCase': return array(new _hx_lambda(array(&$o), 'strtoupper'), 'execute');
  336. case 'toLowerCase': return array(new _hx_lambda(array(&$o), 'strtolower'), 'execute');
  337. case 'toString' : return array(new _hx_lambda(array(&$o), '_hx_deref'), 'execute');
  338. }
  339. return null;
  340. }
  341. } else {
  342. if(property_exists($o, $field)) {
  343. if(is_array($o->$field) && is_callable($o->$field)) {
  344. return $o->$field;
  345. } else {
  346. if(is_string($o->$field) && _hx_is_lambda($o->$field)) {
  347. return array($o, $field);
  348. } else {
  349. return $o->$field;
  350. }
  351. }
  352. } else if(isset($o->__dynamics) && isset($o->__dynamics[$field])) {
  353. return $o->__dynamics[$field];
  354. } else {
  355. return array($o, $field);
  356. }
  357. }
  358. }
  359. } else {
  360. return null;
  361. }
  362. }
  363. function _hx_get_object_vars($o) {
  364. $a = array_keys(get_object_vars($o));
  365. if(isset($o->__dynamics))
  366. $a = array_merge($a, array_keys($o->__dynamics));
  367. $arr = array();
  368. for($i=0;$i<count($a); $i++)
  369. {
  370. $arr[] = '' . $a[$i];
  371. }
  372. return $arr;
  373. }
  374. function _hx_has_field($o, $field) {
  375. return
  376. (is_object($o) && (method_exists($o, $field) || isset($o->$field) || property_exists($o, $field) || isset($o->__dynamics[$field])))
  377. ||
  378. (is_string($o) && (in_array($field, array('toUpperCase', 'toLowerCase', 'charAt', 'charCodeAt', 'indexOf', 'lastIndexOf', 'split', 'substr', 'toString', 'length'))))
  379. ;
  380. }
  381. function _hx_index_of($s, $value, $startIndex = null) {
  382. $x = strpos($s, $value, $startIndex);
  383. if($x === false)
  384. return -1;
  385. else
  386. return $x;
  387. }
  388. function _hx_instanceof($v, $t) {
  389. if($t === null) {
  390. return false;
  391. }
  392. switch($t->__tname__) {
  393. case 'Array' : return is_array($v);
  394. case 'String' : return is_string($v) && !_hx_is_lambda($v);
  395. case 'Bool' : return is_bool($v);
  396. case 'Int' : return (is_int($v) || (is_float($v) && intval($v) == $v && !is_nan($v))) && abs($v) <= 0x80000000;
  397. case 'Float' : return is_float($v) || is_int($v);
  398. case 'Dynamic': return true;
  399. case 'Class' : return ($v instanceof _hx_class || $v instanceof _hx_interface) && $v->__tname__ != 'Enum';
  400. case 'Enum' : return $v instanceof _hx_enum;
  401. default : return is_a($v, $t->__tname__);
  402. }
  403. }
  404. function _hx_is_lambda($s) {
  405. return (is_string($s) && substr($s, 0, 8) == chr(0).'lambda_') || (is_array($s) && count($s) > 0 && (is_a($s[0], '_hx_lambda') || is_a($s[0], '_hx_lambda2')));
  406. }
  407. function _hx_is_numeric($v)
  408. {
  409. return is_numeric($v) && !is_string($v);
  410. }
  411. function _hx_last_index_of($s, $value, $startIndex = null) {
  412. $x = strrpos($s, $value, $startIndex === null ? 0 : $startIndex-strlen($s));
  413. if($x === false)
  414. return -1;
  415. else
  416. return $x;
  417. }
  418. function _hx_len($o) {
  419. return is_string($o) ? strlen($o) : $o->length;
  420. }
  421. class _hx_list_iterator implements Iterator {
  422. private $h;
  423. private $list;
  424. private $counter;
  425. public function __construct($list) {
  426. $this->list = $list;
  427. $this->rewind();
  428. }
  429. public function next() {
  430. if($this->h == null) return null;
  431. $this->counter++;
  432. $x = $this->h[0];
  433. $this->h = $this->h[1];
  434. return $x;
  435. }
  436. public function hasNext() {
  437. return $this->h != null;
  438. }
  439. public function current() {
  440. if (!$this->hasNext()) return null;
  441. return $this->h[0];
  442. }
  443. public function key() {
  444. return $this->counter;
  445. }
  446. public function valid() {
  447. return $this->current() !== null;
  448. }
  449. public function rewind() {
  450. $this->counter = -1;
  451. $this->h = $this->list->h;
  452. }
  453. public function size() {
  454. return $this->list->length;
  455. }
  456. }
  457. function _hx_null() { return null; }
  458. class _hx_nullob {
  459. function _throw() { throw new HException('Null object'); }
  460. function __call($f, $a) { $this->_throw(); }
  461. function __get($f) { $this->_throw(); }
  462. function __set($f, $v) { $this->_throw(); }
  463. function __isset($f) { $this->_throw(); }
  464. function __unset($f) { $this->_throw(); }
  465. function __toString() { return 'null'; }
  466. static $inst;
  467. }
  468. _hx_nullob::$inst = new _hx_nullob();
  469. function _hx_nullob() { return _hx_nullob::$inst; }
  470. function _hx_qtype($n) {
  471. return isset(php_Boot::$qtypes[$n]) ? php_Boot::$qtypes[$n] : null;
  472. }
  473. function _hx_register_type($t) {
  474. php_Boot::$qtypes[$t->__qname__] = $t;
  475. php_Boot::$ttypes[$t->__tname__] = $t;
  476. if($t->__path__ !== null)
  477. php_Boot::$tpaths[$t->__tname__] = $t->__path__;
  478. }
  479. function _hx_set_method($o, $field, $func) {
  480. $value[0]->scope = $o;
  481. $o->$field = $func;
  482. }
  483. function _hx_shift_right($v, $n) {
  484. return ($n == 0) ? $v : ($v >= 0) ? ($v >> $n) : ($v >> $n) & (0x7fffffff >> ($n-1));
  485. }
  486. function _hx_string_call($s, $method, $params) {
  487. if(!is_string($s)) return call_user_func_array(array($s, $method), $params);
  488. switch($method) {
  489. case 'toUpperCase': return strtoupper($s);
  490. case 'toLowerCase': return strtolower($s);
  491. case 'charAt' : return substr($s, $params[0], 1);
  492. case 'charCodeAt' : return _hx_char_code_at($s, $params[0]);
  493. case 'indexOf' : return _hx_index_of($s, $params[0], (count($params) > 1 ? $params[1] : null));
  494. case 'lastIndexOf': return _hx_last_index_of($s, $params[0], (count($params) > 1 ? $params[1] : null));
  495. case 'split' : return _hx_explode($params[0], $s);
  496. case 'substr' : return _hx_substr($s, $params[0], (count($params) > 1 ? $params[1] : null));
  497. case 'toString' : return $s;
  498. default : throw new HException('Invalid Operation: ' . $method);
  499. }
  500. }
  501. function _hx_string_or_null($s) {
  502. return $s === null ? 'null' : $s;
  503. }
  504. function _hx_string_rec($o, $s) {
  505. if($o === null) return 'null';
  506. if(strlen($s) >= 5) return '<...>';
  507. if(is_int($o) || is_float($o)) return '' . $o;
  508. if(is_bool($o)) return $o ? 'true' : 'false';
  509. if(is_object($o)) {
  510. $c = get_class($o);
  511. if($o instanceof Enum) {
  512. $b = $o->tag;
  513. if(!empty($o->params)) {
  514. $s .= \"\t\";
  515. $b .= '(';
  516. for($i = 0; $i < count($o->params); $i++) {
  517. if($i > 0)
  518. $b .= ',' . _hx_string_rec($o->params[$i], $s);
  519. else
  520. $b .= _hx_string_rec($o->params[$i], $s);
  521. }
  522. $b .= ')';
  523. }
  524. return $b;
  525. } else {
  526. if ($o instanceof _hx_anonymous) {
  527. if ($o->toString && is_callable($o->toString)) {
  528. return call_user_func($o->toString);
  529. }
  530. $rfl = new ReflectionObject($o);
  531. $b2 = \"{\n\";
  532. $s .= \"\t\";
  533. $properties = $rfl->getProperties();
  534. for($i = 0; $i < count($properties); $i++) {
  535. $prop = $properties[$i];
  536. $f = $prop->getName();
  537. if($i > 0)
  538. $b2 .= \", \n\";
  539. $b2 .= $s . $f . ' : ' . _hx_string_rec($o->$f, $s);
  540. }
  541. $s = substr($s, 1);
  542. $b2 .= \"\n\" . $s . '}';
  543. return $b2;
  544. } else {
  545. if($o instanceof _hx_type)
  546. return $o->__qname__;
  547. else {
  548. if(is_callable(array($o, 'toString')))
  549. return $o->toString();
  550. else {
  551. if(is_callable(array($o, '__toString')))
  552. return $o->__toString();
  553. else
  554. return '[' . _hx_ttype($c) . ']';
  555. }
  556. }
  557. }
  558. }
  559. }
  560. if(is_string($o)) {
  561. if(_hx_is_lambda($o)) return '<function>';
  562. // if(strlen($s) > 0) return '\"' . str_replace('\"', '\\\"', $o) . '\"';
  563. else return $o;
  564. }
  565. if(is_array($o)) {
  566. if(is_callable($o)) return '<function>';
  567. $str = '[';
  568. $s .= \"\t\";
  569. $first = true;
  570. $assoc = true;
  571. foreach($o as $k => $v)
  572. {
  573. if ($first && $k === 0)
  574. $assoc = false;
  575. $str .= ($first ? '' : ',') . ($assoc
  576. ? _hx_string_rec($k, $s) . '=>' . _hx_string_rec($o[$k], $s)
  577. : _hx_string_rec($o[$k], $s)
  578. );
  579. $first = false;
  580. }
  581. $str .= ']';
  582. return $str;
  583. }
  584. return '';
  585. }
  586. function _hx_substr($s, $pos, $len) {
  587. if($pos !== null && $pos !== 0 && $len !== null && $len < 0) return '';
  588. if($len === null) $len = strlen($s);
  589. if($pos < 0) {
  590. $pos = strlen($s) + $pos;
  591. if($pos < 0) $pos = 0;
  592. } else if($len < 0 )
  593. $len = strlen($s) + $len - $pos;
  594. $s = substr($s, $pos, $len);
  595. if($s === false)
  596. return '';
  597. else
  598. return $s;
  599. }
  600. function _hx_substring($s, $startIndex, $endIndex) {
  601. $len = strlen($s);
  602. if ($endIndex === null)
  603. $endIndex = $len;
  604. else if ($endIndex < 0)
  605. $endIndex = 0;
  606. else if ($endIndex > $len)
  607. $endIndex = $len;
  608. if ($startIndex < 0)
  609. $startIndex = 0;
  610. else if ($startIndex > $len)
  611. $startIndex = $len;
  612. if ($startIndex > $endIndex) {
  613. $tmp = $startIndex;
  614. $startIndex = $endIndex;
  615. $endIndex = $tmp;
  616. }
  617. return _hx_substr($s, $startIndex, $endIndex - $startIndex);
  618. }
  619. function _hx_trace($v, $i) {
  620. $msg = $i !== null ? $i->fileName.':'.$i->lineNumber.': ' : '';
  621. echo $msg._hx_string_rec($v, '').\"\n\";
  622. }
  623. function _hx_ttype($n) {
  624. return isset(php_Boot::$ttypes[$n]) ? php_Boot::$ttypes[$n] : null;
  625. }
  626. function _hx_make_var_args() {
  627. $args = func_get_args();
  628. $f = array_shift($args);
  629. return call_user_func($f, new _hx_array($args));
  630. }
  631. class _hx_anonymous extends stdClass {
  632. public function __call($m, $a) {
  633. return call_user_func_array($this->$m, $a);
  634. }
  635. public function __set($n, $v) {
  636. $this->$n = $v;
  637. }
  638. public function &__get($n) {
  639. if(isset($this->$n))
  640. return $this->$n;
  641. $null = null;
  642. return $null;
  643. }
  644. public function __isset($n) {
  645. return isset($this->$n);
  646. }
  647. public function __unset($n) {
  648. unset($this->$n);
  649. }
  650. public function __toString() {
  651. $rfl = new ReflectionObject($this);
  652. $b = '{ ';
  653. $properties = $rfl->getProperties();
  654. $first = true;
  655. while(list(, $prop) = each($properties)) {
  656. if($first)
  657. $first = false;
  658. else
  659. $b .= ', ';
  660. $f = $prop->getName();
  661. $b .= $f . ' => ' . $this->$f;
  662. }
  663. $b .= ' }';
  664. return $b;
  665. }
  666. }
  667. class _hx_type {
  668. public $__tname__;
  669. public $__qname__;
  670. public $__path__;
  671. public function __construct($cn, $qn, $path = null) {
  672. $this->__tname__ = $cn;
  673. $this->__qname__ = $qn;
  674. $this->__path__ = $path;
  675. if(property_exists($cn, '__meta__'))
  676. $this->__meta__ = eval($cn.'::$__meta__');
  677. }
  678. public function toString() { return $this->__toString(); }
  679. public function __toString() {
  680. return $this->__qname__;
  681. }
  682. private $rfl = false;
  683. public function __rfl__() {
  684. if($this->rfl !== false) return $this->rfl;
  685. if(class_exists($this->__tname__) || interface_exists($this->__tname__))
  686. $this->rfl = new ReflectionClass($this->__tname__);
  687. else
  688. $this->rfl = null;
  689. return $this->rfl;
  690. }
  691. public function __call($n, $a) {
  692. return call_user_func_array(array($this->__tname__, $n), $a);
  693. }
  694. public function __get($n) {
  695. if(($r = $this->__rfl__())==null) return null;
  696. if($r->hasProperty($n))
  697. return $r->getStaticPropertyValue($n);
  698. else if($r->hasMethod($n))
  699. return array($r->name, $n);
  700. else
  701. return null;
  702. }
  703. public function __set($n, $v) {
  704. if(($r = $this->__rfl__())==null) return null;
  705. return $r->setStaticPropertyValue($n, $v);
  706. }
  707. public function __isset($n) {
  708. if(($r = $this->__rfl__())==null) return null;
  709. return $r->hasProperty($n) || $r->hasMethod($n);
  710. }
  711. }
  712. class _hx_class extends _hx_type {}
  713. class _hx_enum extends _hx_type {}
  714. class _hx_interface extends _hx_type {}
  715. class HException extends Exception {
  716. public function __construct($e, $message = null, $code = null, $p = null) {
  717. $message = _hx_string_rec($e, '') . $message;
  718. parent::__construct($message,$code);
  719. $this->e = $e;
  720. $this->p = $p;
  721. }
  722. public $e;
  723. public $p;
  724. public function setLine($l) {
  725. $this->line = $l;
  726. }
  727. public function setFile($f) {
  728. $this->file = $f;
  729. }
  730. }
  731. class _hx_lambda {
  732. public function __construct($locals, $func) {
  733. $this->locals = $locals;
  734. $this->func = $func;
  735. }
  736. public $locals;
  737. public $func;
  738. public function execute() {
  739. // if use $this->locals directly in array_merge it works only if I make the assignement loop,
  740. // so I've decided to reference $arr
  741. $arr = array();
  742. for ($i = 0; $i<count($this->locals);$i++)
  743. $arr[] = & $this->locals[$i];
  744. $args = func_get_args();
  745. return call_user_func_array($this->func, array_merge($arr, $args));
  746. }
  747. }
  748. class Enum {
  749. public function __construct($tag, $index, $params = null) { $this->tag = $tag; $this->index = $index; $this->params = $params; }
  750. public $tag;
  751. public $index;
  752. public $params;
  753. public function __toString() {
  754. return $this->tag;
  755. }
  756. }
  757. error_reporting(E_ALL & ~E_STRICT);
  758. set_error_handler('_hx_error_handler', E_ALL & ~E_STRICT);
  759. set_exception_handler('_hx_exception_handler');
  760. php_Boot::$qtypes = array();
  761. php_Boot::$ttypes = array();
  762. php_Boot::$tpaths = array();
  763. _hx_register_type(new _hx_class('String', 'String'));
  764. _hx_register_type(new _hx_class('_hx_array', 'Array'));
  765. _hx_register_type(new _hx_class('Int', 'Int'));
  766. _hx_register_type(new _hx_class('Float', 'Float'));
  767. _hx_register_type(new _hx_class('Class', 'Class'));
  768. _hx_register_type(new _hx_class('Enum', 'Enum'));
  769. _hx_register_type(new _hx_class('Dynamic', 'Dynamic'));
  770. _hx_register_type(new _hx_enum('Bool', 'Bool'));
  771. _hx_register_type(new _hx_enum('Void', 'Void'));
  772. $_hx_libdir = dirname(__FILE__) . '/..';
  773. $_hx_autload_cache_file = $_hx_libdir . '/../cache/haxe_autoload.php';
  774. if(!file_exists($_hx_autload_cache_file)) {
  775. function _hx_build_paths($d, &$_hx_types_array, $pack, $prefix) {
  776. $h = opendir($d);
  777. while(false !== ($f = readdir($h))) {
  778. $p = $d.'/'.$f;
  779. if($f == '.' || $f == '..')
  780. continue;
  781. if (is_file($p) && substr($f, -4) == '.php') {
  782. $bn = basename($f, '.php');
  783. if ($prefix)
  784. {
  785. if ($prefix != substr($bn, 0, $lenprefix = strlen($prefix)))
  786. continue;
  787. $bn = substr($bn, $lenprefix);
  788. }
  789. if(substr($bn, -6) == '.class') {
  790. $bn = substr($bn, 0, -6);
  791. $t = 0;
  792. } else if(substr($bn, -5) == '.enum') {
  793. $bn = substr($bn, 0, -5);
  794. $t = 1;
  795. } else if(substr($bn, -10) == '.interface') {
  796. $bn = substr($bn, 0, -10);
  797. $t = 2;
  798. } else if(substr($bn, -7) == '.extern') {
  799. $bn = substr($bn, 0, -7);
  800. $t = 3;
  801. } else
  802. continue;
  803. $qname = ($bn == 'HList' && empty($pack)) ? 'List' : join(array_merge($pack, array($bn)), '.');
  804. $_hx_types_array[] = array(
  805. 'path' => $p,
  806. 'name' => $prefix . $bn,
  807. 'type' => $t,
  808. 'qname' => $qname,
  809. 'phpname' => join(array_merge($pack, array($prefix . $bn)), '_')
  810. );
  811. } else if(is_dir($p))
  812. _hx_build_paths($p, $_hx_types_array, array_merge($pack, array($f)), $prefix);
  813. }
  814. closedir($h);
  815. }
  816. $_hx_cache_content = '<?php\n\n';
  817. $_hx_types_array = array();
  818. _hx_build_paths($_hx_libdir, $_hx_types_array, array(), $_hx_class_prefix);
  819. for($i=0;$i<count($_hx_types_array);$i++) {
  820. $_hx_cache_content .= '_hx_register_type(new ';
  821. $t = null;
  822. if($_hx_types_array[$i]['type'] == 0) {
  823. $t = new _hx_class($_hx_types_array[$i]['phpname'], $_hx_types_array[$i]['qname'], $_hx_types_array[$i]['path']);
  824. $_hx_cache_content .= '_hx_class';
  825. } else if($_hx_types_array[$i]['type'] == 1) {
  826. $t = new _hx_enum($_hx_types_array[$i]['phpname'], $_hx_types_array[$i]['qname'], $_hx_types_array[$i]['path']);
  827. $_hx_cache_content .= '_hx_enum';
  828. } else if($_hx_types_array[$i]['type'] == 2) {
  829. $t = new _hx_interface($_hx_types_array[$i]['phpname'], $_hx_types_array[$i]['qname'], $_hx_types_array[$i]['path']);
  830. $_hx_cache_content .= '_hx_interface';
  831. } else if($_hx_types_array[$i]['type'] == 3) {
  832. $t = new _hx_class($_hx_types_array[$i]['name'], $_hx_types_array[$i]['qname'], $_hx_types_array[$i]['path']);
  833. $_hx_cache_content .= '_hx_class';
  834. }
  835. _hx_register_type($t);
  836. $_hx_cache_content .= '(\\''.($_hx_types_array[$i]['type'] == 3 ? $_hx_types_array[$i]['name'] : $_hx_types_array[$i]['phpname']).'\\', \\''.$_hx_types_array[$i]['qname'].'\\', \\''.$_hx_types_array[$i]['path'].'\\'));\n';
  837. }
  838. try {
  839. file_put_contents($_hx_autload_cache_file, $_hx_cache_content);
  840. } catch(Exception $e) {}
  841. unset($_hx_types_array);
  842. unset($_hx_cache_content);
  843. } else {
  844. require($_hx_autload_cache_file);
  845. }
  846. function _hx_autoload($name) {
  847. if(!isset(php_Boot::$tpaths[$name])) return false;
  848. require_once(php_Boot::$tpaths[$name]);
  849. return true;
  850. }
  851. if(!ini_get('date.timezone'))
  852. date_default_timezone_set('UTC');
  853. spl_autoload_register('_hx_autoload')");
  854. }
  855. }