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
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 12, 2018
Nov 12, 2018
Mar 19, 2018
Mar 19, 2018
Mar 19, 2018
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
Oct 13, 2019
Apr 25, 2020
Newer
100644
2581 lines (2366 sloc)
81.9 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
716
if(self === undefined){
717
throw _b_.TypeError.$factory(
718
"not enough arguments for format string")
745
throw _b_.ValueError.$factory(
746
"unsupported format character '" + invalid_char +
747
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
748
") at index " + newpos)
749
}else if(err.name === "NotANumber"){
750
var try_char = s[newpos],
751
cls = self.__class__
752
if(!cls){
753
if(typeof(self) === "string"){
754
cls = "str"
755
}else{
761
throw _b_.TypeError.$factory("%" + try_char +
762
" format: a number is required, not " + cls)
763
}else{
795
}while(pos < length)
796
797
if(argpos !== null){
798
if(args.length > argpos){
799
throw _b_.TypeError.$factory(
800
"not enough arguments for format string")
801
}else if(args.length < argpos){
802
throw _b_.TypeError.$factory(
803
"not all arguments converted during string formatting")
805
}else if(nbph == 0){
806
throw _b_.TypeError.$factory(
807
"not all arguments converted during string formatting")
815
var $ = $B.args("__mul__", 2, {self: null, other: null},
816
["self", "other"], arguments, {}, null, null)
817
if(! isinstance($.other, _b_.int)){throw _b_.TypeError.$factory(
818
"Can't multiply sequence by non-int of type '" +
830
res = self.replace(/\\/g, "\\\\")
831
// special cases
832
res = res.replace(new RegExp("\u0007", "g"), "\\x07").
833
replace(new RegExp("\b", "g"), "\\x08").
835
replace(new RegExp("\f", "g"), "\\x0c").
836
replace(new RegExp("\n", "g"), "\\n").
837
replace(new RegExp("\r", "g"), "\\r").
838
replace(new RegExp("\t", "g"), "\\t")
840
// Replace unassigned code point by \uabcd...
841
// Uses function $B.is_unicode_cn() in unicode_data.js
842
var repl = ''
843
for(var i = 0; i < res.length; i++){
844
if($B.is_unicode_cn(res.codePointAt(i))){
845
var s = res.codePointAt(i).toString(16)
846
while(s.length < 4){
847
s = '0' + s
848
}
849
repl += '\\u' + s
850
}else{
851
repl += res.charAt(i)
852
}
853
}
854
res = repl
855
if(res.search('"') == -1 && res.search("'") == -1){
856
return "'" + res + "'"
857
}else if(self.search('"') == -1){
858
return '"' + res + '"'
859
}
860
var qesc = new RegExp("'", "g") // to escape single quote
861
res = "'" + res.replace(qesc, "\\'") + "'"
865
str.__setitem__ = function(self, attr, value){
866
throw _b_.TypeError.$factory(
867
"'str' object does not support item assignment")
869
var combining = []
870
for(var cp = 0x300; cp <= 0x36F; cp++){
871
combining.push(String.fromCharCode(cp))
872
}
873
var combining_re = new RegExp("(" + combining.join("|") + ")")
885
$comp_func += "" // source code
886
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
895
var $notimplemented = function(self, other){
896
throw NotImplementedError.$factory(
897
"OPERATOR not implemented for class str")
900
str.capitalize = function(self){
901
var $ = $B.args("capitalize", 1, {self}, ["self"],
902
arguments, {}, null, null)
903
if(self.length == 0){return ""}
904
return self.charAt(0).toUpperCase() + self.substr(1)
905
}
906
907
str.casefold = function(self){
908
var $ = $B.args("casefold", 1, {self}, ["self"],
909
arguments, {}, null, null),
910
res = "",
911
char,
912
cf
913
for(var i = 0, len = self.length; i < len; i++){
914
char = self.charCodeAt(i)
915
cf = $B.unicode_casefold[char]
916
if(cf){
917
cf.forEach(function(cp){
918
res += String.fromCharCode(cp)
919
})
920
}else{
921
res += self.charAt(i).toLowerCase()
922
}
923
}
924
return res
925
}
927
str.center = function(){
928
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
929
["self", "width", "fillchar"],
930
arguments, {fillchar:" "}, null, null),
931
self = $.self
943
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
944
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
952
if($.stop !== null){_slice = _b_.slice.$factory($.start, $.stop)}
953
else{_slice = _b_.slice.$factory($.start, $.self.length)}
958
if($.sub.length == 0){
959
if($.start == $.self.length){return 1}
960
else if(substr.length == 0){return 0}
961
return substr.length + 1
963
var n = 0,
964
pos = 0
965
while(pos < substr.length){
966
pos = substr.indexOf($.sub, pos)
967
if(pos >= 0){n++; pos += $.sub.length}
968
else{break}
973
str.encode = function(){
974
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
975
["self", "encoding", "errors"], arguments,
976
{encoding: "utf-8", errors: "strict"}, null, null)
977
if($.encoding == "rot13" || $.encoding == "rot_13"){
982
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
983
res += String.fromCharCode(String.charCodeAt(char) + 13)
984
}else if(("m" < char && char <= "z") ||
985
("M" < char && char <= "Z")){
986
res += String.fromCharCode(String.charCodeAt(char) - 13)
995
// Return True if the string ends with the specified suffix, otherwise
996
// return False. suffix can also be a tuple of suffixes to look for.
997
// With optional start, test beginning at that position. With optional
1001
["self", "suffix", "start", "end"],
1002
arguments, {start: 0, end: null}, null, null)
1009
var s = $.self.substring($.start, $.end)
1010
for(var i = 0, len = suffixes.length; i < len; i++){
1014
if(suffix.length <= s.length &&
1015
s.substr(s.length - suffix.length) == suffix){return true}
1021
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
1022
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
1023
var s = $B.$GetInt($.tabsize),
1024
col = 0,
1025
pos = 0,
1026
res = ""
1027
if(s == 1){return self.replace(/\t/g," ")}
1028
while(pos < self.length){
1036
res += car
1037
col = 0
1038
break
1039
default:
1040
res += car
1041
col++
1042
break
1043
}
1044
pos++
1045
}
1051
// Return the lowest index in the string where substring sub is found,
1052
// such that sub is contained in the slice s[start:end]. Optional
1053
// arguments start and end are interpreted as in slice notation.
1056
{self: null, sub: null, start: null, end: null},
1057
["self", "sub", "start", "end"],
1058
arguments, {start: 0, end: null}, null, null)
1062
if(!isinstance($.start, _b_.int)||!isinstance($.end, _b_.int)){
1063
throw _b_.TypeError.$factory("slice indices must be " +
1064
"integers or None or have an __index__ method")}
1065
// Can't use string.substring(start, end) because if end < start,
1066
// Javascript transforms it into substring(end, start)...
1067
var s = ""
1068
for(var i = $.start; i < $.end; i++){
1069
s += $.self.charAt(i)
1070
}
1072
if($.sub.length == 0 && $.start == $.self.length){return $.self.length}
1073
if(s.length + $.sub.length == 0){return -1}
1075
var last_search = s.length - $.sub.length
1076
for(var i = 0; i <= last_search; i++){
1077
if(s.substr(i, $.sub.length) == $.sub){return $.start + i}
1088
// a.x[z]!r:...
1089
// the object has attributes :
1090
// - name : "a"
1091
// - name_ext : [".x", "[z]"]
1092
// - conv : r
1093
// - spec : rest of string after :
1101
// No : in the string : it only contains a name
1102
name = fmt_string
1103
}else{
1104
// name is before the first ":"
1105
// spec (the format specification) is after
1106
name = elts[0]
1110
var elts = name.split("!")
1111
if(elts.length > 1){
1112
name = elts[0]
1113
conv = elts[1] // conversion flag
1117
// "name' may be a subscription or attribute
1118
// Put these "extensions" in the list "name_ext"
1119
function name_repl(match){
1120
name_ext.push(match)
1122
}
1123
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1124
name = name.replace(name_ext_re, name_repl)
1125
}
1132
// Parse self to detect formatting instructions
1133
// Create a list "parts" made of sections of the string :
1134
// - elements of even rank are literal text
1135
// - elements of odd rank are "format objects", built from the
1136
// format strings in self (of the form {...})
1147
text += "{"
1148
pos += 2
1149
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1156
// Store current literal text
1157
parts.push(text)
1158
1159
// Search the end of the format string, ie the } closing the
1160
// opening {. Since the string can contain other pairs {} for
1161
// nested formatting, an integer nb is incremented for each { and
1162
// decremented for each } ; the end of the format string is
1163
// reached when nb == 0
1164
var end = pos + 1,
1165
nb = 1
1166
while(end < _len){
1167
if(self.charAt(end) == "{"){nb++; end++}
1168
else if(self.charAt(end) == "}"){
1169
nb--; end++
1170
if(nb == 0){
1175
var fmt_obj = $B.parse_format(fmt_string)
1176
fmt_obj.raw_name = fmt_obj.name
1177
fmt_obj.raw_spec = fmt_obj.spec
1212
return parts
1213
}
1214
1215
str.format = function(self) {
1216
var $ = $B.args("format", 1, {self: null}, ["self"],
1217
arguments, {}, "$args", "$kw")
1218
1219
var parts = $B.split_format($.self)
1220
1231
1232
if(fmt.spec !== undefined){
1233
// "spec" may contain "nested replacement fields"
1234
// In this case, evaluate them using the positional
1235
// or keyword arguments passed to format()
1236
function replace_nested(name, key){
1237
if(/\d+/.exec(key)){
1238
// If key is numeric, search in positional
1239
// arguments
1240
return _b_.tuple.__getitem__($.$args,
1241
parseInt(key))
1242
}else{
1243
// Else try in keyword arguments
1244
return _b_.dict.__getitem__($.$kw, key)
1245
}
1246
}
1247
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1248
replace_nested)
1249
}
1251
// Numerical reference : use positional arguments
1252
var pos = parseInt(fmt.name),
1262
// Attribute
1263
value = _b_.getattr(value, ext.substr(1))
1264
}else{
1265
// Subscription
1268
if(key.charAt(0).search(/\d/) > -1){key = parseInt(key)}
1269
value = _b_.getattr(value, "__getitem__")(key)
1273
// If the conversion flag is set, first call a function to convert
1274
// the value
1275
if(fmt.conv == "a"){value = _b_.ascii(value)}
1276
else if(fmt.conv == "r"){value = _b_.repr(value)}
1277
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1291
throw NotImplementedError.$factory(
1292
"function format_map not implemented yet")
1303
/* Return true if the string is empty or all characters in the string are
1304
ASCII, false otherwise. ASCII characters have code points in the range
1305
U+0000-U+007F. */
1306
for(var i = 0, len = self.length; i < len; i++){
1307
if(self.charCodeAt(i) > 127){return false}
1308
}
1309
return true
1310
}
1311
1312
str.isalnum = function(self){
1313
/* Return true if all characters in the string are alphanumeric and there
1314
is at least one character, false otherwise. A character c is alphanumeric
1315
if one of the following returns True: c.isalpha(), c.isdecimal(),
1316
c.isdigit(), or c.isnumeric(). */
1317
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1318
arguments, {}, null, null),
1319
char
1320
for(var i = 0, len = self.length; i < len; i++){
1321
char = self.charCodeAt(i)
1322
if(unicode_tables.Ll[char] ||
1323
unicode_tables.Lu[char] ||
1324
unicode_tables.Lm[char] ||
1325
unicode_tables.Lt[char] ||
1326
unicode_tables.Lo[char] ||
1327
unicode_tables.Nd[char] ||
1328
unicode_tables.digits[char] ||
1329
unicode_tables.numeric[char]){
1330
continue
1331
}
1332
return false
1333
}
1334
return true
1335
}
1336
1337
str.isalpha = function(self){
1338
/* Return true if all characters in the string are alphabetic and there is
1339
at least one character, false otherwise. Alphabetic characters are those
1340
characters defined in the Unicode character database as "Letter", i.e.,
1341
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1342
or "Lo". */
1343
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1344
arguments, {}, null, null),
1345
char
1346
for(var i = 0, len = self.length; i < len; i++){
1347
char = self.charCodeAt(i)
1348
if(unicode_tables.Ll[char] ||
1349
unicode_tables.Lu[char] ||
1350
unicode_tables.Lm[char] ||
1351
unicode_tables.Lt[char] ||
1352
unicode_tables.Lo[char]){
1353
continue
1354
}
1355
return false
1356
}
1357
return true
1358
}
1359
1360
str.isdecimal = function(self){
1361
/* Return true if all characters in the string are decimal characters and
1362
there is at least one character, false otherwise. Decimal characters are
1363
those that can be used to form numbers in base 10, e.g. U+0660,
1364
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1365
the Unicode General Category "Nd". */
1366
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1367
arguments, {}, null, null),
1368
char
1369
for(var i = 0, len = self.length; i < len; i++){
1370
char = self.charCodeAt(i)
1371
if(! unicode_tables.Nd[char]){
1372
return false
1373
}
1374
}
1375
return self.length > 0
1376
}
1377
1378
str.isdigit = function(self){
1379
/* Return true if all characters in the string are digits and there is at
1380
least one character, false otherwise. */
1381
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1382
arguments, {}, null, null),
1383
char
1384
for(var i = 0, len = self.length; i < len; i++){
1385
char = self.charCodeAt(i)
1386
if(! unicode_tables.digits[char]){
1387
return false
1388
}
1389
}
1390
return self.length > 0
1391
}
1392
1393
str.isidentifier = function(self){
1394
/* Return true if the string is a valid identifier according to the
1395
language definition. */
1396
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1397
arguments, {}, null, null),
1398
char
1399
if(self.length == 0){return false}
1400
else if(unicode_tables.XID_Start[self.charCodeAt(0)] === undefined){
1401
return false
1402
}else{
1403
for(var i = 1, len = self.length; i < len; i++){
1404
if(unicode_tables.XID_Continue[self.charCodeAt(i)] === undefined){
1405
return false
1406
}
1407
}
1408
}
1409
return true
1410
}
1411
1412
str.islower = function(self){
1413
/* Return true if all cased characters 4 in the string are lowercase and
1414
there is at least one cased character, false otherwise. */
1415
var $ = $B.args("islower", 1, {self: null}, ["self"],
1416
arguments, {}, null, null),
1417
has_cased = false,
1418
char
1419
1420
for(var i = 0, len = self.length; i < len; i++){
1421
char = self.charCodeAt(i)
1422
if(unicode_tables.Ll[char]){has_cased = true; continue}
1423
else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1424
return false
1425
}
1426
}
1427
return has_cased
1428
}
1429
1430
str.isnumeric = function(self){
1431
/* Return true if all characters in the string are numeric characters, and
1432
there is at least one character, false otherwise. Numeric characters
1433
include digit characters, and all characters that have the Unicode numeric
1434
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1435
characters are those with the property value Numeric_Type=Digit,
1436
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1437
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1438
arguments, {}, null, null)
1439
for(var i = 0, len = self.length; i < len; i++){
1440
if(! unicode_tables.numeric[self.charCodeAt(i)]){
1441
return false
1442
}
1443
}
1444
return self.length > 0
1445
}
1446
1447
var unprintable = {},
1448
unprintable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1449
1450
str.isprintable = function(self){
1451
/* Return true if all characters in the string are printable or the string
1452
is empty, false otherwise. Nonprintable characters are those characters
1453
defined in the Unicode character database as "Other" or "Separator",
1454
excepting the ASCII space (0x20) which is considered printable. */
1455
1456
// Set unprintable if not set yet
1457
if(Object.keys(unprintable).length == 0){
1458
for(var i = 0; i < unprintable_gc.length; i++){
1459
var table = unicode_tables[unprintable_gc[i]]
1470
return false
1471
}
1472
}
1473
return true
1474
}
1475
1476
str.isspace = function(self){
1477
/* Return true if there are only whitespace characters in the string and
1478
there is at least one character, false otherwise.
1479
1480
A character is whitespace if in the Unicode character database, either its
1481
general category is Zs ("Separator, space"), or its bidirectional class is
1482
one of WS, B, or S.*/
1483
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1484
arguments, {}, null, null),
1485
char
1486
for(var i = 0, len = self.length; i < len; i++){
1487
char = self.charCodeAt(i)
1488
if(! unicode_tables.Zs[char] &&
1489
$B.unicode_bidi_whitespace.indexOf(char) == -1){
1490
return false
1491
}
1492
}
1493
return self.length > 0
1494
}
1495
1496
str.istitle = function(self){
1497
/* Return true if the string is a titlecased string and there is at least
1498
one character, for example uppercase characters may only follow uncased
1499
characters and lowercase characters only cased ones. Return false
1500
otherwise. */
1501
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1502
arguments, {}, null, null)
1503
return self.length > 0 && str.title(self) == self
1504
}
1505
1506
str.isupper = function(self){
1507
/* Return true if all cased characters 4 in the string are lowercase and
1508
there is at least one cased character, false otherwise. */
1509
var $ = $B.args("islower", 1, {self: null}, ["self"],
1510
arguments, {}, null, null),
1511
has_cased = false,
1512
char
1513
1514
for(var i = 0, len = self.length; i < len; i++){
1515
char = self.charCodeAt(i)
1516
if(unicode_tables.Lu[char]){has_cased = true; continue}
1517
else if(unicode_tables.Ll[char] || unicode_tables.Lt[char]){
1535
if(! isinstance(obj2, str)){throw _b_.TypeError.$factory(
1536
"sequence item " + count + ": expected str instance, " +
1550
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1551
["self", "width", "fillchar"],
1552
arguments, {fillchar: " "}, null, null)
1558
str.lower = function(self){
1559
var $ = $B.args("lower", 1, {self: null}, ["self"],
1560
arguments, {}, null, null)
1561
return self.toLowerCase()
1562
}
1563
1565
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1566
arguments, {chars:_b_.None}, null, null)
1567
if($.chars === _b_.None){return $.self.trimLeft()}
1568
for(var i = 0; i < $.self.length; i++){
1569
if($.chars.indexOf($.self.charAt(i)) === -1){
1570
return $.self.substring(i)
1578
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1579
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1584
// If there is only one argument, it must be a dictionary mapping
1585
// Unicode ordinals (integers) or characters (strings of length 1) to
1586
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1588
if(! _b_.isinstance($.x, _b_.dict)){
1589
throw _b_.TypeError.$factory(
1590
"maketrans only argument must be a dict")
1593
for(var i = 0, len = items.length; i < len; i++){
1594
var k = items[i][0],
1595
v = items[i][1]
1596
if(! _b_.isinstance(k, _b_.int)){
1597
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1598
k = _b_.ord(k)
1599
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1602
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1603
throw _b_.TypeError.$factory("dictionary value " + v +
1611
// and in the resulting dictionary, each character in x will be mapped
1612
// to the character at the same position in y
1615
}else if($.x.length !== $.y.length){
1616
throw _b_.TypeError.$factory(
1617
"maketrans arguments must be strings or same length")
1623
if(! _b_.isinstance($.z, _b_.str)){
1624
throw _b_.TypeError.$factory(
1625
"maketrans third argument must be a string")
1647
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1648
arguments, {}, null, null)
1653
return _b_.tuple.$factory([$.self.substring(0, i), $.sep,
1654
$.self.substring(i + $.sep.length)])
1655
}
1656
1657
str.removeprefix = function(){
1658
var $ = $B.args("removeprefix", 2, {self: null, prefix: null},
1659
["self", "prefix"], arguments, {}, null, null)
1660
if(!_b_.isinstance($.prefix, str)){
1661
throw _b_.ValueError.$factory("prefix should be str, not " +
1662
`'${$B.class_name($.prefix)}'`)
1663
}
1664
if(str.startswith($.self, $.prefix)){
1665
return $.self.substr($.prefix.length)
1666
}
1667
return $.self.substr(0)
1668
}
1669
1670
str.removesuffix = function(){
1671
var $ = $B.args("removesuffix", 2, {self: null, prefix: null},
1672
["self", "suffix"], arguments, {}, null, null)
1673
if(!_b_.isinstance($.suffix, str)){
1674
throw _b_.ValueError.$factory("suffix should be str, not " +
1675
`'${$B.class_name($.prefix)}'`)
1676
}
1677
if($.suffix.length > 0 && str.endswith($.self, $.suffix)){
1678
return $.self.substr(0, $.self.length - $.suffix.length)
1679
}
1680
return $.self.substr(0)
1681
}
1682
1683
function $re_escape(str){
1684
var specials = "[.*+?|()$^"
1685
for(var i = 0, len = specials.length; i < len; i++){
1686
var re = new RegExp("\\"+specials.charAt(i), "g")
1687
str = str.replace(re, "\\"+specials.charAt(i))
1688
}
1689
return str
1696
var $ = $B.args("replace", 4,
1697
{self: null, old: null, $$new: null, count: null},
1698
["self", "old", "$$new", "count"],
1699
arguments, {count: -1}, null, null),
1700
count = $.count,
1701
self = $.self,
1702
old = $.old,
1703
_new = $.$$new
1710
"' object cannot be interpreted as an integer")
1711
}else if(isinstance(count, _b_.float)){
1712
throw _b_.TypeError.$factory("integer argument expected, got float")
1713
}
1714
if(count == 0){return self}
1715
if(count.__class__ == $B.long_int){count = parseInt(count.value)}
1716
if(old == ""){
1717
if(_new == ""){return self}
1718
if(self == ""){return _new}
1719
var elts = self.split("")
1720
if(count > -1 && elts.length >= count){
1721
var rest = elts.slice(count).join("")
1722
return _new + elts.slice(0, count).join(_new) + rest
1723
}else{return _new + elts.join(_new) + _new}
1738
if(count < 0){count = res.length}
1739
while(count > 0){
1740
pos = res.indexOf(old, pos)
1741
if(pos < 0){break}
1742
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1743
pos = pos + _new.length
1744
count--
1750
// Return the highest index in the string where substring sub is found,
1751
// such that sub is contained within s[start:end]. Optional arguments
1753
if(arguments.length == 2 && typeof substr == "string"){
1754
return self.lastIndexOf(substr)
1755
}
1757
{self: null, sub: null, start: null, end: null},
1758
["self", "sub", "start", "end"],
1759
arguments, {start: 0, end: null}, null, null)
1771
for(var i = $.end - sublen; i >= $.start; i--){
1772
if($.self.substr(i, sublen) == $.sub){return i}
1779
var res = str.rfind.apply(null, arguments)
1780
if(res == -1){throw _b_.ValueError.$factory("substring not found")}
1785
var $ = $B.args("rjust",3,
1786
{self: null, width: null, fillchar: null},
1787
["self", "width", "fillchar"],
1788
arguments, {fillchar: " "}, null, null)
1796
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
1797
arguments, {}, null, null)
1801
var items = str.partition(self, sep).reverse()
1802
for(var i = 0; i < items.length; i++){
1803
items[i] = items[i].split("").reverse().join("")
1809
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
1810
["self", "sep", "maxsplit"], arguments,
1811
{sep: _b_.None, maxsplit: -1}, null, null),
1812
sep = $.sep
1815
var rev_str = reverse($.self),
1816
rev_sep = sep === _b_.None ? sep : reverse($.sep),
1827
str.rstrip = function(self, x){
1828
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
1829
arguments, {chars: _b_.None}, null, null)
1830
if($.chars === _b_.None){return $.self.trimRight()}
1832
if($.chars.indexOf($.self.charAt(j)) == -1){
1833
return $.self.substring(0, j + 1)
1840
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
1841
["self", "sep", "maxsplit"], arguments,
1842
{sep: _b_.None, maxsplit: -1}, null, null),
1843
sep = $.sep,
1844
maxsplit = $.maxsplit,
1845
self = $.self,
1846
pos = 0
1847
if(maxsplit.__class__ === $B.long_int){maxsplit = parseInt(maxsplit.value)}
1848
if(sep == ""){throw _b_.ValueError.$factory("empty separator")}
1849
if(sep === _b_.None){
1851
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){pos++}
1852
if(pos === self.length - 1){return [self]}
1853
var name = ""
1855
if(self.charAt(pos).search(/\s/) == -1){
1856
if(name == ""){name = self.charAt(pos)}
1857
else{name += self.charAt(pos)}
1877
var res = [],
1878
s = "",
1879
seplen = sep.length
1880
if(maxsplit == 0){return [self]}
1881
while(pos < self.length){
1882
if(self.substr(pos, seplen) == sep){
1900
str.splitlines = function(self) {
1901
var $ = $B.args('splitlines', 2, {self: null, keepends: null},
1902
['self','keepends'], arguments, {keepends: false},
1903
null, null)
1904
if(!_b_.isinstance($.keepends,[_b_.bool, _b_.int])){
1905
throw _b_.TypeError('integer argument expected, got '+
1908
var keepends = _b_.int.$factory($.keepends),
1909
res = [],
1910
self = $.self,
1911
start = 0,
1912
pos = 0
1913
if(!self.length){
1916
while (pos < self.length) {
1917
if(self.substr(pos, 2) == '\r\n'){
1918
res.push(self.slice(start, keepends ? pos + 2 : pos))
1919
start = pos = pos+2
1920
}else if(self[pos] == '\r' || self[pos] == '\n'){
1921
res.push(self.slice(start, keepends ? pos+1 : pos))
1922
start = pos = pos+1
1923
}else{
1924
pos++
1925
}
1926
}
1927
if(start < self.length){
1928
res.push(self.slice(start))
1929
}
1930
return res
1934
// Return True if string starts with the prefix, otherwise return False.
1935
// prefix can also be a tuple of prefixes to look for. With optional
1936
// start, test string beginning at that position. With optional end,
1938
var $ = $B.args("startswith", 4,
1939
{self: null, prefix: null, start: null, end: null},
1940
["self", "prefix", "start", "end"],
1941
arguments, {start: 0, end: null}, null, null)
1948
var s = $.self.substring($.start, $.end)
1949
for(var i = 0, len = prefixes.length; i < len; i++){
1960
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
1961
arguments, {chars: _b_.None}, null, null)
1962
if($.chars === _b_.None){return $.self.trim()}
1963
for(var i = 0; i < $.self.length; i++){
1964
if($.chars.indexOf($.self.charAt(i)) == -1){
1965
break
1968
for(var j = $.self.length - 1; j >= i; j--){
1969
if($.chars.indexOf($.self.charAt(j)) == -1){
1970
break
1976
str.swapcase = function(self){
1977
var $ = $B.args("swapcase", 1, {self}, ["self"],
1978
arguments, {}, null, null),
1979
res = "",
1980
char
1981
1982
for(var i = 0, len = self.length; i < len; i++){
1983
char = self.charCodeAt(i)
1984
if(unicode_tables.Ll[char]){
1985
res += self.charAt(i).toUpperCase()
1986
}else if(unicode_tables.Lu[char]){
1987
res += self.charAt(i).toLowerCase()
1988
}else{
1989
res += self.charAt(i)
1990
}
1991
}
1992
return res
1993
}
1994
1995
str.title = function(self){
1996
var $ = $B.args("title", 1, {self}, ["self"],
1997
arguments, {}, null, null),
1998
state,
1999
char,
2000
res = ""
2001
for(var i = 0, len = self.length; i < len; i++){
2002
char = self.charCodeAt(i)
2003
if(unicode_tables.Ll[char]){
2004
if(! state){
2005
res += self.charAt(i).toUpperCase()
2006
state = "word"
2007
}else{
2008
res += self.charAt(i)
2009
}
2010
}else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
2011
res += state ? self.charAt(i).toLowerCase() : self.charAt(i)
2012
state = "word"
2013
}else{
2014
state = null
2015
res += self.charAt(i)
2016
}
2017
}
2018
return res
2019
}
2020
2023
getitem = $B.$getattr(table, "__getitem__")
2024
for(var i = 0, len = self.length; i < len; i++){
2025
try{
2026
var repl = getitem(self.charCodeAt(i))
2027
if(repl !== _b_.None){
2028
if(typeof repl == "string"){
2029
res.push(repl)
2030
}else if(typeof repl == "number"){
2031
res.push(String.fromCharCode(repl))
2032
}
2041
str.upper = function(self){
2042
var $ = $B.args("upper", 1, {self: null}, ["self"],
2043
arguments, {}, null, null)
2044
return self.toUpperCase()
2045
}
2046
2049
["self", "width"], arguments, {}, null, null)
2050
if($.width <= self.length){return self}
2052
case "+":
2053
case "-":
2054
return self.charAt(0) +
2055
"0".repeat($.width - self.length) + self.substr(1)
2066
if(encoding !== undefined){
2067
// Arguments may be passed as keywords (cf. issue #1060)
2068
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2069
["arg", "encoding", "errors"], arguments,
2070
{encoding: "utf-8", errors: "strict"}, null, null),
2071
encoding = $.encoding,
2072
errors = $.errors
2073
}
2084
// class or its subclasses, but the attribute __str__ of the
2085
// class metaclass (usually "type") or its subclasses (usually
2086
// "object")
2087
// The metaclass is the attribute __class__ of the class dictionary
2092
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2093
encoding !== undefined){
2094
// str(bytes, encoding, errors) is equal to
2095
// bytes.decode(encoding, errors)
2098
// Implicit invocation of __str__ uses method __str__ on the class,
2099
// even if arg has an attribute __str__
2100
var klass = arg.__class__ || $B.get_class(arg)
2106
// if not better than object.__str__, try __repr__
2107
(arg.__class__ && arg.__class__ !== _b_.object &&
2108
method.$infos && method.$infos.__func__ === _b_.object.__str__)){
2109
var method = $B.$getattr(klass, "__repr__")
2115
if($B.debug > 1){console.log(err)}
2116
console.log("Warning - no method __str__ or __repr__, " +
2117
"default to toString", arg)
2124
if(cls === undefined){
2125
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2149
var args = [],
2150
pos = 0
2151
if(arguments.length > 0){
2152
var args = [arguments[0].valueOf()],
2153
pos = 1
2154
for(var i = 1, len = arguments.length; i < len; i++){
2155
args[pos++] = arguments[i]
2171
// Function to parse the 2nd argument of format()
2172
$B.parse_format_spec = function(spec){
2175
var pos = 0,
2176
aligns = "<>=^",
2177
digits = "0123456789",
2178
types = "bcdeEfFgGnosxX%",
2180
if(align_pos != -1){
2181
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2182
// If the second char is also an alignment specifier, the
2183
// first char is the fill value
2184
this.fill = spec.charAt(0)
2185
this.align = spec.charAt(1)
2186
pos = 2
2187
}else{
2188
// The first character defines alignment : fill defaults to ' '
2203
if(car == "+" || car == "-" || car == " "){
2204
this.sign = car
2205
pos++
2206
car = spec.charAt(pos)
2208
if(car == "#"){this.alternate = true; pos++; car = spec.charAt(pos)}
2209
if(car == "0"){
2218
while(car && digits.indexOf(car) > -1){
2219
if(this.width === undefined){this.width = car}
2220
else{this.width += car}
2221
pos++
2222
car = spec.charAt(pos)
2225
if(this.width === undefined && car == "{"){
2226
// Width is determined by a parameter
2227
var end_param_pos = spec.substr(pos).search("}")
2228
this.width = spec.substring(pos, end_param_pos)
2229
console.log("width", "[" + this.width + "]")
2230
pos += end_param_pos + 1
2231
}
2232
if(car == ","){this.comma = true; pos++; car = spec.charAt(pos)}
2233
if(car == "."){
2234
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2235
throw _b_.ValueError.$factory(
2236
"Missing precision in format spec")
2238
this.precision = spec.charAt(pos + 1)
2239
pos += 2
2240
car = spec.charAt(pos)
2241
while(car && digits.indexOf(car) > -1){
2248
if(car && types.indexOf(car) > -1){
2249
this.type = car
2250
pos++
2251
car = spec.charAt(pos)
2252
}
2253
if(pos !== spec.length){
2259
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2260
(this.align || "") +
2261
(this.sign || "") +
2262
(this.alternate ? "#" : "") +
2263
(this.sign_aware ? "0" : "") +
2264
(this.width || "") +
2265
(this.comma ? "," : "") +
2266
(this.precision ? "." + this.precision : "") +
2267
(this.type || "")
2272
if(fmt.width && s.length < fmt.width){
2273
var fill = fmt.fill || " ",
2274
align = fmt.align || "<",
2275
missing = fmt.width - s.length
2277
case "<":
2278
return s + fill.repeat(missing)
2279
case ">":
2280
return fill.repeat(missing) + s
2281
case "=":
2282
if("+-".indexOf(s.charAt(0)) > -1){
2283
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2287
case "^":
2288
var left = parseInt(missing / 2)
2289
return fill.repeat(left) + s + fill.repeat(missing - left)
2302
$B.parse_fstring = function(string){
2303
// Parse a f-string
2304
var elts = [],
2305
pos = 0,
2329
}else{
2330
throw Error(" f-string: single '}' is not allowed")
2331
}
2332
}else{
2354
current += car
2355
i += 2
2356
}else{
2357
throw Error(" f-string: single '}' is not allowed")
2358
}
2359
}else{
2360
current += car
2361
i++
2362
}
2363
}
2365
}else if(ctype == "debug"){
2366
// after the equal sign, whitespace are ignored and the only
2367
// valid characters are } and :
2368
while(string.charAt(i) == " "){i++}
2369
if(string.charAt(i) == "}"){
2370
// end of debug expression
2371
elts.push(current)
2372
ctype = null
2373
current = ""
2374
pos = i + 1
2375
}
2376
}else{
2377
// End of expression is the } matching the opening {
2378
// There may be nested braces
2379
var i = pos,
2380
nb_braces = 1,
2402
// backslash is not allowed in expressions
2403
throw Error("f-string expression part cannot include a" +
2404
" backslash")
2411
throw Error("f-string: invalid conversion character:" +
2412
" expected 's', 'r', or 'a'")
2413
}else{
2427
if(string.substr(i, 3) == '"""'){
2428
var end = string.indexOf('"""', i + 3)
2429
if(end == -1){
2430
throw Error("f-string: unterminated string")
2431
}else{
2432
var trs = string.substring(i, end + 3)
2433
trs = trs.replace("\n", "\\n\\")
2438
var end = string.indexOf('"', i + 1)
2439
if(end == -1){
2440
throw Error("f-string: unterminated string")
2441
}else{
2442
current.expression += string.substring(i, end + 1)
2443
i = end + 1
2452
var ce = current.expression,
2453
last_char = ce.charAt(ce.length - 1),
2454
last_char_re = ('()'.indexOf(last_char) > -1 ? "\\" : "") + last_char
2461
}else{
2462
// add debug string
2463
tail = car
2464
while(string.charAt(i + 1).match(/\s/)){
2465
tail += string.charAt(i + 1)
2466
i++
2467
}
2468
elts.push(current.expression + tail)
2469
// remove trailing whitespace from expression
2470
while(ce.match(/\s$/)){
2471
ce = ce.substr(0, ce.length - 1)
2472
}
2473
current.expression = ce
2474
ctype = "debug"
2475
i++
2476
}
2491
// Class for strings with surrogate pairs. We can't rely on Javascript
2492
// strings in this case because they don't count characters like Python
2493
2494
var surrogate = str.$surrogate = $B.make_class("surrogate_string", function(s){
2495
// create an instance of str subclass for strings with surrogate pairs
2496
var items = []
2497
for(var i = 0, len = s.length; i < len; i++){
2498
var code = s.charCodeAt(i)
2499
if(code >= 0xD800 && code <= 0xDBFF){
2500
i++
2501
var low = s.charCodeAt(i)
2502
code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000
2503
}
2504
items.push(String.fromCodePoint(code))
2505
}
2506
return {
2507
__class__: str.$surrogate,
2508
items: items
2509
}
2510
})
2511
2512
surrogate.__mro__ = [str, object]
2513
2514
surrogate.__contains__ = function(self, other){
2515
return str.__contains__(self.items.join(''), other)
2516
}
2517
2518
surrogate.__getitem__ = function(self, arg){
2519
if(isinstance(arg, _b_.int)){
2520
var pos = arg
2521
if(arg < 0){
2522
pos += self.items.length
2523
}
2524
if(pos >= 0 && pos < self.items.length){
2525
if(self.items[pos].length == 2){
2526
return surrogate.$factory(self.items[pos])
2527
}
2528
return self.items[pos]
2529
}
2530
throw _b_.IndexError.$factory("string index out of range")
2531
}
2532
if(isinstance(arg, slice)) {
2533
var s = _b_.slice.$conv_for_seq(arg, self.items.length),
2534
start = s.start,
2535
stop = s.stop,
2536
step = s.step
2537
var res = "",
2538
i = null
2539
if(step > 0){
2540
if(stop <= start){return ""}
2541
for(var i = start; i < stop; i += step){
2542
res += self.items[i]
2543
}
2544
}else{
2545
if(stop >= start){return ''}
2546
for(var i = start; i > stop; i += step){
2547
res += self.items[i]
2548
}
2549
}
2550
return res
2551
}
2552
if(isinstance(arg, _b_.bool)){
2553
return surrogate.__getitem__(self, _b_.int.$factory(arg))
2554
}
2555
throw _b_.TypeError.$factory("string indices must be integers")
2556
}
2557
2558
surrogate.__hash__ = function(self){
2559
return str.__hash__(self.items.join(''))
2560
}
2561
2562
surrogate.__iter__ = function(self){
2563
return str_iterator.$factory(self.items)
2564
}
2565
2566
surrogate.__len__ = function(self){
2567
return self.items.length
2568
}
2569
2570
surrogate.__repr__ = function(self){
2571
return str.__repr__(self.items.join(''))
2572
}
2573
2574
surrogate.__str__ = function(self){
2575
return str.__str__(self.items.join(''))
2576
}
2577
2578
$B.set_func_names(surrogate, "builtins")
2579
2580