abstract.js.html 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>JSDoc: Source: abstract.js</title>
  6. <script src="scripts/prettify/prettify.js"> </script>
  7. <script src="scripts/prettify/lang-css.js"> </script>
  8. <!--[if lt IE 9]>
  9. <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  10. <![endif]-->
  11. <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
  12. <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
  13. </head>
  14. <body>
  15. <div id="main">
  16. <h1 class="page-title">Source: abstract.js</h1>
  17. <section>
  18. <article>
  19. <pre class="prettyprint source linenums"><code>/**
  20. * @namespace Sk.abstr
  21. *
  22. */
  23. Sk.abstr = {};
  24. //
  25. // Number
  26. //
  27. Sk.abstr.typeName = function (v) {
  28. var vtypename;
  29. if (v.tp$name !== undefined) {
  30. vtypename = v.tp$name;
  31. } else {
  32. vtypename = "&lt;invalid type>";
  33. }
  34. return vtypename;
  35. };
  36. Sk.abstr.binop_type_error = function (v, w, name) {
  37. var vtypename = Sk.abstr.typeName(v),
  38. wtypename = Sk.abstr.typeName(w);
  39. throw new Sk.builtin.TypeError("unsupported operand type(s) for " + name + ": '" + vtypename + "' and '" + wtypename + "'");
  40. };
  41. Sk.abstr.unop_type_error = function (v, name) {
  42. var vtypename = Sk.abstr.typeName(v),
  43. uop = {
  44. "UAdd" : "+",
  45. "USub" : "-",
  46. "Invert": "~"
  47. }[name];
  48. throw new Sk.builtin.TypeError("bad operand type for unary " + uop + ": '" + vtypename + "'");
  49. };
  50. /**
  51. * lookup and return the LHS object slot function method. This coudl be either a builtin slot function or a dunder method defined by the user.
  52. * @param obj
  53. * @param name
  54. * @returns {Object|null|undefined}
  55. * @private
  56. */
  57. Sk.abstr.boNameToSlotFuncLhs_ = function (obj, name) {
  58. if (obj === null) {
  59. return undefined;
  60. }
  61. switch (name) {
  62. case "Add":
  63. return obj.nb$add ? obj.nb$add : obj["__add__"];
  64. case "Sub":
  65. return obj.nb$subtract ? obj.nb$subtract : obj["__sub__"];
  66. case "Mult":
  67. return obj.nb$multiply ? obj.nb$multiply : obj["__mul__"];
  68. case "Div":
  69. return obj.nb$divide ? obj.nb$divide : obj["__div__"];
  70. case "FloorDiv":
  71. return obj.nb$floor_divide ? obj.nb$floor_divide : obj["__floordiv__"];
  72. case "Mod":
  73. return obj.nb$remainder ? obj.nb$remainder : obj["__mod__"];
  74. case "DivMod":
  75. return obj.nb$divmod ? obj.nb$divmod : obj["__divmod__"];
  76. case "Pow":
  77. return obj.nb$power ? obj.nb$power : obj["__pow__"];
  78. case "LShift":
  79. return obj.nb$lshift ? obj.nb$lshift : obj["__lshift__"];
  80. case "RShift":
  81. return obj.nb$rshift ? obj.nb$rshift : obj["__rshift__"];
  82. case "BitAnd":
  83. return obj.nb$and ? obj.nb$and : obj["__and__"];
  84. case "BitXor":
  85. return obj.nb$xor ? obj.nb$xor : obj["__xor__"];
  86. case "BitOr":
  87. return obj.nb$or ? obj.nb$or : obj["__or__"];
  88. }
  89. };
  90. Sk.abstr.boNameToSlotFuncRhs_ = function (obj, name) {
  91. if (obj === null) {
  92. return undefined;
  93. }
  94. switch (name) {
  95. case "Add":
  96. return obj.nb$reflected_add ? obj.nb$reflected_add : obj["__radd__"];
  97. case "Sub":
  98. return obj.nb$reflected_subtract ? obj.nb$reflected_subtract : obj["__rsub__"];
  99. case "Mult":
  100. return obj.nb$reflected_multiply ? obj.nb$reflected_multiply : obj["__rmul__"];
  101. case "Div":
  102. return obj.nb$reflected_divide ? obj.nb$reflected_divide : obj["__rdiv__"];
  103. case "FloorDiv":
  104. return obj.nb$reflected_floor_divide ? obj.nb$reflected_floor_divide : obj["__rfloordiv__"];
  105. case "Mod":
  106. return obj.nb$reflected_remainder ? obj.nb$reflected_remainder : obj["__rmod__"];
  107. case "DivMod":
  108. return obj.nb$reflected_divmod ? obj.nb$reflected_divmod : obj["__rdivmod__"];
  109. case "Pow":
  110. return obj.nb$reflected_power ? obj.nb$reflected_power : obj["__rpow__"];
  111. case "LShift":
  112. return obj.nb$reflected_lshift ? obj.nb$reflected_lshift : obj["__rlshift__"];
  113. case "RShift":
  114. return obj.nb$reflected_rshift ? obj.nb$reflected_rshift : obj["__rrshift__"];
  115. case "BitAnd":
  116. return obj.nb$reflected_and ? obj.nb$reflected_and : obj["__rand__"];
  117. case "BitXor":
  118. return obj.nb$reflected_xor ? obj.nb$reflected_xor : obj["__rxor__"];
  119. case "BitOr":
  120. return obj.nb$reflected_or ? obj.nb$reflected_or : obj["__ror__"];
  121. }
  122. };
  123. Sk.abstr.iboNameToSlotFunc_ = function (obj, name) {
  124. switch (name) {
  125. case "Add":
  126. return obj.nb$inplace_add ? obj.nb$inplace_add : obj["__iadd__"];
  127. case "Sub":
  128. return obj.nb$inplace_subtract ? obj.nb$inplace_subtract : obj["__isub__"];
  129. case "Mult":
  130. return obj.nb$inplace_multiply ? obj.nb$inplace_multiply : obj["__imul__"];
  131. case "Div":
  132. return obj.nb$inplace_divide ? obj.nb$inplace_divide : obj["__idiv__"];
  133. case "FloorDiv":
  134. return obj.nb$inplace_floor_divide ? obj.nb$inplace_floor_divide : obj["__ifloordiv__"];
  135. case "Mod":
  136. return obj.nb$inplace_remainder;
  137. case "Pow":
  138. return obj.nb$inplace_power;
  139. case "LShift":
  140. return obj.nb$inplace_lshift ? obj.nb$inplace_lshift : obj["__ilshift__"];
  141. case "RShift":
  142. return obj.nb$inplace_rshift ? obj.nb$inplace_rshift : obj["__irshift__"];
  143. case "BitAnd":
  144. return obj.nb$inplace_and;
  145. case "BitOr":
  146. return obj.nb$inplace_or;
  147. case "BitXor":
  148. return obj.nb$inplace_xor ? obj.nb$inplace_xor : obj["__ixor__"];
  149. }
  150. };
  151. Sk.abstr.uoNameToSlotFunc_ = function (obj, name) {
  152. if (obj === null) {
  153. return undefined;
  154. }
  155. switch (name) {
  156. case "USub":
  157. return obj.nb$negative ? obj.nb$negative : obj["__neg__"];
  158. case "UAdd":
  159. return obj.nb$positive ? obj.nb$positive : obj["__pos__"];
  160. case "Invert":
  161. return obj.nb$invert ? obj.nb$invert : obj["__invert__"];
  162. }
  163. };
  164. Sk.abstr.binary_op_ = function (v, w, opname) {
  165. var wop;
  166. var ret;
  167. var vop;
  168. // All Python inheritance is now enforced with Javascript inheritance
  169. // (see Sk.abstr.setUpInheritance). This checks if w's type is a strict
  170. // subclass of v's type
  171. var w_is_subclass = w.constructor.prototype instanceof v.constructor;
  172. // From the Python 2.7 docs:
  173. //
  174. // "If the right operand’s type is a subclass of the left operand’s type and
  175. // that subclass provides the reflected method for the operation, this
  176. // method will be called before the left operand’s non-reflected method.
  177. // This behavior allows subclasses to override their ancestors’ operations."
  178. //
  179. // -- https://docs.python.org/2/reference/datamodel.html#index-92
  180. if (w_is_subclass) {
  181. wop = Sk.abstr.boNameToSlotFuncRhs_(w, opname);
  182. if (wop !== undefined) {
  183. if (wop.call) {
  184. ret = wop.call(w, v);
  185. } else {
  186. ret = Sk.misceval.callsim(wop, w, v);
  187. }
  188. if (ret !== undefined &amp;&amp; ret !== Sk.builtin.NotImplemented.NotImplemented$) {
  189. return ret;
  190. }
  191. }
  192. }
  193. vop = Sk.abstr.boNameToSlotFuncLhs_(v, opname);
  194. if (vop !== undefined) {
  195. if (vop.call) {
  196. ret = vop.call(v, w);
  197. } else {
  198. ret = Sk.misceval.callsim(vop, v, w);
  199. }
  200. if (ret !== undefined &amp;&amp; ret !== Sk.builtin.NotImplemented.NotImplemented$) {
  201. return ret;
  202. }
  203. }
  204. // Don't retry RHS if failed above
  205. if (!w_is_subclass) {
  206. wop = Sk.abstr.boNameToSlotFuncRhs_(w, opname);
  207. if (wop !== undefined) {
  208. if (wop.call) {
  209. ret = wop.call(w, v);
  210. } else {
  211. ret = Sk.misceval.callsim(wop, w, v);
  212. }
  213. if (ret !== undefined &amp;&amp; ret !== Sk.builtin.NotImplemented.NotImplemented$) {
  214. return ret;
  215. }
  216. }
  217. }
  218. Sk.abstr.binop_type_error(v, w, opname);
  219. };
  220. Sk.abstr.binary_iop_ = function (v, w, opname) {
  221. var wop;
  222. var ret;
  223. var vop = Sk.abstr.iboNameToSlotFunc_(v, opname);
  224. if (vop !== undefined) {
  225. if (vop.call) {
  226. ret = vop.call(v, w);
  227. } else { // assume that vop is an __xxx__ type method
  228. ret = Sk.misceval.callsim(vop, v, w); // added to be like not-in-place... is this okay?
  229. }
  230. if (ret !== undefined &amp;&amp; ret !== Sk.builtin.NotImplemented.NotImplemented$) {
  231. return ret;
  232. }
  233. }
  234. wop = Sk.abstr.iboNameToSlotFunc_(w, opname);
  235. if (wop !== undefined) {
  236. if (wop.call) {
  237. ret = wop.call(w, v);
  238. } else { // assume that wop is an __xxx__ type method
  239. ret = Sk.misceval.callsim(wop, w, v); // added to be like not-in-place... is this okay?
  240. }
  241. if (ret !== undefined &amp;&amp; ret !== Sk.builtin.NotImplemented.NotImplemented$) {
  242. return ret;
  243. }
  244. }
  245. Sk.abstr.binop_type_error(v, w, opname);
  246. };
  247. Sk.abstr.unary_op_ = function (v, opname) {
  248. var ret;
  249. var vop = Sk.abstr.uoNameToSlotFunc_(v, opname);
  250. if (vop !== undefined) {
  251. if (vop.call) {
  252. ret = vop.call(v);
  253. } else { // assume that vop is an __xxx__ type method
  254. ret = Sk.misceval.callsim(vop, v); // added to be like not-in-place... is this okay?
  255. }
  256. if (ret !== undefined) {
  257. return ret;
  258. }
  259. }
  260. Sk.abstr.unop_type_error(v, opname);
  261. };
  262. //
  263. // handle upconverting a/b from number to long if op causes too big/small a
  264. // result, or if either of the ops are already longs
  265. Sk.abstr.numOpAndPromote = function (a, b, opfn) {
  266. var tmp;
  267. var ans;
  268. if (a === null || b === null) {
  269. return undefined;
  270. }
  271. if (typeof a === "number" &amp;&amp; typeof b === "number") {
  272. ans = opfn(a, b);
  273. // todo; handle float Removed RNL (bugs in lng, and it should be a question of precision, not magnitude -- this was just wrong)
  274. if ((ans > Sk.builtin.int_.threshold$ || ans &lt; -Sk.builtin.int_.threshold$) &amp;&amp; Math.floor(ans) === ans) {
  275. return [Sk.builtin.lng.fromInt$(a), Sk.builtin.lng.fromInt$(b)];
  276. } else {
  277. return ans;
  278. }
  279. } else if (a === undefined || b === undefined) {
  280. throw new Sk.builtin.NameError("Undefined variable in expression");
  281. }
  282. if (a.constructor === Sk.builtin.lng) {
  283. return [a, b];
  284. } else if ((a.constructor === Sk.builtin.int_ ||
  285. a.constructor === Sk.builtin.float_) &amp;&amp;
  286. b.constructor === Sk.builtin.complex) {
  287. // special case of upconverting nmber and complex
  288. // can we use here the Sk.builtin.checkComplex() method?
  289. tmp = new Sk.builtin.complex(a);
  290. return [tmp, b];
  291. } else if (a.constructor === Sk.builtin.int_ ||
  292. a.constructor === Sk.builtin.float_) {
  293. return [a, b];
  294. } else if (typeof a === "number") {
  295. tmp = Sk.builtin.assk$(a);
  296. return [tmp, b];
  297. } else {
  298. return undefined;
  299. }
  300. };
  301. Sk.abstr.boNumPromote_ = {
  302. "Add" : function (a, b) {
  303. return a + b;
  304. },
  305. "Sub" : function (a, b) {
  306. return a - b;
  307. },
  308. "Mult" : function (a, b) {
  309. return a * b;
  310. },
  311. "Mod" : function (a, b) {
  312. var m;
  313. if (b === 0) {
  314. throw new Sk.builtin.ZeroDivisionError("division or modulo by zero");
  315. }
  316. m = a % b;
  317. return ((m * b) &lt; 0 ? (m + b) : m);
  318. },
  319. "Div" : function (a, b) {
  320. if (b === 0) {
  321. throw new Sk.builtin.ZeroDivisionError("division or modulo by zero");
  322. } else {
  323. return a / b;
  324. }
  325. },
  326. "FloorDiv": function (a, b) {
  327. if (b === 0) {
  328. throw new Sk.builtin.ZeroDivisionError("division or modulo by zero");
  329. } else {
  330. return Math.floor(a / b);
  331. } // todo; wrong? neg?
  332. },
  333. "Pow" : Math.pow,
  334. "BitAnd" : function (a, b) {
  335. var m = a &amp; b;
  336. if (m &lt; 0) {
  337. m = m + 4294967296; // convert back to unsigned
  338. }
  339. return m;
  340. },
  341. "BitOr" : function (a, b) {
  342. var m = a | b;
  343. if (m &lt; 0) {
  344. m = m + 4294967296; // convert back to unsigned
  345. }
  346. return m;
  347. },
  348. "BitXor" : function (a, b) {
  349. var m = a ^ b;
  350. if (m &lt; 0) {
  351. m = m + 4294967296; // convert back to unsigned
  352. }
  353. return m;
  354. },
  355. "LShift" : function (a, b) {
  356. var m;
  357. if (b &lt; 0) {
  358. throw new Sk.builtin.ValueError("negative shift count");
  359. }
  360. m = a &lt;&lt; b;
  361. if (m > a) {
  362. return m;
  363. } else {
  364. // Fail, this will get recomputed with longs
  365. return a * Math.pow(2, b);
  366. }
  367. },
  368. "RShift" : function (a, b) {
  369. var m;
  370. if (b &lt; 0) {
  371. throw new Sk.builtin.ValueError("negative shift count");
  372. }
  373. m = a >> b;
  374. if ((a > 0) &amp;&amp; (m &lt; 0)) {
  375. // fix incorrect sign extension
  376. m = m &amp; (Math.pow(2, 32 - b) - 1);
  377. }
  378. return m;
  379. }
  380. };
  381. Sk.abstr.numberBinOp = function (v, w, op) {
  382. var tmp;
  383. var numPromoteFunc = Sk.abstr.boNumPromote_[op];
  384. if (numPromoteFunc !== undefined) {
  385. tmp = Sk.abstr.numOpAndPromote(v, w, numPromoteFunc);
  386. if (typeof tmp === "number") {
  387. return tmp;
  388. } else if (tmp !== undefined &amp;&amp; tmp.constructor === Sk.builtin.int_) {
  389. return tmp;
  390. } else if (tmp !== undefined &amp;&amp; tmp.constructor === Sk.builtin.float_) {
  391. return tmp;
  392. } else if (tmp !== undefined &amp;&amp; tmp.constructor === Sk.builtin.lng) {
  393. return tmp;
  394. } else if (tmp !== undefined) {
  395. v = tmp[0];
  396. w = tmp[1];
  397. }
  398. }
  399. return Sk.abstr.binary_op_(v, w, op);
  400. };
  401. goog.exportSymbol("Sk.abstr.numberBinOp", Sk.abstr.numberBinOp);
  402. Sk.abstr.numberInplaceBinOp = function (v, w, op) {
  403. var tmp;
  404. var numPromoteFunc = Sk.abstr.boNumPromote_[op];
  405. if (numPromoteFunc !== undefined) {
  406. tmp = Sk.abstr.numOpAndPromote(v, w, numPromoteFunc);
  407. if (typeof tmp === "number") {
  408. return tmp;
  409. } else if (tmp !== undefined &amp;&amp; tmp.constructor === Sk.builtin.int_) {
  410. return tmp;
  411. } else if (tmp !== undefined &amp;&amp; tmp.constructor === Sk.builtin.float_) {
  412. return tmp;
  413. } else if (tmp !== undefined &amp;&amp; tmp.constructor === Sk.builtin.lng) {
  414. return tmp;
  415. } else if (tmp !== undefined) {
  416. v = tmp[0];
  417. w = tmp[1];
  418. }
  419. }
  420. return Sk.abstr.binary_iop_(v, w, op);
  421. };
  422. goog.exportSymbol("Sk.abstr.numberInplaceBinOp", Sk.abstr.numberInplaceBinOp);
  423. Sk.abstr.numberUnaryOp = function (v, op) {
  424. var value;
  425. if (op === "Not") {
  426. return Sk.misceval.isTrue(v) ? Sk.builtin.bool.false$ : Sk.builtin.bool.true$;
  427. } else if (v instanceof Sk.builtin.bool) {
  428. value = Sk.builtin.asnum$(v);
  429. if (op === "USub") {
  430. return new Sk.builtin.int_(-value);
  431. }
  432. if (op === "UAdd") {
  433. return new Sk.builtin.int_(value);
  434. }
  435. if (op === "Invert") {
  436. return new Sk.builtin.int_(~value);
  437. }
  438. } else {
  439. if (op === "USub" &amp;&amp; v.nb$negative) {
  440. return v.nb$negative();
  441. }
  442. if (op === "UAdd" &amp;&amp; v.nb$positive) {
  443. return v.nb$positive();
  444. }
  445. if (op === "Invert" &amp;&amp; v.nb$invert) {
  446. return v.nb$invert();
  447. }
  448. }
  449. return Sk.abstr.unary_op_(v, op);
  450. };
  451. goog.exportSymbol("Sk.abstr.numberUnaryOp", Sk.abstr.numberUnaryOp);
  452. //
  453. // Sequence
  454. //
  455. Sk.abstr.fixSeqIndex_ = function (seq, i) {
  456. i = Sk.builtin.asnum$(i);
  457. if (i &lt; 0 &amp;&amp; seq.sq$length) {
  458. i += seq.sq$length();
  459. }
  460. return i;
  461. };
  462. Sk.abstr.sequenceContains = function (seq, ob) {
  463. var it, i;
  464. var seqtypename;
  465. var special;
  466. if (seq.sq$contains) {
  467. return seq.sq$contains(ob);
  468. }
  469. /**
  470. * Look for special method and call it, we have to distinguish between built-ins and
  471. * python objects
  472. */
  473. special = Sk.abstr.lookupSpecial(seq, "__contains__");
  474. if (special != null) {
  475. // method on builtin, provide this arg
  476. return Sk.misceval.isTrue(Sk.misceval.callsim(special, seq, ob));
  477. }
  478. if (!Sk.builtin.checkIterable(seq)) {
  479. seqtypename = Sk.abstr.typeName(seq);
  480. throw new Sk.builtin.TypeError("argument of type '" + seqtypename + "' is not iterable");
  481. }
  482. for (it = Sk.abstr.iter(seq), i = it.tp$iternext(); i !== undefined; i = it.tp$iternext()) {
  483. if (Sk.misceval.richCompareBool(i, ob, "Eq")) {
  484. return true;
  485. }
  486. }
  487. return false;
  488. };
  489. Sk.abstr.sequenceConcat = function (seq1, seq2) {
  490. var seq1typename;
  491. if (seq1.sq$concat) {
  492. return seq1.sq$concat(seq2);
  493. }
  494. seq1typename = Sk.abstr.typeName(seq1);
  495. throw new Sk.builtin.TypeError("'" + seq1typename + "' object can't be concatenated");
  496. };
  497. Sk.abstr.sequenceGetIndexOf = function (seq, ob) {
  498. var seqtypename;
  499. var i, it;
  500. var index;
  501. if (seq.index) {
  502. return Sk.misceval.callsim(seq.index, seq, ob);
  503. }
  504. if (Sk.builtin.checkIterable(seq)) {
  505. index = 0;
  506. for (it = Sk.abstr.iter(seq), i = it.tp$iternext();
  507. i !== undefined; i = it.tp$iternext()) {
  508. if (Sk.misceval.richCompareBool(ob, i, "Eq")) {
  509. return new Sk.builtin.int_(index);
  510. }
  511. index += 1;
  512. }
  513. throw new Sk.builtin.ValueError("sequence.index(x): x not in sequence");
  514. }
  515. seqtypename = Sk.abstr.typeName(seq);
  516. throw new Sk.builtin.TypeError("argument of type '" + seqtypename + "' is not iterable");
  517. };
  518. Sk.abstr.sequenceGetCountOf = function (seq, ob) {
  519. var seqtypename;
  520. var i, it;
  521. var count;
  522. if (seq.count) {
  523. return Sk.misceval.callsim(seq.count, seq, ob);
  524. }
  525. if (Sk.builtin.checkIterable(seq)) {
  526. count = 0;
  527. for (it = Sk.abstr.iter(seq), i = it.tp$iternext();
  528. i !== undefined; i = it.tp$iternext()) {
  529. if (Sk.misceval.richCompareBool(ob, i, "Eq")) {
  530. count += 1;
  531. }
  532. }
  533. return new Sk.builtin.int_(count);
  534. }
  535. seqtypename = Sk.abstr.typeName(seq);
  536. throw new Sk.builtin.TypeError("argument of type '" + seqtypename + "' is not iterable");
  537. };
  538. Sk.abstr.sequenceGetItem = function (seq, i, canSuspend) {
  539. var seqtypename;
  540. if (seq.mp$subscript) {
  541. return seq.mp$subscript(i);
  542. }
  543. seqtypename = Sk.abstr.typeName(seq);
  544. throw new Sk.builtin.TypeError("'" + seqtypename + "' object is unsubscriptable");
  545. };
  546. Sk.abstr.sequenceSetItem = function (seq, i, x, canSuspend) {
  547. var seqtypename;
  548. if (seq.mp$ass_subscript) {
  549. return seq.mp$ass_subscript(i, x);
  550. }
  551. seqtypename = Sk.abstr.typeName(seq);
  552. throw new Sk.builtin.TypeError("'" + seqtypename + "' object does not support item assignment");
  553. };
  554. Sk.abstr.sequenceDelItem = function (seq, i) {
  555. var seqtypename;
  556. if (seq.sq$del_item) {
  557. i = Sk.abstr.fixSeqIndex_(seq, i);
  558. seq.sq$del_item(i);
  559. return;
  560. }
  561. seqtypename = Sk.abstr.typeName(seq);
  562. throw new Sk.builtin.TypeError("'" + seqtypename + "' object does not support item deletion");
  563. };
  564. Sk.abstr.sequenceRepeat = function (f, seq, n) {
  565. var ntypename;
  566. var count;
  567. n = Sk.builtin.asnum$(n);
  568. count = Sk.misceval.asIndex(n);
  569. if (count === undefined) {
  570. ntypename = Sk.abstr.typeName(n);
  571. throw new Sk.builtin.TypeError("can't multiply sequence by non-int of type '" + ntypename + "'");
  572. }
  573. return f.call(seq, n);
  574. };
  575. Sk.abstr.sequenceGetSlice = function (seq, i1, i2) {
  576. var seqtypename;
  577. if (seq.sq$slice) {
  578. i1 = Sk.abstr.fixSeqIndex_(seq, i1);
  579. i2 = Sk.abstr.fixSeqIndex_(seq, i2);
  580. return seq.sq$slice(i1, i2);
  581. } else if (seq.mp$subscript) {
  582. return seq.mp$subscript(new Sk.builtin.slice(i1, i2));
  583. }
  584. seqtypename = Sk.abstr.typeName(seq);
  585. throw new Sk.builtin.TypeError("'" + seqtypename + "' object is unsliceable");
  586. };
  587. Sk.abstr.sequenceDelSlice = function (seq, i1, i2) {
  588. var seqtypename;
  589. if (seq.sq$del_slice) {
  590. i1 = Sk.abstr.fixSeqIndex_(seq, i1);
  591. i2 = Sk.abstr.fixSeqIndex_(seq, i2);
  592. seq.sq$del_slice(i1, i2);
  593. return;
  594. }
  595. seqtypename = Sk.abstr.typeName(seq);
  596. throw new Sk.builtin.TypeError("'" + seqtypename + "' doesn't support slice deletion");
  597. };
  598. Sk.abstr.sequenceSetSlice = function (seq, i1, i2, x) {
  599. var seqtypename;
  600. if (seq.sq$ass_slice) {
  601. i1 = Sk.abstr.fixSeqIndex_(seq, i1);
  602. i2 = Sk.abstr.fixSeqIndex_(seq, i2);
  603. seq.sq$ass_slice(i1, i2, x);
  604. } else if (seq.mp$ass_subscript) {
  605. seq.mp$ass_subscript(new Sk.builtin.slice(i1, i2), x);
  606. } else {
  607. seqtypename = Sk.abstr.typeName(seq);
  608. throw new Sk.builtin.TypeError("'" + seqtypename + "' object doesn't support slice assignment");
  609. }
  610. };
  611. // seq - Python object to unpack
  612. // n - JavaScript number of items to unpack
  613. Sk.abstr.sequenceUnpack = function (seq, n) {
  614. var res = [];
  615. var it, i;
  616. if (!Sk.builtin.checkIterable(seq)) {
  617. throw new Sk.builtin.TypeError("'" + Sk.abstr.typeName(seq) + "' object is not iterable");
  618. }
  619. for (it = Sk.abstr.iter(seq), i = it.tp$iternext();
  620. (i !== undefined) &amp;&amp; (res.length &lt; n);
  621. i = it.tp$iternext()) {
  622. res.push(i);
  623. }
  624. if (res.length &lt; n) {
  625. throw new Sk.builtin.ValueError("need more than " + res.length + " values to unpack");
  626. }
  627. if (i !== undefined) {
  628. throw new Sk.builtin.ValueError("too many values to unpack");
  629. }
  630. // Return Javascript array of items
  631. return res;
  632. };
  633. //
  634. // Object
  635. //
  636. Sk.abstr.objectFormat = function (obj, format_spec) {
  637. var meth; // PyObject
  638. var result; // PyObject
  639. // If no format_spec is provided, use an empty string
  640. if(format_spec == null) {
  641. format_spec = "";
  642. }
  643. // Find the (unbound!) __format__ method (a borrowed reference)
  644. meth = Sk.abstr.lookupSpecial(obj, "__format__");
  645. if (meth == null) {
  646. throw new Sk.builtin.TypeError("Type " + Sk.abstr.typeName(obj) + "doesn't define __format__");
  647. }
  648. // And call it
  649. result = Sk.misceval.callsim(meth, obj, format_spec);
  650. if (!Sk.builtin.checkString(result)) {
  651. throw new Sk.builtin.TypeError("__format__ must return a str, not " + Sk.abstr.typeName(result));
  652. }
  653. return result;
  654. };
  655. Sk.abstr.objectAdd = function (a, b) {
  656. var btypename;
  657. var atypename;
  658. if (a.nb$add) {
  659. return a.nb$add(b);
  660. }
  661. atypename = Sk.abstr.typeName(a);
  662. btypename = Sk.abstr.typeName(b);
  663. throw new Sk.builtin.TypeError("unsupported operand type(s) for +: '" + atypename + "' and '" + btypename + "'");
  664. };
  665. // in Python 2.6, this behaviour seems to be defined for numbers and bools (converts bool to int)
  666. Sk.abstr.objectNegative = function (obj) {
  667. var objtypename;
  668. var obj_asnum = Sk.builtin.asnum$(obj); // this will also convert bool type to int
  669. if (obj instanceof Sk.builtin.bool) {
  670. obj = new Sk.builtin.int_(obj_asnum);
  671. }
  672. if (obj.nb$negative) {
  673. return obj.nb$negative();
  674. }
  675. objtypename = Sk.abstr.typeName(obj);
  676. throw new Sk.builtin.TypeError("bad operand type for unary -: '" + objtypename + "'");
  677. };
  678. // in Python 2.6, this behaviour seems to be defined for numbers and bools (converts bool to int)
  679. Sk.abstr.objectPositive = function (obj) {
  680. var objtypename = Sk.abstr.typeName(obj);
  681. var obj_asnum = Sk.builtin.asnum$(obj); // this will also convert bool type to int
  682. if (obj instanceof Sk.builtin.bool) {
  683. obj = new Sk.builtin.int_(obj_asnum);
  684. }
  685. if (obj.nb$negative) {
  686. return obj.nb$positive();
  687. }
  688. throw new Sk.builtin.TypeError("bad operand type for unary +: '" + objtypename + "'");
  689. };
  690. Sk.abstr.objectDelItem = function (o, key) {
  691. var otypename;
  692. var keytypename;
  693. var keyValue;
  694. if (o !== null) {
  695. if (o.mp$del_subscript) {
  696. o.mp$del_subscript(key);
  697. return;
  698. }
  699. if (o.sq$ass_item) {
  700. keyValue = Sk.misceval.asIndex(key);
  701. if (keyValue === undefined) {
  702. keytypename = Sk.abstr.typeName(key);
  703. throw new Sk.builtin.TypeError("sequence index must be integer, not '" + keytypename + "'");
  704. }
  705. Sk.abstr.sequenceDelItem(o, keyValue);
  706. return;
  707. }
  708. // if o is a slice do something else...
  709. }
  710. otypename = Sk.abstr.typeName(o);
  711. throw new Sk.builtin.TypeError("'" + otypename + "' object does not support item deletion");
  712. };
  713. goog.exportSymbol("Sk.abstr.objectDelItem", Sk.abstr.objectDelItem);
  714. Sk.abstr.objectGetItem = function (o, key, canSuspend) {
  715. var otypename;
  716. if (o !== null) {
  717. if (o.tp$getitem) {
  718. return o.tp$getitem(key, canSuspend);
  719. } else if (o.mp$subscript) {
  720. return o.mp$subscript(key, canSuspend);
  721. } else if (Sk.misceval.isIndex(key) &amp;&amp; o.sq$item) {
  722. return Sk.abstr.sequenceGetItem(o, Sk.misceval.asIndex(key), canSuspend);
  723. }
  724. }
  725. otypename = Sk.abstr.typeName(o);
  726. throw new Sk.builtin.TypeError("'" + otypename + "' does not support indexing");
  727. };
  728. goog.exportSymbol("Sk.abstr.objectGetItem", Sk.abstr.objectGetItem);
  729. Sk.abstr.objectSetItem = function (o, key, v, canSuspend) {
  730. var otypename;
  731. if (o !== null) {
  732. if (o.tp$setitem) {
  733. return o.tp$setitem(key, v, canSuspend);
  734. } else if (o.mp$ass_subscript) {
  735. return o.mp$ass_subscript(key, v, canSuspend);
  736. } else if (Sk.misceval.isIndex(key) &amp;&amp; o.sq$ass_item) {
  737. return Sk.abstr.sequenceSetItem(o, Sk.misceval.asIndex(key), v, canSuspend);
  738. }
  739. }
  740. otypename = Sk.abstr.typeName(o);
  741. throw new Sk.builtin.TypeError("'" + otypename + "' does not support item assignment");
  742. };
  743. goog.exportSymbol("Sk.abstr.objectSetItem", Sk.abstr.objectSetItem);
  744. Sk.abstr.gattr = function (obj, nameJS, canSuspend) {
  745. var ret, f;
  746. var objname = Sk.abstr.typeName(obj);
  747. if (obj === null) {
  748. throw new Sk.builtin.AttributeError("'" + objname + "' object has no attribute '" + nameJS + "'");
  749. }
  750. if (obj.tp$getattr !== undefined) {
  751. f = obj.tp$getattr("__getattribute__");
  752. }
  753. if (f !== undefined) {
  754. ret = Sk.misceval.callsimOrSuspend(f, new Sk.builtin.str(nameJS));
  755. }
  756. ret = Sk.misceval.chain(ret, function(ret) {
  757. var f;
  758. if (ret === undefined &amp;&amp; obj.tp$getattr !== undefined) {
  759. ret = obj.tp$getattr(nameJS);
  760. if (ret === undefined) {
  761. f = obj.tp$getattr("__getattr__");
  762. if (f !== undefined) {
  763. ret = Sk.misceval.callsimOrSuspend(f, new Sk.builtin.str(nameJS));
  764. }
  765. }
  766. }
  767. return ret;
  768. }, function(r) {
  769. if (r === undefined) {
  770. throw new Sk.builtin.AttributeError("'" + objname + "' object has no attribute '" + nameJS + "'");
  771. }
  772. return r;
  773. });
  774. return canSuspend ? ret : Sk.misceval.retryOptionalSuspensionOrThrow(ret);
  775. };
  776. goog.exportSymbol("Sk.abstr.gattr", Sk.abstr.gattr);
  777. Sk.abstr.sattr = function (obj, nameJS, data, canSuspend) {
  778. var objname = Sk.abstr.typeName(obj), r, setf;
  779. if (obj === null) {
  780. throw new Sk.builtin.AttributeError("'" + objname + "' object has no attribute '" + nameJS + "'");
  781. }
  782. if (obj.tp$getattr !== undefined) {
  783. setf = obj.tp$getattr("__setattr__");
  784. if (setf !== undefined) {
  785. r = Sk.misceval.callsimOrSuspend(setf, new Sk.builtin.str(nameJS), data);
  786. return canSuspend ? r : Sk.misceval.retryOptionalSuspensionOrThrow(r);
  787. }
  788. }
  789. if (obj.tp$setattr !== undefined) {
  790. obj.tp$setattr(nameJS, data);
  791. } else {
  792. throw new Sk.builtin.AttributeError("'" + objname + "' object has no attribute '" + nameJS + "'");
  793. }
  794. };
  795. goog.exportSymbol("Sk.abstr.sattr", Sk.abstr.sattr);
  796. Sk.abstr.iternext = function (it, canSuspend) {
  797. return it.tp$iternext(canSuspend);
  798. };
  799. goog.exportSymbol("Sk.abstr.iternext", Sk.abstr.iternext);
  800. /**
  801. * Get the iterator for a Python object This iterator could be one of the following.
  802. * This is the preferred mechanism for consistently getting the correct iterator. You should
  803. * not just use tp$iter because that could lead to incorrect behavior of a user created class.
  804. *
  805. * - tp$iter
  806. * - A user defined `__iter__` method
  807. * - A user defined `__getitem__` method
  808. *
  809. * @param obj
  810. *
  811. * @throws {Sk.builtin.TypeError}
  812. * @returns {Object}
  813. */
  814. Sk.abstr.iter = function(obj) {
  815. var iter;
  816. var getit;
  817. var ret;
  818. /**
  819. * Builds an iterator around classes that have a __getitem__ method.
  820. *
  821. * @constructor
  822. */
  823. var seqIter = function (obj) {
  824. this.idx = 0;
  825. this.myobj = obj;
  826. this.getitem = Sk.abstr.lookupSpecial(obj, "__getitem__");
  827. this.tp$iternext = function () {
  828. var ret;
  829. try {
  830. ret = Sk.misceval.callsim(this.getitem, this.myobj, Sk.ffi.remapToPy(this.idx));
  831. } catch (e) {
  832. if (e instanceof Sk.builtin.IndexError) {
  833. return undefined;
  834. } else {
  835. throw e;
  836. }
  837. }
  838. this.idx++;
  839. return ret;
  840. };
  841. };
  842. if (obj.tp$getattr) {
  843. iter = Sk.abstr.lookupSpecial(obj,"__iter__");
  844. if (iter) {
  845. return Sk.misceval.callsim(iter,obj);
  846. }
  847. }
  848. if (obj.tp$iter) {
  849. try { // catch and ignore not iterable error here.
  850. ret = obj.tp$iter();
  851. if (ret.tp$iternext) {
  852. return ret;
  853. }
  854. } catch (e) { }
  855. }
  856. getit = Sk.abstr.lookupSpecial(obj, "__getitem__");
  857. if (getit) {
  858. // create internal iterobject if __getitem__
  859. return new seqIter(obj);
  860. }
  861. throw new Sk.builtin.TypeError("'" + Sk.abstr.typeName(obj) + "' object is not iterable");
  862. };
  863. goog.exportSymbol("Sk.abstr.iter", Sk.abstr.iter);
  864. /**
  865. * Special method look up. First try getting the method via
  866. * internal dict and getattr. If getattr is not present (builtins)
  867. * try if method is defined on the object itself
  868. *
  869. * @returns {null|Object} Return null if not found or the function
  870. */
  871. Sk.abstr.lookupSpecial = function(op, str) {
  872. var res;
  873. var obtp;
  874. if (op.ob$type) {
  875. obtp = op.ob$type;
  876. } else {
  877. return null;
  878. }
  879. return Sk.builtin.type.typeLookup(obtp, str);
  880. };
  881. goog.exportSymbol("Sk.abstr.lookupSpecial", Sk.abstr.lookupSpecial);
  882. /**
  883. * Mark a class as unhashable and prevent its `__hash__` function from being called.
  884. * @param {function(...[?])} thisClass The class to mark as unhashable.
  885. * @return {undefined}
  886. */
  887. Sk.abstr.markUnhashable = function (thisClass) {
  888. var proto = thisClass.prototype;
  889. proto.__hash__ = Sk.builtin.none.none$;
  890. proto.tp$hash = Sk.builtin.none.none$;
  891. };
  892. /**
  893. * Set up inheritance between two Python classes. This allows only for single
  894. * inheritance -- multiple inheritance is not supported by Javascript.
  895. *
  896. * Javascript's inheritance is prototypal. This means that properties must
  897. * be defined on the superclass' prototype in order for subclasses to inherit
  898. * them.
  899. *
  900. * ```
  901. * Sk.superclass.myProperty # will NOT be inherited
  902. * Sk.superclass.prototype.myProperty # will be inherited
  903. * ```
  904. *
  905. * In order for a class to be subclassable, it must (directly or indirectly)
  906. * inherit from Sk.builtin.object so that it will be properly initialized in
  907. * {@link Sk.doOneTimeInitialization} (in src/import.js). Further, all Python
  908. * builtins should inherit from Sk.builtin.object.
  909. *
  910. * @param {string} childName The Python name of the child (subclass).
  911. * @param {function(...[?])} child The subclass.
  912. * @param {function(...[?])} parent The superclass.
  913. * @return {undefined}
  914. */
  915. Sk.abstr.setUpInheritance = function (childName, child, parent) {
  916. goog.inherits(child, parent);
  917. child.prototype.tp$base = parent;
  918. child.prototype.tp$name = childName;
  919. child.prototype.ob$type = Sk.builtin.type.makeIntoTypeObj(childName, child);
  920. };
  921. /**
  922. * Call the super constructor of the provided class, with the object `self` as
  923. * the `this` value of that constructor. Any arguments passed to this function
  924. * after `self` will be passed as-is to the constructor.
  925. *
  926. * @param {function(...[?])} thisClass The subclass.
  927. * @param {Object} self The instance of the subclas.
  928. * @param {...?} args Arguments to pass to the constructor.
  929. * @return {undefined}
  930. */
  931. Sk.abstr.superConstructor = function (thisClass, self, args) {
  932. var argumentsForConstructor = Array.prototype.slice.call(arguments, 2);
  933. thisClass.prototype.tp$base.apply(self, argumentsForConstructor);
  934. };
  935. </code></pre>
  936. </article>
  937. </section>
  938. </div>
  939. <nav>
  940. <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Sk.abstr.iter-seqIter.html">seqIter</a></li><li><a href="Sk.builtin.bool.html">bool</a></li><li><a href="Sk.builtin.float_.html">float_</a></li><li><a href="Sk.builtin.func.html">func</a></li><li><a href="Sk.builtin.int_.html">int_</a></li><li><a href="Sk.builtin.none.html">none</a></li><li><a href="Sk.builtin.NotImplemented.html">NotImplemented</a></li><li><a href="Sk.builtin.numtype.html">numtype</a></li><li><a href="Sk.builtin.object.html">object</a></li><li><a href="Sk.builtin.seqtype.html">seqtype</a></li><li><a href="Sk.misceval.Suspension.html">Suspension</a></li></ul><h3>Namespaces</h3><ul><li><a href="Sk.html">Sk</a></li><li><a href="Sk.abstr.html">abstr</a></li><li><a href="Sk.builtin.html">builtin</a></li><li><a href="Sk.ffi.html">ffi</a></li><li><a href="Sk.misceval.html">misceval</a></li></ul>
  941. </nav>
  942. <br class="clear">
  943. <footer>
  944. Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.0</a> on Thu Aug 13 2015 08:14:27 GMT-0500 (CDT)
  945. </footer>
  946. <script> prettyPrint(); </script>
  947. <script src="scripts/linenumber.js"> </script>
  948. </body>
  949. </html>