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
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
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
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
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
May 3, 2020
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
Oct 13, 2019
Dec 27, 2019
Oct 13, 2019
Apr 25, 2020
Newer
100644
2525 lines (2314 sloc)
80 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")
120
if(arg < 0) {pos += self.length}
121
if(pos >= 0 && pos < self.length){return self.charAt(pos)}
122
throw _b_.IndexError.$factory("string index out of range")
123
}
124
if(isinstance(arg, slice)) {
125
var s = _b_.slice.$conv_for_seq(arg, self.length),
126
start = s.start,
127
stop = s.stop,
128
step = s.step
129
var res = "",
131
if(step > 0){
132
if(stop <= start){return ""}
133
for(var i = start; i < stop; i += step){res += self.charAt(i)}
135
if(stop >= start){return ''}
136
for(var i = start; i > stop; i += step){res += self.charAt(i)}
144
var prefix = 2,
145
suffix = 3,
146
mask = (2 ** 32 - 1)
147
function fnv(p){
148
if(p.length == 0){
149
return 0
150
}
152
var x = prefix
153
x = (x ^ (p.charCodeAt(0) << 7)) & mask
154
for(var i = 0, len = p.length; i < len; i++){
155
x = ((1000003 * x) ^ p.charCodeAt(i)) & mask
156
}
157
x = (x ^ p.length) & mask
158
x = (x ^ suffix) & mask
218
// left adjusted
219
return s + get_char_array(padding - s.length, flags.pad_char)
220
}
221
}
222
230
if(val.__class__ === $B.long_int){
231
s = $B.long_int.to_base(val, 10)
232
}else{
233
s = val.toString()
235
if(s[0] === "-"){
236
return "-" + get_char_array(precision - s.length + 1, "0") + s.slice(1)
247
if(val === Infinity){
248
val = "inf"
249
}else if(val === -Infinity){
250
val = "-inf"
251
}else{
252
val = "nan"
274
var str_format = function(val, flags) {
275
// string format supports left and right padding
276
flags.pad_char = " " // even if 0 padding is defined, don't use it
282
if(val.__class__ === $B.long_int){
283
val = $B.long_int.to_base(val, 10)
284
}else{
285
val = parseInt(val)
303
var repr_format = function(val, flags) {
304
flags.pad_char = " " // even if 0 padding is defined, don't use it
305
return format_padding(repr(val), flags)
306
}
308
var ascii_format = function(val, flags) {
309
flags.pad_char = " " // even if 0 padding is defined, don't use it
310
return format_padding(ascii(val), flags)
311
}
323
flags.precision = parseInt(flags.precision, 10)
324
validate_precision(flags.precision)
325
}
326
return parseFloat(val)
327
}
330
var trailing_zeros = /(.*?)(0+)([eE].*)/,
331
leading_zeros = /\.(0*)/,
332
trailing_dot = /\.$/
334
var validate_precision = function(precision) {
335
// force precision to limits of javascript
340
var floating_point_format = function(val, upper, flags){
341
val = _float_helper(val, flags),
342
v = val.toString(),
343
v_len = v.length,
344
dot_idx = v.indexOf('.')
345
if(dot_idx < 0){dot_idx = v_len}
346
if(val < 1 && val > -1){
347
var zeros = leading_zeros.exec(v),
348
numzeros
349
if(zeros){
354
if(numzeros >= 4){
355
val = format_sign(val, flags) + format_float_precision(val, upper,
356
flags, _floating_g_exp_helper)
357
if(!flags.alternate){
370
return format_padding(format_sign(val, flags) +
371
format_float_precision(val, upper, flags,
372
function(val, precision) {
373
return val.toFixed(min(precision, v_len - dot_idx) +
374
numzeros)
375
}),
376
flags
377
)
378
}
379
380
if(dot_idx > flags.precision){
381
val = format_sign(val, flags) + format_float_precision(val, upper,
382
flags, _floating_g_exp_helper)
383
if(! flags.alternate){
395
return format_padding(format_sign(val, flags) +
396
format_float_precision(val, upper, flags,
397
function(val, precision) {
398
if(!flags.decimal_point){
399
precision = min(v_len - 1, 6)
400
}else if (precision > v_len){
401
if(! flags.alternate){
402
precision = v_len
403
}
405
if(precision < dot_idx){
406
precision = dot_idx
407
}
408
return val.toFixed(precision - dot_idx)
409
}),
410
flags
411
)
414
var _floating_g_exp_helper = function(val, precision, flags, upper){
415
if(precision){--precision}
418
var e_idx = val.lastIndexOf("e")
419
if(e_idx > val.length - 4){
420
val = val.substring(0, e_idx + 2) + "0" + val.substring(e_idx + 2)
423
return val
424
}
425
426
// fF
427
var floating_point_decimal_format = function(val, upper, flags) {
428
val = _float_helper(val, flags)
429
return format_padding(format_sign(val, flags) +
430
format_float_precision(val, upper, flags,
431
function(val, precision, flags) {
432
val = val.toFixed(precision)
433
if(precision === 0 && flags.alternate){
434
val += '.'
435
}
436
return val
437
}),
438
flags
439
)
440
}
441
442
var _floating_exp_helper = function(val, precision, flags, upper) {
443
val = val.toExponential(precision)
444
// pad exponent to two digits
457
return format_padding(format_sign(val, flags) +
458
format_float_precision(val, upper, flags, _floating_exp_helper), flags)
484
if(flags.alternate){
485
if(ret.charAt(0) === "-"){
486
if(upper){ret = "-0X" + ret.slice(1)}
487
else{ret = "-0x" + ret.slice(1)}
488
}else{
489
if(upper){ret = "0X" + ret}
490
else{ret = "0x" + ret}
500
if(val.__class__ === $B.long_int){
501
ret = $B.long_int.to_base(8)
502
}else{
503
ret = parseInt(val)
504
ret = ret.toString(8)
520
if(flags.alternate){
521
if(ret.charAt(0) === "-"){ret = "-0o" + ret.slice(1)}
522
else{ret = "0o" + ret}
527
function series_of_bytes(val, flags){
528
if(val.__class__ && val.__class__.$buffer_protocol){
529
var it = _b_.iter(val),
530
ints = []
531
while(true){
532
try{
533
ints.push(_b_.next(it))
534
}catch(err){
535
if(err.__class__ === _b_.StopIteration){
536
var b = _b_.bytes.$factory(ints)
537
return format_padding(_b_.bytes.decode(b, "ascii"), flags)
538
}
539
throw err
540
}
541
}
542
}else{
543
try{
544
bytes_obj = $B.$getattr(val, "__bytes__")
545
return format_padding(_b_.bytes.decode(bytes_obj), flags)
546
}catch(err){
547
if(err.__class__ === _b_.AttributeError){
548
throw _b_.TypeError.$factory("%b does not accept '" +
549
$B.class_name(val) + "'")
550
}
551
throw err
552
}
553
}
554
}
555
557
if(isinstance(val, str) && val.length == 1){
558
return val
559
}else if(isinstance(val, bytes) && val.source.length == 1){
560
val = val.source[0]
561
}else{
562
try{
563
val = _b_.int.$factory(val) // yes, floats are valid (they are cast to int)
564
}catch (err){
565
throw _b_.TypeError.$factory("%c requires int or char")
566
}
571
var num_flag = function(c, flags){
572
if(c === "0" && ! flags.padding && ! flags.decimal_point && ! flags.left){
573
flags.pad_char = "0"
579
flags.precision = (flags.precision || "") + c
580
}
581
}
582
583
var decimal_point_flag = function(val, flags) {
585
// can only have one decimal point
586
throw new UnsupportedChar()
587
}
588
flags.decimal_point = true
589
}
590
591
var neg_flag = function(val, flags){
592
flags.pad_char = " " // overrides '0' flag
610
"s": str_format,
611
"d": num_format,
612
"i": num_format,
613
"u": num_format,
614
"o": octal_format,
615
"r": repr_format,
616
"a": ascii_format,
617
"g": function(val, flags){
618
return floating_point_format(val, false, flags)
619
},
620
"G": function(val, flags){return floating_point_format(val, true, flags)},
621
"f": function(val, flags){
622
return floating_point_decimal_format(val, false, flags)
623
},
624
"F": function(val, flags){
625
return floating_point_decimal_format(val, true, flags)
626
},
627
"e": function(val, flags){
628
return floating_point_exponential_format(val, false, flags)
629
},
630
"E": function(val, flags){
631
return floating_point_exponential_format(val, true, flags)
632
},
633
"x": function(val, flags){return signed_hex_format(val, false, flags)},
634
"X": function(val, flags){return signed_hex_format(val, true, flags)},
635
"c": single_char_format,
636
"0": function(val, flags){return num_flag("0", flags)},
637
"1": function(val, flags){return num_flag("1", flags)},
638
"2": function(val, flags){return num_flag("2", flags)},
639
"3": function(val, flags){return num_flag("3", flags)},
640
"4": function(val, flags){return num_flag("4", flags)},
641
"5": function(val, flags){return num_flag("5", flags)},
642
"6": function(val, flags){return num_flag("6", flags)},
643
"7": function(val, flags){return num_flag("7", flags)},
644
"8": function(val, flags){return num_flag("8", flags)},
645
"9": function(val, flags){return num_flag("9", flags)},
646
"-": neg_flag,
647
" ": space_flag,
648
"+": sign_flag,
649
".": decimal_point_flag,
650
"#": alternate_flag
651
}
652
653
// exception thrown when an unsupported char is encountered in legacy format
700
if(self === undefined){
701
throw _b_.TypeError.$factory(
702
"not enough arguments for format string")
729
throw _b_.ValueError.$factory(
730
"unsupported format character '" + invalid_char +
731
"' (0x" + invalid_char.charCodeAt(0).toString(16) +
732
") at index " + newpos)
733
}else if(err.name === "NotANumber"){
734
var try_char = s[newpos],
735
cls = self.__class__
736
if(!cls){
737
if(typeof(self) === "string"){
738
cls = "str"
739
}else{
745
throw _b_.TypeError.$factory("%" + try_char +
746
" format: a number is required, not " + cls)
747
}else{
779
}while(pos < length)
780
781
if(argpos !== null){
782
if(args.length > argpos){
783
throw _b_.TypeError.$factory(
784
"not enough arguments for format string")
785
}else if(args.length < argpos){
786
throw _b_.TypeError.$factory(
787
"not all arguments converted during string formatting")
789
}else if(nbph == 0){
790
throw _b_.TypeError.$factory(
791
"not all arguments converted during string formatting")
799
var $ = $B.args("__mul__", 2, {self: null, other: null},
800
["self", "other"], arguments, {}, null, null)
801
if(! isinstance($.other, _b_.int)){throw _b_.TypeError.$factory(
802
"Can't multiply sequence by non-int of type '" +
814
res = self.replace(/\\/g, "\\\\")
815
// special cases
816
res = res.replace(new RegExp("\u0007", "g"), "\\x07").
817
replace(new RegExp("\b", "g"), "\\x08").
819
replace(new RegExp("\f", "g"), "\\x0c").
820
replace(new RegExp("\n", "g"), "\\n").
821
replace(new RegExp("\r", "g"), "\\r").
822
replace(new RegExp("\t", "g"), "\\t")
824
if(res.search('"') == -1 && res.search("'") == -1){
825
return "'" + res + "'"
826
}else if(self.search('"') == -1){
827
return '"' + res + '"'
828
}
829
var qesc = new RegExp("'", "g") // to escape single quote
830
res = "'" + res.replace(qesc, "\\'") + "'"
834
str.__setitem__ = function(self, attr, value){
835
throw _b_.TypeError.$factory(
836
"'str' object does not support item assignment")
838
var combining = []
839
for(var cp = 0x300; cp <= 0x36F; cp++){
840
combining.push(String.fromCharCode(cp))
841
}
842
var combining_re = new RegExp("(" + combining.join("|") + ")")
854
$comp_func += "" // source code
855
var $comps = {">": "gt", ">=": "ge", "<": "lt", "<=": "le"}
864
var $notimplemented = function(self, other){
865
throw NotImplementedError.$factory(
866
"OPERATOR not implemented for class str")
869
str.capitalize = function(self){
870
var $ = $B.args("capitalize", 1, {self}, ["self"],
871
arguments, {}, null, null)
872
if(self.length == 0){return ""}
873
return self.charAt(0).toUpperCase() + self.substr(1)
874
}
875
876
str.casefold = function(self){
877
var $ = $B.args("casefold", 1, {self}, ["self"],
878
arguments, {}, null, null),
879
res = "",
880
char,
881
cf
882
for(var i = 0, len = self.length; i < len; i++){
883
char = self.charCodeAt(i)
884
cf = $B.unicode_casefold[char]
885
if(cf){
886
cf.forEach(function(cp){
887
res += String.fromCharCode(cp)
888
})
889
}else{
890
res += self.charAt(i).toLowerCase()
891
}
892
}
893
return res
894
}
896
str.center = function(){
897
var $ = $B.args("center", 3, {self: null, width: null, fillchar: null},
898
["self", "width", "fillchar"],
899
arguments, {fillchar:" "}, null, null),
900
self = $.self
912
var $ = $B.args("count", 4, {self:null, sub:null, start:null, stop:null},
913
["self", "sub", "start", "stop"], arguments, {start:null, stop:null},
921
if($.stop !== null){_slice = _b_.slice.$factory($.start, $.stop)}
922
else{_slice = _b_.slice.$factory($.start, $.self.length)}
927
if($.sub.length == 0){
928
if($.start == $.self.length){return 1}
929
else if(substr.length == 0){return 0}
930
return substr.length + 1
932
var n = 0,
933
pos = 0
934
while(pos < substr.length){
935
pos = substr.indexOf($.sub, pos)
936
if(pos >= 0){n++; pos += $.sub.length}
937
else{break}
942
str.encode = function(){
943
var $ = $B.args("encode", 3, {self: null, encoding: null, errors: null},
944
["self", "encoding", "errors"], arguments,
945
{encoding: "utf-8", errors: "strict"}, null, null)
946
if($.encoding == "rot13" || $.encoding == "rot_13"){
951
if(("a" <= char && char <= "m") || ("A" <= char && char <= "M")){
952
res += String.fromCharCode(String.charCodeAt(char) + 13)
953
}else if(("m" < char && char <= "z") ||
954
("M" < char && char <= "Z")){
955
res += String.fromCharCode(String.charCodeAt(char) - 13)
964
// Return True if the string ends with the specified suffix, otherwise
965
// return False. suffix can also be a tuple of suffixes to look for.
966
// With optional start, test beginning at that position. With optional
970
["self", "suffix", "start", "end"],
971
arguments, {start: 0, end: null}, null, null)
978
var s = $.self.substring($.start, $.end)
979
for(var i = 0, len = suffixes.length; i < len; i++){
983
if(suffix.length <= s.length &&
984
s.substr(s.length - suffix.length) == suffix){return true}
990
var $ = $B.args("expandtabs", 2, {self: null, tabsize: null},
991
["self", "tabsize"], arguments, {tabsize: 8}, null, null)
992
var s = $B.$GetInt($.tabsize),
993
col = 0,
994
pos = 0,
995
res = ""
996
if(s == 1){return self.replace(/\t/g," ")}
997
while(pos < self.length){
1005
res += car
1006
col = 0
1007
break
1008
default:
1009
res += car
1010
col++
1011
break
1012
}
1013
pos++
1014
}
1020
// Return the lowest index in the string where substring sub is found,
1021
// such that sub is contained in the slice s[start:end]. Optional
1022
// arguments start and end are interpreted as in slice notation.
1025
{self: null, sub: null, start: null, end: null},
1026
["self", "sub", "start", "end"],
1027
arguments, {start: 0, end: null}, null, null)
1031
if(!isinstance($.start, _b_.int)||!isinstance($.end, _b_.int)){
1032
throw _b_.TypeError.$factory("slice indices must be " +
1033
"integers or None or have an __index__ method")}
1034
// Can't use string.substring(start, end) because if end < start,
1035
// Javascript transforms it into substring(end, start)...
1036
var s = ""
1037
for(var i = $.start; i < $.end; i++){
1038
s += $.self.charAt(i)
1039
}
1041
if($.sub.length == 0 && $.start == $.self.length){return $.self.length}
1042
if(s.length + $.sub.length == 0){return -1}
1044
var last_search = s.length - $.sub.length
1045
for(var i = 0; i <= last_search; i++){
1046
if(s.substr(i, $.sub.length) == $.sub){return $.start + i}
1057
// a.x[z]!r:...
1058
// the object has attributes :
1059
// - name : "a"
1060
// - name_ext : [".x", "[z]"]
1061
// - conv : r
1062
// - spec : rest of string after :
1070
// No : in the string : it only contains a name
1071
name = fmt_string
1072
}else{
1073
// name is before the first ":"
1074
// spec (the format specification) is after
1075
name = elts[0]
1079
var elts = name.split("!")
1080
if(elts.length > 1){
1081
name = elts[0]
1082
conv = elts[1] // conversion flag
1086
// "name' may be a subscription or attribute
1087
// Put these "extensions" in the list "name_ext"
1088
function name_repl(match){
1089
name_ext.push(match)
1091
}
1092
var name_ext_re = /\.[_a-zA-Z][_a-zA-Z0-9]*|\[[_a-zA-Z][_a-zA-Z0-9]*\]|\[[0-9]+\]/g
1093
name = name.replace(name_ext_re, name_repl)
1094
}
1101
// Parse self to detect formatting instructions
1102
// Create a list "parts" made of sections of the string :
1103
// - elements of even rank are literal text
1104
// - elements of odd rank are "format objects", built from the
1105
// format strings in self (of the form {...})
1116
text += "{"
1117
pos += 2
1118
}else if(car == "}" && self.charAt(pos + 1) == "}"){
1125
// Store current literal text
1126
parts.push(text)
1127
1128
// Search the end of the format string, ie the } closing the
1129
// opening {. Since the string can contain other pairs {} for
1130
// nested formatting, an integer nb is incremented for each { and
1131
// decremented for each } ; the end of the format string is
1132
// reached when nb == 0
1133
var end = pos + 1,
1134
nb = 1
1135
while(end < _len){
1136
if(self.charAt(end) == "{"){nb++; end++}
1137
else if(self.charAt(end) == "}"){
1138
nb--; end++
1139
if(nb == 0){
1144
var fmt_obj = $B.parse_format(fmt_string)
1145
fmt_obj.raw_name = fmt_obj.name
1146
fmt_obj.raw_spec = fmt_obj.spec
1181
return parts
1182
}
1183
1184
str.format = function(self) {
1185
var $ = $B.args("format", 1, {self: null}, ["self"],
1186
arguments, {}, "$args", "$kw")
1187
1188
var parts = $B.split_format($.self)
1189
1200
1201
if(fmt.spec !== undefined){
1202
// "spec" may contain "nested replacement fields"
1203
// In this case, evaluate them using the positional
1204
// or keyword arguments passed to format()
1205
function replace_nested(name, key){
1206
if(/\d+/.exec(key)){
1207
// If key is numeric, search in positional
1208
// arguments
1209
return _b_.tuple.__getitem__($.$args,
1210
parseInt(key))
1211
}else{
1212
// Else try in keyword arguments
1213
return _b_.dict.__getitem__($.$kw, key)
1214
}
1215
}
1216
fmt.spec = fmt.spec.replace(/\{(.*?)\}/g,
1217
replace_nested)
1218
}
1220
// Numerical reference : use positional arguments
1221
var pos = parseInt(fmt.name),
1231
// Attribute
1232
value = _b_.getattr(value, ext.substr(1))
1233
}else{
1234
// Subscription
1237
if(key.charAt(0).search(/\d/) > -1){key = parseInt(key)}
1238
value = _b_.getattr(value, "__getitem__")(key)
1242
// If the conversion flag is set, first call a function to convert
1243
// the value
1244
if(fmt.conv == "a"){value = _b_.ascii(value)}
1245
else if(fmt.conv == "r"){value = _b_.repr(value)}
1246
else if(fmt.conv == "s"){value = _b_.str.$factory(value)}
1260
throw NotImplementedError.$factory(
1261
"function format_map not implemented yet")
1272
/* Return true if the string is empty or all characters in the string are
1273
ASCII, false otherwise. ASCII characters have code points in the range
1274
U+0000-U+007F. */
1275
for(var i = 0, len = self.length; i < len; i++){
1276
if(self.charCodeAt(i) > 127){return false}
1277
}
1278
return true
1279
}
1280
1281
str.isalnum = function(self){
1282
/* Return true if all characters in the string are alphanumeric and there
1283
is at least one character, false otherwise. A character c is alphanumeric
1284
if one of the following returns True: c.isalpha(), c.isdecimal(),
1285
c.isdigit(), or c.isnumeric(). */
1286
var $ = $B.args("isalnum", 1, {self: null}, ["self"],
1287
arguments, {}, null, null),
1288
char
1289
for(var i = 0, len = self.length; i < len; i++){
1290
char = self.charCodeAt(i)
1291
if(unicode_tables.Ll[char] ||
1292
unicode_tables.Lu[char] ||
1293
unicode_tables.Lm[char] ||
1294
unicode_tables.Lt[char] ||
1295
unicode_tables.Lo[char] ||
1296
unicode_tables.Nd[char] ||
1297
unicode_tables.digits[char] ||
1298
unicode_tables.numeric[char]){
1299
continue
1300
}
1301
return false
1302
}
1303
return true
1304
}
1305
1306
str.isalpha = function(self){
1307
/* Return true if all characters in the string are alphabetic and there is
1308
at least one character, false otherwise. Alphabetic characters are those
1309
characters defined in the Unicode character database as "Letter", i.e.,
1310
those with general category property being one of "Lm", "Lt", "Lu", "Ll",
1311
or "Lo". */
1312
var $ = $B.args("isalpha", 1, {self: null}, ["self"],
1313
arguments, {}, null, null),
1314
char
1315
for(var i = 0, len = self.length; i < len; i++){
1316
char = self.charCodeAt(i)
1317
if(unicode_tables.Ll[char] ||
1318
unicode_tables.Lu[char] ||
1319
unicode_tables.Lm[char] ||
1320
unicode_tables.Lt[char] ||
1321
unicode_tables.Lo[char]){
1322
continue
1323
}
1324
return false
1325
}
1326
return true
1327
}
1328
1329
str.isdecimal = function(self){
1330
/* Return true if all characters in the string are decimal characters and
1331
there is at least one character, false otherwise. Decimal characters are
1332
those that can be used to form numbers in base 10, e.g. U+0660,
1333
ARABIC-INDIC DIGIT ZERO. Formally a decimal character is a character in
1334
the Unicode General Category "Nd". */
1335
var $ = $B.args("isdecimal", 1, {self: null}, ["self"],
1336
arguments, {}, null, null),
1337
char
1338
for(var i = 0, len = self.length; i < len; i++){
1339
char = self.charCodeAt(i)
1340
if(! unicode_tables.Nd[char]){
1341
return false
1342
}
1343
}
1344
return self.length > 0
1345
}
1346
1347
str.isdigit = function(self){
1348
/* Return true if all characters in the string are digits and there is at
1349
least one character, false otherwise. */
1350
var $ = $B.args("isdigit", 1, {self: null}, ["self"],
1351
arguments, {}, null, null),
1352
char
1353
for(var i = 0, len = self.length; i < len; i++){
1354
char = self.charCodeAt(i)
1355
if(! unicode_tables.digits[char]){
1356
return false
1357
}
1358
}
1359
return self.length > 0
1360
}
1361
1362
str.isidentifier = function(self){
1363
/* Return true if the string is a valid identifier according to the
1364
language definition. */
1365
var $ = $B.args("isidentifier", 1, {self: null}, ["self"],
1366
arguments, {}, null, null),
1367
char
1368
if(self.length == 0){return false}
1369
else if(unicode_tables.XID_Start[self.charCodeAt(0)] === undefined){
1370
return false
1371
}else{
1372
for(var i = 1, len = self.length; i < len; i++){
1373
if(unicode_tables.XID_Continue[self.charCodeAt(i)] === undefined){
1374
return false
1375
}
1376
}
1377
}
1378
return true
1379
}
1380
1381
str.islower = function(self){
1382
/* Return true if all cased characters 4 in the string are lowercase and
1383
there is at least one cased character, false otherwise. */
1384
var $ = $B.args("islower", 1, {self: null}, ["self"],
1385
arguments, {}, null, null),
1386
has_cased = false,
1387
char
1388
1389
for(var i = 0, len = self.length; i < len; i++){
1390
char = self.charCodeAt(i)
1391
if(unicode_tables.Ll[char]){has_cased = true; continue}
1392
else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1393
return false
1394
}
1395
}
1396
return has_cased
1397
}
1398
1399
str.isnumeric = function(self){
1400
/* Return true if all characters in the string are numeric characters, and
1401
there is at least one character, false otherwise. Numeric characters
1402
include digit characters, and all characters that have the Unicode numeric
1403
value property, e.g. U+2155, VULGAR FRACTION ONE FIFTH. Formally, numeric
1404
characters are those with the property value Numeric_Type=Digit,
1405
Numeric_Type=Decimal or Numeric_Type=Numeric.*/
1406
var $ = $B.args("isnumeric", 1, {self: null}, ["self"],
1407
arguments, {}, null, null)
1408
for(var i = 0, len = self.length; i < len; i++){
1409
if(! unicode_tables.numeric[self.charCodeAt(i)]){
1410
return false
1411
}
1412
}
1413
return self.length > 0
1414
}
1415
1416
var printable,
1417
printable_gc = ['Cc', 'Cf', 'Co', 'Cs','Zl', 'Zp', 'Zs']
1418
1419
str.isprintable = function(self){
1420
/* Return true if all characters in the string are printable or the string
1421
is empty, false otherwise. Nonprintable characters are those characters
1422
defined in the Unicode character database as "Other" or "Separator",
1423
excepting the ASCII space (0x20) which is considered printable. */
1424
1425
// Set printable if not set yet
1426
if(printable === undefined){
1427
for(var i = 0; i < printable_gc.length; i++){
1428
var table = unicode_tables[printable_gc[i]]
1429
for(var cp in table){
1430
printable[cp] = true
1431
}
1432
}
1433
printable[32] = true
1434
}
1435
1436
var $ = $B.args("isprintable", 1, {self: null}, ["self"],
1437
arguments, {}, null, null),
1438
char,
1439
flag
1440
for(var i = 0, len = self.length; i < len; i++){
1441
char = self.charCodeAt(i)
1442
if(! printable[char]){
1443
return false
1444
}
1445
}
1446
return true
1447
}
1448
1449
str.isspace = function(self){
1450
/* Return true if there are only whitespace characters in the string and
1451
there is at least one character, false otherwise.
1452
1453
A character is whitespace if in the Unicode character database, either its
1454
general category is Zs ("Separator, space"), or its bidirectional class is
1455
one of WS, B, or S.*/
1456
var $ = $B.args("isspace", 1, {self: null}, ["self"],
1457
arguments, {}, null, null),
1458
char
1459
for(var i = 0, len = self.length; i < len; i++){
1460
char = self.charCodeAt(i)
1461
if(! unicode_tables.Zs[char] &&
1462
$B.unicode_bidi_whitespace.indexOf(char) == -1){
1463
return false
1464
}
1465
}
1466
return self.length > 0
1467
}
1468
1469
str.istitle = function(self){
1470
/* Return true if the string is a titlecased string and there is at least
1471
one character, for example uppercase characters may only follow uncased
1472
characters and lowercase characters only cased ones. Return false
1473
otherwise. */
1474
var $ = $B.args("istitle", 1, {self: null}, ["self"],
1475
arguments, {}, null, null)
1476
return self.length > 0 && str.title(self) == self
1477
}
1478
1479
str.isupper = function(self){
1480
/* Return true if all cased characters 4 in the string are lowercase and
1481
there is at least one cased character, false otherwise. */
1482
var $ = $B.args("islower", 1, {self: null}, ["self"],
1483
arguments, {}, null, null),
1484
has_cased = false,
1485
char
1486
1487
for(var i = 0, len = self.length; i < len; i++){
1488
char = self.charCodeAt(i)
1489
if(unicode_tables.Lu[char]){has_cased = true; continue}
1490
else if(unicode_tables.Ll[char] || unicode_tables.Lt[char]){
1508
if(! isinstance(obj2, str)){throw _b_.TypeError.$factory(
1509
"sequence item " + count + ": expected str instance, " +
1523
var $ = $B.args("ljust", 3, {self: null, width: null, fillchar:null},
1524
["self", "width", "fillchar"],
1525
arguments, {fillchar: " "}, null, null)
1531
str.lower = function(self){
1532
var $ = $B.args("lower", 1, {self: null}, ["self"],
1533
arguments, {}, null, null)
1534
return self.toLowerCase()
1535
}
1536
1538
var $ = $B.args("lstrip", 2, {self: null, chars: null}, ["self", "chars"],
1539
arguments, {chars:_b_.None}, null, null)
1540
if($.chars === _b_.None){return $.self.trimLeft()}
1541
for(var i = 0; i < $.self.length; i++){
1542
if($.chars.indexOf($.self.charAt(i)) === -1){
1543
return $.self.substring(i)
1551
var $ = $B.args("maketrans", 3, {x: null, y: null, z: null},
1552
["x", "y", "z"], arguments, {y: null, z: null}, null, null)
1557
// If there is only one argument, it must be a dictionary mapping
1558
// Unicode ordinals (integers) or characters (strings of length 1) to
1559
// Unicode ordinals, strings (of arbitrary lengths) or None. Character
1561
if(! _b_.isinstance($.x, _b_.dict)){
1562
throw _b_.TypeError.$factory(
1563
"maketrans only argument must be a dict")
1566
for(var i = 0, len = items.length; i < len; i++){
1567
var k = items[i][0],
1568
v = items[i][1]
1569
if(! _b_.isinstance(k, _b_.int)){
1570
if(_b_.isinstance(k, _b_.str) && k.length == 1){
1571
k = _b_.ord(k)
1572
}else{throw _b_.TypeError.$factory("dictionary key " + k +
1575
if(v !== _b_.None && ! _b_.isinstance(v, [_b_.int, _b_.str])){
1576
throw _b_.TypeError.$factory("dictionary value " + v +
1584
// and in the resulting dictionary, each character in x will be mapped
1585
// to the character at the same position in y
1588
}else if($.x.length !== $.y.length){
1589
throw _b_.TypeError.$factory(
1590
"maketrans arguments must be strings or same length")
1596
if(! _b_.isinstance($.z, _b_.str)){
1597
throw _b_.TypeError.$factory(
1598
"maketrans third argument must be a string")
1620
var $ = $B.args("partition", 2, {self: null, sep: null}, ["self", "sep"],
1621
arguments, {}, null, null)
1626
return _b_.tuple.$factory([$.self.substring(0, i), $.sep,
1627
$.self.substring(i + $.sep.length)])
1628
}
1629
1630
function $re_escape(str){
1631
var specials = "[.*+?|()$^"
1632
for(var i = 0, len = specials.length; i < len; i++){
1633
var re = new RegExp("\\"+specials.charAt(i), "g")
1634
str = str.replace(re, "\\"+specials.charAt(i))
1635
}
1636
return str
1643
var $ = $B.args("replace", 4,
1644
{self: null, old: null, $$new: null, count: null},
1645
["self", "old", "$$new", "count"],
1646
arguments, {count: -1}, null, null),
1647
count = $.count,
1648
self = $.self,
1649
old = $.old,
1650
_new = $.$$new
1657
"' object cannot be interpreted as an integer")
1658
}else if(isinstance(count, _b_.float)){
1659
throw _b_.TypeError.$factory("integer argument expected, got float")
1660
}
1661
if(count == 0){return self}
1662
if(count.__class__ == $B.long_int){count = parseInt(count.value)}
1663
if(old == ""){
1664
if(_new == ""){return self}
1665
if(self == ""){return _new}
1666
var elts = self.split("")
1667
if(count > -1 && elts.length >= count){
1668
var rest = elts.slice(count).join("")
1669
return _new + elts.slice(0, count).join(_new) + rest
1670
}else{return _new + elts.join(_new) + _new}
1685
if(count < 0){count = res.length}
1686
while(count > 0){
1687
pos = res.indexOf(old, pos)
1688
if(pos < 0){break}
1689
res = res.substr(0, pos) + _new + res.substr(pos + old.length)
1690
pos = pos + _new.length
1691
count--
1697
// Return the highest index in the string where substring sub is found,
1698
// such that sub is contained within s[start:end]. Optional arguments
1700
if(arguments.length == 2 && typeof substr == "string"){
1701
return self.lastIndexOf(substr)
1702
}
1704
{self: null, sub: null, start: null, end: null},
1705
["self", "sub", "start", "end"],
1706
arguments, {start: 0, end: null}, null, null)
1718
for(var i = $.end - sublen; i >= $.start; i--){
1719
if($.self.substr(i, sublen) == $.sub){return i}
1726
var res = str.rfind.apply(null, arguments)
1727
if(res == -1){throw _b_.ValueError.$factory("substring not found")}
1732
var $ = $B.args("rjust",3,
1733
{self: null, width: null, fillchar: null},
1734
["self", "width", "fillchar"],
1735
arguments, {fillchar: " "}, null, null)
1743
var $ = $B.args("rpartition", 2, {self: null, sep: null}, ["self", "sep"],
1744
arguments, {}, null, null)
1748
var items = str.partition(self, sep).reverse()
1749
for(var i = 0; i < items.length; i++){
1750
items[i] = items[i].split("").reverse().join("")
1756
var $ = $B.args("rsplit", 3, {self: null, sep: null, maxsplit: null},
1757
["self", "sep", "maxsplit"], arguments,
1758
{sep: _b_.None, maxsplit: -1}, null, null),
1759
sep = $.sep
1762
var rev_str = reverse($.self),
1763
rev_sep = sep === _b_.None ? sep : reverse($.sep),
1774
str.rstrip = function(self, x){
1775
var $ = $B.args("rstrip", 2, {self: null, chars: null}, ["self", "chars"],
1776
arguments, {chars: _b_.None}, null, null)
1777
if($.chars === _b_.None){return $.self.trimRight()}
1779
if($.chars.indexOf($.self.charAt(j)) == -1){
1780
return $.self.substring(0, j + 1)
1787
var $ = $B.args("split", 3, {self: null, sep: null, maxsplit: null},
1788
["self", "sep", "maxsplit"], arguments,
1789
{sep: _b_.None, maxsplit: -1}, null, null),
1790
sep = $.sep,
1791
maxsplit = $.maxsplit,
1792
self = $.self,
1793
pos = 0
1794
if(maxsplit.__class__ === $B.long_int){maxsplit = parseInt(maxsplit.value)}
1795
if(sep == ""){throw _b_.ValueError.$factory("empty separator")}
1796
if(sep === _b_.None){
1798
while(pos < self.length && self.charAt(pos).search(/\s/) > -1){pos++}
1799
if(pos === self.length - 1){return [self]}
1800
var name = ""
1802
if(self.charAt(pos).search(/\s/) == -1){
1803
if(name == ""){name = self.charAt(pos)}
1804
else{name += self.charAt(pos)}
1824
var res = [],
1825
s = "",
1826
seplen = sep.length
1827
if(maxsplit == 0){return [self]}
1828
while(pos < self.length){
1829
if(self.substr(pos, seplen) == sep){
1847
str.splitlines = function(self) {
1848
var $ = $B.args('splitlines', 2, {self: null, keepends: null},
1849
['self','keepends'], arguments, {keepends: false},
1850
null, null)
1851
if(!_b_.isinstance($.keepends,[_b_.bool, _b_.int])){
1852
throw _b_.TypeError('integer argument expected, got '+
1855
var keepends = _b_.int.$factory($.keepends),
1856
res = [],
1857
self = $.self,
1858
start = 0,
1859
pos = 0
1860
if(!self.length){
1863
while (pos < self.length) {
1864
if(self.substr(pos, 2) == '\r\n'){
1865
res.push(self.slice(start, keepends ? pos + 2 : pos))
1866
start = pos = pos+2
1867
}else if(self[pos] == '\r' || self[pos] == '\n'){
1868
res.push(self.slice(start, keepends ? pos+1 : pos))
1869
start = pos = pos+1
1870
}else{
1871
pos++
1872
}
1873
}
1874
if(start < self.length){
1875
res.push(self.slice(start))
1876
}
1877
return res
1881
// Return True if string starts with the prefix, otherwise return False.
1882
// prefix can also be a tuple of prefixes to look for. With optional
1883
// start, test string beginning at that position. With optional end,
1885
var $ = $B.args("startswith", 4,
1886
{self: null, prefix: null, start: null, end: null},
1887
["self", "prefix", "start", "end"],
1888
arguments, {start: 0, end: null}, null, null)
1895
var s = $.self.substring($.start, $.end)
1896
for(var i = 0, len = prefixes.length; i < len; i++){
1907
var $ = $B.args("strip", 2, {self: null, chars: null}, ["self", "chars"],
1908
arguments, {chars: _b_.None}, null, null)
1909
if($.chars === _b_.None){return $.self.trim()}
1910
for(var i = 0; i < $.self.length; i++){
1911
if($.chars.indexOf($.self.charAt(i)) == -1){
1912
break
1915
for(var j = $.self.length - 1; j >= i; j--){
1916
if($.chars.indexOf($.self.charAt(j)) == -1){
1917
break
1923
str.swapcase = function(self){
1924
var $ = $B.args("swapcase", 1, {self}, ["self"],
1925
arguments, {}, null, null),
1926
res = "",
1927
char
1928
1929
for(var i = 0, len = self.length; i < len; i++){
1930
char = self.charCodeAt(i)
1931
if(unicode_tables.Ll[char]){
1932
res += self.charAt(i).toUpperCase()
1933
}else if(unicode_tables.Lu[char]){
1934
res += self.charAt(i).toLowerCase()
1935
}else{
1936
res += self.charAt(i)
1937
}
1938
}
1939
return res
1940
}
1941
1942
str.title = function(self){
1943
var $ = $B.args("title", 1, {self}, ["self"],
1944
arguments, {}, null, null),
1945
state,
1946
char,
1947
res = ""
1948
for(var i = 0, len = self.length; i < len; i++){
1949
char = self.charCodeAt(i)
1950
if(unicode_tables.Ll[char]){
1951
if(! state){
1952
res += self.charAt(i).toUpperCase()
1953
state = "word"
1954
}else{
1955
res += self.charAt(i)
1956
}
1957
}else if(unicode_tables.Lu[char] || unicode_tables.Lt[char]){
1958
res += state ? self.charAt(i).toLowerCase() : self.charAt(i)
1959
state = "word"
1960
}else{
1961
state = null
1962
res += self.charAt(i)
1963
}
1964
}
1965
return res
1966
}
1967
1970
getitem = $B.$getattr(table, "__getitem__")
1971
for(var i = 0, len = self.length; i < len; i++){
1972
try{
1973
var repl = getitem(self.charCodeAt(i))
1974
if(repl !== _b_.None){
1975
if(typeof repl == "string"){
1976
res.push(repl)
1977
}else if(typeof repl == "number"){
1978
res.push(String.fromCharCode(repl))
1979
}
1988
str.upper = function(self){
1989
var $ = $B.args("upper", 1, {self: null}, ["self"],
1990
arguments, {}, null, null)
1991
return self.toUpperCase()
1992
}
1993
1996
["self", "width"], arguments, {}, null, null)
1997
if($.width <= self.length){return self}
1999
case "+":
2000
case "-":
2001
return self.charAt(0) +
2002
"0".repeat($.width - self.length) + self.substr(1)
2013
if(encoding !== undefined){
2014
// Arguments may be passed as keywords (cf. issue #1060)
2015
var $ = $B.args("str", 3, {arg: null, encoding: null, errors: null},
2016
["arg", "encoding", "errors"], arguments,
2017
{encoding: "utf-8", errors: "strict"}, null, null),
2018
encoding = $.encoding,
2019
errors = $.errors
2020
}
2031
// class or its subclasses, but the attribute __str__ of the
2032
// class metaclass (usually "type") or its subclasses (usually
2033
// "object")
2034
// The metaclass is the attribute __class__ of the class dictionary
2039
if(arg.__class__ && arg.__class__ === _b_.bytes &&
2040
encoding !== undefined){
2041
// str(bytes, encoding, errors) is equal to
2042
// bytes.decode(encoding, errors)
2045
// Implicit invocation of __str__ uses method __str__ on the class,
2046
// even if arg has an attribute __str__
2047
var klass = arg.__class__ || $B.get_class(arg)
2048
if(klass === undefined){
2049
return $B.JSObject.__str__($B.JSObject.$factory(arg))
2050
}
2053
// if not better than object.__str__, try __repr__
2054
(arg.__class__ && arg.__class__ !== _b_.object &&
2055
method.$infos && method.$infos.__func__ === _b_.object.__str__)){
2056
var method = $B.$getattr(klass, "__repr__")
2062
if($B.debug > 1){console.log(err)}
2063
console.log("Warning - no method __str__ or __repr__, " +
2064
"default to toString", arg)
2071
if(cls === undefined){
2072
throw _b_.TypeError.$factory("str.__new__(): not enough arguments")
2096
var args = [],
2097
pos = 0
2098
if(arguments.length > 0){
2099
var args = [arguments[0].valueOf()],
2100
pos = 1
2101
for(var i = 1, len = arguments.length; i < len; i++){
2102
args[pos++] = arguments[i]
2118
// Function to parse the 2nd argument of format()
2119
$B.parse_format_spec = function(spec){
2122
var pos = 0,
2123
aligns = "<>=^",
2124
digits = "0123456789",
2125
types = "bcdeEfFgGnosxX%",
2127
if(align_pos != -1){
2128
if(spec.charAt(1) && aligns.indexOf(spec.charAt(1)) != -1){
2129
// If the second char is also an alignment specifier, the
2130
// first char is the fill value
2131
this.fill = spec.charAt(0)
2132
this.align = spec.charAt(1)
2133
pos = 2
2134
}else{
2135
// The first character defines alignment : fill defaults to ' '
2150
if(car == "+" || car == "-" || car == " "){
2151
this.sign = car
2152
pos++
2153
car = spec.charAt(pos)
2155
if(car == "#"){this.alternate = true; pos++; car = spec.charAt(pos)}
2156
if(car == "0"){
2165
while(car && digits.indexOf(car) > -1){
2166
if(this.width === undefined){this.width = car}
2167
else{this.width += car}
2168
pos++
2169
car = spec.charAt(pos)
2172
if(this.width === undefined && car == "{"){
2173
// Width is determined by a parameter
2174
var end_param_pos = spec.substr(pos).search("}")
2175
this.width = spec.substring(pos, end_param_pos)
2176
console.log("width", "[" + this.width + "]")
2177
pos += end_param_pos + 1
2178
}
2179
if(car == ","){this.comma = true; pos++; car = spec.charAt(pos)}
2180
if(car == "."){
2181
if(digits.indexOf(spec.charAt(pos + 1)) == -1){
2182
throw _b_.ValueError.$factory(
2183
"Missing precision in format spec")
2185
this.precision = spec.charAt(pos + 1)
2186
pos += 2
2187
car = spec.charAt(pos)
2188
while(car && digits.indexOf(car) > -1){
2195
if(car && types.indexOf(car) > -1){
2196
this.type = car
2197
pos++
2198
car = spec.charAt(pos)
2199
}
2200
if(pos !== spec.length){
2206
return (this.fill === undefined ? "" : _b_.str.$factory(this.fill)) +
2207
(this.align || "") +
2208
(this.sign || "") +
2209
(this.alternate ? "#" : "") +
2210
(this.sign_aware ? "0" : "") +
2211
(this.width || "") +
2212
(this.comma ? "," : "") +
2213
(this.precision ? "." + this.precision : "") +
2214
(this.type || "")
2219
if(fmt.width && s.length < fmt.width){
2220
var fill = fmt.fill || " ",
2221
align = fmt.align || "<",
2222
missing = fmt.width - s.length
2224
case "<":
2225
return s + fill.repeat(missing)
2226
case ">":
2227
return fill.repeat(missing) + s
2228
case "=":
2229
if("+-".indexOf(s.charAt(0)) > -1){
2230
return s.charAt(0) + fill.repeat(missing) + s.substr(1)
2234
case "^":
2235
var left = parseInt(missing / 2)
2236
return fill.repeat(left) + s + fill.repeat(missing - left)
2249
$B.parse_fstring = function(string){
2250
// Parse a f-string
2251
var elts = [],
2252
pos = 0,
2276
}else{
2277
throw Error(" f-string: single '}' is not allowed")
2278
}
2279
}else{
2301
current += car
2302
i += 2
2303
}else{
2304
throw Error(" f-string: single '}' is not allowed")
2305
}
2306
}else{
2307
current += car
2308
i++
2309
}
2310
}
2312
}else if(ctype == "debug"){
2313
// after the equal sign, whitespace are ignored and the only
2314
// valid characters are } and :
2315
while(string.charAt(i) == " "){i++}
2316
if(string.charAt(i) == "}"){
2317
// end of debug expression
2318
elts.push(current)
2319
ctype = null
2320
current = ""
2321
pos = i + 1
2322
}
2323
}else{
2324
// End of expression is the } matching the opening {
2325
// There may be nested braces
2326
var i = pos,
2327
nb_braces = 1,
2349
// backslash is not allowed in expressions
2350
throw Error("f-string expression part cannot include a" +
2351
" backslash")
2358
throw Error("f-string: invalid conversion character:" +
2359
" expected 's', 'r', or 'a'")
2360
}else{
2374
if(string.substr(i, 3) == '"""'){
2375
var end = string.indexOf('"""', i + 3)
2376
if(end == -1){
2377
throw Error("f-string: unterminated string")
2378
}else{
2379
var trs = string.substring(i, end + 3)
2380
trs = trs.replace("\n", "\\n\\")
2385
var end = string.indexOf('"', i + 1)
2386
if(end == -1){
2387
throw Error("f-string: unterminated string")
2388
}else{
2389
current.expression += string.substring(i, end + 1)
2390
i = end + 1
2397
}else if(car == "="){
2398
// might be a "debug expression", eg f"{x=}"
2399
var ce = current.expression
2400
if(ce.length == 0 ||
2401
string.charAt(i + 1) == "=" ||
2402
"=!<>:".search(ce.charAt(ce.length - 1)) > -1){
2405
}else{
2406
// add debug string
2407
tail = car
2408
while(string.charAt(i + 1).match(/\s/)){
2409
tail += string.charAt(i + 1)
2410
i++
2411
}
2412
elts.push(current.expression + tail)
2413
// remove trailing whitespace from expression
2414
while(ce.match(/\s$/)){
2415
ce = ce.substr(0, ce.length - 1)
2416
}
2417
current.expression = ce
2418
ctype = "debug"
2419
i++
2420
}
2435
// Class for strings with surrogate pairs. We can't rely on Javascript
2436
// strings in this case because they don't count characters like Python
2437
2438
var surrogate = str.$surrogate = $B.make_class("surrogate_string", function(s){
2439
// create an instance of str subclass for strings with surrogate pairs
2440
var items = []
2441
for(var i = 0, len = s.length; i < len; i++){
2442
var code = s.charCodeAt(i)
2443
if(code >= 0xD800 && code <= 0xDBFF){
2444
i++
2445
var low = s.charCodeAt(i)
2446
code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000
2447
}
2448
items.push(String.fromCodePoint(code))
2449
}
2450
return {
2451
__class__: str.$surrogate,
2452
items: items
2453
}
2454
})
2455
2456
surrogate.__mro__ = [str, object]
2457
2458
surrogate.__contains__ = function(self, other){
2459
return str.__contains__(self.items.join(''), other)
2460
}
2461
2462
surrogate.__getitem__ = function(self, arg){
2463
if(isinstance(arg, _b_.int)){
2464
var pos = arg
2465
if(arg < 0){
2466
pos += self.items.length
2467
}
2468
if(pos >= 0 && pos < self.items.length){
2469
if(self.items[pos].length == 2){
2470
return surrogate.$factory(self.items[pos])
2471
}
2472
return self.items[pos]
2473
}
2474
throw _b_.IndexError.$factory("string index out of range")
2475
}
2476
if(isinstance(arg, slice)) {
2477
var s = _b_.slice.$conv_for_seq(arg, self.items.length),
2478
start = s.start,
2479
stop = s.stop,
2480
step = s.step
2481
var res = "",
2482
i = null
2483
if(step > 0){
2484
if(stop <= start){return ""}
2485
for(var i = start; i < stop; i += step){
2486
res += self.items[i]
2487
}
2488
}else{
2489
if(stop >= start){return ''}
2490
for(var i = start; i > stop; i += step){
2491
res += self.items[i]
2492
}
2493
}
2494
return res
2495
}
2496
if(isinstance(arg, _b_.bool)){
2497
return surrogate.__getitem__(self, _b_.int.$factory(arg))
2498
}
2499
throw _b_.TypeError.$factory("string indices must be integers")
2500
}
2501
2502
surrogate.__hash__ = function(self){
2503
return str.__hash__(self.items.join(''))
2504
}
2505
2506
surrogate.__iter__ = function(self){
2507
return str_iterator.$factory(self.items)
2508
}
2509
2510
surrogate.__len__ = function(self){
2511
return self.items.length
2512
}
2513
2514
surrogate.__repr__ = function(self){
2515
return str.__repr__(self.items.join(''))
2516
}
2517
2518
surrogate.__str__ = function(self){
2519
return str.__str__(self.items.join(''))
2520
}
2521
2522
$B.set_func_names(surrogate, "builtins")
2523
2524