collections.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. var $builtinmodule = function (name) {
  2. var mod = {};
  3. // defaultdict object
  4. mod.defaultdict = function defaultdict(default_, args) {
  5. if (!(this instanceof mod.defaultdict)) {
  6. return new mod.defaultdict(default_, args);
  7. }
  8. Sk.abstr.superConstructor(mod.defaultdict, this, args);
  9. if (default_ === undefined) {
  10. this.default_factory = Sk.builtin.none.none$;
  11. }
  12. else {
  13. if (!Sk.builtin.checkCallable(default_) && !(default_ instanceof Sk.builtin.none)) {
  14. throw new Sk.builtin.TypeError("first argument must be callable");
  15. }
  16. this.default_factory = default_;
  17. }
  18. if (this['$d']) {
  19. this['$d']['default_factory'] = this.default_factory;
  20. }
  21. else {
  22. this['$d'] = {'default_factory': this.default_factory};
  23. }
  24. return this;
  25. };
  26. Sk.abstr.setUpInheritance("defaultdict", mod.defaultdict, Sk.builtin.dict);
  27. mod.defaultdict.prototype['$r'] = function () {
  28. var def_str = Sk.misceval.objectRepr(this.default_factory).v;
  29. var dict_str = Sk.builtin.dict.prototype['$r'].call(this).v;
  30. return new Sk.builtin.str("defaultdict(" + def_str + ", " + dict_str + ")");
  31. };
  32. mod.defaultdict.prototype['__missing__'] = function (key) {
  33. Sk.builtin.pyCheckArgs('__missing__', arguments, 0, 1);
  34. if (key) {
  35. throw new Sk.builtin.KeyError(Sk.misceval.objectRepr(key));
  36. }
  37. else {
  38. return Sk.misceval.callsim(this.default_factory);
  39. }
  40. };
  41. mod.defaultdict.prototype.mp$subscript = function (key) {
  42. try {
  43. return Sk.builtin.dict.prototype.mp$subscript.call(this, key);
  44. }
  45. catch (e) {
  46. if (this.default_factory instanceof Sk.builtin.none) {
  47. return this.__missing__(key);
  48. }
  49. else {
  50. ret = this.__missing__();
  51. this.mp$ass_subscript(key, ret);
  52. return ret;
  53. }
  54. }
  55. };
  56. // Counter object
  57. mod.Counter = function Counter(iter_or_map) {
  58. if (!(this instanceof mod.Counter)) {
  59. return new mod.Counter(iter_or_map);
  60. }
  61. if (iter_or_map instanceof Sk.builtin.dict || iter_or_map === undefined) {
  62. Sk.abstr.superConstructor(mod.Counter, this, iter_or_map);
  63. }
  64. else {
  65. if (!(Sk.builtin.checkIterable(iter_or_map))) {
  66. throw new Sk.builtin.TypeError("'" + Sk.abstr.typeName(iter_or_map) + "' object is not iterable");
  67. }
  68. Sk.abstr.superConstructor(mod.Counter, this);
  69. var one = new Sk.builtin.int_(1);
  70. for (var iter = iter_or_map.tp$iter(), k = iter.tp$iternext();
  71. k !== undefined;
  72. k = iter.tp$iternext()) {
  73. var count = this.mp$subscript(k);
  74. count = count.nb$add(one);
  75. this.mp$ass_subscript(k, count);
  76. }
  77. }
  78. return this;
  79. };
  80. Sk.abstr.setUpInheritance("Counter", mod.Counter, Sk.builtin.dict);
  81. mod.Counter.prototype['$r'] = function () {
  82. var dict_str = this.size > 0 ? Sk.builtin.dict.prototype['$r'].call(this).v : '';
  83. return new Sk.builtin.str('Counter(' + dict_str + ')');
  84. };
  85. mod.Counter.prototype.mp$subscript = function (key) {
  86. try {
  87. return Sk.builtin.dict.prototype.mp$subscript.call(this, key);
  88. }
  89. catch (e) {
  90. return new Sk.builtin.int_(0);
  91. }
  92. };
  93. mod.Counter.prototype['elements'] = new Sk.builtin.func(function (self) {
  94. Sk.builtin.pyCheckArgs('elements', arguments, 1, 1);
  95. var all_elements = [];
  96. for (var iter = self.tp$iter(), k = iter.tp$iternext();
  97. k !== undefined;
  98. k = iter.tp$iternext()) {
  99. for (var i = 0; i < self.mp$subscript(k).v; i++) {
  100. all_elements.push(k);
  101. }
  102. }
  103. var ret =
  104. {
  105. tp$iter: function () {
  106. return ret;
  107. },
  108. $obj: this,
  109. $index: 0,
  110. $elem: all_elements,
  111. tp$iternext: function () {
  112. if (ret.$index >= ret.$elem.length) {
  113. return undefined;
  114. }
  115. return ret.$elem[ret.$index++];
  116. }
  117. };
  118. return ret;
  119. });
  120. mod.Counter.prototype['most_common'] = new Sk.builtin.func(function (self, n) {
  121. Sk.builtin.pyCheckArgs('most_common', arguments, 1, 2);
  122. var length = self.mp$length();
  123. if (n === undefined) {
  124. n = length;
  125. }
  126. else {
  127. if (!Sk.builtin.checkInt(n)) {
  128. if (n instanceof Sk.builtin.float_) {
  129. throw new Sk.builtin.TypeError("integer argument expected, got float");
  130. }
  131. else {
  132. throw new Sk.builtin.TypeError("an integer is required");
  133. }
  134. }
  135. n = Sk.builtin.asnum$(n);
  136. n = n <= length ? n : length;
  137. n = n >= 0 ? n : 0;
  138. }
  139. var most_common_elem = [];
  140. for (var iter = self.tp$iter(), k = iter.tp$iternext();
  141. k !== undefined;
  142. k = iter.tp$iternext()) {
  143. most_common_elem.push([k, self.mp$subscript(k)]);
  144. }
  145. var sort_func = function (a, b) {
  146. if (a[1].v < b[1].v) {
  147. return 1;
  148. } else if (a[1].v > b[1].v) {
  149. return -1;
  150. } else {
  151. return 0;
  152. }
  153. };
  154. most_common_elem = most_common_elem.sort(sort_func);
  155. var ret = [];
  156. for (var i = 0; i < n; i++) {
  157. ret.push(new Sk.builtin.tuple(most_common_elem.shift()));
  158. }
  159. return new Sk.builtin.list(ret);
  160. });
  161. mod.Counter.prototype['update'] = new Sk.builtin.func(function (self, other) {
  162. Sk.builtin.pyCheckArgs('update', arguments, 1, 2);
  163. if (other instanceof Sk.builtin.dict) {
  164. for (var iter = other.tp$iter(), k = iter.tp$iternext();
  165. k !== undefined;
  166. k = iter.tp$iternext()) {
  167. var count = self.mp$subscript(k);
  168. self.mp$ass_subscript(k, count.nb$add(other.mp$subscript(k)));
  169. }
  170. }
  171. else if (other !== undefined) {
  172. if (!Sk.builtin.checkIterable(other)) {
  173. throw new Sk.builtin.TypeError("'" + Sk.abstr.typeName(other) + "' object is not iterable");
  174. }
  175. var one = new Sk.builtin.int_(1);
  176. for (var iter = other.tp$iter(), k = iter.tp$iternext();
  177. k !== undefined;
  178. k = iter.tp$iternext()) {
  179. var count = self.mp$subscript(k);
  180. self.mp$ass_subscript(k, count.nb$add(one));
  181. }
  182. }
  183. });
  184. mod.Counter.prototype['subtract'] = new Sk.builtin.func(function (self, other) {
  185. Sk.builtin.pyCheckArgs('subtract', arguments, 1, 2);
  186. if (other instanceof Sk.builtin.dict) {
  187. for (var iter = other.tp$iter(), k = iter.tp$iternext();
  188. k !== undefined;
  189. k = iter.tp$iternext()) {
  190. var count = self.mp$subscript(k);
  191. self.mp$ass_subscript(k, count.nb$subtract(other.mp$subscript(k)));
  192. }
  193. }
  194. else if (other !== undefined) {
  195. if (!Sk.builtin.checkIterable(other)) {
  196. throw new Sk.builtin.TypeError("'" + Sk.abstr.typeName(other) + "' object is not iterable");
  197. }
  198. var one = new Sk.builtin.int_(1);
  199. for (var iter = other.tp$iter(), k = iter.tp$iternext();
  200. k !== undefined;
  201. k = iter.tp$iternext()) {
  202. var count = self.mp$subscript(k);
  203. self.mp$ass_subscript(k, count.nb$subtract(one));
  204. }
  205. }
  206. });
  207. // OrderedDict
  208. mod.OrderedDict = function OrderedDict(items)
  209. {
  210. if (!(this instanceof mod.OrderedDict))
  211. {
  212. return new mod.OrderedDict(items);
  213. }
  214. this.orderedkeys = [];
  215. Sk.abstr.superConstructor(mod.OrderedDict, this, items);
  216. return this;
  217. }
  218. Sk.abstr.setUpInheritance("OrderedDict", mod.OrderedDict, Sk.builtin.dict);
  219. mod.OrderedDict.prototype['$r'] = function()
  220. {
  221. var v;
  222. var iter, k;
  223. var ret = [];
  224. var pairstr;
  225. for (iter = this.tp$iter(), k = iter.tp$iternext();
  226. k !== undefined;
  227. k = iter.tp$iternext()) {
  228. v = this.mp$subscript(k);
  229. if (v === undefined) {
  230. //print(k, "had undefined v");
  231. v = null;
  232. }
  233. ret.push("(" + Sk.misceval.objectRepr(k).v + ", " + Sk.misceval.objectRepr(v).v + ")");
  234. }
  235. pairstr = ret.join(", ");
  236. if (ret.length > 0)
  237. {
  238. pairstr = "[" + pairstr + "]";
  239. }
  240. return new Sk.builtin.str("OrderedDict(" + pairstr + ")");
  241. }
  242. mod.OrderedDict.prototype.mp$ass_subscript = function(key, w)
  243. {
  244. var idx = this.orderedkeys.indexOf(key);
  245. if (idx == -1)
  246. {
  247. this.orderedkeys.push(key);
  248. }
  249. return Sk.builtin.dict.prototype.mp$ass_subscript.call(this, key, w);
  250. }
  251. mod.OrderedDict.prototype.mp$del_subscript = function(key)
  252. {
  253. var idx = this.orderedkeys.indexOf(key);
  254. if (idx != -1)
  255. {
  256. this.orderedkeys.splice(idx, 1);
  257. }
  258. return Sk.builtin.dict.prototype.mp$del_subscript.call(this, key);
  259. }
  260. mod.OrderedDict.prototype.__iter__ = new Sk.builtin.func(function (self) {
  261. Sk.builtin.pyCheckArgs("__iter__", arguments, 0, 0, false, true);
  262. return mod.OrderedDict.prototype.tp$iter.call(self);
  263. });
  264. mod.OrderedDict.prototype.tp$iter = function()
  265. {
  266. var ret;
  267. ret =
  268. {
  269. tp$iter : function () {
  270. return ret;
  271. },
  272. $obj : this,
  273. $index : 0,
  274. $keys : this.orderedkeys.slice(0),
  275. tp$iternext: function () {
  276. // todo; StopIteration
  277. if (ret.$index >= ret.$keys.length) {
  278. return undefined;
  279. }
  280. return ret.$keys[ret.$index++];
  281. }
  282. };
  283. return ret;
  284. }
  285. mod.OrderedDict.prototype.ob$eq = function (other) {
  286. var l;
  287. var otherl;
  288. var iter;
  289. var k;
  290. var v;
  291. if (!(other instanceof mod.OrderedDict))
  292. {
  293. return Sk.builtin.dict.prototype.ob$eq.call(this, other);
  294. }
  295. l = this.mp$length();
  296. otherl = other.mp$length();
  297. if (l !== otherl) {
  298. return Sk.builtin.bool.false$;
  299. }
  300. for (iter = this.tp$iter(), otheriter = other.tp$iter(),
  301. k = iter.tp$iternext(), otherk = otheriter.tp$iternext();
  302. k !== undefined;
  303. k = iter.tp$iternext(), otherk = otheriter.tp$iternext())
  304. {
  305. if (!Sk.misceval.isTrue(Sk.misceval.richCompareBool(k, otherk, "Eq")))
  306. {
  307. return Sk.builtin.bool.false$;
  308. }
  309. v = this.mp$subscript(k);
  310. otherv = other.mp$subscript(otherk);
  311. if (!Sk.misceval.isTrue(Sk.misceval.richCompareBool(v, otherv, "Eq"))) {
  312. return Sk.builtin.bool.false$;
  313. }
  314. }
  315. return Sk.builtin.bool.true$;
  316. };
  317. mod.OrderedDict.prototype.ob$ne = function (other) {
  318. var l;
  319. var otherl;
  320. var iter;
  321. var k;
  322. var v;
  323. if (!(other instanceof mod.OrderedDict))
  324. {
  325. return Sk.builtin.dict.prototype.ob$ne.call(this, other);
  326. }
  327. l = this.size;
  328. otherl = other.size;
  329. if (l !== otherl) {
  330. return Sk.builtin.bool.true$;
  331. }
  332. for (iter = this.tp$iter(), otheriter = other.tp$iter(),
  333. k = iter.tp$iternext(), otherk = otheriter.tp$iternext();
  334. k !== undefined;
  335. k = iter.tp$iternext(), otherk = otheriter.tp$iternext())
  336. {
  337. if (!Sk.misceval.isTrue(Sk.misceval.richCompareBool(k, otherk, "Eq")))
  338. {
  339. return Sk.builtin.bool.true$;
  340. }
  341. v = this.mp$subscript(k);
  342. otherv = other.mp$subscript(otherk);
  343. if (!Sk.misceval.isTrue(Sk.misceval.richCompareBool(v, otherv, "Eq"))) {
  344. return Sk.builtin.bool.true$;
  345. }
  346. }
  347. return Sk.builtin.bool.false$;
  348. };
  349. mod.OrderedDict.prototype["pop"] = new Sk.builtin.func(function (self, key, d) {
  350. var s;
  351. var idx;
  352. Sk.builtin.pyCheckArgs('pop', arguments, 2, 3);
  353. idx = self.orderedkeys.indexOf(key);
  354. if (idx != -1)
  355. {
  356. self.orderedkeys.splice(idx, 1);
  357. }
  358. return Sk.misceval.callsim(Sk.builtin.dict.prototype["pop"], self, key, d);
  359. });
  360. mod.OrderedDict.prototype["popitem"] = new Sk.builtin.func(function (self, last) {
  361. var key, val;
  362. var s;
  363. Sk.builtin.pyCheckArgs('popitem', arguments, 1, 2);
  364. // Empty dictionary
  365. if (self.orderedkeys.length == 0)
  366. {
  367. s = new Sk.builtin.str('dictionary is empty');
  368. throw new Sk.builtin.KeyError(s.v);
  369. }
  370. key = self.orderedkeys[0];
  371. if (last === undefined || Sk.misceval.isTrue(last))
  372. {
  373. key = self.orderedkeys[self.orderedkeys.length - 1];
  374. }
  375. val = Sk.misceval.callsim(self["pop"], self, key);
  376. return Sk.builtin.tuple([key, val]);
  377. });
  378. // deque
  379. mod.deque = function deque(iterable, maxlen) {
  380. throw new Sk.builtin.NotImplementedError("deque is not implemented")
  381. };
  382. // namedtuple
  383. mod.namedtuples = {};
  384. var keywds = Sk.importModule("keyword", false, false);
  385. // should cover most things. Does not:
  386. // * keyword args
  387. // _make
  388. // _replace
  389. // _asdict
  390. // _fields
  391. var hasDupes = function(a) {
  392. var counts = [];
  393. for(var i = 0; i <= a.length; i++) {
  394. if(counts[a[i]] === undefined) {
  395. counts[a[i]] = 1;
  396. } else {
  397. return true;
  398. }
  399. }
  400. return false;
  401. }
  402. var Skinherits = function(childCtor, parentCtor) {
  403. /** @constructor */
  404. function tempCtor() {};
  405. tempCtor.prototype = parentCtor.prototype;
  406. childCtor.superClass_ = parentCtor.prototype;
  407. childCtor.prototype = new tempCtor();
  408. /** @override */
  409. childCtor.prototype.constructor = childCtor;
  410. };
  411. mod.namedtuple = function (name, fields) {
  412. if (Sk.ffi.remapToJs(Sk.misceval.callsim(keywds.$d['iskeyword'],name ))) {
  413. throw new Sk.builtin.ValueError("Type names and field names cannot be a keyword: " + name.v);
  414. }
  415. var nm = Sk.ffi.remapToJs(name);
  416. startsw = new RegExp(/^[0-9].*/);
  417. startsw2 = new RegExp(/^[0-9_].*/);
  418. alnum = new RegExp(/^\w*$/);
  419. if (startsw.test(nm) || (! alnum.test(nm))) {
  420. throw new Sk.builtin.ValueError(" Bad type name " + nm);
  421. }
  422. // fields could be a string or a tuple or list of strings
  423. var flds = Sk.ffi.remapToJs(fields);
  424. if (typeof(flds) === 'string') {
  425. flds = flds.split(/\s+/);
  426. }
  427. // import the keyword module here and use iskeyword
  428. for (i = 0; i < flds.length; i++) {
  429. if (Sk.ffi.remapToJs(Sk.misceval.callsim(keywds.$d['iskeyword'],Sk.ffi.remapToPy(flds[i]))) ||
  430. startsw2.test(flds[i]) || (! alnum.test(flds[i]))
  431. ) {
  432. throw new Sk.builtin.ValueError("Type names and field names cannot be a keyword: " + flds[i]);
  433. }
  434. }
  435. if (hasDupes(flds)) {
  436. throw new Sk.builtin.ValueError("Field names must be unique.");
  437. }
  438. var cons = function nametuple_constructor() {
  439. var o;
  440. if (arguments.length !== flds.length ) {
  441. throw new Sk.builtin.TypeError("Number of arguments must match");
  442. }
  443. if (!(this instanceof mod.namedtuples[nm])) {
  444. o = Object.create(mod.namedtuples[nm].prototype);
  445. o.constructor.apply(o, arguments);
  446. return o;
  447. }
  448. this.__class__ = mod.namedtuples[nm];
  449. this.v = Array.prototype.slice.call(arguments);
  450. };
  451. mod.namedtuples[nm] = cons;
  452. Skinherits(cons, Sk.builtin.tuple);
  453. cons.prototype.tp$name = nm;
  454. cons.prototype.ob$type = Sk.builtin.type.makeIntoTypeObj(nm, mod.namedtuples[nm]);
  455. cons.prototype["$r"] = function () {
  456. var ret;
  457. var i;
  458. var bits;
  459. if (this.v.length === 0) {
  460. return new Sk.builtin.str(nm + "()");
  461. }
  462. bits = [];
  463. for (i = 0; i < this.v.length; ++i) {
  464. bits[i] = flds[i] + "=" + Sk.misceval.objectRepr(this.v[i]).v;
  465. }
  466. ret = bits.join(", ");
  467. if (this.v.length === 1) {
  468. ret += ",";
  469. }
  470. return new Sk.builtin.str(nm + "(" + ret + ")");
  471. };
  472. cons.prototype.tp$getattr = function (name) {
  473. var i = flds.indexOf(name);
  474. if (i >= 0) {
  475. return this.v[i];
  476. }
  477. return undefined;
  478. };
  479. cons.prototype.tp$setattr = function (name, value) {
  480. throw new Sk.builtin.AttributeError("can't set attribute");
  481. };
  482. return cons;
  483. };
  484. return mod;
  485. };