Permalink
Jan 14, 2015
Jan 14, 2015
Feb 10, 2018
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Aug 31, 2017
Jan 14, 2015
Aug 31, 2017
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Aug 31, 2017
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Feb 9, 2016
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Feb 10, 2018
Feb 10, 2018
Feb 10, 2018
Feb 9, 2018
Aug 31, 2017
Aug 31, 2017
Dec 3, 2015
Dec 3, 2015
Feb 9, 2018
Dec 28, 2017
Jan 6, 2016
Jan 6, 2016
Aug 31, 2017
Jan 6, 2016
Jan 6, 2016
Jan 6, 2016
Jan 6, 2016
Jan 6, 2016
Feb 10, 2018
Jan 6, 2016
Jan 6, 2016
Jan 6, 2016
Jan 1, 2015
Aug 31, 2017
Aug 31, 2017
Feb 10, 2018
Jul 10, 2017
Jun 29, 2017
Jun 29, 2017
Jun 29, 2017
Jun 29, 2017
Jul 10, 2017
Jul 10, 2017
Jul 14, 2017
Jun 29, 2017
Newer
100644
1948 lines (1782 sloc)
63.4 KB
5
if (!String.prototype.trim) {
6
// Polyfill for older browsers
7
// The code does not use a regex to make it a bit faster.
8
// Implementation taken from a comment by Timo on the blog:
9
// http://blog.stevenlevithan.com/archives/faster-trim-javascript
10
String.prototype.trim = function () {
11
var c;
12
for (var i = 0; i < this.length; i++) {
13
c = this.charCodeAt(i);
14
if (c == 32 || c == 10 || c == 13 || c == 9 || c == 12 || c == 11 || c == 160 || c == 5760 || c == 6158 || c == 8192 || c == 8193 || c == 8194 || c == 8195 || c == 8196 || c == 8197 || c == 8198 || c == 8199 || c == 8200 || c == 8201 || c == 8202 || c == 8232 || c == 8233 || c == 8239 || c == 8287 || c == 12288 || c == 65279)
15
continue; else break;
16
}
17
for (var j = this.length - 1; j >= i; j--) {
18
c = this.charCodeAt(j);
19
if (c == 32 || c == 10 || c == 13 || c == 9 || c == 12 || c == 11 || c == 160 || c == 5760 || c == 6158 || c == 8192 || c == 8193 || c == 8194 || c == 8195 || c == 8196 || c == 8197 || c == 8198 || c == 8199 || c == 8200 || c == 8201 || c == 8202 || c == 8232 || c == 8233 || c == 8239 || c == 8287 || c == 12288 || c == 65279)
20
continue; else break;
21
}
22
return this.substring(i, j + 1);
23
}
24
}
25
if (!String.prototype.trimLeft) {
26
// Convenience method for browsers which do not have a native trimLeft
27
// (which is a nonstandard extension in Firefox and Chrome)
28
String.prototype.trimLeft = function () {
29
var c;
30
for (var i = 0; i < this.length; i++) {
31
c = this.charCodeAt(i);
32
if (c == 32 || c == 10 || c == 13 || c == 9 || c == 12 || c == 11 || c == 160 || c == 5760 || c == 6158 || c == 8192 || c == 8193 || c == 8194 || c == 8195 || c == 8196 || c == 8197 || c == 8198 || c == 8199 || c == 8200 || c == 8201 || c == 8202 || c == 8232 || c == 8233 || c == 8239 || c == 8287 || c == 12288 || c == 65279)
33
continue; else break;
34
}
35
return this.substring(i);
36
};
37
}
38
if (!String.prototype.trimRight) {
39
String.prototype.trimRight = function () {
40
// Convenience method for browsers which do not have a native trimRight
41
// (which is a nonstandard extension in Firefox and Chrome)
42
var c;
43
for (var j = this.length - 1; j >= 0; j--) {
44
c = this.charCodeAt(j);
45
if (c == 32 || c == 10 || c == 13 || c == 9 || c == 12 || c == 11 || c == 160 || c == 5760 || c == 6158 || c == 8192 || c == 8193 || c == 8194 || c == 8195 || c == 8196 || c == 8197 || c == 8198 || c == 8199 || c == 8200 || c == 8201 || c == 8202 || c == 8232 || c == 8233 || c == 8239 || c == 8287 || c == 12288 || c == 65279)
46
continue; else break;
47
}
48
return this.substring(0, j + 1);
49
};
50
}
62
function normalize_start_end($){
63
if($.start===null||$.start===_b_.None){$.start = 0}
64
else if($.start<0){$.start += $.self.length; $.start=Math.max(0, $.start)}
65
if($.end===null||$.end===_b_.None){$.end = $.self.length}
66
else if($.end<0){$.end += $.self.length; $.end=Math.max(0, $.end)}
67
68
if(!isinstance($.start,_b_.int)||!isinstance($.end,_b_.int)){
74
function reverse(s){
75
// Reverse a string
76
return s.split('').reverse().join('')
77
}
78
79
function check_str(obj){
88
"Can't convert "+$B.get_class(other).__name__+" to str implicitely")}
89
}
90
return self+other
91
}
92
95
"'in <string>' requires string as left operand, not "+item.__class__)}
96
var nbcar = item.length
97
if(nbcar==0) return true // a string contains the empty string
98
if(self.length==0) return nbcar==0
109
// __dir__must be assigned explicitely because attribute resolution for builtin
110
// classes doesn't use __mro__
114
if(other===undefined){ // compare object "self" to class "str"
115
return self===str
116
}
117
if (_b_.isinstance(other, _b_.str)) {
118
return other.valueOf() == self.valueOf()
119
}
137
// For strings, alignment default to left
138
fmt.align = fmt.align || '<'
139
return $B.format_width(preformat(self, fmt), fmt)
143
if(isinstance(arg,_b_.int)){
144
var pos = arg
145
if(arg<0) pos+=self.length
146
if(pos>=0 && pos<self.length) return self.charAt(pos)
150
var s=_b_.slice.$dict.$conv_for_seq(arg, self.length),
151
start=s.start, stop=s.stop, step=s.step
152
var res = '',i=null
153
if(step>0){
154
if(stop<=start) return ''
155
for(var i=start;i<stop;i+=step) res += self.charAt(i)
156
} else {
157
if(stop>=start) return ''
168
return str.__hashvalue__ || $B.$py_next_hash-- // for hash of string type (not instance of string)
171
//http://stackoverflow.com/questions/2909106/python-whats-a-correct-and-good-way-to-implement-hash
172
// this implementation for strings maybe good enough for us..
173
174
var hash=1;
176
hash=(101*hash + self.charCodeAt(i)) & 0xFFFFFFFF
177
}
178
179
return hash
180
}
181
190
var items = self.split('') // list of all characters in string
191
return $B.$iterator(items,$str_iterator)
192
}
193
198
var kwarg_key = new RegExp('([^\\)]*)\\)')
199
200
var NotANumber = function() {
201
this.name = 'NotANumber'
202
}
203
204
var number_check=function(s) {
205
if(!isinstance(s,[_b_.int,_b_.float])){
206
throw new NotANumber()
207
}
208
}
209
210
var get_char_array = function(size, char) {
211
if (size <= 0)
212
return ''
213
return new Array(size + 1).join(char)
214
}
215
216
var format_padding = function(s, flags, minus_one) {
217
var padding = flags.padding
218
if (!padding) { // undefined
219
return s
220
}
221
s = s.toString()
222
padding = parseInt(padding, 10)
223
if (minus_one) { // numeric formatting where sign goes in front of padding
224
padding -= 1
225
}
226
if (!flags.left) {
227
return get_char_array(padding - s.length, flags.pad_char) + s
228
} else {
229
// left adjusted
230
return s + get_char_array(padding - s.length, flags.pad_char)
231
}
232
}
233
234
var format_int_precision = function(val, flags) {
235
var precision = flags.precision
236
if (!precision) {
237
return val.toString()
238
}
239
precision = parseInt(precision, 10)
240
var s
241
if (val.__class__ === $B.LongInt.$dict) {
242
s=$B.LongInt.$dict.to_base(val, 10)
243
} else {
244
s=val.toString()
245
}
246
if (s[0] === '-') {
247
return '-' + get_char_array(precision - s.length + 1, '0') + s.slice(1)
248
}
249
return get_char_array(precision - s.length, '0') + s
250
}
251
252
var format_float_precision = function(val, upper, flags, modifier) {
253
var precision = flags.precision
254
// val is a float
255
if (isFinite(val)) {
257
}
258
if (val === Infinity) {
259
val = 'inf'
260
} else if (val === -Infinity) {
261
val = '-inf'
262
} else {
263
val = 'nan'
264
}
265
if (upper) {
266
return val.toUpperCase()
267
}
268
return val
270
}
271
272
var format_sign = function(val, flags) {
273
if (flags.sign) {
274
if (val >= 0) {
275
return "+"
277
} else if (flags.space) {
278
if (val >= 0) {
279
return " "
280
}
281
}
282
return ""
283
}
285
var str_format = function(val, flags) {
286
// string format supports left and right padding
287
flags.pad_char = " " // even if 0 padding is defined, don't use it
293
if (val.__class__ === $B.LongInt.$dict) {
294
val = $B.LongInt.$dict.to_base(val, 10)
295
} else {
296
val = parseInt(val)
297
}
298
299
var s = format_int_precision(val, flags)
300
if (flags.pad_char === '0') {
301
if (val < 0) {
302
s = s.substring(1)
303
return '-' + format_padding(s, flags, true)
304
}
305
var sign = format_sign(val, flags)
306
if (sign !== '') {
307
return sign + format_padding(s, flags, true)
308
}
309
}
314
var repr_format = function(val, flags) {
315
flags.pad_char = " " // even if 0 padding is defined, don't use it
316
return format_padding(repr(val), flags)
317
}
319
var ascii_format = function(val, flags) {
320
flags.pad_char = " " // even if 0 padding is defined, don't use it
321
return format_padding(ascii(val), flags)
322
}
325
var _float_helper = function(val, flags) {
326
number_check(val)
327
if (!flags.precision) {
328
if (!flags.decimal_point) {
329
flags.precision = 6
330
} else {
331
flags.precision = 0
332
}
333
} else {
334
flags.precision = parseInt(flags.precision, 10)
335
validate_precision(flags.precision)
336
}
337
return parseFloat(val)
338
}
340
// used to capture and remove trailing zeroes
341
var trailing_zeros = /(.*?)(0+)([eE].*)/
342
var leading_zeros = /\.(0*)/
343
var trailing_dot = /\.$/
345
var validate_precision = function(precision) {
346
// force precision to limits of javascript
348
}
349
350
// gG
351
var floating_point_format = function(val, upper, flags) {
352
val = _float_helper(val, flags)
353
var v = val.toString()
354
var v_len = v.length
355
var dot_idx = v.indexOf('.')
356
if (dot_idx < 0) {
357
dot_idx = v_len
358
}
359
if (val < 1 && val > -1) {
360
var zeros = leading_zeros.exec(v)
361
var numzeros
362
if (zeros) {
363
numzeros = zeros[1].length
364
} else {
365
numzeros = 0
366
}
367
if (numzeros >= 4) {
368
val = format_sign(val, flags) + format_float_precision(val, upper, flags, _floating_g_exp_helper)
369
if (!flags.alternate) {
370
var trl = trailing_zeros.exec(val)
371
if (trl) {
372
val = trl[1].replace(trailing_dot, '') + trl[3] // remove trailing
382
return format_padding(format_sign(val, flags) + format_float_precision(val, upper, flags,
388
if (dot_idx > flags.precision) {
389
val = format_sign(val, flags) + format_float_precision(val, upper, flags, _floating_g_exp_helper)
390
if (!flags.alternate) {
391
var trl = trailing_zeros.exec(val)
392
if (trl) {
393
val = trl[1].replace(trailing_dot, '') + trl[3] // remove trailing
394
}
395
} else {
396
if (flags.precision <= 1) {
397
val = val[0] + '.' + val.substring(1)
398
}
399
}
400
return format_padding(val, flags)
401
}
402
return format_padding(format_sign(val, flags) + format_float_precision(val, upper, flags,
403
function(val, precision) {
404
if (!flags.decimal_point) {
405
precision = min(v_len - 1, 6)
406
} else if (precision > v_len) {
407
if (!flags.alternate) {
408
precision = v_len
410
}
411
if (precision < dot_idx) {
412
precision = dot_idx
413
}
414
return val.toFixed(precision - dot_idx)
415
}), flags)
416
}
418
var _floating_g_exp_helper = function(val, precision, flags, upper) {
419
if (precision) {
420
--precision
421
}
422
val = val.toExponential(precision)
423
// pad exponent to two digits
424
var e_idx = val.lastIndexOf('e')
425
if (e_idx > val.length - 4) {
427
}
428
if (upper) {
429
return val.toUpperCase()
430
}
431
return val
432
}
433
434
// fF
435
var floating_point_decimal_format = function(val, upper, flags) {
436
val = _float_helper(val, flags)
437
return format_padding(format_sign(val, flags) + format_float_precision(val, upper, flags,
438
function(val, precision, flags) {
439
val = val.toFixed(precision)
440
if (precision === 0 && flags.alternate) {
441
val += '.'
442
}
443
return val
444
}), flags)
445
}
446
447
var _floating_exp_helper = function(val, precision, flags, upper) {
448
val = val.toExponential(precision)
449
// pad exponent to two digits
450
var e_idx = val.lastIndexOf('e')
451
if (e_idx > val.length - 4) {
453
}
454
if (upper) {
455
return val.toUpperCase()
456
}
457
return val
458
}
459
460
// eE
461
var floating_point_exponential_format = function(val, upper, flags) {
462
val = _float_helper(val, flags)
464
return format_padding(format_sign(val, flags) + format_float_precision(val, upper, flags, _floating_exp_helper), flags)
465
}
466
467
var signed_hex_format = function(val, upper, flags) {
470
471
if (val.__class__ === $B.LongInt.$dict) {
472
ret=$B.LongInt.$dict.to_base(val, 16)
473
} else {
474
ret = parseInt(val)
475
ret = ret.toString(16)
476
}
477
ret = format_int_precision(ret, flags)
478
if (upper) {
479
ret = ret.toUpperCase()
480
}
481
if (flags.pad_char === '0') {
482
if (val < 0) {
483
ret = ret.substring(1)
484
ret = '-' + format_padding(ret, flags, true)
485
}
486
var sign = format_sign(val, flags)
487
if (sign !== '') {
488
ret = sign + format_padding(ret, flags, true)
492
if (flags.alternate) {
493
if (ret.charAt(0) === '-') {
494
if (upper) {
495
ret = "-0X" + ret.slice(1)
496
} else {
497
ret = "-0x" + ret.slice(1)
498
}
499
} else {
500
if (upper) {
501
ret = "0X" + ret
502
} else {
503
ret = "0x" + ret
504
}
505
}
506
}
507
return format_padding(format_sign(val, flags) + ret, flags)
508
}
513
514
if (val.__class__ === $B.LongInt.$dict) {
515
ret = $B.LongInt.$dict.to_base(8)
516
} else {
517
ret = parseInt(val)
518
ret = ret.toString(8)
519
}
520
523
if (flags.pad_char === '0') {
524
if (val < 0) {
525
ret = ret.substring(1)
526
ret = '-' + format_padding(ret, flags, true)
527
}
528
var sign = format_sign(val, flags)
529
if (sign !== '') {
530
ret = sign + format_padding(ret, flags, true)
531
}
534
if (flags.alternate) {
535
if (ret.charAt(0) === '-') {
536
ret = "-0o" + ret.slice(1)
537
} else {
538
ret = "0o" + ret
539
}
541
return format_padding(ret, flags)
542
}
543
544
var single_char_format = function(val, flags) {
545
if(isinstance(val,str) && val.length==1) return val
546
try {
550
}
551
return format_padding(chr(val), flags)
552
}
553
554
var num_flag = function(c, flags) {
555
if (c === '0' && !flags.padding && !flags.decimal_point && !flags.left) {
556
flags.pad_char = '0'
557
return
558
}
559
if (!flags.decimal_point) {
560
flags.padding = (flags.padding || "") + c
561
} else {
562
flags.precision = (flags.precision || "") + c
563
}
564
}
565
566
var decimal_point_flag = function(val, flags) {
567
if (flags.decimal_point) {
568
// can only have one decimal point
569
throw new UnsupportedChar()
570
}
571
flags.decimal_point = true
572
}
573
574
var neg_flag = function(val, flags) {
575
flags.pad_char = ' ' // overrides '0' flag
576
flags.left = true
577
}
578
579
var space_flag = function(val, flags) {
580
flags.space = true
581
}
582
583
var sign_flag = function(val, flags) {
584
flags.sign = true
585
}
586
587
var alternate_flag = function(val, flags) {
588
flags.alternate = true
589
}
590
592
's': str_format,
593
'd': num_format,
594
'i': num_format,
595
'u': num_format,
596
'o': octal_format,
597
'r': repr_format,
598
'a': ascii_format,
599
'g': function(val, flags) {return floating_point_format(val, false, flags)},
600
'G': function(val, flags) {return floating_point_format(val, true, flags)},
601
'f': function(val, flags) {return floating_point_decimal_format(val, false, flags)},
602
'F': function(val, flags) {return floating_point_decimal_format(val, true, flags)},
603
'e': function(val, flags) {return floating_point_exponential_format(val, false, flags)},
604
'E': function(val, flags) {return floating_point_exponential_format(val, true, flags)},
605
'x': function(val, flags) {return signed_hex_format(val, false, flags)},
606
'X': function(val, flags) {return signed_hex_format(val, true, flags)},
607
'c': single_char_format,
608
'0': function(val, flags) {return num_flag('0', flags)},
609
'1': function(val, flags) {return num_flag('1', flags)},
610
'2': function(val, flags) {return num_flag('2', flags)},
611
'3': function(val, flags) {return num_flag('3', flags)},
612
'4': function(val, flags) {return num_flag('4', flags)},
613
'5': function(val, flags) {return num_flag('5', flags)},
614
'6': function(val, flags) {return num_flag('6', flags)},
615
'7': function(val, flags) {return num_flag('7', flags)},
616
'8': function(val, flags) {return num_flag('8', flags)},
617
'9': function(val, flags) {return num_flag('9', flags)},
618
'-': neg_flag,
619
' ': space_flag,
620
'+': sign_flag,
621
'.': decimal_point_flag,
622
'#': alternate_flag
623
}
624
625
// exception thrown when an unsupported char is encountered in legacy format
626
var UnsupportedChar = function() {
627
this.name = "UnsupportedChar"
628
}
629
632
var length = self.length,
633
pos = 0 |0,
634
argpos = null,
635
getitem
636
if (_b_.isinstance(args, _b_.tuple)) {
679
// todo: get flags, type
680
// todo: string value based on flags, type, value
681
var flags = {'pad_char': ' '}
682
do {
689
if (ret !== undefined) {
690
return ret
691
}
692
++newpos
693
}
694
} catch (err) {
695
if (err.name === "UnsupportedChar") {
696
invalid_char = s[newpos]
697
if (invalid_char === undefined) {
701
"' (0x" + invalid_char.charCodeAt(0).toString(16) + ") at index " + newpos)
702
} else if (err.name === "NotANumber") {
703
var try_char = s[newpos]
714
throw _b_.TypeError.$factory("%" + try_char + " format: a number is required, not " + cls)
753
throw _b_.TypeError.$factory('not all arguments converted during string formatting')
756
throw _b_.TypeError.$factory('not all arguments converted during string formatting')
764
var $=$B.args('__mul__',2,{self:null,other:null},['self','other'],
765
arguments,{},null,null)
777
var res = self.replace(/\n/g,'\\\\n')
778
// escape the escape char
779
res = res.replace(/\\/g, '\\\\')
780
if(res.search('"')==-1 && res.search("'")==-1){
781
return "'"+res+"'"
802
"unorderable types: 'str' > "+$B.get_class(other).__name__+"()")}
803
return self > other
804
}
805
$comp_func += '' // source code
806
var $comps = {'>':'gt','>=':'ge','<':'lt','<=':'le'}
807
for(var $op in $comps){
819
// Copy static methods from unicode
820
var from_unicode = [
821
"title",
822
"capitalize",
823
"casefold",
824
"islower",
825
"isupper",
826
"istitle",
827
"isspace",
828
"isalpha",
829
"isalnum",
830
"isdecimal",
831
"isdigit",
832
"isnumeric",
833
"isidentifier",
834
"isprintable",
835
"lower",
836
"swapcase",
837
"upper"
838
]
839
for(var i=0;i<from_unicode.length;i++){
840
var name = from_unicode[i]
845
var $=$B.args("center",3,
846
{self:null, width:null, fillchar:null},
847
['self', 'width', 'fillchar'],
848
arguments,{fillchar:' '},null,null)
849
850
if($.width<=self.length) return self
865
var substr = $.self
866
if($.start!==null){
867
var _slice
868
if($.stop!==null){_slice = _b_.slice($.start, $.stop)}
869
else{_slice = _b_.slice($.start,$.self.length)}
871
}else{
872
if($.self.length+$.sub.length==0){return 1} // ''.count('') = 1
873
}
874
if($.sub.length==0){
875
if($.start==$.self.length){return 1} // 'aaa'.count('',3) = 1
876
else if(substr.length==0){return 0} // 'aaa'.count('',4) = 0
877
return substr.length+1
878
}
879
var n=0, pos=0
880
while(pos<substr.length){
881
pos=substr.indexOf($.sub,pos)
889
if(encoding=='rot13' || encoding=='rot_13'){
890
// Special case : returns a string
891
var res = ''
892
for(var i=0, _len = self.length; i<_len ; i++){
893
var char = self.charAt(i)
894
if(('a'<=char && char<='m') || ('A'<=char && char<='M')){
895
res += String.fromCharCode(String.charCodeAt(char)+13)
896
}else if(('m'<char && char<='z') || ('M'<char && char<='Z')){
897
res += String.fromCharCode(String.charCodeAt(char)-13)
898
}else{res += char}
899
}
900
return res
901
}
906
// Return True if the string ends with the specified suffix, otherwise
907
// return False. suffix can also be a tuple of suffixes to look for.
908
// With optional start, test beginning at that position. With optional
913
arguments,{start:0, end:null},null,null)
914
915
normalize_start_end($)
916
917
var suffixes = $.suffix
925
if(suffix.length<=s.length &&
926
s.substr(s.length-suffix.length)==suffix) return true
927
}
928
return false
929
}
930
932
var $ = $B.args('expandtabs', 2, {self:null, tabsize:null},
933
['self', 'tabsize'], arguments, {tabsize:8}, null, null)
934
var s=$B.$GetInt($.tabsize), col=0,pos=0,res=''
935
if(s==1){return self.replace(/\t/g,' ')}
936
while(pos<self.length){
937
var car = self.charAt(pos)
938
switch(car){
939
case '\t':
940
while(col%s > 0){res += ' ';col++}
941
break
942
case '\r':
943
case '\n':
944
res += car
945
col = 0
946
break
947
default:
948
res += car
949
col++
950
break
951
}
952
pos++
953
}
959
// Return the lowest index in the string where substring sub is found,
960
// such that sub is contained in the slice s[start:end]. Optional
961
// arguments start and end are interpreted as in slice notation.
973
var s = $.self.substring($.start,$.end)
974
975
if($.sub.length==0 && $.start==$.self.length){return $.self.length}
976
if(s.length+$.sub.length==0){return -1}
977
978
var last_search = s.length-$.sub.length
979
for(var i=0;i<=last_search;i++){
980
if(s.substr(i, $.sub.length)==$.sub){return $.start+i}
991
// a.x[z]!r:...
992
// the object has attributes :
993
// - name : "a"
994
// - name_ext : [".x", "[z]"]
995
// - conv : r
996
// - spec : rest of string after :
998
var elts = fmt_string.split(':'), name, conv, spec, name_ext=[]
999
if(elts.length==1){
1000
// No : in the string : it only contains a name
1001
name = fmt_string
1002
}else{
1003
// name is before the first ":"
1004
// spec (the format specification) is after
1005
name = elts[0]
1006
spec = elts.splice(1).join(':')
1007
}
1008
1009
var elts = name.split('!')
1010
if(elts.length>1){
1011
name=elts[0]
1012
conv=elts[1] // conversion flag
1013
if(conv.length!==1 || 'ras'.search(conv)==-1){
1018
if(name!==undefined){
1019
// "name' may be a subscription or attribute
1020
// Put these "extensions" in the list "name_ext"
1021
function name_repl(match){
1022
name_ext.push(match)
1023
return ''
1024
}
1025
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1026
name = name.replace(name_ext_re, name_repl)
1027
}
1036
1037
// Parse self to detect formatting instructions
1038
// Create a list "parts" made of sections of the string :
1039
// - elements of even rank are literal text
1040
// - elements of odd rank are "format objects", built from the
1041
// format strings in self (of the form {...})
1048
while(pos<_len){
1049
car = self.charAt(pos)
1050
if(car=='{' && self.charAt(pos+1)=='{'){
1051
// replace {{ by literal {
1052
text += '{'
1053
pos+=2
1054
}else if(car=='}' && self.charAt(pos+1)=='}'){
1055
// replace }} by literal }
1056
text += '}'
1057
pos+=2
1058
}else if(car=='{'){
1059
// Start of a format string
1061
// Store current literal text
1062
parts.push(text)
1063
1064
// Search the end of the format string, ie the } closing the
1065
// opening {. Since the string can contain other pairs {} for
1066
// nested formatting, an integer nb is incremented for each { and
1067
// decremented for each } ; the end of the format string is
1068
// reached when nb==0
1069
var end = pos+1, nb=1
1070
while(end<_len){
1071
if(self.charAt(end)=='{'){nb++;end++}
1072
else if(self.charAt(end)=='}'){
1073
nb--;end++
1074
if(nb==0){
1075
// End of format string
1076
var fmt_string = self.substring(pos+1, end-1)
1077
1078
// Create a format object, by function parse_format
1079
var fmt_obj = parse_format(fmt_string)
1080
1081
// If no name is explicitely provided, use the rank
1082
if(!fmt_obj.name){
1083
fmt_obj.name=rank+''
1084
rank++
1085
}
1089
// In this case, evaluate them using the positional
1090
// or keyword arguments passed to format()
1092
if(/\d+/.exec(key)){
1093
// If key is numeric, search in positional
1094
// arguments
1106
// Store format object in list "parts"
1107
parts.push(fmt_obj)
1108
text = ''
1109
break
1110
}
1111
}else{end++}
1117
if(text){parts.push(text)}
1118
// Apply formatting to the values passed to format()
1119
var res = '', fmt
1120
for(var i=0;i<parts.length;i++){
1121
// Literal text is added unchanged
1122
if(typeof parts[i]=='string'){res += parts[i];continue}
1124
// Format objects
1125
fmt = parts[i]
1126
if(fmt.name.charAt(0).search(/\d/)>-1){
1127
// Numerical reference : use positional arguments
1128
var pos = parseInt(fmt.name),
1133
}
1134
// If name has extensions (attributes or subscriptions)
1135
for(var j=0;j<fmt.name_ext.length;j++){
1136
var ext = fmt.name_ext[j]
1137
if(ext.charAt(0)=='.'){
1138
// Attribute
1139
value = _b_.getattr(value, ext.substr(1))
1140
}else{
1141
// Subscription
1142
var key = ext.substr(1, ext.length-2)
1143
// An index made of digits is transformed into an integer
1144
if(key.charAt(0).search(/\d/)>-1){key = parseInt(key)}
1145
value = _b_.getattr(value, '__getitem__')(key)
1146
}
1147
}
1148
// XXX temporary
1149
value = value.__class__ === $B.$factory ? value.$dict : value
1150
// If the conversion flag is set, first call a function to convert
1151
// the value
1152
if(fmt.conv=='a'){value = _b_.ascii(value)}
1153
else if(fmt.conv=='r'){value = _b_.repr(value)}
1179
var $=$B.args('join',2,{self:null,iterable:null},
1180
['self', 'iterable'], arguments, {}, null, null)
1190
"sequence item "+count+": expected str instance, "+$B.get_class(obj2).__name__+" found")}
1193
if(_b_.isinstance(err, _b_.StopIteration)){
1194
$B.current_exception = ce
1195
break
1196
}
1204
var $=$B.args('ljust',3,{self:null,width:null,fillchar:null},
1205
['self','width','fillchar'],arguments,{fillchar:' '},null,null)
1206
1207
if ($.width <= self.length) return self
1208
return self + $.fillchar.repeat($.width - self.length)
1212
var $=$B.args('lstrip',2,{self:null,chars:null},['self','chars'],
1213
arguments,{chars:_b_.None},null,null)
1214
if($.chars===_b_.None){return $.self.trimLeft()}
1215
for (var i = 0; i < $.self.length; i++) {
1216
if ($.chars.indexOf($.self.charAt(i)) === -1) {
1217
return $.self.substring(i);
1218
}
1219
}
1220
return '';
1225
var $ = $B.args('maketrans', 3, {x:null,y:null,z:null},['x','y','z'],
1226
arguments, {y:null, z:null}, null, null)
1228
var _t=_b_.dict()
1229
// make 'default' translate table
1230
for(var i=0; i < 256; i++) _t.$numeric_dict[i]=i
1231
1232
if($.y===null && $.z===null){
1233
// If there is only one argument, it must be a dictionary mapping
1234
// Unicode ordinals (integers) or characters (strings of length 1) to
1235
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1236
// keys will then be converted to ordinals.
1237
if(!_b_.isinstance($.x, _b_.dict)){
1239
}
1240
var items = _b_.list(_b_.dict.$dict.items($.x))
1241
for(var i=0, len=items.length;i<len;i++){
1242
var k = items[i][0], v=items[i][1]
1243
if(!_b_.isinstance(k, _b_.int)){
1244
if(_b_.isinstance(k, _b_.str) && k.length==1){k = _b_.ord(k)}
1246
" is not int or 1-char string")}
1247
}
1248
if(v!==_b_.None && !_b_.isinstance(v, [_b_.int, _b_.str])){
1250
" is not None, integer or string")
1251
}
1252
_t.$numeric_dict[k] = v
1253
}
1254
return _t
1255
}else{
1257
// and in the resulting dictionary, each character in x will be mapped
1258
// to the character at the same position in y
1259
if(!(_b_.isinstance($.x, _b_.str) && _b_.isinstance($.y, _b_.str))){
1262
throw _b_.TypeError.$factory("maketrans arguments must be strings or same length")
1267
// characters will be mapped to None in the result
1268
if(!_b_.isinstance($.z, _b_.str)){
1270
}
1271
for(var i=0,len=$.z.length;i<len;i++){
1272
toNone[_b_.ord($.z.charAt(i))] = true
1273
}
1275
for(var i=0,len=$.x.length;i<len;i++){
1276
_t.$numeric_dict[_b_.ord($.x.charAt(i))] = _b_.ord($.y.charAt(i))
1277
}
1278
for(var k in toNone){
1279
_t.$numeric_dict[k] = _b_.None
1280
}
1281
return _t
1282
}
1283
}
1287
var $=$B.args('partition',2,{self:null,sep:null},['self','sep'],
1288
arguments,{},null,null)
1290
check_str($.sep)
1291
var i=$.self.indexOf($.sep)
1292
if (i== -1) return _b_.tuple([$.self, '', ''])
1301
var re = new RegExp('\\'+specials.charAt(i),'g')
1302
str = str.replace(re, "\\"+specials.charAt(i))
1303
}
1304
return str
1305
}
1306
1311
var $ = $B.args('replace', 4, {self:null,old:null,$$new:null,count:null},
1312
['self','old','$$new','count'], arguments, {count:-1},null,null),
1313
count=$.count,self=$.self,old=$.old,_new=$.$$new
1317
// Validate instance type of 'count'
1318
if (!isinstance(count,[_b_.int,_b_.float])) {
1320
"' object cannot be interpreted as an integer");
1321
} else if (isinstance(count, _b_.float)) {
1323
}
1324
if(count==0){return self}
1325
if(count.__class__==$B.LongInt.$dict){count=parseInt(count.value)}
1326
if(old==''){
1327
if(_new==''){return self}
1328
if(self==''){return _new}
1329
var elts=self.split('')
1330
if(count>-1 && elts.length>=count){
1331
var rest = elts.slice(count).join('')
1332
return _new+elts.slice(0, count).join(_new)+rest
1333
}else{return _new+elts.join(_new)+_new}
1334
}else{
1338
var res = self, pos = -1
1339
if(old.length==0){
1340
var res = _new
1341
for(var i=0;i<elts.length;i++){
1342
res += elts[i]+_new
1343
}
1344
return res+rest
1345
}
1347
if (count < 0) count = res.length;
1348
while (count > 0) {
1349
pos = res.indexOf(old, pos);
1350
if (pos < 0)
1351
break;
1352
res = res.substr(0, pos) + _new + res.substr(pos + old.length);
1353
pos = pos + _new.length;
1354
count--;
1355
}
1356
return res;
1360
// Return the highest index in the string where substring sub is found,
1361
// such that sub is contained within s[start:end]. Optional arguments
1372
if($.sub.length==0){
1373
if($.start>$.self.length){return -1}
1374
else{return $.self.length}
1375
}
1376
var sublen = $.sub.length
1378
for(var i=$.end-sublen;i>=$.start;i--){
1379
if($.self.substr(i, sublen)==$.sub){return i}
1380
}
1381
return -1
1393
{self:null, width:null, fillchar:null},
1394
['self', 'width', 'fillchar'],
1395
arguments,{fillchar:' '},null,null)
1403
var $=$B.args('rpartition',2,{self:null,sep:null},['self','sep'],
1404
arguments,{},null,null)
1405
check_str($.sep)
1409
for(var i=0;i<items.length;i++){
1410
items[i]=items[i].split('').reverse().join('')
1411
}
1412
return items
1416
var $=$B.args("rsplit",3,{self:null,sep:null,maxsplit:null},
1417
['self','sep','maxsplit'],arguments,
1418
{sep:_b_.None, maxsplit:-1},null,null),
1422
var rev_str = reverse($.self),
1423
rev_sep = sep === _b_.None ? sep : reverse($.sep),
1426
// Reverse the list, then each string inside the list
1427
rev_res.reverse()
1428
for(var i=0;i<rev_res.length;i++){
1435
var $=$B.args('rstrip',2,{self:null,chars:null},['self','chars'],
1436
arguments,{chars:_b_.None},null,null)
1437
if($.chars===_b_.None){return $.self.trimRight()}
1438
for (var j = $.self.length-1; j >= 0; j--) {
1439
if ($.chars.indexOf($.self.charAt(j)) === -1) {
1440
return $.self.substring(0,j+1);
1441
}
1442
}
1443
return '';
1448
var $=$B.args("split",3,{self:null,sep:null,maxsplit:null},
1449
['self','sep','maxsplit'],arguments,
1450
{sep:_b_.None, maxsplit:-1},null,null)
1451
var sep=$.sep,maxsplit=$.maxsplit,self=$.self
1452
if(maxsplit.__class__===$B.LongInt.$dict){maxsplit=parseInt(maxsplit.value)}
1458
var name = ''
1459
while(1){
1460
if(self.charAt(pos).search(/\s/)===-1){
1461
if(name===''){name=self.charAt(pos)}
1462
else{name+=self.charAt(pos)}
1463
}else{
1464
if(name!==''){
1465
res.push(name)
1466
if(maxsplit!==-1&&res.length===maxsplit+1){
1467
res.pop()
1468
res.push(name+self.substr(pos))
1469
return res
1470
}
1471
name=''
1472
}
1473
}
1474
pos++
1475
if(pos>self.length-1){
1476
if(name){res.push(name)}
1477
break
1478
}
1479
}
1480
return res
1481
}else{
1483
if(maxsplit==0){return [self]}
1484
while(pos<self.length){
1485
if(self.substr(pos,seplen)==sep){
1486
res.push(s)
1487
pos += seplen
1488
if(maxsplit>-1 && res.length>=maxsplit){
1489
res.push(self.substr(pos))
1490
return res
1491
}
1492
s= ''
1493
}else{
1494
s += self.charAt(pos)
1495
pos++
1504
var $=$B.args('splitlines',2,{self:null,keepends:null},
1505
['self','keepends'],arguments,{keepends:false},null,null)
1506
if(!_b_.isinstance($.keepends,[_b_.bool, _b_.int])){
1517
while(pos<self.length){
1518
if(self.substr(pos,2)=='\r\n'){
1519
res.push(self.substring(start,pos+2))
1520
start = pos+2
1521
pos = start
1522
}else if(self.charAt(pos)=='\r' || self.charAt(pos)=='\n'){
1523
res.push(self.substring(start,pos+1))
1524
start = pos+1
1525
pos = start
1526
}else{pos++}
1527
}
1528
var rest = self.substr(start)
1529
if(rest){res.push(rest)}
1530
return res
1531
}else{
1532
var self = $.self.replace(/[\r\n]$/,'')
1533
return self.split(/\n|\r\n|\r/)
1534
}
1535
}
1538
// Return True if string starts with the prefix, otherwise return False.
1539
// prefix can also be a tuple of prefixes to look for. With optional
1540
// start, test string beginning at that position. With optional end,
1547
normalize_start_end($)
1548
1549
var prefixes = $.prefix
1550
if(!isinstance(prefixes,_b_.tuple)){prefixes=[prefixes]}
1552
var s = $.self.substring($.start,$.end)
1553
for(var i=0, _len_i = prefixes.length; i < _len_i;i++){
1554
prefix = prefixes[i]
1556
"endswith first arg must be str or a tuple of str, not int")}
1557
if(s.substr(0,prefix.length)==prefix) return true
1564
var $=$B.args('strip',2,{self:null,chars:null},['self','chars'],
1565
arguments,{chars:_b_.None},null,null)
1566
if($.chars===_b_.None){return $.self.trim()}
1567
for (var i = 0; i < $.self.length; i++) {
1568
if ($.chars.indexOf($.self.charAt(i)) === -1) {
1569
break;
1570
}
1571
}
1572
for (var j = $.self.length-1; j >= i; j--) {
1573
if ($.chars.indexOf($.self.charAt(j)) === -1) {
1574
break;
1575
}
1576
}
1577
return $.self.substring(i,j+1);
1593
var $=$B.args('zfill',2,{self:null,width:null},
1594
['self','width'],arguments,{},null,null)
1595
if ($.width <= self.length) {return self}
1596
switch(self.charAt(0)){
1597
case '+':
1598
case '-':
1599
return self.charAt(0)+'0'.repeat($.width-self.length)+self.substr(1)
1600
default:
1601
return '0'.repeat(width - self.length)+self
1602
}
1619
// class or its subclasses, but the attribute __str__ of the
1620
// class metaclass (usually "type") or its subclasses (usually
1621
// "object")
1622
// The metaclass is the attribute __class__ of the class dictionary
1626
var f = getattr(arg,'__str__')
1627
// XXX fix : if not better than object.__str__, try __repr__
1636
if($B.debug>1){console.log(err)}
1637
console.log('Warning - no method __str__ or __repr__, default to toString', arg)
1663
for(var $attr in str){
1664
if(typeof str[$attr]=='function'){
1665
StringSubclass[$attr]=(function(attr){
1687
// Function to parse the 2nd argument of format()
1688
$B.parse_format_spec = function(spec){
1698
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1))!=-1){
1699
// If the second char is also an alignment specifier, the
1700
// first char is the fill value
1701
this.fill = spec.charAt(0)
1702
this.align = spec.charAt(1)
1703
pos = 2
1704
}else{
1705
// The first character defines alignment : fill defaults to ' '
1706
this.align=aligns[align_pos];
1707
this.fill=' ';
1708
pos++
1709
}
1710
}else{
1711
align_pos = aligns.indexOf(spec.charAt(1))
1712
if(spec.charAt(1) && align_pos!=-1){
1713
// The second character defines alignment : fill is the first one
1714
this.align=aligns[align_pos]
1715
this.fill=spec.charAt(0)
1716
pos = 2
1717
}
1718
}
1719
var car = spec.charAt(pos)
1720
if(car=='+'||car=='-'||car==' '){
1721
this.sign=car;
1722
pos++;
1723
car=spec.charAt(pos);
1726
if(car=='0'){
1727
// sign-aware : equivalent to fill=0 and align=='='
1728
this.fill='0'
1729
this.align = '='
1730
pos++;car=spec.charAt(pos)
1731
}
1733
if(this.width===undefined){this.width=car}
1734
else{this.width+=car}
1735
pos++;car=spec.charAt(pos)
1737
if(this.width!==undefined){this.width=parseInt(this.width)}
1738
if(car==','){this.comma=true;pos++;car=spec.charAt(pos)}
1739
if(car=='.'){
1740
if(digits.indexOf(spec.charAt(pos+1))==-1){
1742
}
1743
this.precision = spec.charAt(pos+1)
1744
pos+=2;car=spec.charAt(pos)
1745
while(car && digits.indexOf(car)>-1){
1746
this.precision+=car;pos++;car=spec.charAt(pos)
1747
}
1748
this.precision = parseInt(this.precision)
1749
}
1750
if(car && types.indexOf(car)>-1){this.type=car;pos++;car=spec.charAt(pos)}
1751
if(pos!==spec.length){
1758
(this.align||'')+
1759
(this.sign||'')+
1760
(this.alternate ? '#' : '')+
1761
(this.sign_aware ? '0' : '')+
1762
(this.width || '')+
1763
(this.comma ? ',' : '')+
1764
(this.precision ? '.'+this.precision : '')+
1765
(this.type || '')
1766
}
1767
}
1768
1769
$B.format_width = function(s, fmt){
1770
if(fmt.width && s.length<fmt.width){
1771
var fill=fmt.fill || ' ', align = fmt.align || '<',
1772
missing = fmt.width-s.length
1773
switch(align){
1774
case '<':
1775
return s+fill.repeat(missing)
1776
case '>':
1777
return fill.repeat(missing)+s
1778
case '=':
1779
if('+-'.indexOf(s.charAt(0))>-1){
1780
return s.charAt(0)+fill.repeat(missing)+s.substr(1)
1792
function fstring_expression(){
1793
this.type = 'expression'
1794
this.expression = ''
1795
this.conversion = null
1796
this.fmt = null
1797
}
1798
1799
$B.parse_fstring = function(string){
1800
// Parse a f-string
1801
var elts = [],
1802
pos = 0,
1803
current = '',
1804
ctype = null,
1805
nb_braces = 0,
1806
car
1807
1808
while(pos<string.length){
1809
if(ctype===null){
1810
car = string.charAt(pos)
1811
if(car=='{'){
1812
if(string.charAt(pos+1)=='{'){
1813
ctype = 'string'
1814
current = '{'
1815
pos += 2
1816
}else{
1817
ctype = 'expression'
1818
nb_braces = 1
1819
pos++
1820
}
1821
}else if(car=='}'){
1822
if(string.charAt(pos+1)==car){
1823
ctype = 'string'
1824
current = '}'
1826
}else{
1827
throw Error(" f-string: single '}' is not allowed")
1828
}
1829
}else{
1830
ctype = 'string'
1831
current = car
1833
}
1834
}else if(ctype=='string'){
1835
// end of string is the first single { or end of string
1837
while(i<string.length){
1838
car = string.charAt(i)
1839
if(car=='{'){
1840
if(string.charAt(i+1)=='{'){
1841
current += '{'
1842
i+=2
1843
}else{
1844
elts.push(current)
1845
ctype = 'expression'
1846
pos = i+1
1847
break
1848
}
1849
}else if(car=='}'){
1850
if(string.charAt(i+1)==car){
1851
current += car
1852
i += 2
1853
}else{
1854
throw Error(" f-string: single '}' is not allowed")
1855
}
1856
}else{
1857
current += car
1858
i++
1859
}
1860
}
1861
pos = i+1
1862
}else{
1863
// End of expression is the } matching the opening {
1864
// There may be nested braces
1865
var i = pos,
1866
nb_braces = 1,
1887
}else if(car=='\\'){
1888
// backslash is not allowed in expressions
1889
throw Error("f-string expression part cannot include a" +
1890
" backslash")
1893
if(current.expression.length==0){
1894
throw Error("f-string: empty expression not allowed")
1895
}
1896
if('ars'.indexOf(string.charAt(i+1)) == -1){
1897
throw Error("f-string: invalid conversion character:" +
1898
" expected 's', 'r', or 'a'")
1899
}else{
1900
current.conversion = string.charAt(i+1)
1901
i += 2
1902
}
1903
}else if(car=='('){
1904
nb_paren++
1905
current.expression += car
1906
i++
1907
}else if(car==')'){
1908
nb_paren--
1909
current.expression += car
1910
i++
1911
}else if(car=='"'){
1912
// triple string ?
1913
if(string.substr(i, 3)=='"""'){
1914
var end = string.indexOf('"""', i+3)
1915
if(end==-1){throw Error("f-string: unterminated string")}
1916
else{
1917
var trs = string.substring(i, end+3)
1918
trs = trs.replace('\n', '\\n\\')
1919
current.expression += trs
1920
i = end+3
1921
}
1922
}else{
1923
var end = string.indexOf('"', i+1)
1924
if(end==-1){throw Error("f-string: unterminated string")}
1925
else{
1926
current.expression += string.substring(i, end+1)
1927
i = end+1
1928
}
1929
}
1930
}else if(nb_paren == 0 && car==':'){
1936
i++
1937
}
1938
}
1939
if(nb_braces>0){
1940
throw Error("f-string: expected '}'")
1941
}
1942
}
1943
}
1944
if(current.length>0){elts.push(current)}
1945
return elts
1946
}
1947