Permalink
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Apr 25, 2020
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Dec 20, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Jan 14, 2015
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Dec 18, 2019
Dec 18, 2019
Mar 19, 2018
Jan 14, 2015
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Jan 14, 2015
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jul 8, 2020
Dec 8, 2020
Dec 8, 2020
Mar 19, 2018
Mar 19, 2018
Mar 27, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Apr 2, 2019
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
Apr 16, 2019
Mar 19, 2018
Apr 16, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 12, 2018
Nov 22, 2020
Nov 12, 2018
Mar 19, 2018
Mar 19, 2018
Nov 22, 2020
Apr 2, 2019
Sep 27, 2020
Sep 27, 2020
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jan 6, 2016
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jun 11, 2020
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Aug 31, 2017
May 24, 2019
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Feb 27, 2020
Feb 27, 2020
Feb 27, 2020
Aug 31, 2017
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 14, 2018
Jan 26, 2020
Mar 19, 2018
Mar 19, 2018
Nov 15, 2019
Jul 28, 2018
Oct 27, 2019
Nov 2, 2018
Oct 27, 2019
Nov 2, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Nov 12, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
Jun 29, 2017
Jun 29, 2017
Jun 29, 2017
Oct 13, 2019
Jun 29, 2017
Jul 10, 2017
Jul 10, 2017
Mar 19, 2018
Mar 19, 2018
Jun 20, 2020
Nov 30, 2020
Oct 13, 2019
Apr 25, 2020
Dec 11, 2020
Apr 25, 2020
Newer
100644
2627 lines (2412 sloc)
83.5 KB
21
if($.start === null || $.start === _b_.None){$.start = 0}
22
else if($.start < 0){
23
$.start += $.self.length
24
$.start = Math.max(0, $.start)
25
}
26
if($.end === null || $.end === _b_.None){$.end = $.self.length}
27
else if($.end < 0){
28
$.end += $.self.length
29
$.end = Math.max(0, $.end)
30
}
32
if(! isinstance($.start, _b_.int) || ! isinstance($.end, _b_.int)){
33
throw _b_.TypeError.$factory("slice indices must be integers " +
34
"or None or have an __index__ method")
35
}
52
if(!(typeof other === "string")){
53
try{return getattr(other, "__radd__")(self)}
54
catch(err){
55
throw _b_.TypeError.$factory("Can't convert " +
63
throw _b_.TypeError.$factory("'in <string>' requires " +
64
"string as left operand, not " + item.__class__)
65
}
66
if(typeof item == "string"){
67
var nbcar = item.length
68
}else{
69
var nbcar = _b_.len(item)
70
}
71
if(nbcar == 0) {return true} // a string contains the empty string
72
if(self.length == 0){return nbcar == 0}
73
for(var i = 0, len = self.length; i < len; i++){
74
if(self.substr(i, nbcar) == item){return true}
83
// __dir__must be assigned explicitely because attribute resolution for
84
// builtin classes doesn't use __mro__
88
if(other === undefined){ // compare object "self" to class "str"
89
return self === str
99
if(fmt.type && fmt.type != "s"){
100
throw _b_.ValueError.$factory("Unknown format code '" + fmt.type +
108
if(fmt.sign !== undefined){
109
throw _b_.ValueError.$factory(
110
"Sign not allowed in string format specifier")
123
if(arg < 0) {pos += self.length}
124
if(pos >= 0 && pos < self.length){return self.charAt(pos)}
125
throw _b_.IndexError.$factory("string index out of range")
126
}
127
if(isinstance(arg, slice)) {
128
var s = _b_.slice.$conv_for_seq(arg, self.length),
129
start = s.start,
130
stop = s.stop,
131
step = s.step
132
var res = "",
134
if(step > 0){
135
if(stop <= start){return ""}
136
for(var i = start; i < stop; i += step){res += self.charAt(i)}
138
if(stop >= start){return ''}
139
for(var i = start; i > stop; i += step){res += self.charAt(i)}
159
var x = prefix
160
x = (x ^ (p.charCodeAt(0) << 7)) & mask
161
for(var i = 0, len = p.length; i < len; i++){
162
x = ((1000003 * x) ^ p.charCodeAt(i)) & mask
163
}
164
x = (x ^ p.length) & mask
165
x = (x ^ suffix) & mask
234
// left adjusted
235
return s + get_char_array(padding - s.length, flags.pad_char)
236
}
237
}
238
246
if(val.__class__ === $B.long_int){
247
s = $B.long_int.to_base(val, 10)
248
}else{
249
s = val.toString()
251
if(s[0] === "-"){
252
return "-" + get_char_array(precision - s.length + 1, "0") + s.slice(1)
263
if(val === Infinity){
264
val = "inf"
265
}else if(val === -Infinity){
266
val = "-inf"
267
}else{
268
val = "nan"
290
var str_format = function(val, flags) {
291
// string format supports left and right padding
292
flags.pad_char = " " // even if 0 padding is defined, don't use it
298
if(val.__class__ === $B.long_int){
299
val = $B.long_int.to_base(val, 10)
300
}else{
301
val = parseInt(val)
319
var repr_format = function(val, flags) {
320
flags.pad_char = " " // even if 0 padding is defined, don't use it
321
return format_padding(repr(val), flags)
322
}
324
var ascii_format = function(val, flags) {
325
flags.pad_char = " " // even if 0 padding is defined, don't use it
326
return format_padding(ascii(val), flags)
327
}
339
flags.precision = parseInt(flags.precision, 10)
340
validate_precision(flags.precision)
341
}
342
return parseFloat(val)
343
}
346
var trailing_zeros = /(.*?)(0+)([eE].*)/,
347
leading_zeros = /\.(0*)/,
348
trailing_dot = /\.$/
350
var validate_precision = function(precision) {
351
// force precision to limits of javascript
356
var floating_point_format = function(val, upper, flags){
357
val = _float_helper(val, flags),
358
v = val.toString(),
359
v_len = v.length,
360
dot_idx = v.indexOf('.')
361
if(dot_idx < 0){dot_idx = v_len}
362
if(val < 1 && val > -1){
363
var zeros = leading_zeros.exec(v),
364
numzeros
365
if(zeros){
370
if(numzeros >= 4){
371
val = format_sign(val, flags) + format_float_precision(val, upper,
372
flags, _floating_g_exp_helper)
373
if(!flags.alternate){
386
return format_padding(format_sign(val, flags) +
387
format_float_precision(val, upper, flags,
388
function(val, precision) {
389
return val.toFixed(min(precision, v_len - dot_idx) +
390
numzeros)
391
}),
392
flags
393
)
394
}
395
396
if(dot_idx > flags.precision){
397
val = format_sign(val, flags) + format_float_precision(val, upper,
398
flags, _floating_g_exp_helper)
399
if(! flags.alternate){
411
return format_padding(format_sign(val, flags) +
412
format_float_precision(val, upper, flags,
413
function(val, precision) {
414
if(!flags.decimal_point){
415
precision = min(v_len - 1, 6)
416
}else if (precision > v_len){
417
if(! flags.alternate){
418
precision = v_len
419
}
421
if(precision < dot_idx){
422
precision = dot_idx
423
}
424
return val.toFixed(precision - dot_idx)
425
}),
426
flags
427
)
430
var _floating_g_exp_helper = function(val, precision, flags, upper){
431
if(precision){--precision}
434
var e_idx = val.lastIndexOf("e")
435
if(e_idx > val.length - 4){
436
val = val.substring(0, e_idx + 2) + "0" + val.substring(e_idx + 2)
439
return val
440
}
441
442
// fF
443
var floating_point_decimal_format = function(val, upper, flags) {
444
val = _float_helper(val, flags)
445
return format_padding(format_sign(val, flags) +
446
format_float_precision(val, upper, flags,
447
function(val, precision, flags) {
448
val = val.toFixed(precision)
449
if(precision === 0 && flags.alternate){
450
val += '.'
451
}
452
return val
453
}),
454
flags
455
)
456
}
457
458
var _floating_exp_helper = function(val, precision, flags, upper) {
459
val = val.toExponential(precision)
460
// pad exponent to two digits
473
return format_padding(format_sign(val, flags) +
474
format_float_precision(val, upper, flags, _floating_exp_helper), flags)
500
if(flags.alternate){
501
if(ret.charAt(0) === "-"){
502
if(upper){ret = "-0X" + ret.slice(1)}
503
else{ret = "-0x" + ret.slice(1)}
504
}else{
505
if(upper){ret = "0X" + ret}
506
else{ret = "0x" + ret}
516
if(val.__class__ === $B.long_int){
517
ret = $B.long_int.to_base(8)
518
}else{
519
ret = parseInt(val)
520
ret = ret.toString(8)
536
if(flags.alternate){
537
if(ret.charAt(0) === "-"){ret = "-0o" + ret.slice(1)}
538
else{ret = "0o" + ret}
543
function series_of_bytes(val, flags){
544
if(val.__class__ && val.__class__.$buffer_protocol){
545
var it = _b_.iter(val),
546
ints = []
547
while(true){
548
try{
549
ints.push(_b_.next(it))
550
}catch(err){
551
if(err.__class__ === _b_.StopIteration){
552
var b = _b_.bytes.$factory(ints)
553
return format_padding(_b_.bytes.decode(b, "ascii"), flags)
554
}
555
throw err
556
}
557
}
558
}else{
559
try{
560
bytes_obj = $B.$getattr(val, "__bytes__")
561
return format_padding(_b_.bytes.decode(bytes_obj), flags)
562
}catch(err){
563
if(err.__class__ === _b_.AttributeError){
564
throw _b_.TypeError.$factory("%b does not accept '" +
565
$B.class_name(val) + "'")
566
}
567
throw err
568
}
569
}
570
}
571
573
if(isinstance(val, str) && val.length == 1){
574
return val
575
}else if(isinstance(val, bytes) && val.source.length == 1){
576
val = val.source[0]
577
}else{
578
try{
579
val = _b_.int.$factory(val) // yes, floats are valid (they are cast to int)
580
}catch (err){
581
throw _b_.TypeError.$factory("%c requires int or char")
582
}
587
var num_flag = function(c, flags){
588
if(c === "0" && ! flags.padding && ! flags.decimal_point && ! flags.left){
589
flags.pad_char = "0"
595
flags.precision = (flags.precision || "") + c
596
}
597
}
598
599
var decimal_point_flag = function(val, flags) {
601
// can only have one decimal point
602
throw new UnsupportedChar()
603
}
604
flags.decimal_point = true
605
}
606
607
var neg_flag = function(val, flags){
608
flags.pad_char = " " // overrides '0' flag
626
"s": str_format,
627
"d": num_format,
628
"i": num_format,
629
"u": num_format,
630
"o": octal_format,
631
"r": repr_format,
632
"a": ascii_format,
633
"g": function(val, flags){
634
return floating_point_format(val, false, flags)
635
},
636
"G": function(val, flags){return floating_point_format(val, true, flags)},
637
"f": function(val, flags){
638
return floating_point_decimal_format(val, false, flags)
639
},
640
"F": function(val, flags){
641
return floating_point_decimal_format(val, true, flags)
642
},
643
"e": function(val, flags){
644
return floating_point_exponential_format(val, false, flags)
645
},
646
"E": function(val, flags){
647
return floating_point_exponential_format(val, true, flags)
648
},
649
"x": function(val, flags){return signed_hex_format(val, false, flags)},
650
"X": function(val, flags){return signed_hex_format(val, true, flags)},
651
"c": single_char_format,
652
"0": function(val, flags){return num_flag("0", flags)},
653
"1": function(val, flags){return num_flag("1", flags)},
654
"2": function(val, flags){return num_flag("2", flags)},
655
"3": function(val, flags){return num_flag("3", flags)},
656
"4": function(val, flags){return num_flag("4", flags)},
657
"5": function(val, flags){return num_flag("5", flags)},
658
"6": function(val, flags){return num_flag("6", flags)},
659
"7": function(val, flags){return num_flag("7", flags)},
660
"8": function(val, flags){return num_flag("8", flags)},
661
"9": function(val, flags){return num_flag("9", flags)},
662
"-": neg_flag,
663
" ": space_flag,
664
"+": sign_flag,
665
".": decimal_point_flag,
666
"#": alternate_flag
667
}
668
669
// exception thrown when an unsupported char is encountered in legacy format
715
if(self === undefined){
716
throw _b_.TypeError.$factory(
717
"not enough arguments for format string")
744
throw _b_.ValueError.$factory(
745
"unsupported format character '" + invalid_char +
746
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
747
") at index " + newpos)
748
}else if(err.name === "NotANumber"){
749
var try_char = s[newpos],
750
cls = self.__class__
751
if(!cls){
752
if(typeof(self) === "string"){
753
cls = "str"
754
}else{
760
throw _b_.TypeError.$factory("%" + try_char +
761
" format: a number is required, not " + cls)
762
}else{
794
}while(pos < length)
795
796
if(argpos !== null){
797
if(args.length > argpos){
798
throw _b_.TypeError.$factory(
799
"not enough arguments for format string")
800
}else if(args.length < argpos){
801
throw _b_.TypeError.$factory(
802
"not all arguments converted during string formatting")
804
}else if(nbph == 0){
805
throw _b_.TypeError.$factory(
806
"not all arguments converted during string formatting")
817
var $ = $B.args("__mul__", 2, {self: null, other: null},
818
["self", "other"], arguments, {}, null, null)
819
if(! isinstance($.other, _b_.int)){throw _b_.TypeError.$factory(
820
"Can't multiply sequence by non-int of type '" +
832
res = self.replace(/\\/g, "\\\\")
833
// special cases
834
res = res.replace(new RegExp("\u0007", "g"), "\\x07").
835
replace(new RegExp("\b", "g"), "\\x08").
837
replace(new RegExp("\f", "g"), "\\x0c").
838
replace(new RegExp("\n", "g"), "\\n").
839
replace(new RegExp("\r", "g"), "\\r").
840
replace(new RegExp("\t", "g"), "\\t")
842
// Replace unassigned code point by \uabcd...
843
// Uses function $B.is_unicode_cn() in unicode_data.js
844
var repl = ''
845
for(var i = 0; i < res.length; i++){
846
var cp = res.codePointAt(i)
847
if($B.is_unicode_cn(cp)){
848
var s = cp.toString(16)
853
}else if(cp < 0x20){
854
cp = cp + ''
855
if(cp.length < 2){
856
cp = '0' + cp
857
}
858
repl += '\\x' + cp
864
if(res.search('"') == -1 && res.search("'") == -1){
865
return "'" + res + "'"
866
}else if(self.search('"') == -1){
867
return '"' + res + '"'
868
}
869
var qesc = new RegExp("'", "g") // to escape single quote
870
res = "'" + res.replace(qesc, "\\'") + "'"
874
str.__setitem__ = function(self, attr, value){
875
throw _b_.TypeError.$factory(
876
"'str' object does not support item assignment")
878
var combining = []
879
for(var cp = 0x300; cp <= 0x36F; cp++){
880
combining.push(String.fromCharCode(cp))
881
}
882
var combining_re = new RegExp("(" + combining.join("|") + ")")
894
$comp_func += "" // source code
895
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
904
var $notimplemented = function(self, other){
905
throw NotImplementedError.$factory(
906
"OPERATOR not implemented for class str")
909
str.capitalize = function(self){
910
var $ = $B.args("capitalize", 1, {self}, ["self"],
911
arguments, {}, null, null)
912
if(self.length == 0){return ""}
913
return self.charAt(0).toUpperCase() + self.substr(1)
914
}
915
916
str.casefold = function(self){
917
var $ = $B.args("casefold", 1, {self}, ["self"],
918
arguments, {}, null, null),
919
res = "",
920
char,
921
cf
922
for(var i = 0, len = self.length; i < len; i++){
923
char = self.charCodeAt(i)
924
cf = $B.unicode_casefold[char]
925
if(cf){
926
cf.forEach(function(cp){
927
res += String.fromCharCode(cp)
928
})
929
}else{
930
res += self.charAt(i).toLowerCase()
931
}
932
}
933
return res
934
}
936
str.center = function(){
937
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
938
["self", "width", "fillchar"],
939
arguments, {fillchar:" "}, null, null),
940
self = $.self
952
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
953
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
961
if($.stop !== null){_slice = _b_.slice.$factory($.start, $.stop)}
962
else{_slice = _b_.slice.$factory($.start, $.self.length)}
967
if($.sub.length == 0){
968
if($.start == $.self.length){return 1}
969
else if(substr.length == 0){return 0}
970
return substr.length + 1
972
var n = 0,
973
pos = 0
974
while(pos < substr.length){
975
pos = substr.indexOf($.sub, pos)
976
if(pos >= 0){n++; pos += $.sub.length}
977
else{break}
982
str.encode = function(){
983
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
984
["self", "encoding", "errors"], arguments,
985
{encoding: "utf-8", errors: "strict"}, null, null)
986
if($.encoding == "rot13" || $.encoding == "rot_13"){
991
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
992
res += String.fromCharCode(String.charCodeAt(char) + 13)
993
}else if(("m" < char && char <= "z") ||
994
("M" < char && char <= "Z")){
995
res += String.fromCharCode(String.charCodeAt(char) - 13)
1004
// Return True if the string ends with the specified suffix, otherwise
1005
// return False. suffix can also be a tuple of suffixes to look for.
1006
// With optional start, test beginning at that position. With optional
1010
["self", "suffix", "start", "end"],
1011
arguments, {start: 0, end: null}, null, null)
1018
var s = $.self.substring($.start, $.end)
1019
for(var i = 0, len = suffixes.length; i < len; i++){
1023
if(suffix.length <= s.length &&
1024
s.substr(s.length - suffix.length) == suffix){return true}
1030
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
1031
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
1032
var s = $B.$GetInt($.tabsize),
1033
col = 0,
1034
pos = 0,
1035
res = ""
1036
if(s == 1){return self.replace(/\t/g," ")}
1037
while(pos < self.length){
1045
res += car
1046
col = 0
1047
break
1048
default:
1049
res += car
1050
col++
1051
break
1052
}
1053
pos++
1054
}
1060
// Return the lowest index in the string where substring sub is found,
1061
// such that sub is contained in the slice s[start:end]. Optional
1062
// arguments start and end are interpreted as in slice notation.
1065
{self: null, sub: null, start: null, end: null},
1066
["self", "sub", "start", "end"],
1067
arguments, {start: 0, end: null}, null, null)
1071
if(!isinstance($.start, _b_.int)||!isinstance($.end, _b_.int)){
1072
throw _b_.TypeError.$factory("slice indices must be " +
1073
"integers or None or have an __index__ method")}
1074
// Can't use string.substring(start, end) because if end < start,
1075
// Javascript transforms it into substring(end, start)...
1076
var s = ""
1077
for(var i = $.start; i < $.end; i++){
1078
s += $.self.charAt(i)
1079
}
1081
if($.sub.length == 0 && $.start == $.self.length){return $.self.length}
1082
if(s.length + $.sub.length == 0){return -1}
1084
var last_search = s.length - $.sub.length
1085
for(var i = 0; i <= last_search; i++){
1086
if(s.substr(i, $.sub.length) == $.sub){return $.start + i}
1097
// a.x[z]!r:...
1098
// the object has attributes :
1099
// - name : "a"
1100
// - name_ext : [".x", "[z]"]
1101
// - conv : r
1102
// - spec : rest of string after :
1110
// No : in the string : it only contains a name
1111
name = fmt_string
1112
}else{
1113
// name is before the first ":"
1114
// spec (the format specification) is after
1115
name = elts[0]
1119
var elts = name.split("!")
1120
if(elts.length > 1){
1121
name = elts[0]
1122
conv = elts[1] // conversion flag
1126
// "name' may be a subscription or attribute
1127
// Put these "extensions" in the list "name_ext"
1128
function name_repl(match){
1129
name_ext.push(match)
1131
}
1132
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1133
name = name.replace(name_ext_re, name_repl)
1134
}
1141
// Parse self to detect formatting instructions
1142
// Create a list "parts" made of sections of the string :
1143
// - elements of even rank are literal text
1144
// - elements of odd rank are "format objects", built from the
1145
// format strings in self (of the form {...})
1156
text += "{"
1157
pos += 2
1158
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1165
// Store current literal text
1166
parts.push(text)
1167
1168
// Search the end of the format string, ie the } closing the
1169
// opening {. Since the string can contain other pairs {} for
1170
// nested formatting, an integer nb is incremented for each { and
1171
// decremented for each } ; the end of the format string is
1172
// reached when nb == 0
1173
var end = pos + 1,
1174
nb = 1
1175
while(end < _len){
1176
if(self.charAt(end) == "{"){nb++; end++}
1177
else if(self.charAt(end) == "}"){
1178
nb--; end++
1179
if(nb == 0){
1184
var fmt_obj = $B.parse_format(fmt_string)
1185
fmt_obj.raw_name = fmt_obj.name
1186
fmt_obj.raw_spec = fmt_obj.spec
1225
// Special management of keyword arguments if str.format is called by
1226
// str.format_map(mapping) : the argument "mapping" might not be a
1227
// dictionary
1228
var last_arg = $B.last(arguments)
1229
if(last_arg.$nat == "mapping"){
1230
var mapping = last_arg.mapping,
1231
getitem = $B.$getattr(mapping, "__getitem__")
1232
// Get the rest of the arguments
1233
var args = []
1234
for(var i = 0, len = arguments.length - 1; i < len; i++){
1235
args.push(arguments[i])
1236
}
1237
var $ = $B.args("format", 1, {self: null}, ["self"],
1238
args, {}, "$args", null)
1239
}else{
1240
var $ = $B.args("format", 1, {self: null}, ["self"],
1241
arguments, {}, "$args", "$kw"),
1242
mapping = $.$kw, // dictionary
1243
getitem = function(key){
1244
return _b_.dict.$getitem(mapping, key)
1245
}
1246
}
1259
1260
if(fmt.spec !== undefined){
1261
// "spec" may contain "nested replacement fields"
1262
// In this case, evaluate them using the positional
1263
// or keyword arguments passed to format()
1264
function replace_nested(name, key){
1265
if(/\d+/.exec(key)){
1266
// If key is numeric, search in positional
1267
// arguments
1268
return _b_.tuple.__getitem__($.$args,
1269
parseInt(key))
1270
}else{
1271
// Else try in keyword arguments
1272
return _b_.dict.__getitem__($.$kw, key)
1273
}
1274
}
1275
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1276
replace_nested)
1277
}
1279
// Numerical reference : use positional arguments
1280
var pos = parseInt(fmt.name),
1290
// Attribute
1291
value = _b_.getattr(value, ext.substr(1))
1292
}else{
1293
// Subscription
1296
if(key.charAt(0).search(/\d/) > -1){key = parseInt(key)}
1297
value = _b_.getattr(value, "__getitem__")(key)
1301
// If the conversion flag is set, first call a function to convert
1302
// the value
1303
if(fmt.conv == "a"){value = _b_.ascii(value)}
1304
else if(fmt.conv == "r"){value = _b_.repr(value)}
1305
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1318
str.format_map = function(self, mapping){
1319
var $ = $B.args("format_map", 2, {self: null, mapping: null},
1320
['self', 'mapping'], arguments, {}, null, null)
1321
return str.format(self, {$nat: 'mapping', mapping})
1332
/* Return true if the string is empty or all characters in the string are
1333
ASCII, false otherwise. ASCII characters have code points in the range
1334
U+0000-U+007F. */
1335
for(var i = 0, len = self.length; i < len; i++){
1336
if(self.charCodeAt(i) > 127){return false}
1337
}
1338
return true
1339
}
1340
1341
str.isalnum = function(self){
1342
/* Return true if all characters in the string are alphanumeric and there
1343
is at least one character, false otherwise. A character c is alphanumeric
1344
if one of the following returns True: c.isalpha(), c.isdecimal(),
1345
c.isdigit(), or c.isnumeric(). */
1346
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1347
arguments, {}, null, null),
1348
char
1349
for(var i = 0, len = self.length; i < len; i++){
1350
char = self.charCodeAt(i)
1351
if(unicode_tables.Ll[char] ||
1352
unicode_tables.Lu[char] ||
1353
unicode_tables.Lm[char] ||
1354
unicode_tables.Lt[char] ||
1355
unicode_tables.Lo[char] ||
1356
unicode_tables.Nd[char] ||
1357
unicode_tables.digits[char] ||
1358
unicode_tables.numeric[char]){
1359
continue
1360
}
1361
return false
1362
}
1363
return true
1364
}
1365
1366
str.isalpha = function(self){
1367
/* Return true if all characters in the string are alphabetic and there is
1368
at least one character, false otherwise. Alphabetic characters are those
1369
characters defined in the Unicode character database as "Letter", i.e.,
1370
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1371
or "Lo". */
1372
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1373
arguments, {}, null, null),
1374
char
1375
for(var i = 0, len = self.length; i < len; i++){
1376
char = self.charCodeAt(i)
1377
if(unicode_tables.Ll[char] ||
1378
unicode_tables.Lu[char] ||
1379
unicode_tables.Lm[char] ||
1380
unicode_tables.Lt[char] ||
1381
unicode_tables.Lo[char]){
1382
continue
1383
}
1384
return false
1385
}
1386
return true
1387
}
1388
1389
str.isdecimal = function(self){
1390
/* Return true if all characters in the string are decimal characters and
1391
there is at least one character, false otherwise. Decimal characters are
1392
those that can be used to form numbers in base 10, e.g. U+0660,
1393
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1394
the Unicode General Category "Nd". */
1395
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1396
arguments, {}, null, null),
1397
char
1398
for(var i = 0, len = self.length; i < len; i++){
1399
char = self.charCodeAt(i)
1400
if(! unicode_tables.Nd[char]){
1401
return false
1402
}
1403
}
1404
return self.length > 0
1405
}
1406
1407
str.isdigit = function(self){
1408
/* Return true if all characters in the string are digits and there is at
1409
least one character, false otherwise. */
1410
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1411
arguments, {}, null, null),
1412
char
1413
for(var i = 0, len = self.length; i < len; i++){
1414
char = self.charCodeAt(i)
1415
if(! unicode_tables.digits[char]){
1416
return false
1417
}
1418
}
1419
return self.length > 0
1420
}
1421
1422
str.isidentifier = function(self){
1423
/* Return true if the string is a valid identifier according to the
1424
language definition. */
1425
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1426
arguments, {}, null, null),
1427
char
1428
if(self.length == 0){return false}
1429
else if(unicode_tables.XID_Start[self.charCodeAt(0)] === undefined){
1430
return false
1431
}else{
1432
for(var i = 1, len = self.length; i < len; i++){
1433
if(unicode_tables.XID_Continue[self.charCodeAt(i)] === undefined){
1434
return false
1435
}
1436
}
1437
}
1438
return true
1439
}
1440
1441
str.islower = function(self){
1442
/* Return true if all cased characters 4 in the string are lowercase and
1443
there is at least one cased character, false otherwise. */
1444
var $ = $B.args("islower", 1, {self: null}, ["self"],
1445
arguments, {}, null, null),
1446
has_cased = false,
1447
char
1448
1449
for(var i = 0, len = self.length; i < len; i++){
1450
char = self.charCodeAt(i)
1451
if(unicode_tables.Ll[char]){has_cased = true; continue}
1452
else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1453
return false
1454
}
1455
}
1456
return has_cased
1457
}
1458
1459
str.isnumeric = function(self){
1460
/* Return true if all characters in the string are numeric characters, and
1461
there is at least one character, false otherwise. Numeric characters
1462
include digit characters, and all characters that have the Unicode numeric
1463
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1464
characters are those with the property value Numeric_Type=Digit,
1465
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1466
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1467
arguments, {}, null, null)
1468
for(var i = 0, len = self.length; i < len; i++){
1469
if(! unicode_tables.numeric[self.charCodeAt(i)]){
1470
return false
1471
}
1472
}
1473
return self.length > 0
1474
}
1475
1476
var unprintable = {},
1477
unprintable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1478
1479
str.isprintable = function(self){
1480
/* Return true if all characters in the string are printable or the string
1481
is empty, false otherwise. Nonprintable characters are those characters
1482
defined in the Unicode character database as "Other" or "Separator",
1483
excepting the ASCII space (0x20) which is considered printable. */
1484
1485
// Set unprintable if not set yet
1486
if(Object.keys(unprintable).length == 0){
1487
for(var i = 0; i < unprintable_gc.length; i++){
1488
var table = unicode_tables[unprintable_gc[i]]
1499
return false
1500
}
1501
}
1502
return true
1503
}
1504
1505
str.isspace = function(self){
1506
/* Return true if there are only whitespace characters in the string and
1507
there is at least one character, false otherwise.
1508
1509
A character is whitespace if in the Unicode character database, either its
1510
general category is Zs ("Separator, space"), or its bidirectional class is
1511
one of WS, B, or S.*/
1512
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1513
arguments, {}, null, null),
1514
char
1515
for(var i = 0, len = self.length; i < len; i++){
1516
char = self.charCodeAt(i)
1517
if(! unicode_tables.Zs[char] &&
1518
$B.unicode_bidi_whitespace.indexOf(char) == -1){
1519
return false
1520
}
1521
}
1522
return self.length > 0
1523
}
1524
1525
str.istitle = function(self){
1526
/* Return true if the string is a titlecased string and there is at least
1527
one character, for example uppercase characters may only follow uncased
1528
characters and lowercase characters only cased ones. Return false
1529
otherwise. */
1530
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1531
arguments, {}, null, null)
1532
return self.length > 0 && str.title(self) == self
1533
}
1534
1535
str.isupper = function(self){
1536
/* Return true if all cased characters 4 in the string are lowercase and
1537
there is at least one cased character, false otherwise. */
1538
var $ = $B.args("islower", 1, {self: null}, ["self"],
1539
arguments, {}, null, null),
1540
has_cased = false,
1541
char
1542
1543
for(var i = 0, len = self.length; i < len; i++){
1544
char = self.charCodeAt(i)
1545
if(unicode_tables.Lu[char]){has_cased = true; continue}
1546
else if(unicode_tables.Ll[char] || unicode_tables.Lt[char]){
1564
if(! isinstance(obj2, str)){throw _b_.TypeError.$factory(
1565
"sequence item " + count + ": expected str instance, " +
1579
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1580
["self", "width", "fillchar"],
1581
arguments, {fillchar: " "}, null, null)
1587
str.lower = function(self){
1588
var $ = $B.args("lower", 1, {self: null}, ["self"],
1589
arguments, {}, null, null)
1590
return self.toLowerCase()
1591
}
1592
1594
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1595
arguments, {chars:_b_.None}, null, null)
1596
if($.chars === _b_.None){return $.self.trimLeft()}
1597
for(var i = 0; i < $.self.length; i++){
1598
if($.chars.indexOf($.self.charAt(i)) === -1){
1599
return $.self.substring(i)
1607
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1608
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1613
// If there is only one argument, it must be a dictionary mapping
1614
// Unicode ordinals (integers) or characters (strings of length 1) to
1615
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1617
if(! _b_.isinstance($.x, _b_.dict)){
1618
throw _b_.TypeError.$factory(
1619
"maketrans only argument must be a dict")
1622
for(var i = 0, len = items.length; i < len; i++){
1623
var k = items[i][0],
1624
v = items[i][1]
1625
if(! _b_.isinstance(k, _b_.int)){
1626
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1627
k = _b_.ord(k)
1628
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1631
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1632
throw _b_.TypeError.$factory("dictionary value " + v +
1640
// and in the resulting dictionary, each character in x will be mapped
1641
// to the character at the same position in y
1644
}else if($.x.length !== $.y.length){
1645
throw _b_.TypeError.$factory(
1646
"maketrans arguments must be strings or same length")
1652
if(! _b_.isinstance($.z, _b_.str)){
1653
throw _b_.TypeError.$factory(
1654
"maketrans third argument must be a string")
1676
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1677
arguments, {}, null, null)
1682
return _b_.tuple.$factory([$.self.substring(0, i), $.sep,
1683
$.self.substring(i + $.sep.length)])
1684
}
1685
1686
str.removeprefix = function(){
1687
var $ = $B.args("removeprefix", 2, {self: null, prefix: null},
1688
["self", "prefix"], arguments, {}, null, null)
1689
if(!_b_.isinstance($.prefix, str)){
1690
throw _b_.ValueError.$factory("prefix should be str, not " +
1691
`'${$B.class_name($.prefix)}'`)
1692
}
1693
if(str.startswith($.self, $.prefix)){
1694
return $.self.substr($.prefix.length)
1695
}
1696
return $.self.substr(0)
1697
}
1698
1699
str.removesuffix = function(){
1700
var $ = $B.args("removesuffix", 2, {self: null, prefix: null},
1701
["self", "suffix"], arguments, {}, null, null)
1702
if(!_b_.isinstance($.suffix, str)){
1703
throw _b_.ValueError.$factory("suffix should be str, not " +
1704
`'${$B.class_name($.prefix)}'`)
1705
}
1706
if($.suffix.length > 0 && str.endswith($.self, $.suffix)){
1707
return $.self.substr(0, $.self.length - $.suffix.length)
1708
}
1709
return $.self.substr(0)
1710
}
1711
1712
function $re_escape(str){
1713
var specials = "[.*+?|()$^"
1714
for(var i = 0, len = specials.length; i < len; i++){
1715
var re = new RegExp("\\"+specials.charAt(i), "g")
1716
str = str.replace(re, "\\"+specials.charAt(i))
1717
}
1718
return str
1725
var $ = $B.args("replace", 4,
1726
{self: null, old: null, $$new: null, count: null},
1727
["self", "old", "$$new", "count"],
1728
arguments, {count: -1}, null, null),
1729
count = $.count,
1730
self = $.self,
1731
old = $.old,
1732
_new = $.$$new
1739
"' object cannot be interpreted as an integer")
1740
}else if(isinstance(count, _b_.float)){
1741
throw _b_.TypeError.$factory("integer argument expected, got float")
1742
}
1743
if(count == 0){return self}
1744
if(count.__class__ == $B.long_int){count = parseInt(count.value)}
1745
if(old == ""){
1746
if(_new == ""){return self}
1747
if(self == ""){return _new}
1748
var elts = self.split("")
1749
if(count > -1 && elts.length >= count){
1750
var rest = elts.slice(count).join("")
1751
return _new + elts.slice(0, count).join(_new) + rest
1752
}else{return _new + elts.join(_new) + _new}
1767
if(count < 0){count = res.length}
1768
while(count > 0){
1769
pos = res.indexOf(old, pos)
1770
if(pos < 0){break}
1771
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1772
pos = pos + _new.length
1773
count--
1779
// Return the highest index in the string where substring sub is found,
1780
// such that sub is contained within s[start:end]. Optional arguments
1782
if(arguments.length == 2 && typeof substr == "string"){
1783
return self.lastIndexOf(substr)
1784
}
1786
{self: null, sub: null, start: null, end: null},
1787
["self", "sub", "start", "end"],
1788
arguments, {start: 0, end: null}, null, null)
1800
for(var i = $.end - sublen; i >= $.start; i--){
1801
if($.self.substr(i, sublen) == $.sub){return i}
1808
var res = str.rfind.apply(null, arguments)
1809
if(res == -1){throw _b_.ValueError.$factory("substring not found")}
1814
var $ = $B.args("rjust",3,
1815
{self: null, width: null, fillchar: null},
1816
["self", "width", "fillchar"],
1817
arguments, {fillchar: " "}, null, null)
1825
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
1826
arguments, {}, null, null)
1830
var items = str.partition(self, sep).reverse()
1831
for(var i = 0; i < items.length; i++){
1832
items[i] = items[i].split("").reverse().join("")
1838
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
1839
["self", "sep", "maxsplit"], arguments,
1840
{sep: _b_.None, maxsplit: -1}, null, null),
1841
sep = $.sep
1844
var rev_str = reverse($.self),
1845
rev_sep = sep === _b_.None ? sep : reverse($.sep),
1856
str.rstrip = function(self, x){
1857
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
1858
arguments, {chars: _b_.None}, null, null)
1859
if($.chars === _b_.None){return $.self.trimRight()}
1861
if($.chars.indexOf($.self.charAt(j)) == -1){
1862
return $.self.substring(0, j + 1)
1869
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
1870
["self", "sep", "maxsplit"], arguments,
1871
{sep: _b_.None, maxsplit: -1}, null, null),
1872
sep = $.sep,
1873
maxsplit = $.maxsplit,
1874
self = $.self,
1875
pos = 0
1876
if(maxsplit.__class__ === $B.long_int){maxsplit = parseInt(maxsplit.value)}
1877
if(sep == ""){throw _b_.ValueError.$factory("empty separator")}
1878
if(sep === _b_.None){
1880
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){pos++}
1881
if(pos === self.length - 1){return [self]}
1882
var name = ""
1884
if(self.charAt(pos).search(/\s/) == -1){
1885
if(name == ""){name = self.charAt(pos)}
1886
else{name += self.charAt(pos)}
1906
var res = [],
1907
s = "",
1908
seplen = sep.length
1909
if(maxsplit == 0){return [self]}
1910
while(pos < self.length){
1911
if(self.substr(pos, seplen) == sep){
1929
str.splitlines = function(self) {
1930
var $ = $B.args('splitlines', 2, {self: null, keepends: null},
1931
['self','keepends'], arguments, {keepends: false},
1932
null, null)
1933
if(!_b_.isinstance($.keepends,[_b_.bool, _b_.int])){
1934
throw _b_.TypeError('integer argument expected, got '+
1937
var keepends = _b_.int.$factory($.keepends),
1938
res = [],
1939
self = $.self,
1940
start = 0,
1941
pos = 0
1942
if(!self.length){
1945
while (pos < self.length) {
1946
if(self.substr(pos, 2) == '\r\n'){
1947
res.push(self.slice(start, keepends ? pos + 2 : pos))
1948
start = pos = pos+2
1949
}else if(self[pos] == '\r' || self[pos] == '\n'){
1950
res.push(self.slice(start, keepends ? pos+1 : pos))
1951
start = pos = pos+1
1952
}else{
1953
pos++
1954
}
1955
}
1956
if(start < self.length){
1957
res.push(self.slice(start))
1958
}
1959
return res
1963
// Return True if string starts with the prefix, otherwise return False.
1964
// prefix can also be a tuple of prefixes to look for. With optional
1965
// start, test string beginning at that position. With optional end,
1967
var $ = $B.args("startswith", 4,
1968
{self: null, prefix: null, start: null, end: null},
1969
["self", "prefix", "start", "end"],
1970
arguments, {start: 0, end: null}, null, null)
1977
var s = $.self.substring($.start, $.end)
1978
for(var i = 0, len = prefixes.length; i < len; i++){
1989
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
1990
arguments, {chars: _b_.None}, null, null)
1991
if($.chars === _b_.None){return $.self.trim()}
1992
for(var i = 0; i < $.self.length; i++){
1993
if($.chars.indexOf($.self.charAt(i)) == -1){
1994
break
1997
for(var j = $.self.length - 1; j >= i; j--){
1998
if($.chars.indexOf($.self.charAt(j)) == -1){
1999
break
2005
str.swapcase = function(self){
2006
var $ = $B.args("swapcase", 1, {self}, ["self"],
2007
arguments, {}, null, null),
2008
res = "",
2009
char
2010
2011
for(var i = 0, len = self.length; i < len; i++){
2012
char = self.charCodeAt(i)
2013
if(unicode_tables.Ll[char]){
2014
res += self.charAt(i).toUpperCase()
2015
}else if(unicode_tables.Lu[char]){
2016
res += self.charAt(i).toLowerCase()
2017
}else{
2018
res += self.charAt(i)
2019
}
2020
}
2021
return res
2022
}
2023
2024
str.title = function(self){
2025
var $ = $B.args("title", 1, {self}, ["self"],
2026
arguments, {}, null, null),
2027
state,
2028
char,
2029
res = ""
2030
for(var i = 0, len = self.length; i < len; i++){
2031
char = self.charCodeAt(i)
2032
if(unicode_tables.Ll[char]){
2033
if(! state){
2034
res += self.charAt(i).toUpperCase()
2035
state = "word"
2036
}else{
2037
res += self.charAt(i)
2038
}
2039
}else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
2040
res += state ? self.charAt(i).toLowerCase() : self.charAt(i)
2041
state = "word"
2042
}else{
2043
state = null
2044
res += self.charAt(i)
2045
}
2046
}
2047
return res
2048
}
2049
2052
getitem = $B.$getattr(table, "__getitem__")
2053
for(var i = 0, len = self.length; i < len; i++){
2054
try{
2055
var repl = getitem(self.charCodeAt(i))
2056
if(repl !== _b_.None){
2057
if(typeof repl == "string"){
2058
res.push(repl)
2059
}else if(typeof repl == "number"){
2060
res.push(String.fromCharCode(repl))
2061
}
2070
str.upper = function(self){
2071
var $ = $B.args("upper", 1, {self: null}, ["self"],
2072
arguments, {}, null, null)
2073
return self.toUpperCase()
2074
}
2075
2078
["self", "width"], arguments, {}, null, null)
2079
if($.width <= self.length){return self}
2081
case "+":
2082
case "-":
2083
return self.charAt(0) +
2084
"0".repeat($.width - self.length) + self.substr(1)
2095
if(encoding !== undefined){
2096
// Arguments may be passed as keywords (cf. issue #1060)
2097
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2098
["arg", "encoding", "errors"], arguments,
2099
{encoding: "utf-8", errors: "strict"}, null, null),
2100
encoding = $.encoding,
2101
errors = $.errors
2102
}
2113
// class or its subclasses, but the attribute __str__ of the
2114
// class metaclass (usually "type") or its subclasses (usually
2115
// "object")
2116
// The metaclass is the attribute __class__ of the class dictionary
2121
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2122
encoding !== undefined){
2123
// str(bytes, encoding, errors) is equal to
2124
// bytes.decode(encoding, errors)
2127
// Implicit invocation of __str__ uses method __str__ on the class,
2128
// even if arg has an attribute __str__
2129
var klass = arg.__class__ || $B.get_class(arg)
2135
// if not better than object.__str__, try __repr__
2136
(arg.__class__ && arg.__class__ !== _b_.object &&
2137
method.$infos && method.$infos.__func__ === _b_.object.__str__)){
2138
var method = $B.$getattr(klass, "__repr__")
2144
if($B.debug > 1){console.log(err)}
2145
console.log("Warning - no method __str__ or __repr__, " +
2146
"default to toString", arg)
2153
if(cls === undefined){
2154
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2178
var args = [],
2179
pos = 0
2180
if(arguments.length > 0){
2181
var args = [arguments[0].valueOf()],
2182
pos = 1
2183
for(var i = 1, len = arguments.length; i < len; i++){
2184
args[pos++] = arguments[i]
2201
// Function to parse the 2nd argument of format()
2202
$B.parse_format_spec = function(spec){
2205
var pos = 0,
2206
aligns = "<>=^",
2207
digits = "0123456789",
2208
types = "bcdeEfFgGnosxX%",
2210
if(align_pos != -1){
2211
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2212
// If the second char is also an alignment specifier, the
2213
// first char is the fill value
2214
this.fill = spec.charAt(0)
2215
this.align = spec.charAt(1)
2216
pos = 2
2217
}else{
2218
// The first character defines alignment : fill defaults to ' '
2233
if(car == "+" || car == "-" || car == " "){
2234
this.sign = car
2235
pos++
2236
car = spec.charAt(pos)
2238
if(car == "#"){this.alternate = true; pos++; car = spec.charAt(pos)}
2239
if(car == "0"){
2248
while(car && digits.indexOf(car) > -1){
2249
if(this.width === undefined){this.width = car}
2250
else{this.width += car}
2251
pos++
2252
car = spec.charAt(pos)
2255
if(this.width === undefined && car == "{"){
2256
// Width is determined by a parameter
2257
var end_param_pos = spec.substr(pos).search("}")
2258
this.width = spec.substring(pos, end_param_pos)
2259
console.log("width", "[" + this.width + "]")
2260
pos += end_param_pos + 1
2261
}
2262
if(car == ","){this.comma = true; pos++; car = spec.charAt(pos)}
2263
if(car == "."){
2264
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2265
throw _b_.ValueError.$factory(
2266
"Missing precision in format spec")
2268
this.precision = spec.charAt(pos + 1)
2269
pos += 2
2270
car = spec.charAt(pos)
2271
while(car && digits.indexOf(car) > -1){
2278
if(car && types.indexOf(car) > -1){
2279
this.type = car
2280
pos++
2281
car = spec.charAt(pos)
2282
}
2283
if(pos !== spec.length){
2289
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2290
(this.align || "") +
2291
(this.sign || "") +
2292
(this.alternate ? "#" : "") +
2293
(this.sign_aware ? "0" : "") +
2294
(this.width || "") +
2295
(this.comma ? "," : "") +
2296
(this.precision ? "." + this.precision : "") +
2297
(this.type || "")
2302
if(fmt.width && s.length < fmt.width){
2303
var fill = fmt.fill || " ",
2304
align = fmt.align || "<",
2305
missing = fmt.width - s.length
2307
case "<":
2308
return s + fill.repeat(missing)
2309
case ">":
2310
return fill.repeat(missing) + s
2311
case "=":
2312
if("+-".indexOf(s.charAt(0)) > -1){
2313
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2317
case "^":
2318
var left = parseInt(missing / 2)
2319
return fill.repeat(left) + s + fill.repeat(missing - left)
2332
$B.parse_fstring = function(string){
2333
// Parse a f-string
2334
var elts = [],
2335
pos = 0,
2359
}else{
2360
throw Error(" f-string: single '}' is not allowed")
2361
}
2362
}else{
2384
current += car
2385
i += 2
2386
}else{
2387
throw Error(" f-string: single '}' is not allowed")
2388
}
2389
}else{
2390
current += car
2391
i++
2392
}
2393
}
2395
}else if(ctype == "debug"){
2396
// after the equal sign, whitespace are ignored and the only
2397
// valid characters are } and :
2398
while(string.charAt(i) == " "){i++}
2399
if(string.charAt(i) == "}"){
2400
// end of debug expression
2401
elts.push(current)
2402
ctype = null
2403
current = ""
2404
pos = i + 1
2405
}
2406
}else{
2407
// End of expression is the } matching the opening {
2408
// There may be nested braces
2409
var i = pos,
2410
nb_braces = 1,
2432
// backslash is not allowed in expressions
2433
throw Error("f-string expression part cannot include a" +
2434
" backslash")
2441
throw Error("f-string: invalid conversion character:" +
2442
" expected 's', 'r', or 'a'")
2443
}else{
2457
if(string.substr(i, 3) == '"""'){
2458
var end = string.indexOf('"""', i + 3)
2459
if(end == -1){
2460
throw Error("f-string: unterminated string")
2461
}else{
2462
var trs = string.substring(i, end + 3)
2463
trs = trs.replace("\n", "\\n\\")
2468
var end = string.indexOf('"', i + 1)
2469
if(end == -1){
2470
throw Error("f-string: unterminated string")
2471
}else{
2472
current.expression += string.substring(i, end + 1)
2473
i = end + 1
2482
var ce = current.expression,
2483
last_char = ce.charAt(ce.length - 1),
2484
last_char_re = ('()'.indexOf(last_char) > -1 ? "\\" : "") + last_char
2489
"=!<>:".search(last_char_re) > -1){
2490
current.expression += car //+ string.charAt(i + 1)
2491
i += 1
2492
}else{
2493
// add debug string
2494
tail = car
2495
while(string.charAt(i + 1).match(/\s/)){
2496
tail += string.charAt(i + 1)
2497
i++
2498
}
2499
elts.push(current.expression + tail)
2500
// remove trailing whitespace from expression
2501
while(ce.match(/\s$/)){
2502
ce = ce.substr(0, ce.length - 1)
2503
}
2504
current.expression = ce
2505
ctype = "debug"
2506
i++
2507
}
2522
// Class for strings with surrogate pairs. We can't rely on Javascript
2523
// strings in this case because they don't count characters like Python
2524
2525
var surrogate = str.$surrogate = $B.make_class("surrogate_string", function(s){
2526
// create an instance of str subclass for strings with surrogate pairs
2527
var items = []
2528
for(var i = 0, len = s.length; i < len; i++){
2529
var code = s.charCodeAt(i)
2530
if(code >= 0xD800 && code <= 0xDBFF){
2531
i++
2532
var low = s.charCodeAt(i)
2533
code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000
2534
}
2535
items.push(String.fromCodePoint(code))
2536
}
2537
return {
2538
__class__: str.$surrogate,
2539
items: items
2540
}
2541
})
2542
2543
surrogate.__mro__ = [str, object]
2544
2545
surrogate.__add__ = function(self, other){
2546
if(other.__class__ === str.$surrogate){
2547
var res = str.$surrogate.$factory('')
2548
res.items = self.items.concat(other.items)
2549
return res
2550
}else if(_b_.isinstance(other, str)){
2551
var res = str.$surrogate.$factory('')
2552
res.items = self.items
2553
for(const char of other + ''){
2554
res.items.push(char)
2555
}
2556
return res
2557
}
2558
}
2559
2560
surrogate.__contains__ = function(self, other){
2561
return str.__contains__(self.items.join(''), other)
2562
}
2563
2564
surrogate.__getitem__ = function(self, arg){
2565
if(isinstance(arg, _b_.int)){
2566
var pos = arg
2567
if(arg < 0){
2568
pos += self.items.length
2569
}
2570
if(pos >= 0 && pos < self.items.length){
2571
if(self.items[pos].length == 2){
2572
return surrogate.$factory(self.items[pos])
2573
}
2574
return self.items[pos]
2575
}
2576
throw _b_.IndexError.$factory("string index out of range")
2577
}
2578
if(isinstance(arg, slice)) {
2579
var s = _b_.slice.$conv_for_seq(arg, self.items.length),
2580
start = s.start,
2581
stop = s.stop,
2582
step = s.step
2583
var res = "",
2584
i = null
2585
if(step > 0){
2586
if(stop <= start){return ""}
2587
for(var i = start; i < stop; i += step){
2588
res += self.items[i]
2589
}
2590
}else{
2591
if(stop >= start){return ''}
2592
for(var i = start; i > stop; i += step){
2593
res += self.items[i]
2594
}
2595
}
2596
return res
2597
}
2598
if(isinstance(arg, _b_.bool)){
2599
return surrogate.__getitem__(self, _b_.int.$factory(arg))
2600
}
2601
throw _b_.TypeError.$factory("string indices must be integers")
2602
}
2603
2604
surrogate.__hash__ = function(self){
2605
return str.__hash__(self.items.join(''))
2606
}
2607
2608
surrogate.__iter__ = function(self){
2609
return str_iterator.$factory(self.items)
2610
}
2611
2612
surrogate.__len__ = function(self){
2613
return self.items.length
2614
}
2615
2616
surrogate.__repr__ = function(self){
2617
return str.__repr__(self.items.join(''))
2618
}
2619
2620
surrogate.__str__ = function(self){
2621
return str.__str__(self.items.join(''))
2622
}
2623
2624
$B.set_func_names(surrogate, "builtins")
2625
2626